Compare commits

..

411 Commits

Author SHA1 Message Date
hank
cf37c9a93c New translations en.po (Indonesian) 2025-11-14 17:51:43 -05:00
hank
402d1d9fec New translations en.po (Hebrew) 2025-11-14 17:51:41 -05:00
hank
b4f2afa4b6 New translations en.po (Chinese Traditional, Hong Kong) 2025-11-14 17:51:40 -05:00
hank
beff2eb43f New translations en.po (Persian) 2025-11-14 17:51:39 -05:00
hank
2e0d12a02d New translations en.po (Vietnamese) 2025-11-14 17:51:38 -05:00
hank
bc2fd34ac5 New translations en.po (Chinese Simplified) 2025-11-14 17:51:37 -05:00
hank
333cfae109 New translations en.po (Ukrainian) 2025-11-14 17:51:36 -05:00
hank
8cf8dd492d New translations en.po (Turkish) 2025-11-14 17:51:35 -05:00
hank
9b664b6400 New translations en.po (Swedish) 2025-11-14 17:51:34 -05:00
hank
c30d2fbe39 New translations en.po (Slovenian) 2025-11-14 17:51:33 -05:00
hank
f1a4fae659 New translations en.po (Russian) 2025-11-14 17:51:32 -05:00
hank
32675e403f New translations en.po (Polish) 2025-11-14 17:51:31 -05:00
hank
d92d67eece New translations en.po (Korean) 2025-11-14 17:51:30 -05:00
hank
ed1fc63ce2 New translations en.po (Japanese) 2025-11-14 17:51:29 -05:00
hank
0e2b1675fa New translations en.po (Italian) 2025-11-14 17:51:28 -05:00
hank
ee8f901918 New translations en.po (Danish) 2025-11-14 17:51:27 -05:00
hank
7dc2a86b1e New translations en.po (Czech) 2025-11-14 17:51:26 -05:00
hank
51699ddc12 New translations en.po (Bulgarian) 2025-11-14 17:51:25 -05:00
hank
e0675567b8 New translations en.po (Arabic) 2025-11-14 17:51:24 -05:00
hank
61b3102eda New translations en.po (Spanish) 2025-11-14 17:51:23 -05:00
hank
7cc8f2b933 New translations en.po (Romanian) 2025-11-14 17:51:22 -05:00
hank
d38e3eab9c New translations en.po (Croatian) 2025-11-14 17:51:21 -05:00
hank
4ceb06b0c5 New translations en.po (Chinese Traditional) 2025-11-14 17:51:19 -05:00
hank
b1a468a0ab New translations en.po (Portuguese) 2025-11-14 17:51:18 -05:00
hank
c6755183a8 New translations en.po (Norwegian) 2025-11-14 17:51:17 -05:00
hank
cdc9f11ac0 New translations en.po (Dutch) 2025-11-14 17:51:16 -05:00
hank
6ccaaee57e New translations en.po (Hungarian) 2025-11-14 17:51:15 -05:00
hank
214ee4a75a New translations en.po (German) 2025-11-14 17:51:14 -05:00
hank
a506d3c84a New translations en.po (French) 2025-11-14 17:51:13 -05:00
hank
812e849769 New translations en.po (Spanish) 2025-11-14 12:09:18 -05:00
hank
774eef1f3f New translations en.po (Polish) 2025-11-13 09:52:30 -05:00
hank
fc85c50f2f New translations en.po (Indonesian) 2025-11-12 15:36:57 -05:00
hank
fad22eee61 New translations en.po (Hebrew) 2025-11-12 15:36:56 -05:00
hank
e84dbd639b New translations en.po (Chinese Traditional, Hong Kong) 2025-11-12 15:36:55 -05:00
hank
2dd59b4e11 New translations en.po (Persian) 2025-11-12 15:36:54 -05:00
hank
bb649971dc New translations en.po (Vietnamese) 2025-11-12 15:36:53 -05:00
hank
3f82ee0330 New translations en.po (Chinese Simplified) 2025-11-12 15:36:52 -05:00
hank
a26fde66e6 New translations en.po (Ukrainian) 2025-11-12 15:36:51 -05:00
hank
ed9b576bde New translations en.po (Turkish) 2025-11-12 15:36:49 -05:00
hank
aea463f5da New translations en.po (Swedish) 2025-11-12 15:36:48 -05:00
hank
45e00c70ab New translations en.po (Slovenian) 2025-11-12 15:36:47 -05:00
hank
7fc4655f13 New translations en.po (Russian) 2025-11-12 15:36:46 -05:00
hank
7dcaeaa2b4 New translations en.po (Polish) 2025-11-12 15:36:45 -05:00
hank
d07293bf1a New translations en.po (Korean) 2025-11-12 15:36:44 -05:00
hank
38298bbeab New translations en.po (Japanese) 2025-11-12 15:36:43 -05:00
hank
0124ccfac1 New translations en.po (Italian) 2025-11-12 15:36:42 -05:00
hank
5f62ebcd7b New translations en.po (Danish) 2025-11-12 15:36:41 -05:00
hank
ac354e9d6b New translations en.po (Czech) 2025-11-12 15:36:40 -05:00
hank
5572cad7f6 New translations en.po (Bulgarian) 2025-11-12 15:36:39 -05:00
hank
5fa6a7c4e4 New translations en.po (Arabic) 2025-11-12 15:36:37 -05:00
hank
0f9442eaf8 New translations en.po (Spanish) 2025-11-12 15:36:36 -05:00
hank
6094d8d92d New translations en.po (Romanian) 2025-11-12 15:36:35 -05:00
hank
1469710166 New translations en.po (Croatian) 2025-11-12 15:36:34 -05:00
hank
c1df7edddc New translations en.po (Chinese Traditional) 2025-11-12 15:36:33 -05:00
hank
e70f06285c New translations en.po (Portuguese) 2025-11-12 15:36:32 -05:00
hank
c5efa9b20c New translations en.po (Norwegian) 2025-11-12 15:36:31 -05:00
hank
29a948ece4 New translations en.po (Dutch) 2025-11-12 15:36:30 -05:00
hank
d9b587c67b New translations en.po (Hungarian) 2025-11-12 15:36:28 -05:00
hank
f806ae58b6 New translations en.po (German) 2025-11-12 15:36:27 -05:00
hank
8b5dd8dedd New translations en.po (French) 2025-11-12 15:36:26 -05:00
hank
222e5addef New translations en.po (French) 2025-11-11 14:25:02 -05:00
hank
21e7bae720 New translations en.po (Romanian) 2025-11-10 20:21:58 -05:00
hank
a13d90d794 New translations en.po (Swedish) 2025-11-09 20:57:18 -05:00
hank
6e900d0f26 New translations en.po (Portuguese) 2025-11-08 18:43:12 -05:00
hank
112f1853ee New translations en.po (Swedish) 2025-11-06 10:06:27 -05:00
hank
7aa9e3a6d3 New translations en.po (Spanish) 2025-11-05 13:06:57 -05:00
hank
6e9bc6a53b New translations en.po (French) 2025-11-05 10:16:19 -05:00
hank
12eb884b1e New translations en.po (Indonesian) 2025-11-04 18:47:36 -05:00
hank
270afa1c00 New translations en.po (Hebrew) 2025-11-04 18:47:35 -05:00
hank
35505f2d50 New translations en.po (Chinese Traditional, Hong Kong) 2025-11-04 18:47:34 -05:00
hank
5a28ba3a74 New translations en.po (Persian) 2025-11-04 18:47:33 -05:00
hank
08d9126883 New translations en.po (Vietnamese) 2025-11-04 18:47:32 -05:00
hank
e9829229b6 New translations en.po (Chinese Simplified) 2025-11-04 18:47:31 -05:00
hank
6d7bb7ceee New translations en.po (Ukrainian) 2025-11-04 18:47:30 -05:00
hank
60a8b06b72 New translations en.po (Turkish) 2025-11-04 18:47:29 -05:00
hank
c4a145836b New translations en.po (Swedish) 2025-11-04 18:47:28 -05:00
hank
ea37451c98 New translations en.po (Slovenian) 2025-11-04 18:47:27 -05:00
hank
1faad84cc2 New translations en.po (Russian) 2025-11-04 18:47:26 -05:00
hank
d0b6200c5b New translations en.po (Polish) 2025-11-04 18:47:25 -05:00
hank
fb66760665 New translations en.po (Korean) 2025-11-04 18:47:24 -05:00
hank
480f1596bb New translations en.po (Japanese) 2025-11-04 18:47:23 -05:00
hank
6c11e2954e New translations en.po (Italian) 2025-11-04 18:47:22 -05:00
hank
6a5f6530ef New translations en.po (Danish) 2025-11-04 18:47:21 -05:00
hank
a4ee88bf7f New translations en.po (Czech) 2025-11-04 18:47:20 -05:00
hank
d9f1f06b15 New translations en.po (Bulgarian) 2025-11-04 18:47:19 -05:00
hank
4c00988a37 New translations en.po (Arabic) 2025-11-04 18:47:18 -05:00
hank
193fbe9d31 New translations en.po (Spanish) 2025-11-04 18:47:17 -05:00
hank
ca6b6394ef New translations en.po (Romanian) 2025-11-04 18:47:16 -05:00
hank
1600b94846 New translations en.po (Croatian) 2025-11-04 18:47:15 -05:00
hank
b5aa66224a New translations en.po (Chinese Traditional) 2025-11-04 18:47:15 -05:00
hank
5a14eafae5 New translations en.po (Portuguese) 2025-11-04 18:47:14 -05:00
hank
0b11dcdb1b New translations en.po (Norwegian) 2025-11-04 18:47:13 -05:00
hank
fc1c135e71 New translations en.po (Dutch) 2025-11-04 18:47:12 -05:00
hank
7cb6966335 New translations en.po (Hungarian) 2025-11-04 18:47:11 -05:00
hank
c090cf9e3e New translations en.po (German) 2025-11-04 18:47:10 -05:00
hank
224bce7616 New translations en.po (French) 2025-11-04 18:47:09 -05:00
hank
7fc3afb82b New translations en.po (Spanish) 2025-11-04 17:13:09 -05:00
hank
affdd66065 New translations en.po (Portuguese) 2025-11-04 17:13:06 -05:00
hank
466c5a237b New translations en.po (Portuguese) 2025-11-02 10:12:47 -05:00
hank
827758c97f New translations en.po (Spanish) 2025-11-02 01:32:54 -05:00
hank
fb4a35b054 New translations en.po (Indonesian) 2025-11-01 15:01:34 -04:00
hank
ba561ec34c New translations en.po (Hebrew) 2025-11-01 15:01:33 -04:00
hank
a94f85794c New translations en.po (Chinese Traditional, Hong Kong) 2025-11-01 15:01:32 -04:00
hank
aa408f82c6 New translations en.po (Persian) 2025-11-01 15:01:31 -04:00
hank
e8045a3438 New translations en.po (Vietnamese) 2025-11-01 15:01:30 -04:00
hank
7afd678f54 New translations en.po (Chinese Simplified) 2025-11-01 15:01:28 -04:00
hank
77e2b98470 New translations en.po (Ukrainian) 2025-11-01 15:01:27 -04:00
hank
70e894caf4 New translations en.po (Turkish) 2025-11-01 15:01:26 -04:00
hank
433bd6dde1 New translations en.po (Swedish) 2025-11-01 15:01:25 -04:00
hank
f60ee6a839 New translations en.po (Slovenian) 2025-11-01 15:01:24 -04:00
hank
56e6dbf0a8 New translations en.po (Russian) 2025-11-01 15:01:23 -04:00
hank
7ae179764d New translations en.po (Polish) 2025-11-01 15:01:22 -04:00
hank
e54cac2c7b New translations en.po (Korean) 2025-11-01 15:01:21 -04:00
hank
6bc8878408 New translations en.po (Japanese) 2025-11-01 15:01:20 -04:00
hank
0f6d85f124 New translations en.po (Italian) 2025-11-01 15:01:19 -04:00
hank
b6717c11ae New translations en.po (Danish) 2025-11-01 15:01:18 -04:00
hank
3cff9ccff8 New translations en.po (Czech) 2025-11-01 15:01:17 -04:00
hank
3fb5f065b8 New translations en.po (Bulgarian) 2025-11-01 15:01:16 -04:00
hank
73e397abbf New translations en.po (Arabic) 2025-11-01 15:01:15 -04:00
hank
38f63b02bd New translations en.po (Spanish) 2025-11-01 15:01:14 -04:00
hank
879e84bb34 New translations en.po (Romanian) 2025-11-01 15:01:13 -04:00
hank
79b709d53c New translations en.po (Croatian) 2025-11-01 15:01:12 -04:00
hank
97e188a619 New translations en.po (Chinese Traditional) 2025-11-01 15:01:11 -04:00
hank
9459b59b14 New translations en.po (Portuguese) 2025-11-01 15:01:10 -04:00
hank
c281a0717f New translations en.po (Norwegian) 2025-11-01 15:01:09 -04:00
hank
b274261d3e New translations en.po (Dutch) 2025-11-01 15:01:08 -04:00
hank
63a78f2829 New translations en.po (Hungarian) 2025-11-01 15:01:07 -04:00
hank
31aa6df5b2 New translations en.po (German) 2025-11-01 15:01:06 -04:00
hank
74d8f685bd New translations en.po (French) 2025-11-01 15:01:05 -04:00
hank
43a32ef0ce New translations en.po (Spanish) 2025-11-01 13:41:18 -04:00
hank
4426b53f47 New translations en.po (Chinese Traditional) 2025-11-01 03:52:31 -04:00
hank
6902e90ca7 New translations en.po (Hebrew) 2025-10-30 17:53:10 -04:00
hank
9aeb80ce88 New translations en.po (Chinese Simplified) 2025-10-30 17:53:08 -04:00
hank
60c557055f New translations en.po (Italian) 2025-10-30 17:53:02 -04:00
hank
0a6020b6b8 New translations en.po (Arabic) 2025-10-30 17:52:59 -04:00
hank
7f85b8f2a9 New translations en.po (Spanish) 2025-10-30 17:52:58 -04:00
hank
5ca388d855 New translations en.po (Portuguese) 2025-10-30 17:52:56 -04:00
hank
34d74b3bcd New translations en.po (Hebrew) 2025-10-30 16:47:52 -04:00
hank
86ff86aa99 New translations en.po (Indonesian) 2025-10-29 17:56:50 -04:00
hank
d9a463e465 New translations en.po (Hebrew) 2025-10-29 17:56:49 -04:00
hank
a5d0690a81 New translations en.po (Chinese Traditional, Hong Kong) 2025-10-28 19:00:28 -04:00
hank
eef4092b16 New translations en.po (Persian) 2025-10-28 19:00:27 -04:00
hank
a4e89676df New translations en.po (Vietnamese) 2025-10-28 19:00:26 -04:00
hank
3f083686fe New translations en.po (Chinese Simplified) 2025-10-28 19:00:25 -04:00
hank
cf2ccc1eb4 New translations en.po (Ukrainian) 2025-10-28 19:00:24 -04:00
hank
43c44a085b New translations en.po (Turkish) 2025-10-28 19:00:23 -04:00
hank
e90dfde12e New translations en.po (Swedish) 2025-10-28 19:00:22 -04:00
hank
a1bb77f4f2 New translations en.po (Slovenian) 2025-10-28 19:00:21 -04:00
hank
ef582ec1ef New translations en.po (Russian) 2025-10-28 19:00:20 -04:00
hank
2c30bdb2e4 New translations en.po (Polish) 2025-10-28 19:00:19 -04:00
hank
5bfbc0420a New translations en.po (Korean) 2025-10-28 19:00:18 -04:00
hank
b7a3222d31 New translations en.po (Japanese) 2025-10-28 19:00:17 -04:00
hank
d4955af3ba New translations en.po (Italian) 2025-10-28 19:00:16 -04:00
hank
bde88dda26 New translations en.po (Danish) 2025-10-28 19:00:14 -04:00
hank
3f51bd5ec6 New translations en.po (Czech) 2025-10-28 19:00:13 -04:00
hank
092e8c9948 New translations en.po (Bulgarian) 2025-10-28 19:00:11 -04:00
hank
c35762de98 New translations en.po (Arabic) 2025-10-28 19:00:10 -04:00
hank
7c43e9e27c New translations en.po (Spanish) 2025-10-28 19:00:09 -04:00
hank
ee07a0d181 New translations en.po (Romanian) 2025-10-28 19:00:06 -04:00
hank
3178587f20 New translations en.po (Croatian) 2025-10-28 19:00:05 -04:00
hank
b07a791d6a New translations en.po (Chinese Traditional) 2025-10-28 19:00:03 -04:00
hank
8b6918b4a5 New translations en.po (Portuguese) 2025-10-28 19:00:02 -04:00
hank
c7733146b7 New translations en.po (Norwegian) 2025-10-28 19:00:01 -04:00
hank
8f23bbd436 New translations en.po (Dutch) 2025-10-28 18:59:59 -04:00
hank
7ca3cca15d New translations en.po (Hungarian) 2025-10-28 18:59:58 -04:00
hank
dd553ec7b6 New translations en.po (German) 2025-10-28 18:59:57 -04:00
hank
1a8dd0ab32 New translations en.po (French) 2025-10-28 18:59:56 -04:00
hank
48e0c1efbf New translations en.po (German) 2025-10-27 19:49:39 -04:00
hank
8cdddc9f5e New translations en.po (Spanish) 2025-10-27 14:01:40 -04:00
hank
756c5eab3e New translations en.po (Italian) 2025-10-26 22:07:18 -04:00
hank
cf8102d547 New translations en.po (Danish) 2025-10-26 15:21:12 -04:00
hank
156a54f26c New translations en.po (Polish) 2025-10-26 05:04:19 -04:00
hank
ad1e7772af New translations en.po (Chinese Traditional, Hong Kong) 2025-10-25 19:16:37 -04:00
hank
62edf55a37 New translations en.po (Persian) 2025-10-25 19:16:36 -04:00
hank
223b627619 New translations en.po (Vietnamese) 2025-10-25 19:16:35 -04:00
hank
d3bc1a6764 New translations en.po (Chinese Simplified) 2025-10-25 19:16:34 -04:00
hank
5157144504 New translations en.po (Ukrainian) 2025-10-25 19:16:33 -04:00
hank
cdb396408f New translations en.po (Turkish) 2025-10-25 19:16:32 -04:00
hank
ca7c68140a New translations en.po (Swedish) 2025-10-25 19:16:31 -04:00
hank
5af7afb970 New translations en.po (Slovenian) 2025-10-25 19:16:30 -04:00
hank
fd053fc8e5 New translations en.po (Russian) 2025-10-25 19:16:29 -04:00
hank
f1f01657c0 New translations en.po (Polish) 2025-10-25 19:16:28 -04:00
hank
1c9f03c848 New translations en.po (Korean) 2025-10-25 19:16:27 -04:00
hank
82b5ee0424 New translations en.po (Japanese) 2025-10-25 19:16:26 -04:00
hank
0885bf2ba4 New translations en.po (Italian) 2025-10-25 19:16:25 -04:00
hank
d541b42bef New translations en.po (Danish) 2025-10-25 19:16:24 -04:00
hank
29599cd59c New translations en.po (Czech) 2025-10-25 19:16:23 -04:00
hank
5fff9bd3ac New translations en.po (Bulgarian) 2025-10-25 19:16:22 -04:00
hank
81b6198ee7 New translations en.po (Arabic) 2025-10-25 19:16:21 -04:00
hank
01f58a328e New translations en.po (Spanish) 2025-10-25 19:16:20 -04:00
hank
6ffef3c33b New translations en.po (Romanian) 2025-10-25 19:16:19 -04:00
hank
3d50d0cbba New translations en.po (Croatian) 2025-10-25 19:16:18 -04:00
hank
a8ec54f5a5 New translations en.po (Chinese Traditional) 2025-10-25 19:16:17 -04:00
hank
3c44f51671 New translations en.po (Portuguese) 2025-10-25 19:16:16 -04:00
hank
449642fdd2 New translations en.po (Norwegian) 2025-10-25 19:16:15 -04:00
hank
bb324258d6 New translations en.po (Dutch) 2025-10-25 19:16:14 -04:00
hank
693117724a New translations en.po (Hungarian) 2025-10-25 19:16:13 -04:00
hank
008dd9d184 New translations en.po (German) 2025-10-25 19:16:12 -04:00
hank
f171ec9932 New translations en.po (French) 2025-10-25 19:16:11 -04:00
hank
9e6e1771d1 New translations en.po (Chinese Simplified) 2025-10-25 17:09:25 -04:00
hank
bde6264d11 New translations en.po (Spanish) 2025-10-25 17:09:17 -04:00
hank
ae61acbedd New translations en.po (German) 2025-10-25 17:09:12 -04:00
hank
af392c8084 New translations en.po (French) 2025-10-25 16:53:16 -04:00
hank
ce8d206004 New translations en.po (Danish) 2025-10-25 06:58:38 -04:00
hank
5a15e7c048 New translations en.po (Danish) 2025-10-25 05:58:43 -04:00
hank
3a360f3ede New translations en.po (Spanish) 2025-10-24 13:47:34 -04:00
hank
7cf2493af7 New translations en.po (Spanish) 2025-10-24 12:17:55 -04:00
hank
d71a0083bb New translations en.po (Chinese Simplified) 2025-10-23 15:40:46 -04:00
hank
6f6aeeb315 New translations en.po (Danish) 2025-10-22 19:14:03 -04:00
hank
7845d25c83 New translations en.po (Danish) 2025-10-22 17:51:32 -04:00
hank
3320707567 New translations en.po (Danish) 2025-10-22 14:17:32 -04:00
hank
e0df2a1e60 New translations en.po (Norwegian) 2025-10-22 06:37:12 -04:00
hank
881c0cd137 New translations en.po (German) 2025-10-22 06:37:11 -04:00
hank
5bde9500b6 New translations en.po (French) 2025-10-21 06:28:47 -04:00
hank
b43541ea60 New translations en.po (German) 2025-10-21 04:08:22 -04:00
hank
339e443bca New translations en.po (Chinese Traditional, Hong Kong) 2025-10-20 17:37:43 -04:00
hank
8643fb2fd5 New translations en.po (Persian) 2025-10-20 17:37:42 -04:00
hank
8dcf03fb15 New translations en.po (Vietnamese) 2025-10-20 17:37:41 -04:00
hank
53c3b0c359 New translations en.po (Chinese Simplified) 2025-10-20 17:37:40 -04:00
hank
1701947b26 New translations en.po (Ukrainian) 2025-10-20 17:37:39 -04:00
hank
c8cb041855 New translations en.po (Turkish) 2025-10-20 17:37:38 -04:00
hank
032d06601e New translations en.po (Swedish) 2025-10-20 17:37:37 -04:00
hank
1507825c16 New translations en.po (Slovenian) 2025-10-20 17:37:36 -04:00
hank
073fc308bb New translations en.po (Russian) 2025-10-20 17:37:35 -04:00
hank
9d5aaaf989 New translations en.po (Polish) 2025-10-20 17:37:34 -04:00
hank
0f6063ebe5 New translations en.po (Korean) 2025-10-20 17:37:33 -04:00
hank
742c217b5f New translations en.po (Japanese) 2025-10-20 17:37:32 -04:00
hank
85589e1e07 New translations en.po (Italian) 2025-10-20 17:37:31 -04:00
hank
6ceb58254b New translations en.po (Greek) 2025-10-20 17:37:30 -04:00
hank
10e21993ce New translations en.po (Danish) 2025-10-20 17:37:29 -04:00
hank
ccff653ef1 New translations en.po (Czech) 2025-10-20 17:37:28 -04:00
hank
323705aced New translations en.po (Bulgarian) 2025-10-20 17:37:27 -04:00
hank
774ddaa726 New translations en.po (Arabic) 2025-10-20 17:37:26 -04:00
hank
e75ada4483 New translations en.po (Spanish) 2025-10-20 17:37:24 -04:00
hank
14e8b28b85 New translations en.po (Romanian) 2025-10-20 17:37:24 -04:00
hank
1f7f764fca New translations en.po (Croatian) 2025-10-20 17:37:23 -04:00
hank
2757e51040 New translations en.po (Chinese Traditional) 2025-10-20 17:37:22 -04:00
hank
1233e6bee6 New translations en.po (Portuguese) 2025-10-20 17:37:21 -04:00
hank
e4619b303e New translations en.po (Norwegian) 2025-10-20 17:37:20 -04:00
hank
3abb7a2a29 New translations en.po (Dutch) 2025-10-20 17:37:19 -04:00
hank
045c3cfdf8 New translations en.po (Hungarian) 2025-10-20 17:37:18 -04:00
hank
4b5e1cc5fa New translations en.po (German) 2025-10-20 17:37:17 -04:00
hank
7600a47d08 New translations en.po (French) 2025-10-20 17:37:16 -04:00
hank
47827c09f6 New translations en.po (French) 2025-10-20 12:38:50 -04:00
hank
c8c84ca0ad New translations en.po (French) 2025-10-20 11:14:32 -04:00
hank
309860f9d0 New translations en.po (Chinese Traditional, Hong Kong) 2025-10-18 19:59:24 -04:00
hank
2a76cf4a1f New translations en.po (Persian) 2025-10-18 19:59:23 -04:00
hank
6d6b6891e1 New translations en.po (Vietnamese) 2025-10-18 19:59:22 -04:00
hank
bdd24b95d2 New translations en.po (Chinese Simplified) 2025-10-18 19:59:21 -04:00
hank
9ae2bee9e3 New translations en.po (Ukrainian) 2025-10-18 19:59:20 -04:00
hank
b2396de0d9 New translations en.po (Turkish) 2025-10-18 19:59:19 -04:00
hank
d85e3bc26f New translations en.po (Swedish) 2025-10-18 19:59:18 -04:00
hank
2a3220be5a New translations en.po (Slovenian) 2025-10-18 19:59:17 -04:00
hank
92910faca0 New translations en.po (Russian) 2025-10-18 19:59:16 -04:00
hank
d596474426 New translations en.po (Polish) 2025-10-18 19:59:15 -04:00
hank
db471ea619 New translations en.po (Korean) 2025-10-18 19:59:13 -04:00
hank
f6e30b1c9f New translations en.po (Japanese) 2025-10-18 19:59:13 -04:00
hank
dcc013330e New translations en.po (Italian) 2025-10-18 19:59:12 -04:00
hank
d6feda8a91 New translations en.po (Greek) 2025-10-18 19:59:11 -04:00
hank
310892d401 New translations en.po (Danish) 2025-10-18 19:59:09 -04:00
hank
302e951bb9 New translations en.po (Czech) 2025-10-18 19:59:08 -04:00
hank
6810270f51 New translations en.po (Bulgarian) 2025-10-18 19:59:07 -04:00
hank
1403f75781 New translations en.po (Arabic) 2025-10-18 19:59:06 -04:00
hank
660a7967f8 New translations en.po (Spanish) 2025-10-18 19:59:05 -04:00
hank
5ad420a6bc New translations en.po (Romanian) 2025-10-18 19:59:04 -04:00
hank
7403f67109 New translations en.po (Croatian) 2025-10-18 19:59:03 -04:00
hank
626b865c3b New translations en.po (Chinese Traditional) 2025-10-18 19:59:02 -04:00
hank
ebbddef0d9 New translations en.po (Portuguese) 2025-10-18 19:59:01 -04:00
hank
a528ddfea3 New translations en.po (Norwegian) 2025-10-18 19:59:00 -04:00
hank
9c6a4873b2 New translations en.po (Dutch) 2025-10-18 19:58:59 -04:00
hank
82e976ff0b New translations en.po (Hungarian) 2025-10-18 19:58:58 -04:00
hank
5342f2cbbc New translations en.po (German) 2025-10-18 19:58:57 -04:00
hank
c7838f744f New translations en.po (French) 2025-10-18 19:58:56 -04:00
hank
74e41851cf New translations en.po (Croatian) 2025-10-18 18:52:43 -04:00
hank
f1342a305c New translations en.po (Hungarian) 2025-10-14 19:40:36 -04:00
hank
7f926c687b New translations en.po (Hungarian) 2025-10-14 16:31:25 -04:00
hank
496cc67390 New translations en.po (Hungarian) 2025-10-14 15:16:43 -04:00
hank
e4b300bc71 New translations en.po (Hungarian) 2025-10-14 14:15:05 -04:00
hank
cee20d701a New translations en.po (Norwegian) 2025-10-13 13:31:12 -04:00
hank
0cd5f3696d New translations en.po (Norwegian) 2025-10-13 11:54:15 -04:00
hank
3686df0f9d New translations en.po (Chinese Traditional) 2025-10-11 23:15:08 -04:00
hank
f58f555367 New translations en.po (French) 2025-10-09 18:25:14 -04:00
hank
adfa14ccbe New translations en.po (Portuguese) 2025-10-09 08:03:07 -04:00
hank
26a147e2e5 New translations en.po (Norwegian) 2025-10-06 03:37:07 -04:00
hank
b9a74e1284 New translations en.po (German) 2025-10-05 12:13:24 -04:00
hank
21d2b3ec7b New translations en.po (Romanian) 2025-10-03 14:42:32 -04:00
hank
69d94b0bf9 New translations en.po (Chinese Traditional, Hong Kong) 2025-10-03 14:42:31 -04:00
hank
5e49fca60e New translations en.po (Croatian) 2025-10-03 14:42:30 -04:00
hank
9babff17d1 New translations en.po (Persian) 2025-10-03 14:42:29 -04:00
hank
be86983f00 New translations en.po (Vietnamese) 2025-10-03 14:42:28 -04:00
hank
907bb4dc52 New translations en.po (Chinese Traditional) 2025-10-03 14:42:27 -04:00
hank
9a34a3700d New translations en.po (Chinese Simplified) 2025-10-03 14:42:26 -04:00
hank
fdb468abf4 New translations en.po (Ukrainian) 2025-10-03 14:42:25 -04:00
hank
0de0326778 New translations en.po (Turkish) 2025-10-03 14:42:24 -04:00
hank
30db58b94f New translations en.po (Swedish) 2025-10-03 14:42:23 -04:00
hank
8e40b1013b New translations en.po (Slovenian) 2025-10-03 14:42:22 -04:00
hank
aa96521696 New translations en.po (Russian) 2025-10-03 14:42:21 -04:00
hank
17f40d58ac New translations en.po (Portuguese) 2025-10-03 14:42:20 -04:00
hank
bdcdda4e9c New translations en.po (Polish) 2025-10-03 14:42:18 -04:00
hank
c36d57f962 New translations en.po (Norwegian) 2025-10-03 14:42:17 -04:00
hank
542ac4bfc0 New translations en.po (Dutch) 2025-10-03 14:42:16 -04:00
hank
68a684f3d6 New translations en.po (Korean) 2025-10-03 14:42:15 -04:00
hank
b9bcb372f7 New translations en.po (Japanese) 2025-10-03 14:42:14 -04:00
hank
3d94451124 New translations en.po (Italian) 2025-10-03 14:42:13 -04:00
hank
0af952d66c New translations en.po (Hungarian) 2025-10-03 14:42:12 -04:00
hank
e46bc1ee36 New translations en.po (Greek) 2025-10-03 14:42:11 -04:00
hank
5d297be871 New translations en.po (German) 2025-10-03 14:42:10 -04:00
hank
6c0bc90f96 New translations en.po (Danish) 2025-10-03 14:42:09 -04:00
hank
db0b6f77e3 New translations en.po (Czech) 2025-10-03 14:42:08 -04:00
hank
7f42ab68d2 New translations en.po (Bulgarian) 2025-10-03 14:42:07 -04:00
hank
c4f6e81c56 New translations en.po (Arabic) 2025-10-03 14:42:06 -04:00
hank
3bf595959b New translations en.po (Spanish) 2025-10-03 14:42:05 -04:00
hank
5af1e058b0 New translations en.po (French) 2025-10-03 14:42:03 -04:00
hank
ec62d1597b New translations en.po (Romanian) 2025-10-03 13:07:14 -04:00
hank
fa06a2935b New translations en.po (Russian) 2025-09-28 03:31:06 -04:00
hank
2cdd521a10 New translations en.po (Portuguese) 2025-09-26 15:48:54 -04:00
hank
90ac853e4f New translations en.po (Slovenian) 2025-09-25 13:11:54 -04:00
hank
007fe0c0af New translations en.po (Croatian) 2025-09-24 18:31:13 -04:00
hank
f3afcd351a New translations en.po (Chinese Traditional) 2025-09-24 18:31:12 -04:00
hank
8eb161171e New translations en.po (Chinese Simplified) 2025-09-24 18:31:11 -04:00
hank
413f829107 New translations en.po (Croatian) 2025-09-23 08:43:25 -04:00
hank
7f09474f33 New translations en.po (Korean) 2025-09-22 22:45:02 -04:00
hank
28386c58db New translations en.po (Chinese Traditional, Hong Kong) 2025-09-22 19:10:36 -04:00
hank
e79aae7925 New translations en.po (Croatian) 2025-09-22 19:10:35 -04:00
hank
fabadf998b New translations en.po (Persian) 2025-09-22 19:10:34 -04:00
hank
2f0d158ed8 New translations en.po (Icelandic) 2025-09-22 19:10:33 -04:00
hank
b5f08d4e4c New translations en.po (Vietnamese) 2025-09-22 19:10:32 -04:00
hank
fce10da7f6 New translations en.po (Chinese Traditional) 2025-09-22 19:10:31 -04:00
hank
d59937dba7 New translations en.po (Chinese Simplified) 2025-09-22 19:10:30 -04:00
hank
0eb2bfab12 New translations en.po (Ukrainian) 2025-09-22 19:10:29 -04:00
hank
bb4111671f New translations en.po (Turkish) 2025-09-22 19:10:28 -04:00
hank
5e50d791fd New translations en.po (Swedish) 2025-09-22 19:10:27 -04:00
hank
cfaf0712d6 New translations en.po (Slovenian) 2025-09-22 19:10:26 -04:00
hank
9cb2d694fe New translations en.po (Russian) 2025-09-22 19:10:25 -04:00
hank
9f4c6b30d8 New translations en.po (Portuguese) 2025-09-22 19:10:24 -04:00
hank
b9055a5d22 New translations en.po (Polish) 2025-09-22 19:10:23 -04:00
hank
aa0d1e7f61 New translations en.po (Norwegian) 2025-09-22 19:10:22 -04:00
hank
35a8cb1d36 New translations en.po (Dutch) 2025-09-22 19:10:21 -04:00
hank
92ba8a0ca3 New translations en.po (Korean) 2025-09-22 19:10:20 -04:00
hank
acbc02162f New translations en.po (Japanese) 2025-09-22 19:10:19 -04:00
hank
8da777b6f4 New translations en.po (Italian) 2025-09-22 19:10:18 -04:00
hank
e62ec1d993 New translations en.po (Hungarian) 2025-09-22 19:10:16 -04:00
hank
4fa11b4c79 New translations en.po (Greek) 2025-09-22 19:10:15 -04:00
hank
c9dba873ee New translations en.po (German) 2025-09-22 19:10:14 -04:00
hank
3e2e897f34 New translations en.po (Danish) 2025-09-22 19:10:13 -04:00
hank
9658fba5aa New translations en.po (Czech) 2025-09-22 19:10:12 -04:00
hank
1c00c39eac New translations en.po (Bulgarian) 2025-09-22 19:10:11 -04:00
hank
2d3f186c18 New translations en.po (Arabic) 2025-09-22 19:10:10 -04:00
hank
983a471e6f New translations en.po (Spanish) 2025-09-22 19:10:08 -04:00
hank
7a228f553c New translations en.po (French) 2025-09-22 19:10:08 -04:00
hank
007dfa9519 New translations en.po (Dutch) 2025-09-21 14:30:42 -04:00
hank
f3a74b1f46 New translations en.po (Polish) 2025-09-18 11:36:03 -04:00
hank
4a76b620e7 New translations en.po (Polish) 2025-09-18 08:40:40 -04:00
hank
25210d031d New translations en.po (Chinese Traditional, Hong Kong) 2025-09-17 14:45:45 -04:00
hank
87b55fd4cf New translations en.po (Croatian) 2025-09-17 14:45:44 -04:00
hank
b4430ac76f New translations en.po (Persian) 2025-09-17 14:45:43 -04:00
hank
5f9aa78b72 New translations en.po (Icelandic) 2025-09-17 14:45:42 -04:00
hank
7537f6bd5c New translations en.po (Vietnamese) 2025-09-17 14:45:41 -04:00
hank
83dee5e554 New translations en.po (Chinese Traditional) 2025-09-17 14:45:40 -04:00
hank
036b4495e6 New translations en.po (Chinese Simplified) 2025-09-17 14:45:39 -04:00
hank
31cd36fcc1 New translations en.po (Ukrainian) 2025-09-17 14:45:38 -04:00
hank
0a2aaf3260 New translations en.po (Turkish) 2025-09-17 14:45:36 -04:00
hank
6e2e90120a New translations en.po (Swedish) 2025-09-17 14:45:35 -04:00
hank
23f95d6ebd New translations en.po (Slovenian) 2025-09-17 14:45:35 -04:00
hank
56dc1096d9 New translations en.po (Russian) 2025-09-17 14:45:34 -04:00
hank
9dd203f85a New translations en.po (Portuguese) 2025-09-17 14:45:32 -04:00
hank
adac9cf79d New translations en.po (Polish) 2025-09-17 14:45:31 -04:00
hank
efd2ba04c5 New translations en.po (Norwegian) 2025-09-17 14:45:30 -04:00
hank
a9055e216d New translations en.po (Dutch) 2025-09-17 14:45:29 -04:00
hank
f64130029b New translations en.po (Korean) 2025-09-17 14:45:28 -04:00
hank
6d172bac82 New translations en.po (Japanese) 2025-09-17 14:45:27 -04:00
hank
354cba5690 New translations en.po (Italian) 2025-09-17 14:45:26 -04:00
hank
e65cde9675 New translations en.po (Hungarian) 2025-09-17 14:45:25 -04:00
hank
fbd2fbb6a6 New translations en.po (Greek) 2025-09-17 14:45:24 -04:00
hank
01bf64083a New translations en.po (German) 2025-09-17 14:45:23 -04:00
hank
103856121d New translations en.po (Danish) 2025-09-17 14:45:21 -04:00
hank
8a798c7e3f New translations en.po (Czech) 2025-09-17 14:45:20 -04:00
hank
beeec5c39e New translations en.po (Bulgarian) 2025-09-17 14:45:19 -04:00
hank
6d43045d79 New translations en.po (Arabic) 2025-09-17 14:45:18 -04:00
hank
88ea94f5b0 New translations en.po (Spanish) 2025-09-17 14:45:17 -04:00
hank
3b8d333f8e New translations en.po (French) 2025-09-17 14:45:16 -04:00
hank
3a06982502 New translations en.po (Chinese Simplified) 2025-09-17 01:21:38 -04:00
hank
b820b46042 New translations en.po (Polish) 2025-09-14 04:46:36 -04:00
hank
fab799f177 New translations en.po (Chinese Traditional, Hong Kong) 2025-09-11 12:53:01 -04:00
hank
5eaf9b9157 New translations en.po (Croatian) 2025-09-11 12:53:00 -04:00
hank
1eed3c53c8 New translations en.po (Persian) 2025-09-11 12:52:59 -04:00
hank
90729a7a95 New translations en.po (Icelandic) 2025-09-11 12:52:58 -04:00
hank
d450f6df10 New translations en.po (Vietnamese) 2025-09-11 12:52:57 -04:00
hank
7aa2bcf761 New translations en.po (Chinese Traditional) 2025-09-11 12:52:55 -04:00
hank
a7a86f46c3 New translations en.po (Chinese Simplified) 2025-09-11 12:52:54 -04:00
hank
17e30aff60 New translations en.po (Ukrainian) 2025-09-11 12:52:53 -04:00
hank
66008e47f3 New translations en.po (Turkish) 2025-09-11 12:52:52 -04:00
hank
56788b1e5b New translations en.po (Swedish) 2025-09-11 12:52:51 -04:00
hank
b72371487a New translations en.po (Slovenian) 2025-09-11 12:52:50 -04:00
hank
7656b4189e New translations en.po (Russian) 2025-09-11 12:52:49 -04:00
hank
8e6731c102 New translations en.po (Portuguese) 2025-09-11 12:52:48 -04:00
hank
e86fa40fe4 New translations en.po (Polish) 2025-09-11 12:52:46 -04:00
hank
f0e728a1ed New translations en.po (Norwegian) 2025-09-11 12:52:45 -04:00
hank
bb076eb439 New translations en.po (Dutch) 2025-09-11 12:52:44 -04:00
hank
2f0b16367a New translations en.po (Korean) 2025-09-11 12:52:43 -04:00
hank
aa33124e18 New translations en.po (Japanese) 2025-09-11 12:52:42 -04:00
hank
42f404c80a New translations en.po (Italian) 2025-09-11 12:52:41 -04:00
hank
5056fddd40 New translations en.po (Hungarian) 2025-09-11 12:52:40 -04:00
hank
2296202ea1 New translations en.po (Greek) 2025-09-11 12:52:39 -04:00
hank
c034e9b0fa New translations en.po (German) 2025-09-11 12:52:38 -04:00
hank
2d45119a98 New translations en.po (Danish) 2025-09-11 12:52:36 -04:00
hank
63be4f1ab5 New translations en.po (Czech) 2025-09-11 12:52:35 -04:00
hank
6d2259100e New translations en.po (Bulgarian) 2025-09-11 12:52:34 -04:00
hank
142af6e7b6 New translations en.po (Arabic) 2025-09-11 12:52:33 -04:00
hank
5c1e009188 New translations en.po (Spanish) 2025-09-11 12:52:32 -04:00
hank
27b2cb84d6 New translations en.po (French) 2025-09-11 12:52:31 -04:00
117 changed files with 17401 additions and 5043 deletions

View File

@@ -33,14 +33,6 @@ jobs:
registry: docker.io
username_secret: DOCKERHUB_USERNAME
password_secret: DOCKERHUB_TOKEN
- image: henrygd/beszel-agent-intel
context: ./
dockerfile: ./internal/dockerfile_agent_intel
platforms: linux/amd64
registry: docker.io
username_secret: DOCKERHUB_USERNAME
password_secret: DOCKERHUB_TOKEN
- image: ghcr.io/${{ github.repository }}/beszel
context: ./
@@ -64,14 +56,6 @@ jobs:
username: ${{ github.actor }}
password_secret: GITHUB_TOKEN
- image: ghcr.io/${{ github.repository }}/beszel-agent-intel
context: ./
dockerfile: ./internal/dockerfile_agent_intel
platforms: linux/amd64
registry: ghcr.io
username: ${{ github.actor }}
password_secret: GITHUB_TOKEN
permissions:
contents: read
packages: write

View File

@@ -77,7 +77,7 @@ dev-hub: export ENV=dev
dev-hub:
mkdir -p ./internal/site/dist && touch ./internal/site/dist/index.html
@if command -v entr >/dev/null 2>&1; then \
find ./internal -type f -name '*.go' | entr -r -s "cd ./internal/cmd/hub && go run -tags development . serve --http 0.0.0.0:8090"; \
find ./internal/cmd/hub/*.go ./internal/{alerts,hub,records,users}/*.go | entr -r -s "cd ./internal/cmd/hub && go run -tags development . serve --http 0.0.0.0:8090"; \
else \
cd ./internal/cmd/hub && go run -tags development . serve --http 0.0.0.0:8090; \
fi

View File

@@ -31,7 +31,6 @@ type Agent struct {
netInterfaces map[string]struct{} // Stores all valid network interfaces
netIoStats system.NetIoStats // Keeps track of bandwidth usage
dockerManager *dockerManager // Manages Docker API requests
systemdManager *systemdManager // Manages systemd services
sensorConfig *SensorConfig // Sensors config
systemInfo system.Info // Host system info
gpuManager *GPUManager // Manages GPU data
@@ -89,13 +88,6 @@ func NewAgent(dataDir ...string) (agent *Agent, err error) {
// initialize docker manager
agent.dockerManager = newDockerManager(agent)
// initialize systemd manager
if sm, err := newSystemdManager(); err != nil {
slog.Debug("Systemd", "err", err)
} else {
agent.systemdManager = sm
}
// initialize GPU manager
if gm, err := NewGPUManager(); err != nil {
slog.Debug("GPU", "err", err)
@@ -145,11 +137,6 @@ func (a *Agent) gatherStats(sessionID string) *system.CombinedData {
}
}
if a.systemdManager != nil {
data.SystemdServices = a.systemdManager.getServiceStats()
slog.Debug("Systemd services", "data", data.SystemdServices)
}
data.Stats.ExtraFs = make(map[string]*system.FsStats)
for name, stats := range a.fsStats {
if !stats.Root && stats.DiskTotal > 0 {

View File

@@ -20,8 +20,9 @@ func HasReadableBattery() bool {
}
haveCheckedBattery = true
bat, err := battery.Get(0)
systemHasBattery = err == nil && bat != nil && bat.Design != 0 && bat.Full != 0
if !systemHasBattery {
if err == nil && bat != nil {
systemHasBattery = true
} else {
slog.Debug("No battery found", "err", err)
}
return systemHasBattery

View File

@@ -85,7 +85,7 @@ func getToken() (string, error) {
if err != nil {
return "", err
}
return strings.TrimSpace(string(tokenBytes)), nil
return string(tokenBytes), nil
}
// getOptions returns the WebSocket client options, creating them if necessary.

View File

@@ -537,25 +537,4 @@ func TestGetToken(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, "", token, "Empty file should return empty string")
})
t.Run("strips whitespace from TOKEN_FILE", func(t *testing.T) {
unsetEnvVars()
tokenWithWhitespace := " test-token-with-whitespace \n\t"
expectedToken := "test-token-with-whitespace"
tokenFile, err := os.CreateTemp("", "token-test-*.txt")
require.NoError(t, err)
defer os.Remove(tokenFile.Name())
_, err = tokenFile.WriteString(tokenWithWhitespace)
require.NoError(t, err)
tokenFile.Close()
os.Setenv("TOKEN_FILE", tokenFile.Name())
defer os.Unsetenv("TOKEN_FILE")
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, expectedToken, token, "Whitespace should be stripped from token file content")
})
}

View File

@@ -9,21 +9,19 @@ import (
"time"
"github.com/henrygd/beszel/agent/health"
"github.com/henrygd/beszel/internal/entities/system"
)
// ConnectionManager manages the connection state and events for the agent.
// It handles both WebSocket and SSH connections, automatically switching between
// them based on availability and managing reconnection attempts.
type ConnectionManager struct {
agent *Agent // Reference to the parent agent
State ConnectionState // Current connection state
eventChan chan ConnectionEvent // Channel for connection events
wsClient *WebSocketClient // WebSocket client for hub communication
serverOptions ServerOptions // Configuration for SSH server
wsTicker *time.Ticker // Ticker for WebSocket connection attempts
isConnecting bool // Prevents multiple simultaneous reconnection attempts
ConnectionType system.ConnectionType
agent *Agent // Reference to the parent agent
State ConnectionState // Current connection state
eventChan chan ConnectionEvent // Channel for connection events
wsClient *WebSocketClient // WebSocket client for hub communication
serverOptions ServerOptions // Configuration for SSH server
wsTicker *time.Ticker // Ticker for WebSocket connection attempts
isConnecting bool // Prevents multiple simultaneous reconnection attempts
}
// ConnectionState represents the current connection state of the agent.
@@ -146,18 +144,15 @@ func (c *ConnectionManager) handleStateChange(newState ConnectionState) {
switch newState {
case WebSocketConnected:
slog.Info("WebSocket connected", "host", c.wsClient.hubURL.Host)
c.ConnectionType = system.ConnectionTypeWebSocket
c.stopWsTicker()
_ = c.agent.StopServer()
c.isConnecting = false
case SSHConnected:
// stop new ws connection attempts
slog.Info("SSH connection established")
c.ConnectionType = system.ConnectionTypeSSH
c.stopWsTicker()
c.isConnecting = false
case Disconnected:
c.ConnectionType = system.ConnectionTypeNone
if c.isConnecting {
// Already handling reconnection, avoid duplicate attempts
return

View File

@@ -1,81 +0,0 @@
// Package deltatracker provides a tracker for calculating differences in numeric values over time.
package deltatracker
import (
"sync"
"golang.org/x/exp/constraints"
)
// Numeric is a constraint that permits any integer or floating-point type.
type Numeric interface {
constraints.Integer | constraints.Float
}
// DeltaTracker is a generic, thread-safe tracker for calculating differences
// in numeric values over time.
// K is the key type (e.g., int, string).
// V is the value type (e.g., int, int64, float32, float64).
type DeltaTracker[K comparable, V Numeric] struct {
sync.RWMutex
current map[K]V
previous map[K]V
}
// NewDeltaTracker creates a new generic tracker.
func NewDeltaTracker[K comparable, V Numeric]() *DeltaTracker[K, V] {
return &DeltaTracker[K, V]{
current: make(map[K]V),
previous: make(map[K]V),
}
}
// Set records the current value for a given ID.
func (t *DeltaTracker[K, V]) Set(id K, value V) {
t.Lock()
defer t.Unlock()
t.current[id] = value
}
// Deltas returns a map of all calculated deltas for the current interval.
func (t *DeltaTracker[K, V]) Deltas() map[K]V {
t.RLock()
defer t.RUnlock()
deltas := make(map[K]V)
for id, currentVal := range t.current {
if previousVal, ok := t.previous[id]; ok {
deltas[id] = currentVal - previousVal
} else {
deltas[id] = 0
}
}
return deltas
}
// Delta returns the delta for a single key.
// Returns 0 if the key doesn't exist or has no previous value.
func (t *DeltaTracker[K, V]) Delta(id K) V {
t.RLock()
defer t.RUnlock()
currentVal, currentOk := t.current[id]
if !currentOk {
return 0
}
previousVal, previousOk := t.previous[id]
if !previousOk {
return 0
}
return currentVal - previousVal
}
// Cycle prepares the tracker for the next interval.
func (t *DeltaTracker[K, V]) Cycle() {
t.Lock()
defer t.Unlock()
t.previous = t.current
t.current = make(map[K]V)
}

View File

@@ -1,217 +0,0 @@
package deltatracker
import (
"fmt"
"testing"
"github.com/stretchr/testify/assert"
)
func ExampleDeltaTracker() {
tracker := NewDeltaTracker[string, int]()
tracker.Set("key1", 10)
tracker.Set("key2", 20)
tracker.Cycle()
tracker.Set("key1", 15)
tracker.Set("key2", 30)
fmt.Println(tracker.Delta("key1"))
fmt.Println(tracker.Delta("key2"))
fmt.Println(tracker.Deltas())
// Output: 5
// 10
// map[key1:5 key2:10]
}
func TestNewDeltaTracker(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
assert.NotNil(t, tracker)
assert.Empty(t, tracker.current)
assert.Empty(t, tracker.previous)
}
func TestSet(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
tracker.Set("key1", 10)
tracker.RLock()
defer tracker.RUnlock()
assert.Equal(t, 10, tracker.current["key1"])
}
func TestDeltas(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
// Test with no previous values
tracker.Set("key1", 10)
tracker.Set("key2", 20)
deltas := tracker.Deltas()
assert.Equal(t, 0, deltas["key1"])
assert.Equal(t, 0, deltas["key2"])
// Cycle to move current to previous
tracker.Cycle()
// Set new values and check deltas
tracker.Set("key1", 15) // Delta should be 5 (15-10)
tracker.Set("key2", 25) // Delta should be 5 (25-20)
tracker.Set("key3", 30) // New key, delta should be 0
deltas = tracker.Deltas()
assert.Equal(t, 5, deltas["key1"])
assert.Equal(t, 5, deltas["key2"])
assert.Equal(t, 0, deltas["key3"])
}
func TestCycle(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
tracker.Set("key1", 10)
tracker.Set("key2", 20)
// Verify current has values
tracker.RLock()
assert.Equal(t, 10, tracker.current["key1"])
assert.Equal(t, 20, tracker.current["key2"])
assert.Empty(t, tracker.previous)
tracker.RUnlock()
tracker.Cycle()
// After cycle, previous should have the old current values
// and current should be empty
tracker.RLock()
assert.Empty(t, tracker.current)
assert.Equal(t, 10, tracker.previous["key1"])
assert.Equal(t, 20, tracker.previous["key2"])
tracker.RUnlock()
}
func TestCompleteWorkflow(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
// First interval
tracker.Set("server1", 100)
tracker.Set("server2", 200)
// Get deltas for first interval (should be zero)
firstDeltas := tracker.Deltas()
assert.Equal(t, 0, firstDeltas["server1"])
assert.Equal(t, 0, firstDeltas["server2"])
// Cycle to next interval
tracker.Cycle()
// Second interval
tracker.Set("server1", 150) // Delta: 50
tracker.Set("server2", 180) // Delta: -20
tracker.Set("server3", 300) // New server, delta: 300
secondDeltas := tracker.Deltas()
assert.Equal(t, 50, secondDeltas["server1"])
assert.Equal(t, -20, secondDeltas["server2"])
assert.Equal(t, 0, secondDeltas["server3"])
}
func TestDeltaTrackerWithDifferentTypes(t *testing.T) {
// Test with int64
intTracker := NewDeltaTracker[string, int64]()
intTracker.Set("pid1", 1000)
intTracker.Cycle()
intTracker.Set("pid1", 1200)
intDeltas := intTracker.Deltas()
assert.Equal(t, int64(200), intDeltas["pid1"])
// Test with float64
floatTracker := NewDeltaTracker[string, float64]()
floatTracker.Set("cpu1", 1.5)
floatTracker.Cycle()
floatTracker.Set("cpu1", 2.7)
floatDeltas := floatTracker.Deltas()
assert.InDelta(t, 1.2, floatDeltas["cpu1"], 0.0001)
// Test with int keys
pidTracker := NewDeltaTracker[int, int64]()
pidTracker.Set(101, 20000)
pidTracker.Cycle()
pidTracker.Set(101, 22500)
pidDeltas := pidTracker.Deltas()
assert.Equal(t, int64(2500), pidDeltas[101])
}
func TestDelta(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
// Test getting delta for non-existent key
result := tracker.Delta("nonexistent")
assert.Equal(t, 0, result)
// Test getting delta for key with no previous value
tracker.Set("key1", 10)
result = tracker.Delta("key1")
assert.Equal(t, 0, result)
// Cycle to move current to previous
tracker.Cycle()
// Test getting delta for key with previous value
tracker.Set("key1", 15)
result = tracker.Delta("key1")
assert.Equal(t, 5, result)
// Test getting delta for key that exists in previous but not current
result = tracker.Delta("key1")
assert.Equal(t, 5, result) // Should still return 5
// Test getting delta for key that exists in current but not previous
tracker.Set("key2", 20)
result = tracker.Delta("key2")
assert.Equal(t, 0, result)
}
func TestDeltaWithDifferentTypes(t *testing.T) {
// Test with int64
intTracker := NewDeltaTracker[string, int64]()
intTracker.Set("pid1", 1000)
intTracker.Cycle()
intTracker.Set("pid1", 1200)
result := intTracker.Delta("pid1")
assert.Equal(t, int64(200), result)
// Test with float64
floatTracker := NewDeltaTracker[string, float64]()
floatTracker.Set("cpu1", 1.5)
floatTracker.Cycle()
floatTracker.Set("cpu1", 2.7)
floatResult := floatTracker.Delta("cpu1")
assert.InDelta(t, 1.2, floatResult, 0.0001)
// Test with int keys
pidTracker := NewDeltaTracker[int, int64]()
pidTracker.Set(101, 20000)
pidTracker.Cycle()
pidTracker.Set(101, 22500)
pidResult := pidTracker.Delta(101)
assert.Equal(t, int64(2500), pidResult)
}
func TestDeltaConcurrentAccess(t *testing.T) {
tracker := NewDeltaTracker[string, int]()
// Set initial values
tracker.Set("key1", 10)
tracker.Set("key2", 20)
tracker.Cycle()
// Set new values
tracker.Set("key1", 15)
tracker.Set("key2", 25)
// Test concurrent access safety
result1 := tracker.Delta("key1")
result2 := tracker.Delta("key2")
assert.Equal(t, 5, result1)
assert.Equal(t, 5, result2)
}

View File

@@ -27,10 +27,13 @@ const (
nvidiaSmiInterval string = "4" // in seconds
tegraStatsInterval string = "3700" // in milliseconds
rocmSmiInterval time.Duration = 4300 * time.Millisecond
// Command retry and timeout constants
retryWaitTime time.Duration = 5 * time.Second
maxFailureRetries int = 5
cmdBufferSize uint16 = 10 * 1024
// Unit Conversions
mebibytesInAMegabyte float64 = 1.024 // nvidia-smi reports memory in MiB
milliwattsInAWatt float64 = 1000.0 // tegrastats reports power in mW
@@ -39,11 +42,10 @@ const (
// GPUManager manages data collection for GPUs (either Nvidia or AMD)
type GPUManager struct {
sync.Mutex
nvidiaSmi bool
rocmSmi bool
tegrastats bool
intelGpuStats bool
GpuDataMap map[string]*system.GPUData
nvidiaSmi bool
rocmSmi bool
tegrastats bool
GpuDataMap map[string]*system.GPUData
}
// RocmSmiJson represents the JSON structure of rocm-smi output
@@ -64,7 +66,6 @@ type gpuCollector struct {
cmdArgs []string
parse func([]byte) bool // returns true if valid data was found
buf []byte
bufSize uint16
}
var errNoValidData = fmt.Errorf("no valid GPU data found") // Error for missing data
@@ -98,7 +99,7 @@ func (c *gpuCollector) collect() error {
scanner := bufio.NewScanner(stdout)
if c.buf == nil {
c.buf = make([]byte, 0, c.bufSize)
c.buf = make([]byte, 0, cmdBufferSize)
}
scanner.Buffer(c.buf, bufio.MaxScanTokenSize)
@@ -243,32 +244,20 @@ func (gm *GPUManager) GetCurrentData() map[string]system.GPUData {
// copy / reset the data
gpuData := make(map[string]system.GPUData, len(gm.GpuDataMap))
for id, gpu := range gm.GpuDataMap {
// avoid division by zero
count := max(gpu.Count, 1)
// average the data
gpuAvg := *gpu
gpuAvg.Temperature = twoDecimals(gpu.Temperature)
gpuAvg.Power = twoDecimals(gpu.Power / count)
// intel gpu stats doesn't provide usage, memory used, or memory total
if gpu.Engines != nil {
maxEngineUsage := 0.0
for name, engine := range gpu.Engines {
gpuAvg.Engines[name] = twoDecimals(engine / count)
maxEngineUsage = max(maxEngineUsage, engine/count)
}
gpuAvg.PowerPkg = twoDecimals(gpu.PowerPkg / count)
gpuAvg.Usage = twoDecimals(maxEngineUsage)
} else {
gpuAvg.Usage = twoDecimals(gpu.Usage / count)
gpuAvg.MemoryUsed = twoDecimals(gpu.MemoryUsed)
gpuAvg.MemoryTotal = twoDecimals(gpu.MemoryTotal)
gpuAvg.Temperature = twoDecimals(gpu.Temperature)
gpuAvg.MemoryUsed = twoDecimals(gpu.MemoryUsed)
gpuAvg.MemoryTotal = twoDecimals(gpu.MemoryTotal)
// avoid division by zero
if gpu.Count > 0 {
gpuAvg.Usage = twoDecimals(gpu.Usage / gpu.Count)
gpuAvg.Power = twoDecimals(gpu.Power / gpu.Count)
}
// reset accumulators in the original gpu data for next collection
gpu.Usage, gpu.Power, gpu.PowerPkg, gpu.Count = gpuAvg.Usage, gpuAvg.Power, gpuAvg.PowerPkg, 1
gpu.Engines = gpuAvg.Engines
// reset accumulators in the original
gpu.Usage, gpu.Power, gpu.Count = 0, 0, 0
// append id to the name if there are multiple GPUs with the same name
if nameCounts[gpu.Name] > 1 {
@@ -295,37 +284,18 @@ func (gm *GPUManager) detectGPUs() error {
gm.tegrastats = true
gm.nvidiaSmi = false
}
if _, err := exec.LookPath(intelGpuStatsCmd); err == nil {
gm.intelGpuStats = true
}
if gm.nvidiaSmi || gm.rocmSmi || gm.tegrastats || gm.intelGpuStats {
if gm.nvidiaSmi || gm.rocmSmi || gm.tegrastats {
return nil
}
return fmt.Errorf("no GPU found - install nvidia-smi, rocm-smi, tegrastats, or intel_gpu_top")
return fmt.Errorf("no GPU found - install nvidia-smi, rocm-smi, or tegrastats")
}
// startCollector starts the appropriate GPU data collector based on the command
func (gm *GPUManager) startCollector(command string) {
collector := gpuCollector{
name: command,
bufSize: 10 * 1024,
name: command,
}
switch command {
case intelGpuStatsCmd:
go func() {
failures := 0
for {
if err := gm.collectIntelStats(); err != nil {
failures++
if failures > maxFailureRetries {
break
}
slog.Warn("Error collecting Intel GPU data; see https://beszel.dev/guide/gpu", "err", err)
time.Sleep(retryWaitTime)
continue
}
}
}()
case nvidiaSmiCmd:
collector.cmdArgs = []string{
"-l", nvidiaSmiInterval,
@@ -359,9 +329,6 @@ func (gm *GPUManager) startCollector(command string) {
// NewGPUManager creates and initializes a new GPUManager
func NewGPUManager() (*GPUManager, error) {
if skipGPU, _ := GetEnv("SKIP_GPU"); skipGPU == "true" {
return nil, nil
}
var gm GPUManager
if err := gm.detectGPUs(); err != nil {
return nil, err
@@ -377,9 +344,6 @@ func NewGPUManager() (*GPUManager, error) {
if gm.tegrastats {
gm.startCollector(tegraStatsCmd)
}
if gm.intelGpuStats {
gm.startCollector(intelGpuStatsCmd)
}
return &gm, nil
}

View File

@@ -1,199 +0,0 @@
package agent
import (
"bufio"
"io"
"os/exec"
"strconv"
"strings"
"github.com/henrygd/beszel/internal/entities/system"
)
const (
intelGpuStatsCmd string = "intel_gpu_top"
intelGpuStatsInterval string = "3300" // in milliseconds
)
type intelGpuStats struct {
PowerGPU float64
PowerPkg float64
Engines map[string]float64
}
// updateIntelFromStats updates aggregated GPU data from a single intelGpuStats sample
func (gm *GPUManager) updateIntelFromStats(sample *intelGpuStats) bool {
gm.Lock()
defer gm.Unlock()
// only one gpu for now - cmd doesn't provide all by default
gpuData, ok := gm.GpuDataMap["0"]
if !ok {
gpuData = &system.GPUData{Name: "GPU", Engines: make(map[string]float64)}
gm.GpuDataMap["0"] = gpuData
}
gpuData.Power += sample.PowerGPU
gpuData.PowerPkg += sample.PowerPkg
if gpuData.Engines == nil {
gpuData.Engines = make(map[string]float64, len(sample.Engines))
}
for name, engine := range sample.Engines {
gpuData.Engines[name] += engine
}
gpuData.Count++
return true
}
// collectIntelStats executes intel_gpu_top in text mode (-l) and parses the output
func (gm *GPUManager) collectIntelStats() (err error) {
cmd := exec.Command(intelGpuStatsCmd, "-s", intelGpuStatsInterval, "-l")
// Avoid blocking if intel_gpu_top writes to stderr
cmd.Stderr = io.Discard
stdout, err := cmd.StdoutPipe()
if err != nil {
return err
}
if err := cmd.Start(); err != nil {
return err
}
// Ensure we always reap the child to avoid zombies on any return path and
// propagate a non-zero exit code if no other error was set.
defer func() {
// Best-effort close of the pipe (unblock the child if it writes)
_ = stdout.Close()
if cmd.ProcessState == nil || !cmd.ProcessState.Exited() {
_ = cmd.Process.Kill()
}
if waitErr := cmd.Wait(); err == nil && waitErr != nil {
err = waitErr
}
}()
scanner := bufio.NewScanner(stdout)
var header1 string
var engineNames []string
var friendlyNames []string
var preEngineCols int
var powerIndex int
var hadDataRow bool
// skip first data row because it sometimes has erroneous data
var skippedFirstDataRow bool
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())
if line == "" {
continue
}
// first header line
if strings.HasPrefix(line, "Freq") {
header1 = line
continue
}
// second header line
if strings.HasPrefix(line, "req") {
engineNames, friendlyNames, powerIndex, preEngineCols = gm.parseIntelHeaders(header1, line)
continue
}
// Data row
if !skippedFirstDataRow {
skippedFirstDataRow = true
continue
}
sample, err := gm.parseIntelData(line, engineNames, friendlyNames, powerIndex, preEngineCols)
if err != nil {
return err
}
hadDataRow = true
gm.updateIntelFromStats(&sample)
}
if scanErr := scanner.Err(); scanErr != nil {
return scanErr
}
if !hadDataRow {
return errNoValidData
}
return nil
}
func (gm *GPUManager) parseIntelHeaders(header1 string, header2 string) (engineNames []string, friendlyNames []string, powerIndex int, preEngineCols int) {
// Build indexes
h1 := strings.Fields(header1)
h2 := strings.Fields(header2)
powerIndex = -1 // Initialize to -1, will be set to actual index if found
// Collect engine names from header1
for _, col := range h1 {
key := strings.TrimRightFunc(col, func(r rune) bool { return r >= '0' && r <= '9' })
var friendly string
switch key {
case "RCS":
friendly = "Render/3D"
case "BCS":
friendly = "Blitter"
case "VCS":
friendly = "Video"
case "VECS":
friendly = "VideoEnhance"
case "CCS":
friendly = "Compute"
default:
continue
}
engineNames = append(engineNames, key)
friendlyNames = append(friendlyNames, friendly)
}
// find power gpu index among pre-engine columns
if n := len(engineNames); n > 0 {
preEngineCols = max(len(h2)-3*n, 0)
limit := min(len(h2), preEngineCols)
for i := range limit {
if strings.EqualFold(h2[i], "gpu") {
powerIndex = i
break
}
}
}
return engineNames, friendlyNames, powerIndex, preEngineCols
}
func (gm *GPUManager) parseIntelData(line string, engineNames []string, friendlyNames []string, powerIndex int, preEngineCols int) (sample intelGpuStats, err error) {
fields := strings.Fields(line)
if len(fields) == 0 {
return sample, errNoValidData
}
// Make sure row has enough columns for engines
if need := preEngineCols + 3*len(engineNames); len(fields) < need {
return sample, errNoValidData
}
if powerIndex >= 0 && powerIndex < len(fields) {
if v, perr := strconv.ParseFloat(fields[powerIndex], 64); perr == nil {
sample.PowerGPU = v
}
if v, perr := strconv.ParseFloat(fields[powerIndex+1], 64); perr == nil {
sample.PowerPkg = v
}
}
if len(engineNames) > 0 {
sample.Engines = make(map[string]float64, len(engineNames))
for k := range engineNames {
base := preEngineCols + 3*k
if base < len(fields) {
busy := 0.0
if v, e := strconv.ParseFloat(fields[base], 64); e == nil {
busy = v
}
cur := sample.Engines[friendlyNames[k]]
sample.Engines[friendlyNames[k]] = cur + busy
} else {
sample.Engines[friendlyNames[k]] = 0
}
}
}
return sample, nil
}

View File

@@ -379,12 +379,12 @@ func TestGetCurrentData(t *testing.T) {
assert.InDelta(t, 60.0, result["1"].Power, 0.01)
// Verify that accumulators in the original map are reset
assert.EqualValues(t, float64(1), gm.GpuDataMap["0"].Count, "GPU 0 Count should be reset")
assert.EqualValues(t, float64(50.0), gm.GpuDataMap["0"].Usage, "GPU 0 Usage should be reset")
assert.Equal(t, float64(100.0), gm.GpuDataMap["0"].Power, "GPU 0 Power should be reset")
assert.Equal(t, float64(1), gm.GpuDataMap["1"].Count, "GPU 1 Count should be reset")
assert.Equal(t, float64(30), gm.GpuDataMap["1"].Usage, "GPU 1 Usage should be reset")
assert.Equal(t, float64(60), gm.GpuDataMap["1"].Power, "GPU 1 Power should be reset")
assert.Equal(t, float64(0), gm.GpuDataMap["0"].Count, "GPU 0 Count should be reset")
assert.Equal(t, float64(0), gm.GpuDataMap["0"].Usage, "GPU 0 Usage should be reset")
assert.Equal(t, float64(0), gm.GpuDataMap["0"].Power, "GPU 0 Power should be reset")
assert.Equal(t, float64(0), gm.GpuDataMap["1"].Count, "GPU 1 Count should be reset")
assert.Equal(t, float64(0), gm.GpuDataMap["1"].Usage, "GPU 1 Usage should be reset")
assert.Equal(t, float64(0), gm.GpuDataMap["1"].Power, "GPU 1 Power should be reset")
})
t.Run("handles zero count without panicking", func(t *testing.T) {
@@ -409,7 +409,7 @@ func TestGetCurrentData(t *testing.T) {
assert.Equal(t, 0.0, result["0"].Power)
// Verify reset count
assert.EqualValues(t, 1, gm.GpuDataMap["0"].Count)
assert.Equal(t, float64(0), gm.GpuDataMap["0"].Count)
})
}
@@ -756,11 +756,11 @@ func TestAccumulation(t *testing.T) {
continue
}
assert.EqualValues(t, expected.temperature, gpu.Temperature, "Temperature should match")
assert.EqualValues(t, expected.memoryUsed, gpu.MemoryUsed, "Memory used should match")
assert.EqualValues(t, expected.memoryTotal, gpu.MemoryTotal, "Memory total should match")
assert.EqualValues(t, expected.usage, gpu.Usage, "Usage should match")
assert.EqualValues(t, expected.power, gpu.Power, "Power should match")
assert.InDelta(t, expected.temperature, gpu.Temperature, 0.01, "Temperature should match")
assert.InDelta(t, expected.memoryUsed, gpu.MemoryUsed, 0.01, "Memory used should match")
assert.InDelta(t, expected.memoryTotal, gpu.MemoryTotal, 0.01, "Memory total should match")
assert.InDelta(t, expected.usage, gpu.Usage, 0.01, "Usage should match")
assert.InDelta(t, expected.power, gpu.Power, 0.01, "Power should match")
assert.Equal(t, expected.count, gpu.Count, "Count should match")
}
@@ -773,320 +773,22 @@ func TestAccumulation(t *testing.T) {
continue
}
assert.EqualValues(t, expected.temperature, gpu.Temperature, "Temperature in GetCurrentData should match")
assert.EqualValues(t, expected.avgUsage, gpu.Usage, "Average usage in GetCurrentData should match")
assert.EqualValues(t, expected.avgPower, gpu.Power, "Average power in GetCurrentData should match")
assert.InDelta(t, expected.temperature, gpu.Temperature, 0.01, "Temperature in GetCurrentData should match")
assert.InDelta(t, expected.avgUsage, gpu.Usage, 0.01, "Average usage in GetCurrentData should match")
assert.InDelta(t, expected.avgPower, gpu.Power, 0.01, "Average power in GetCurrentData should match")
}
// Verify that accumulators in the original map are reset
for id, expected := range tt.expectedValues {
for id := range tt.expectedValues {
gpu, exists := gm.GpuDataMap[id]
assert.True(t, exists, "GPU with ID %s should still exist after GetCurrentData", id)
if !exists {
continue
}
assert.EqualValues(t, 1, gpu.Count, "Count should be reset for GPU ID %s", id)
assert.EqualValues(t, expected.avgUsage, gpu.Usage, "Usage should be reset for GPU ID %s", id)
assert.EqualValues(t, expected.avgPower, gpu.Power, "Power should be reset for GPU ID %s", id)
assert.Equal(t, float64(0), gpu.Count, "Count should be reset for GPU ID %s", id)
assert.Equal(t, float64(0), gpu.Usage, "Usage should be reset for GPU ID %s", id)
assert.Equal(t, float64(0), gpu.Power, "Power should be reset for GPU ID %s", id)
}
})
}
}
func TestIntelUpdateFromStats(t *testing.T) {
gm := &GPUManager{
GpuDataMap: make(map[string]*system.GPUData),
}
// First sample with power and two engines
sample1 := intelGpuStats{
PowerGPU: 10.5,
Engines: map[string]float64{
"Render/3D": 20.0,
"Video": 5.0,
},
}
ok := gm.updateIntelFromStats(&sample1)
assert.True(t, ok)
gpu := gm.GpuDataMap["0"]
require.NotNil(t, gpu)
assert.Equal(t, "GPU", gpu.Name)
assert.EqualValues(t, 10.5, gpu.Power)
assert.EqualValues(t, 20.0, gpu.Engines["Render/3D"])
assert.EqualValues(t, 5.0, gpu.Engines["Video"])
assert.Equal(t, float64(1), gpu.Count)
// Second sample with zero power (should not add) and additional engine busy
sample2 := intelGpuStats{
PowerGPU: 0.0,
Engines: map[string]float64{
"Render/3D": 10.0,
"Video": 2.5,
"Blitter": 1.0,
},
}
// zero power should not increment power accumulator
ok = gm.updateIntelFromStats(&sample2)
assert.True(t, ok)
gpu = gm.GpuDataMap["0"]
require.NotNil(t, gpu)
assert.EqualValues(t, 10.5, gpu.Power)
assert.EqualValues(t, 30.0, gpu.Engines["Render/3D"]) // 20 + 10
assert.EqualValues(t, 7.5, gpu.Engines["Video"]) // 5 + 2.5
assert.EqualValues(t, 1.0, gpu.Engines["Blitter"])
assert.Equal(t, float64(2), gpu.Count)
}
func TestIntelCollectorStreaming(t *testing.T) {
// Save and override PATH
origPath := os.Getenv("PATH")
defer os.Setenv("PATH", origPath)
dir := t.TempDir()
os.Setenv("PATH", dir)
// Create a fake intel_gpu_top that prints -l format with four samples (first will be skipped) and exits
scriptPath := filepath.Join(dir, "intel_gpu_top")
script := `#!/bin/sh
echo "Freq MHz IRQ RC6 Power W IMC MiB/s RCS BCS VCS"
echo " req act /s % gpu pkg rd wr % se wa % se wa % se wa"
echo "373 373 224 45 1.50 4.13 2554 714 12.34 0 0 0.00 0 0 5.00 0 0"
echo "226 223 338 58 2.00 2.69 1820 965 0.00 0 0 0.00 0 0 0.00 0 0"
echo "189 187 412 67 1.80 2.45 1950 823 8.50 2 1 15.00 1 0 22.00 0 1"
echo "298 295 278 51 2.20 3.12 1675 942 5.75 1 2 9.50 3 1 12.00 1 0"`
if err := os.WriteFile(scriptPath, []byte(script), 0755); err != nil {
t.Fatal(err)
}
gm := &GPUManager{
GpuDataMap: make(map[string]*system.GPUData),
}
// Run the collector once; it should read four samples but skip the first and return
if err := gm.collectIntelStats(); err != nil {
t.Fatalf("collectIntelStats error: %v", err)
}
gpu := gm.GpuDataMap["0"]
require.NotNil(t, gpu)
// Power should be sum of samples 2-4 (first is skipped): 2.0 + 1.8 + 2.2 = 6.0
assert.EqualValues(t, 6.0, gpu.Power)
assert.InDelta(t, 8.26, gpu.PowerPkg, 0.01) // Allow small floating point differences
// Engines aggregated from samples 2-4
assert.EqualValues(t, 14.25, gpu.Engines["Render/3D"]) // 0.00 + 8.50 + 5.75
assert.EqualValues(t, 34.0, gpu.Engines["Video"]) // 0.00 + 22.00 + 12.00
assert.EqualValues(t, 24.5, gpu.Engines["Blitter"]) // 0.00 + 15.00 + 9.50
// Count should be 3 samples (first is skipped)
assert.Equal(t, float64(3), gpu.Count)
}
func TestParseIntelHeaders(t *testing.T) {
tests := []struct {
name string
header1 string
header2 string
wantEngineNames []string
wantFriendlyNames []string
wantPowerIndex int
wantPreEngineCols int
}{
{
name: "basic headers with RCS BCS VCS",
header1: "Freq MHz IRQ RC6 Power W IMC MiB/s RCS BCS VCS",
header2: " req act /s % gpu pkg rd wr % se wa % se wa % se wa",
wantEngineNames: []string{"RCS", "BCS", "VCS"},
wantFriendlyNames: []string{"Render/3D", "Blitter", "Video"},
wantPowerIndex: 4, // "gpu" is at index 4
wantPreEngineCols: 8, // 17 total cols - 3*3 = 8
},
{
name: "headers with only RCS",
header1: "Freq MHz IRQ RC6 Power W IMC MiB/s RCS",
header2: " req act /s % gpu pkg rd wr % se wa",
wantEngineNames: []string{"RCS"},
wantFriendlyNames: []string{"Render/3D"},
wantPowerIndex: 4,
wantPreEngineCols: 8, // 11 total - 3*1 = 8
},
{
name: "headers with VECS and CCS",
header1: "Freq MHz IRQ RC6 Power W IMC MiB/s VECS CCS",
header2: " req act /s % gpu pkg rd wr % se wa % se wa",
wantEngineNames: []string{"VECS", "CCS"},
wantFriendlyNames: []string{"VideoEnhance", "Compute"},
wantPowerIndex: 4,
wantPreEngineCols: 8, // 14 total - 3*2 = 8
},
{
name: "no engines",
header1: "Freq MHz IRQ RC6 Power W IMC MiB/s",
header2: " req act /s % gpu pkg rd wr",
wantEngineNames: nil, // no engines found, slices remain nil
wantFriendlyNames: nil,
wantPowerIndex: -1, // no engines, so no search
wantPreEngineCols: 0,
},
{
name: "power index not found",
header1: "Freq MHz IRQ RC6 Power W IMC MiB/s RCS",
header2: " req act /s % pkg cpu rd wr % se wa", // no "gpu"
wantEngineNames: []string{"RCS"},
wantFriendlyNames: []string{"Render/3D"},
wantPowerIndex: -1, // "gpu" not found
wantPreEngineCols: 8, // 11 total - 3*1 = 8
},
{
name: "empty headers",
header1: "",
header2: "",
wantEngineNames: nil, // empty input, slices remain nil
wantFriendlyNames: nil,
wantPowerIndex: -1,
wantPreEngineCols: 0,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gm := &GPUManager{}
engineNames, friendlyNames, powerIndex, preEngineCols := gm.parseIntelHeaders(tt.header1, tt.header2)
assert.Equal(t, tt.wantEngineNames, engineNames)
assert.Equal(t, tt.wantFriendlyNames, friendlyNames)
assert.Equal(t, tt.wantPowerIndex, powerIndex)
assert.Equal(t, tt.wantPreEngineCols, preEngineCols)
})
}
}
func TestParseIntelData(t *testing.T) {
tests := []struct {
name string
line string
engineNames []string
friendlyNames []string
powerIndex int
preEngineCols int
wantPowerGPU float64
wantEngines map[string]float64
wantErr error
}{
{
name: "basic data with power and engines",
line: "373 373 224 45 1.50 4.13 2554 714 12.34 0 0 0.00 0 0 5.00 0 0",
engineNames: []string{"RCS", "BCS", "VCS"},
friendlyNames: []string{"Render/3D", "Blitter", "Video"},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 1.50,
wantEngines: map[string]float64{
"Render/3D": 12.34,
"Blitter": 0.00,
"Video": 5.00,
},
},
{
name: "data with zero power",
line: "226 223 338 58 0.00 2.69 1820 965 0.00 0 0 0.00 0 0 0.00 0 0",
engineNames: []string{"RCS", "BCS", "VCS"},
friendlyNames: []string{"Render/3D", "Blitter", "Video"},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 0.00,
wantEngines: map[string]float64{
"Render/3D": 0.00,
"Blitter": 0.00,
"Video": 0.00,
},
},
{
name: "data with no power index",
line: "373 373 224 45 1.50 4.13 2554 714 12.34 0 0 0.00 0 0 5.00 0 0",
engineNames: []string{"RCS", "BCS", "VCS"},
friendlyNames: []string{"Render/3D", "Blitter", "Video"},
powerIndex: -1,
preEngineCols: 8,
wantPowerGPU: 0.0, // no power parsed
wantEngines: map[string]float64{
"Render/3D": 12.34,
"Blitter": 0.00,
"Video": 5.00,
},
},
{
name: "data with insufficient columns",
line: "373 373 224 45 1.50", // too few columns
engineNames: []string{"RCS", "BCS", "VCS"},
friendlyNames: []string{"Render/3D", "Blitter", "Video"},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 0.0,
wantEngines: nil, // empty sample returned
wantErr: errNoValidData,
},
{
name: "empty line",
line: "",
engineNames: []string{"RCS"},
friendlyNames: []string{"Render/3D"},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 0.0,
wantEngines: nil,
wantErr: errNoValidData,
},
{
name: "data with invalid power value",
line: "373 373 224 45 N/A 4.13 2554 714 12.34 0 0 0.00 0 0 5.00 0 0",
engineNames: []string{"RCS", "BCS", "VCS"},
friendlyNames: []string{"Render/3D", "Blitter", "Video"},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 0.0, // N/A can't be parsed
wantEngines: map[string]float64{
"Render/3D": 12.34,
"Blitter": 0.00,
"Video": 5.00,
},
},
{
name: "data with invalid engine value",
line: "373 373 224 45 1.50 4.13 2554 714 N/A 0 0 0.00 0 0 5.00 0 0",
engineNames: []string{"RCS", "BCS", "VCS"},
friendlyNames: []string{"Render/3D", "Blitter", "Video"},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 1.50,
wantEngines: map[string]float64{
"Render/3D": 0.0, // N/A becomes 0
"Blitter": 0.00,
"Video": 5.00,
},
},
{
name: "data with no engines",
line: "373 373 224 45 1.50 4.13 2554 714",
engineNames: []string{},
friendlyNames: []string{},
powerIndex: 4,
preEngineCols: 8,
wantPowerGPU: 1.50,
wantEngines: nil,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gm := &GPUManager{}
sample, err := gm.parseIntelData(tt.line, tt.engineNames, tt.friendlyNames, tt.powerIndex, tt.preEngineCols)
assert.Equal(t, tt.wantErr, err)
assert.Equal(t, tt.wantPowerGPU, sample.PowerGPU)
assert.Equal(t, tt.wantEngines, sample.Engines)
})
}
}

View File

@@ -1,163 +1,25 @@
package agent
import (
"fmt"
"log/slog"
"path"
"strings"
"time"
"github.com/henrygd/beszel/agent/deltatracker"
"github.com/henrygd/beszel/internal/entities/system"
psutilNet "github.com/shirou/gopsutil/v4/net"
)
var netInterfaceDeltaTracker = deltatracker.NewDeltaTracker[string, uint64]()
// NicConfig controls inclusion/exclusion of network interfaces via the NICS env var
//
// Behavior mirrors SensorConfig's matching logic:
// - Leading '-' means blacklist mode; otherwise whitelist mode
// - Supports '*' wildcards using path.Match
// - In whitelist mode with an empty list, no NICs are selected
// - In blacklist mode with an empty list, all NICs are selected
type NicConfig struct {
nics map[string]struct{}
isBlacklist bool
hasWildcards bool
}
func newNicConfig(nicsEnvVal string) *NicConfig {
cfg := &NicConfig{
nics: make(map[string]struct{}),
}
if strings.HasPrefix(nicsEnvVal, "-") {
cfg.isBlacklist = true
nicsEnvVal = nicsEnvVal[1:]
}
for nic := range strings.SplitSeq(nicsEnvVal, ",") {
nic = strings.TrimSpace(nic)
if nic != "" {
cfg.nics[nic] = struct{}{}
if strings.Contains(nic, "*") {
cfg.hasWildcards = true
}
}
}
return cfg
}
// isValidNic determines if a NIC should be included based on NicConfig rules
func isValidNic(nicName string, cfg *NicConfig) bool {
// Empty list behavior differs by mode: blacklist: allow all; whitelist: allow none
if len(cfg.nics) == 0 {
return cfg.isBlacklist
}
// Exact match: return true if whitelist, false if blacklist
if _, exactMatch := cfg.nics[nicName]; exactMatch {
return !cfg.isBlacklist
}
// If no wildcards, return true if blacklist, false if whitelist
if !cfg.hasWildcards {
return cfg.isBlacklist
}
// Check for wildcard patterns
for pattern := range cfg.nics {
if !strings.Contains(pattern, "*") {
continue
}
if match, _ := path.Match(pattern, nicName); match {
return !cfg.isBlacklist
}
}
return cfg.isBlacklist
}
func (a *Agent) updateNetworkStats(systemStats *system.Stats) {
// network stats
if len(a.netInterfaces) == 0 {
// if no network interfaces, initialize again
// this is a fix if agent started before network is online (#466)
// maybe refactor this in the future to not cache interface names at all so we
// don't miss an interface that's been added after agent started in any circumstance
a.initializeNetIoStats()
}
if systemStats.NetworkInterfaces == nil {
systemStats.NetworkInterfaces = make(map[string][4]uint64, 0)
}
if netIO, err := psutilNet.IOCounters(true); err == nil {
msElapsed := uint64(time.Since(a.netIoStats.Time).Milliseconds())
a.netIoStats.Time = time.Now()
totalBytesSent := uint64(0)
totalBytesRecv := uint64(0)
netInterfaceDeltaTracker.Cycle()
// sum all bytes sent and received
for _, v := range netIO {
// skip if not in valid network interfaces list
if _, exists := a.netInterfaces[v.Name]; !exists {
continue
}
totalBytesSent += v.BytesSent
totalBytesRecv += v.BytesRecv
// track deltas for each network interface
var upDelta, downDelta uint64
upKey, downKey := fmt.Sprintf("%sup", v.Name), fmt.Sprintf("%sdown", v.Name)
netInterfaceDeltaTracker.Set(upKey, v.BytesSent)
netInterfaceDeltaTracker.Set(downKey, v.BytesRecv)
if msElapsed > 0 {
upDelta = netInterfaceDeltaTracker.Delta(upKey) * 1000 / msElapsed
downDelta = netInterfaceDeltaTracker.Delta(downKey) * 1000 / msElapsed
}
// add interface to systemStats
systemStats.NetworkInterfaces[v.Name] = [4]uint64{upDelta, downDelta, v.BytesSent, v.BytesRecv}
}
// add to systemStats
var bytesSentPerSecond, bytesRecvPerSecond uint64
if msElapsed > 0 {
bytesSentPerSecond = (totalBytesSent - a.netIoStats.BytesSent) * 1000 / msElapsed
bytesRecvPerSecond = (totalBytesRecv - a.netIoStats.BytesRecv) * 1000 / msElapsed
}
networkSentPs := bytesToMegabytes(float64(bytesSentPerSecond))
networkRecvPs := bytesToMegabytes(float64(bytesRecvPerSecond))
// add check for issue (#150) where sent is a massive number
if networkSentPs > 10_000 || networkRecvPs > 10_000 {
slog.Warn("Invalid net stats. Resetting.", "sent", networkSentPs, "recv", networkRecvPs)
for _, v := range netIO {
if _, exists := a.netInterfaces[v.Name]; !exists {
continue
}
slog.Info(v.Name, "recv", v.BytesRecv, "sent", v.BytesSent)
}
// reset network I/O stats
a.initializeNetIoStats()
} else {
systemStats.NetworkSent = networkSentPs
systemStats.NetworkRecv = networkRecvPs
systemStats.Bandwidth[0], systemStats.Bandwidth[1] = bytesSentPerSecond, bytesRecvPerSecond
// update netIoStats
a.netIoStats.BytesSent = totalBytesSent
a.netIoStats.BytesRecv = totalBytesRecv
}
}
}
func (a *Agent) initializeNetIoStats() {
// reset valid network interfaces
a.netInterfaces = make(map[string]struct{}, 0)
// parse NICS env var for whitelist / blacklist
nicsEnvVal, nicsEnvExists := GetEnv("NICS")
var nicCfg *NicConfig
// map of network interface names passed in via NICS env var
var nicsMap map[string]struct{}
nics, nicsEnvExists := GetEnv("NICS")
if nicsEnvExists {
nicCfg = newNicConfig(nicsEnvVal)
nicsMap = make(map[string]struct{}, 0)
for nic := range strings.SplitSeq(nics, ",") {
nicsMap[nic] = struct{}{}
}
}
// reset network I/O stats
@@ -168,11 +30,17 @@ func (a *Agent) initializeNetIoStats() {
if netIO, err := psutilNet.IOCounters(true); err == nil {
a.netIoStats.Time = time.Now()
for _, v := range netIO {
if nicsEnvExists && !isValidNic(v.Name, nicCfg) {
continue
}
if a.skipNetworkInterface(v) {
continue
switch {
// skip if nics exists and the interface is not in the list
case nicsEnvExists:
if _, nameInNics := nicsMap[v.Name]; !nameInNics {
continue
}
// otherwise run the interface name through the skipNetworkInterface function
default:
if a.skipNetworkInterface(v) {
continue
}
}
slog.Info("Detected network interface", "name", v.Name, "sent", v.BytesSent, "recv", v.BytesRecv)
a.netIoStats.BytesSent += v.BytesSent
@@ -190,7 +58,6 @@ func (a *Agent) skipNetworkInterface(v psutilNet.IOCountersStat) bool {
strings.HasPrefix(v.Name, "br-"),
strings.HasPrefix(v.Name, "veth"),
strings.HasPrefix(v.Name, "bond"),
strings.HasPrefix(v.Name, "cali"),
v.BytesRecv == 0,
v.BytesSent == 0:
return true

View File

@@ -1,259 +0,0 @@
//go:build testing
package agent
import (
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestIsValidNic(t *testing.T) {
tests := []struct {
name string
nicName string
config *NicConfig
expectedValid bool
}{
{
name: "Whitelist - NIC in list",
nicName: "eth0",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}},
isBlacklist: false,
},
expectedValid: true,
},
{
name: "Whitelist - NIC not in list",
nicName: "wlan0",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}},
isBlacklist: false,
},
expectedValid: false,
},
{
name: "Blacklist - NIC in list",
nicName: "eth0",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}},
isBlacklist: true,
},
expectedValid: false,
},
{
name: "Blacklist - NIC not in list",
nicName: "wlan0",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}},
isBlacklist: true,
},
expectedValid: true,
},
{
name: "Whitelist with wildcard - matching pattern",
nicName: "eth1",
config: &NicConfig{
nics: map[string]struct{}{"eth*": {}},
isBlacklist: false,
hasWildcards: true,
},
expectedValid: true,
},
{
name: "Whitelist with wildcard - non-matching pattern",
nicName: "wlan0",
config: &NicConfig{
nics: map[string]struct{}{"eth*": {}},
isBlacklist: false,
hasWildcards: true,
},
expectedValid: false,
},
{
name: "Blacklist with wildcard - matching pattern",
nicName: "eth1",
config: &NicConfig{
nics: map[string]struct{}{"eth*": {}},
isBlacklist: true,
hasWildcards: true,
},
expectedValid: false,
},
{
name: "Blacklist with wildcard - non-matching pattern",
nicName: "wlan0",
config: &NicConfig{
nics: map[string]struct{}{"eth*": {}},
isBlacklist: true,
hasWildcards: true,
},
expectedValid: true,
},
{
name: "Empty whitelist config - no NICs allowed",
nicName: "eth0",
config: &NicConfig{
nics: map[string]struct{}{},
isBlacklist: false,
},
expectedValid: false,
},
{
name: "Empty blacklist config - all NICs allowed",
nicName: "eth0",
config: &NicConfig{
nics: map[string]struct{}{},
isBlacklist: true,
},
expectedValid: true,
},
{
name: "Multiple patterns - exact match",
nicName: "eth0",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "wlan*": {}},
isBlacklist: false,
},
expectedValid: true,
},
{
name: "Multiple patterns - wildcard match",
nicName: "wlan1",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "wlan*": {}},
isBlacklist: false,
hasWildcards: true,
},
expectedValid: true,
},
{
name: "Multiple patterns - no match",
nicName: "bond0",
config: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "wlan*": {}},
isBlacklist: false,
hasWildcards: true,
},
expectedValid: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := isValidNic(tt.nicName, tt.config)
assert.Equal(t, tt.expectedValid, result)
})
}
}
func TestNewNicConfig(t *testing.T) {
tests := []struct {
name string
nicsEnvVal string
expectedCfg *NicConfig
}{
{
name: "Empty string",
nicsEnvVal: "",
expectedCfg: &NicConfig{
nics: map[string]struct{}{},
isBlacklist: false,
hasWildcards: false,
},
},
{
name: "Single NIC whitelist",
nicsEnvVal: "eth0",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth0": {}},
isBlacklist: false,
hasWildcards: false,
},
},
{
name: "Multiple NICs whitelist",
nicsEnvVal: "eth0,wlan0",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "wlan0": {}},
isBlacklist: false,
hasWildcards: false,
},
},
{
name: "Blacklist mode",
nicsEnvVal: "-eth0,wlan0",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "wlan0": {}},
isBlacklist: true,
hasWildcards: false,
},
},
{
name: "With wildcards",
nicsEnvVal: "eth*,wlan0",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth*": {}, "wlan0": {}},
isBlacklist: false,
hasWildcards: true,
},
},
{
name: "Blacklist with wildcards",
nicsEnvVal: "-eth*,wlan0",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth*": {}, "wlan0": {}},
isBlacklist: true,
hasWildcards: true,
},
},
{
name: "With whitespace",
nicsEnvVal: "eth0, wlan0 , eth1",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "wlan0": {}, "eth1": {}},
isBlacklist: false,
hasWildcards: false,
},
},
{
name: "Only wildcards",
nicsEnvVal: "eth*,wlan*",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth*": {}, "wlan*": {}},
isBlacklist: false,
hasWildcards: true,
},
},
{
name: "Leading dash only",
nicsEnvVal: "-",
expectedCfg: &NicConfig{
nics: map[string]struct{}{},
isBlacklist: true,
hasWildcards: false,
},
},
{
name: "Mixed exact and wildcard",
nicsEnvVal: "eth0,br-*",
expectedCfg: &NicConfig{
nics: map[string]struct{}{"eth0": {}, "br-*": {}},
isBlacklist: false,
hasWildcards: true,
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
cfg := newNicConfig(tt.nicsEnvVal)
require.NotNil(t, cfg)
assert.Equal(t, tt.expectedCfg.isBlacklist, cfg.isBlacklist)
assert.Equal(t, tt.expectedCfg.hasWildcards, cfg.hasWildcards)
assert.Equal(t, tt.expectedCfg.nics, cfg.nics)
})
}
}

View File

@@ -18,6 +18,7 @@ import (
"github.com/shirou/gopsutil/v4/host"
"github.com/shirou/gopsutil/v4/load"
"github.com/shirou/gopsutil/v4/mem"
psutilNet "github.com/shirou/gopsutil/v4/net"
)
// Sets initial / non-changing values about the host system
@@ -31,7 +32,7 @@ func (a *Agent) initializeSystemInfo() {
a.systemInfo.KernelVersion = version
a.systemInfo.Os = system.Darwin
} else if strings.Contains(platform, "indows") {
a.systemInfo.KernelVersion = fmt.Sprintf("%s %s", strings.Replace(platform, "Microsoft ", "", 1), version)
a.systemInfo.KernelVersion = strings.Replace(platform, "Microsoft ", "", 1) + " " + version
a.systemInfo.Os = system.Windows
} else if platform == "freebsd" {
a.systemInfo.Os = system.Freebsd
@@ -69,7 +70,7 @@ func (a *Agent) initializeSystemInfo() {
// Returns current info, stats about the host system
func (a *Agent) getSystemStats() system.Stats {
var systemStats system.Stats
systemStats := system.Stats{}
// battery
if battery.HasReadableBattery() {
@@ -100,22 +101,14 @@ func (a *Agent) getSystemStats() system.Stats {
systemStats.Swap = bytesToGigabytes(v.SwapTotal)
systemStats.SwapUsed = bytesToGigabytes(v.SwapTotal - v.SwapFree - v.SwapCached)
// cache + buffers value for default mem calculation
// note: gopsutil automatically adds SReclaimable to v.Cached
cacheBuff := v.Cached + v.Buffers - v.Shared
if cacheBuff <= 0 {
cacheBuff = max(v.Total-v.Free-v.Used, 0)
}
// htop memory calculation overrides (likely outdated as of mid 2025)
cacheBuff := v.Total - v.Free - v.Used
// htop memory calculation overrides
if a.memCalc == "htop" {
// cacheBuff = v.Cached + v.Buffers - v.Shared
// note: gopsutil automatically adds SReclaimable to v.Cached
cacheBuff = v.Cached + v.Buffers - v.Shared
v.Used = v.Total - (v.Free + cacheBuff)
v.UsedPercent = float64(v.Used) / float64(v.Total) * 100.0
}
// if a.memCalc == "legacy" {
// v.Used = v.Total - v.Free - v.Buffers - v.Cached
// cacheBuff = v.Total - v.Free - v.Used
// v.UsedPercent = float64(v.Used) / float64(v.Total) * 100.0
// }
// subtract ZFS ARC size from used memory and add as its own category
if a.zfs {
if arcSize, _ := getARCSize(); arcSize > 0 && arcSize < v.Used {
@@ -180,7 +173,55 @@ func (a *Agent) getSystemStats() system.Stats {
}
// network stats
a.updateNetworkStats(&systemStats)
if len(a.netInterfaces) == 0 {
// if no network interfaces, initialize again
// this is a fix if agent started before network is online (#466)
// maybe refactor this in the future to not cache interface names at all so we
// don't miss an interface that's been added after agent started in any circumstance
a.initializeNetIoStats()
}
if netIO, err := psutilNet.IOCounters(true); err == nil {
msElapsed := uint64(time.Since(a.netIoStats.Time).Milliseconds())
a.netIoStats.Time = time.Now()
totalBytesSent := uint64(0)
totalBytesRecv := uint64(0)
// sum all bytes sent and received
for _, v := range netIO {
// skip if not in valid network interfaces list
if _, exists := a.netInterfaces[v.Name]; !exists {
continue
}
totalBytesSent += v.BytesSent
totalBytesRecv += v.BytesRecv
}
// add to systemStats
var bytesSentPerSecond, bytesRecvPerSecond uint64
if msElapsed > 0 {
bytesSentPerSecond = (totalBytesSent - a.netIoStats.BytesSent) * 1000 / msElapsed
bytesRecvPerSecond = (totalBytesRecv - a.netIoStats.BytesRecv) * 1000 / msElapsed
}
networkSentPs := bytesToMegabytes(float64(bytesSentPerSecond))
networkRecvPs := bytesToMegabytes(float64(bytesRecvPerSecond))
// add check for issue (#150) where sent is a massive number
if networkSentPs > 10_000 || networkRecvPs > 10_000 {
slog.Warn("Invalid net stats. Resetting.", "sent", networkSentPs, "recv", networkRecvPs)
for _, v := range netIO {
if _, exists := a.netInterfaces[v.Name]; !exists {
continue
}
slog.Info(v.Name, "recv", v.BytesRecv, "sent", v.BytesSent)
}
// reset network I/O stats
a.initializeNetIoStats()
} else {
systemStats.NetworkSent = networkSentPs
systemStats.NetworkRecv = networkRecvPs
systemStats.Bandwidth[0], systemStats.Bandwidth[1] = bytesSentPerSecond, bytesRecvPerSecond
// update netIoStats
a.netIoStats.BytesSent = totalBytesSent
a.netIoStats.BytesRecv = totalBytesRecv
}
}
// temperatures
// TODO: maybe refactor to methods on systemStats
@@ -220,7 +261,6 @@ func (a *Agent) getSystemStats() system.Stats {
}
// update base system info
a.systemInfo.ConnectionType = a.connectionManager.ConnectionType
a.systemInfo.Cpu = systemStats.Cpu
a.systemInfo.LoadAvg = systemStats.LoadAvg
// TODO: remove these in future release in favor of load avg array

View File

@@ -1,107 +0,0 @@
//go:build linux
package agent
import (
"context"
"log/slog"
"math"
"strings"
"sync"
"github.com/coreos/go-systemd/v22/dbus"
"github.com/henrygd/beszel/internal/entities/systemd"
)
// systemdManager manages the collection of systemd service statistics.
type systemdManager struct {
conn *dbus.Conn
serviceStatsMap map[string]*systemd.Service
mu sync.Mutex
}
// newSystemdManager creates a new systemdManager.
func newSystemdManager() (*systemdManager, error) {
conn, err := dbus.New()
if err != nil {
if strings.Contains(err.Error(), "permission denied") {
slog.Error("Permission denied when connecting to systemd. Run as root or with appropriate user permissions.", "err", err)
return nil, err
}
slog.Error("Error connecting to systemd", "err", err)
return nil, err
}
return &systemdManager{
conn: conn,
serviceStatsMap: make(map[string]*systemd.Service),
}, nil
}
// getServiceStats collects statistics for all running systemd services.
func (sm *systemdManager) getServiceStats() []*systemd.Service {
units, err := sm.conn.ListUnitsContext(context.Background())
if err != nil {
slog.Error("Error listing systemd units", "err", err)
return nil
}
var services []*systemd.Service
for _, unit := range units {
if strings.HasSuffix(unit.Name, ".service") {
service := sm.updateServiceStats(unit)
services = append(services, service)
}
}
return services
}
// updateServiceStats updates the statistics for a single systemd service.
func (sm *systemdManager) updateServiceStats(unit dbus.UnitStatus) *systemd.Service {
sm.mu.Lock()
defer sm.mu.Unlock()
props, err := sm.conn.GetUnitTypeProperties(unit.Name, "Service")
if err != nil {
slog.Debug("could not get unit type properties", "unit", unit.Name, "err", err)
return &systemd.Service{
Name: unit.Name,
Status: unit.ActiveState,
}
}
var cpuUsage uint64
if val, ok := props["CPUUsageNSec"]; ok {
if v, ok := val.(uint64); ok {
cpuUsage = v
}
}
var memUsage uint64
if val, ok := props["MemoryCurrent"]; ok {
if v, ok := val.(uint64); ok {
memUsage = v
}
}
service, exists := sm.serviceStatsMap[unit.Name]
if !exists {
service = &systemd.Service{
Name: unit.Name,
Status: unit.ActiveState,
}
sm.serviceStatsMap[unit.Name] = service
}
service.Status = unit.ActiveState
// If memUsage is MaxUint64 the api is saying it's not available, return 0
if memUsage == math.MaxUint64 {
memUsage = 0
}
service.Mem = float64(memUsage) / (1024 * 1024) // Convert to MB
service.CalculateCPUPercent(cpuUsage)
return service
}

View File

@@ -1,18 +0,0 @@
//go:build !linux
package agent
import "github.com/henrygd/beszel/internal/entities/systemd"
// systemdManager manages the collection of systemd service statistics.
type systemdManager struct{}
// newSystemdManager creates a new systemdManager.
func newSystemdManager() (*systemdManager, error) {
return &systemdManager{}, nil
}
// getServiceStats returns nil for non-linux systems.
func (sm *systemdManager) getServiceStats() []*systemd.Service {
return nil
}

View File

@@ -30,11 +30,11 @@ func (s *systemdRestarter) Restart() error {
type openRCRestarter struct{ cmd string }
func (o *openRCRestarter) Restart() error {
if err := exec.Command(o.cmd, "beszel-agent", "status").Run(); err != nil {
if err := exec.Command(o.cmd, "status", "beszel-agent").Run(); err != nil {
return nil
}
ghupdate.ColorPrint(ghupdate.ColorYellow, "Restarting beszel-agent via OpenRC…")
return exec.Command(o.cmd, "beszel-agent", "restart").Run()
return exec.Command(o.cmd, "restart", "beszel-agent").Run()
}
type openWRTRestarter struct{ cmd string }

View File

@@ -6,7 +6,7 @@ import "github.com/blang/semver"
const (
// Version is the current version of the application.
Version = "0.12.12"
Version = "0.12.7"
// AppName is the name of the application.
AppName = "beszel"
)

40
go.mod
View File

@@ -3,26 +3,25 @@ module github.com/henrygd/beszel
go 1.25.1
// lock shoutrrr to specific version to allow review before updating
replace github.com/nicholas-fedor/shoutrrr => github.com/nicholas-fedor/shoutrrr v0.9.1
replace github.com/nicholas-fedor/shoutrrr => github.com/nicholas-fedor/shoutrrr v0.8.8
require (
github.com/blang/semver v3.5.1+incompatible
github.com/coreos/go-systemd/v22 v22.6.0
github.com/distatus/battery v0.11.0
github.com/fxamacker/cbor/v2 v2.9.0
github.com/gliderlabs/ssh v0.3.8
github.com/google/uuid v1.6.0
github.com/lxzan/gws v1.8.9
github.com/nicholas-fedor/shoutrrr v0.9.1
github.com/nicholas-fedor/shoutrrr v0.8.17
github.com/pocketbase/dbx v1.11.0
github.com/pocketbase/pocketbase v0.30.0
github.com/shirou/gopsutil/v4 v4.25.8
github.com/spf13/cast v1.10.0
github.com/spf13/cobra v1.10.1
github.com/spf13/pflag v1.0.10
github.com/stretchr/testify v1.11.1
golang.org/x/crypto v0.42.0
golang.org/x/exp v0.0.0-20250911091902-df9299821621
github.com/pocketbase/pocketbase v0.29.3
github.com/shirou/gopsutil/v4 v4.25.6
github.com/spf13/cast v1.9.2
github.com/spf13/cobra v1.9.1
github.com/spf13/pflag v1.0.7
github.com/stretchr/testify v1.11.0
golang.org/x/crypto v0.41.0
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b
gopkg.in/yaml.v3 v3.0.1
)
@@ -34,18 +33,17 @@ require (
github.com/dolthub/maphash v0.1.0 // indirect
github.com/domodwyer/mailyak/v3 v3.6.2 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
github.com/ebitengine/purego v0.9.0 // indirect
github.com/ebitengine/purego v0.8.4 // indirect
github.com/fatih/color v1.18.0 // indirect
github.com/gabriel-vasile/mimetype v1.4.10 // indirect
github.com/gabriel-vasile/mimetype v1.4.9 // indirect
github.com/ganigeorgiev/fexpr v0.5.0 // indirect
github.com/go-ole/go-ole v1.3.0 // indirect
github.com/go-ozzo/ozzo-validation/v4 v4.3.0 // indirect
github.com/go-sql-driver/mysql v1.9.1 // indirect
github.com/godbus/dbus/v5 v5.1.0 // indirect
github.com/golang-jwt/jwt/v5 v5.3.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 // indirect
github.com/lufia/plan9stats v0.0.0-20250821153705-5981dea3221d // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/ncruces/go-strftime v0.1.9 // indirect
@@ -56,12 +54,12 @@ require (
github.com/tklauser/numcpus v0.10.0 // indirect
github.com/x448/float16 v0.8.4 // indirect
github.com/yusufpapurcu/wmi v1.2.4 // indirect
golang.org/x/image v0.31.0 // indirect
golang.org/x/net v0.44.0 // indirect
golang.org/x/oauth2 v0.31.0 // indirect
golang.org/x/sync v0.17.0 // indirect
golang.org/x/sys v0.36.0 // indirect
golang.org/x/text v0.29.0 // indirect
golang.org/x/image v0.30.0 // indirect
golang.org/x/net v0.43.0 // indirect
golang.org/x/oauth2 v0.30.0 // indirect
golang.org/x/sync v0.16.0 // indirect
golang.org/x/sys v0.35.0 // indirect
golang.org/x/text v0.28.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
howett.net/plist v1.0.1 // indirect
modernc.org/libc v1.66.3 // indirect

132
go.sum
View File

@@ -1,7 +1,5 @@
filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=
filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=
github.com/Masterminds/semver/v3 v3.4.0 h1:Zog+i5UMtVoCU8oKka5P7i9q9HgrJeGzI9SA1Xbatp0=
github.com/Masterminds/semver/v3 v3.4.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
github.com/asaskevich/govalidator v0.0.0-20200108200545-475eaeb16496/go.mod h1:oGkLhpf+kjZl6xBf758TQhh5XrAeiJv/7FRz/2spLIg=
@@ -9,8 +7,6 @@ github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3d
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
github.com/coreos/go-systemd/v22 v22.6.0 h1:aGVa/v8B7hpb0TKl0MWoAavPDmHvobFe5R5zn0bCJWo=
github.com/coreos/go-systemd/v22 v22.6.0/go.mod h1:iG+pp635Fo7ZmV/j14KUcmEyWF+0X7Lua8rrTWzYgWU=
github.com/cpuguy83/go-md2man/v2 v2.0.6/go.mod h1:oOW0eioCTA6cOiMLiUPZOpcVxMig6NIQQ7OS05n1F4g=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
@@ -25,22 +21,22 @@ github.com/domodwyer/mailyak/v3 v3.6.2 h1:x3tGMsyFhTCaxp6ycgR0FE/bu5QiNp+hetUuCO
github.com/domodwyer/mailyak/v3 v3.6.2/go.mod h1:lOm/u9CyCVWHeaAmHIdF4RiKVxKUT/H5XX10lIKAL6c=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/ebitengine/purego v0.9.0 h1:mh0zpKBIXDceC63hpvPuGLiJ8ZAa3DfrFTudmfi8A4k=
github.com/ebitengine/purego v0.9.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/ebitengine/purego v0.8.4 h1:CF7LEKg5FFOsASUj0+QwaXf8Ht6TlFxg09+S9wz0omw=
github.com/ebitengine/purego v0.8.4/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8=
github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fxamacker/cbor/v2 v2.9.0 h1:NpKPmjDBgUfBms6tr6JZkTHtfFGcMKsw3eGcmD/sapM=
github.com/fxamacker/cbor/v2 v2.9.0/go.mod h1:vM4b+DJCtHn+zz7h3FFp/hDAI9WNWCsZj23V5ytsSxQ=
github.com/gabriel-vasile/mimetype v1.4.10 h1:zyueNbySn/z8mJZHLt6IPw0KoZsiQNszIpU+bX4+ZK0=
github.com/gabriel-vasile/mimetype v1.4.10/go.mod h1:d+9Oxyo1wTzWdyVUPMmXFvp4F9tea18J8ufA774AB3s=
github.com/gabriel-vasile/mimetype v1.4.9 h1:5k+WDwEsD9eTLL8Tz3L0VnmVh9QxGjRmjBvAG7U/oYY=
github.com/gabriel-vasile/mimetype v1.4.9/go.mod h1:WnSQhFKJuBlRyLiKohA/2DtIlPFAbguNaG7QCHcyGok=
github.com/ganigeorgiev/fexpr v0.5.0 h1:XA9JxtTE/Xm+g/JFI6RfZEHSiQlk+1glLvRK1Lpv/Tk=
github.com/ganigeorgiev/fexpr v0.5.0/go.mod h1:RyGiGqmeXhEQ6+mlGdnUleLHgtzzu/VGO2WtJkF5drE=
github.com/gliderlabs/ssh v0.3.8 h1:a4YXD1V7xMF9g5nTkdfnja3Sxy1PVDCj1Zg4Wb8vY6c=
github.com/gliderlabs/ssh v0.3.8/go.mod h1:xYoytBv1sV0aL3CavoDuJIQNURXkkfPA/wxQ1pL1fAU=
github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI=
github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY=
github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE=
github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78=
@@ -51,21 +47,19 @@ github.com/go-sql-driver/mysql v1.9.1 h1:FrjNGn/BsJQjVRuSa8CBrM5BWA9BWoXXat3KrtS
github.com/go-sql-driver/mysql v1.9.1/go.mod h1:qn46aNg1333BRMNU69Lq93t8du/dwxI64Gl8i5p1WMU=
github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI=
github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo=
github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU=
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6 h1:EEHtgt9IwisQ2AZ4pIsMjahcegHh6rmhqxzIRQIyepY=
github.com/google/pprof v0.0.0-20250820193118-f64d9cf942d6/go.mod h1:I6V7YzU0XDpsHqbsyrghnFZLO1gwK6NPTNvmetQIk9U=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6 h1:BHT72Gu3keYf3ZEu2J0b1vyeLSOYI8bm5wbJM/8yDe8=
github.com/google/pprof v0.0.0-20250403155104-27863c87afa6/go.mod h1:boTsfXsheKC2y+lKOCMpSfarhxDeIzfZG1jqGcPl3cA=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
github.com/jarcoal/httpmock v1.4.1 h1:0Ju+VCFuARfFlhVXFc2HxlcQkfB+Xq12/EotHko+x2A=
github.com/jarcoal/httpmock v1.4.1/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
github.com/jarcoal/httpmock v1.4.0 h1:BvhqnH0JAYbNudL2GMJKgOHe2CtKlzJ/5rWKyp+hc2k=
github.com/jarcoal/httpmock v1.4.0/go.mod h1:ftW1xULwo+j0R0JJkJIIi7UKigZUXCLLanykgjwBXL0=
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
github.com/klauspost/compress v1.18.0 h1:c/Cqfb0r+Yi+JtIEq73FWXVkRonBlf0CRNYc8Zttxdo=
github.com/klauspost/compress v1.18.0/go.mod h1:2Pp+KzxcywXVXMr50+X0Q/Lsb43OQHYWRCY2AiWywWQ=
@@ -73,8 +67,8 @@ github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54 h1:mFWunSatvkQQDhpdyuFAYwyAan3hzCuma+Pz8sqvOfg=
github.com/lufia/plan9stats v0.0.0-20250827001030-24949be3fa54/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/lufia/plan9stats v0.0.0-20250821153705-5981dea3221d h1:vFzYZc8yji+9DmNRhpEbs8VBK4CgV/DPfGzeVJSSp/8=
github.com/lufia/plan9stats v0.0.0-20250821153705-5981dea3221d/go.mod h1:autxFIvghDt3jPTLoqZ9OZ7s9qTGNAWmYCjVFWPX/zg=
github.com/lxzan/gws v1.8.9 h1:VU3SGUeWlQrEwfUSfokcZep8mdg/BrUF+y73YYshdBM=
github.com/lxzan/gws v1.8.9/go.mod h1:d9yHaR1eDTBHagQC6KY7ycUOaz5KWeqQtP3xu7aMK8Y=
github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE=
@@ -83,19 +77,19 @@ github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWE
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4=
github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls=
github.com/nicholas-fedor/shoutrrr v0.9.1 h1:SEBhM6P1favzILO0f55CY3P9JwvM9RZ7B1ZMCl+Injs=
github.com/nicholas-fedor/shoutrrr v0.9.1/go.mod h1:khue5m8LYyMzdPWuJxDTJeT89l9gjwjA+a+r0e8qxxk=
github.com/onsi/ginkgo/v2 v2.25.3 h1:Ty8+Yi/ayDAGtk4XxmmfUy4GabvM+MegeB4cDLRi6nw=
github.com/onsi/ginkgo/v2 v2.25.3/go.mod h1:43uiyQC4Ed2tkOzLsEYm7hnrb7UJTWHYNsuy3bG/snE=
github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A=
github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k=
github.com/nicholas-fedor/shoutrrr v0.8.8 h1:F/oyoatWK5cbHPPgkjRZrA0262TP7KWuUQz9KskRtR8=
github.com/nicholas-fedor/shoutrrr v0.8.8/go.mod h1:T30Y+eoZFEjDk4HtOItcHQioZSOe3Z6a6aNfSz6jc5c=
github.com/onsi/ginkgo/v2 v2.23.4 h1:ktYTpKJAVZnDT4VjxSbiBenUjmlL/5QkBEocaWXiQus=
github.com/onsi/ginkgo/v2 v2.23.4/go.mod h1:Bt66ApGPBFzHyR+JO10Zbt0Gsp4uWxu5mIOTusL46e8=
github.com/onsi/gomega v1.37.0 h1:CdEG8g0S133B4OswTDC/5XPSzE1OeP29QOioj2PID2Y=
github.com/onsi/gomega v1.37.0/go.mod h1:8D9+Txp43QWKhM24yyOBEdpkzN8FvJyAwecBgsU4KU0=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pocketbase/dbx v1.11.0 h1:LpZezioMfT3K4tLrqA55wWFw1EtH1pM4tzSVa7kgszU=
github.com/pocketbase/dbx v1.11.0/go.mod h1:xXRCIAKTHMgUCyCKZm55pUOdvFziJjQfXaWKhu2vhMs=
github.com/pocketbase/pocketbase v0.30.0 h1:7v9O3hBYyHyptnnFjdP8tEJIuyHEfjhG6PC4gjf5eoE=
github.com/pocketbase/pocketbase v0.30.0/go.mod h1:gZIwampw4VqMcEdGHwBZgSa54xWIDgVJb4uINUMXLmA=
github.com/pocketbase/pocketbase v0.29.3 h1:Mj8o5awsbVJIdIoTuQNhfC2oL/c4aImQ3RyfFZlzFVg=
github.com/pocketbase/pocketbase v0.29.3/go.mod h1:oGpT67LObxCFK4V2fSL7J9YnPbBnnshOpJ5v3zcneww=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55 h1:o4JXh1EVt9k/+g42oCprj/FisM4qX9L3sZB3upGN2ZU=
github.com/power-devops/perfstat v0.0.0-20240221224432-82ca36839d55/go.mod h1:OmDBASR4679mdNQnz2pUhc2G8CO2JrUAVFDRBDP/hJE=
github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE=
@@ -103,19 +97,19 @@ github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qq
github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8=
github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/shirou/gopsutil/v4 v4.25.8 h1:NnAsw9lN7587WHxjJA9ryDnqhJpFH6A+wagYWTOH970=
github.com/shirou/gopsutil/v4 v4.25.8/go.mod h1:q9QdMmfAOVIw7a+eF86P7ISEU6ka+NLgkUxlopV4RwI=
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.10.1 h1:lJeBwCfmrnXthfAupyUTzJ/J4Nc1RsHC/mSRU2dll/s=
github.com/spf13/cobra v1.10.1/go.mod h1:7SmJGaTHFVBY0jW4NXGluQoLvhqFQM+6XSKD+P4XaB0=
github.com/spf13/pflag v1.0.9/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/shirou/gopsutil/v4 v4.25.6 h1:kLysI2JsKorfaFPcYmcJqbzROzsBWEOAtw6A7dIfqXs=
github.com/shirou/gopsutil/v4 v4.25.6/go.mod h1:PfybzyydfZcN+JMMjkF6Zb8Mq1A/VcogFFg7hj50W9c=
github.com/spf13/cast v1.9.2 h1:SsGfm7M8QOFtEzumm7UZrZdLLquNdzFYfIbEXntcFbE=
github.com/spf13/cast v1.9.2/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
github.com/spf13/cobra v1.9.1 h1:CXSaggrXdbHK9CF+8ywj8Amf7PBRmPCOJugH954Nnlo=
github.com/spf13/cobra v1.9.1/go.mod h1:nDyEzZ8ogv936Cinf6g1RU9MRY64Ir93oCnqb9wxYW0=
github.com/spf13/pflag v1.0.6/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/spf13/pflag v1.0.7 h1:vN6T9TfwStFPFM5XzjsvmzZkLuaLX+HS+0SeFLRgU6M=
github.com/spf13/pflag v1.0.7/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/stretchr/testify v1.11.0 h1:ib4sjIrwZKxE5u/Japgo/7SJV3PvgjGiRNAvTVGqQl8=
github.com/stretchr/testify v1.11.0/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
github.com/tklauser/go-sysconf v0.3.15 h1:VE89k0criAymJ/Os65CSn1IXaol+1wrsFHEB8Ol49K4=
github.com/tklauser/go-sysconf v0.3.15/go.mod h1:Dmjwr6tYFIseJw7a3dRLJfsHAMXZ3nEnL/aZY+0IuI4=
github.com/tklauser/numcpus v0.10.0 h1:18njr6LDBk1zuna922MgdjQuJFjrdppsZG60sHGfjso=
@@ -126,44 +120,42 @@ github.com/yusufpapurcu/wmi v1.2.4 h1:zFUKzehAFReQwLys1b/iSMl+JQGSCSjtVqQn9bBrPo
github.com/yusufpapurcu/wmi v1.2.4/go.mod h1:SBZ9tNy3G9/m5Oi98Zks0QjeHVDvuK0qfxQmPyzfmi0=
go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs=
go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8=
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.42.0 h1:chiH31gIWm57EkTXpwnqf8qeuMUi0yekh6mT2AvFlqI=
golang.org/x/crypto v0.42.0/go.mod h1:4+rDnOTJhQCx2q7/j6rAN5XDw8kPjeaXEUR2eL94ix8=
golang.org/x/exp v0.0.0-20250911091902-df9299821621 h1:2id6c1/gto0kaHYyrixvknJ8tUK/Qs5IsmBtrc+FtgU=
golang.org/x/exp v0.0.0-20250911091902-df9299821621/go.mod h1:TwQYMMnGpvZyc+JpB/UAuTNIsVJifOlSkrZkhcvpVUk=
golang.org/x/crypto v0.41.0 h1:WKYxWedPGCTVVl5+WHSSrOBT0O8lx32+zxmHxijgXp4=
golang.org/x/crypto v0.41.0/go.mod h1:pO5AFd7FA68rFak7rOAGVuygIISepHftHnr8dr6+sUc=
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b h1:DXr+pvt3nC887026GRP39Ej11UATqWDmWuS99x26cD0=
golang.org/x/exp v0.0.0-20250819193227-8b4c13bb791b/go.mod h1:4QTo5u+SEIbbKW1RacMZq1YEfOBqeXa19JeshGi+zc4=
golang.org/x/image v0.0.0-20191009234506-e7c1f5e7dbb8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
golang.org/x/image v0.31.0 h1:mLChjE2MV6g1S7oqbXC0/UcKijjm5fnJLUYKIYrLESA=
golang.org/x/image v0.31.0/go.mod h1:R9ec5Lcp96v9FTF+ajwaH3uGxPH4fKfHHAVbUILxghA=
golang.org/x/mod v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/mod v0.28.0/go.mod h1:yfB/L0NOf/kmEbXjzCPOx1iK1fRutOydrCMsqRhEBxI=
golang.org/x/image v0.30.0 h1:jD5RhkmVAnjqaCUXfbGBrn3lpxbknfN9w2UhHHU+5B4=
golang.org/x/image v0.30.0/go.mod h1:SAEUTxCCMWSrJcCy/4HwavEsfZZJlYxeHLc6tTiAe/c=
golang.org/x/mod v0.27.0 h1:kb+q2PyFnEADO2IEF935ehFUXlWiNjJWtRNgBLSfbxQ=
golang.org/x/mod v0.27.0/go.mod h1:rWI627Fq0DEoudcK+MBkNkCe0EetEaDSwJJkCcjpazc=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
golang.org/x/oauth2 v0.31.0 h1:8Fq0yVZLh4j4YA47vHKFTa9Ew5XIrCP8LC6UeNZnLxo=
golang.org/x/oauth2 v0.31.0/go.mod h1:lzm5WQJQwKZ3nwavOZ3IS5Aulzxi68dUSgRHujetwEA=
golang.org/x/sync v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sync v0.17.0/go.mod h1:9KTHXmSnoGruLpwFjVSX0lNNA75CykiMECbovNTZqGI=
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
golang.org/x/oauth2 v0.30.0 h1:dnDm7JmhM45NNpd8FDDeLhK6FwqbOf4MLCM9zb1BOHI=
golang.org/x/oauth2 v0.30.0/go.mod h1:B++QgG3ZKulg6sRPGD/mqlHQs5rB3Ml9erfeDY7xKlU=
golang.org/x/sync v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
golang.org/x/sync v0.16.0/go.mod h1:1dzgHSNfp02xaA81J2MS99Qcpr2w7fw1gpm99rleRqA=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/sys v0.36.0/go.mod h1:OgkHotnGiDImocRcuBABYBEXf8A9a87e/uXjp9XT3ks=
golang.org/x/term v0.35.0 h1:bZBVKBudEyhRcajGcNc3jIfWPqV4y/Kt2XcoigOWtDQ=
golang.org/x/term v0.35.0/go.mod h1:TPGtkTLesOwf2DE8CgVYiZinHAOuy5AYUYT1lENIZnA=
golang.org/x/sys v0.35.0 h1:vz1N37gP5bs89s7He8XuIYXpyY0+QlsKmzipCbUtyxI=
golang.org/x/sys v0.35.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
golang.org/x/term v0.34.0 h1:O/2T7POpk0ZZ7MAzMeWFSg6S5IpWd/RXDlM9hgM3DR4=
golang.org/x/term v0.34.0/go.mod h1:5jC53AEywhIVebHgPVeg0mj8OD3VO9OzclacVrqpaAw=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/text v0.29.0/go.mod h1:7MhJOA9CD2qZyOKYazxdYMF85OwPdEr9jTtBpO7ydH4=
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.37.0 h1:DVSRzp7FwePZW356yEAChSdNcQo6Nsp+fex1SUW09lE=
golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w=
golang.org/x/tools v0.36.0 h1:kWS0uv/zsvHEle1LbV5LE8QujrxB3wfQyxHfhOk0Qkg=
golang.org/x/tools v0.36.0/go.mod h1:WBDiHKJK8YgLHlcQPYQzNCkUxUypCaa5ZegCVutKm+s=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
google.golang.org/protobuf v1.36.7 h1:IgrO7UwFQGJdRNXH/sQux4R1Dj1WAKcLElzeeRaXV2A=
google.golang.org/protobuf v1.36.7/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
google.golang.org/protobuf v1.36.6 h1:z1NpPI8ku2WgiWnf+t9wTPsn6eP1L7ksHUlkfLvd9xY=
google.golang.org/protobuf v1.36.6/go.mod h1:jduwjTPXsFjZGTmRluh+L6NjiWu7pchiJ2/5YcXBHnY=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 h1:qIbj1fsPNlZgppZ+VLlY7N33q108Sa+fhmuc+sWQYwY=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@@ -173,20 +165,18 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
howett.net/plist v1.0.1 h1:37GdZ8tP09Q35o9ych3ehygcsL+HqKSwzctveSlarvM=
howett.net/plist v1.0.1/go.mod h1:lqaXoTrLY4hg8tnEzNru53gicrbv7rrk+2xJA/7hw9g=
modernc.org/cc/v4 v4.26.4 h1:jPhG8oNjtTYuP2FA4YefTJ/wioNUGALmGuEWt7SUR6s=
modernc.org/cc/v4 v4.26.4/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.1 h1:wPKYn5EC/mYTqBO373jKjvX2n+3+aK7+sICCv4Fjy1A=
modernc.org/ccgo/v4 v4.28.1/go.mod h1:uD+4RnfrVgE6ec9NGguUNdhqzNIeeomeXf6CL0GTE5Q=
modernc.org/fileutil v1.3.28 h1:Vp156KUA2nPu9F1NEv036x9UGOjg2qsi5QlWTjZmtMk=
modernc.org/fileutil v1.3.28/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/cc/v4 v4.26.2 h1:991HMkLjJzYBIfha6ECZdjrIYz2/1ayr+FL8GN+CNzM=
modernc.org/cc/v4 v4.26.2/go.mod h1:uVtb5OGqUKpoLWhqwNQo/8LwvoiEBLvZXIQ/SmO6mL0=
modernc.org/ccgo/v4 v4.28.0 h1:rjznn6WWehKq7dG4JtLRKxb52Ecv8OUGah8+Z/SfpNU=
modernc.org/ccgo/v4 v4.28.0/go.mod h1:JygV3+9AV6SmPhDasu4JgquwU81XAKLd3OKTUDNOiKE=
modernc.org/fileutil v1.3.8 h1:qtzNm7ED75pd1C7WgAGcK4edm4fvhtBsEiI/0NQ54YM=
modernc.org/fileutil v1.3.8/go.mod h1:HxmghZSZVAz/LXcMNwZPA/DRrQZEVP9VX0V4LQGQFOc=
modernc.org/gc/v2 v2.6.5 h1:nyqdV8q46KvTpZlsw66kWqwXRHdjIlJOhG6kxiV/9xI=
modernc.org/gc/v2 v2.6.5/go.mod h1:YgIahr1ypgfe7chRuJi2gD7DBQiKSLMPgBQe9oIiito=
modernc.org/goabi0 v0.2.0 h1:HvEowk7LxcPd0eq6mVOAEMai46V+i7Jrj13t4AzuNks=
modernc.org/goabi0 v0.2.0/go.mod h1:CEFRnnJhKvWT1c1JTI3Avm+tgOWbkOu5oPA8eH8LnMI=
modernc.org/libc v1.66.3 h1:cfCbjTUcdsKyyZZfEUKfoHcP3S0Wkvz3jgSzByEWVCQ=
modernc.org/libc v1.66.3/go.mod h1:XD9zO8kt59cANKvHPXpx7yS2ELPheAey0vjIuZOhOU8=
modernc.org/libc v1.66.9 h1:YkHp7E1EWrN2iyNav7JE/nHasmshPvlGkon1VxGqOw0=
modernc.org/libc v1.66.9/go.mod h1:aVdcY7udcawRqauu0HukYYxtBSizV+R80n/6aQe9D5k=
modernc.org/mathutil v1.7.1 h1:GCZVGXdaN8gTqB1Mf/usp1Y/hSqgI2vAGGP4jZMCxOU=
modernc.org/mathutil v1.7.1/go.mod h1:4p5IwJITfppl0G4sUEDtCr4DthTaT47/N3aT6MhfgJg=
modernc.org/memory v1.11.0 h1:o4QC8aMQzmcwCK3t3Ux/ZHmwFPzE6hf2Y5LbkRs+hbI=

View File

@@ -25,12 +25,7 @@ type alertInfo struct {
// startWorker is a long-running goroutine that processes alert tasks
// every x seconds. It must be running to process status alerts.
func (am *AlertManager) startWorker() {
processPendingAlerts := time.Tick(15 * time.Second)
// check for status alerts that are not resolved when system comes up
// (can be removed if we figure out core bug in #1052)
checkStatusAlerts := time.Tick(561 * time.Second)
tick := time.Tick(15 * time.Second)
for {
select {
case <-am.stopChan:
@@ -46,9 +41,7 @@ func (am *AlertManager) startWorker() {
case "cancel":
am.pendingAlerts.Delete(task.alertRecord.Id)
}
case <-checkStatusAlerts:
resolveStatusAlerts(am.hub)
case <-processPendingAlerts:
case <-tick:
// Check for expired alerts every tick
now := time.Now()
for key, value := range am.pendingAlerts.Range {
@@ -177,35 +170,3 @@ func (am *AlertManager) sendStatusAlert(alertStatus string, systemName string, a
LinkText: "View " + systemName,
})
}
// resolveStatusAlerts resolves any status alerts that weren't resolved
// when system came up (https://github.com/henrygd/beszel/issues/1052)
func resolveStatusAlerts(app core.App) error {
db := app.DB()
// Find all active status alerts where the system is actually up
var alertIds []string
err := db.NewQuery(`
SELECT a.id
FROM alerts a
JOIN systems s ON a.system = s.id
WHERE a.name = 'Status'
AND a.triggered = true
AND s.status = 'up'
`).Column(&alertIds)
if err != nil {
return err
}
// resolve all matching alert records
for _, alertId := range alertIds {
alert, err := app.FindRecordById("alerts", alertId)
if err != nil {
return err
}
alert.Set("triggered", false)
err = app.Save(alert)
if err != nil {
return err
}
}
return nil
}

View File

@@ -13,7 +13,6 @@ import (
"testing/synctest"
"time"
"github.com/henrygd/beszel/internal/alerts"
beszelTests "github.com/henrygd/beszel/internal/tests"
"github.com/pocketbase/dbx"
@@ -370,9 +369,33 @@ func TestUserAlertsApi(t *testing.T) {
}
}
func getHubWithUser(t *testing.T) (*beszelTests.TestHub, *core.Record) {
hub, err := beszelTests.NewTestHub(t.TempDir())
assert.NoError(t, err)
hub.StartHub()
// Manually initialize the system manager to bind event hooks
err = hub.GetSystemManager().Initialize()
assert.NoError(t, err)
// Create a test user
user, err := beszelTests.CreateUser(hub, "test@example.com", "password")
assert.NoError(t, err)
// Create user settings for the test user (required for alert notifications)
userSettingsData := map[string]any{
"user": user.Id,
"settings": `{"emails":[test@example.com],"webhooks":[]}`,
}
_, err = beszelTests.CreateRecord(hub, "user_settings", userSettingsData)
assert.NoError(t, err)
return hub, user
}
func TestStatusAlerts(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
hub, user := beszelTests.GetHubWithUser(t)
hub, user := getHubWithUser(t)
defer hub.Cleanup()
systems, err := beszelTests.CreateSystems(hub, 4, user.Id, "paused")
@@ -453,7 +476,7 @@ func TestStatusAlerts(t *testing.T) {
func TestAlertsHistory(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
hub, user := beszelTests.GetHubWithUser(t)
hub, user := getHubWithUser(t)
defer hub.Cleanup()
// Create systems and alerts
@@ -579,102 +602,3 @@ func TestAlertsHistory(t *testing.T) {
assert.EqualValues(t, 2, totalHistoryCount, "Should have 2 total alert history records")
})
}
func TestResolveStatusAlerts(t *testing.T) {
hub, user := beszelTests.GetHubWithUser(t)
defer hub.Cleanup()
// Create a systemUp
systemUp, err := beszelTests.CreateRecord(hub, "systems", map[string]any{
"name": "test-system",
"users": []string{user.Id},
"host": "127.0.0.1",
"status": "up",
})
assert.NoError(t, err)
systemDown, err := beszelTests.CreateRecord(hub, "systems", map[string]any{
"name": "test-system-2",
"users": []string{user.Id},
"host": "127.0.0.2",
"status": "up",
})
assert.NoError(t, err)
// Create a status alertUp for the system
alertUp, err := beszelTests.CreateRecord(hub, "alerts", map[string]any{
"name": "Status",
"system": systemUp.Id,
"user": user.Id,
"min": 1,
})
assert.NoError(t, err)
alertDown, err := beszelTests.CreateRecord(hub, "alerts", map[string]any{
"name": "Status",
"system": systemDown.Id,
"user": user.Id,
"min": 1,
})
assert.NoError(t, err)
// Verify alert is not triggered initially
assert.False(t, alertUp.GetBool("triggered"), "Alert should not be triggered initially")
// Set the system to 'up' (this should not trigger the alert)
systemUp.Set("status", "up")
err = hub.SaveNoValidate(systemUp)
assert.NoError(t, err)
systemDown.Set("status", "down")
err = hub.SaveNoValidate(systemDown)
assert.NoError(t, err)
// Wait a moment for any processing
time.Sleep(10 * time.Millisecond)
// Verify alertUp is still not triggered after setting system to up
alertUp, err = hub.FindFirstRecordByFilter("alerts", "id={:id}", dbx.Params{"id": alertUp.Id})
assert.NoError(t, err)
assert.False(t, alertUp.GetBool("triggered"), "Alert should not be triggered when system is up")
// Manually set both alerts triggered to true
alertUp.Set("triggered", true)
err = hub.SaveNoValidate(alertUp)
assert.NoError(t, err)
alertDown.Set("triggered", true)
err = hub.SaveNoValidate(alertDown)
assert.NoError(t, err)
// Verify we have exactly one alert with triggered true
triggeredCount, err := hub.CountRecords("alerts", dbx.HashExp{"triggered": true})
assert.NoError(t, err)
assert.EqualValues(t, 2, triggeredCount, "Should have exactly two alerts with triggered true")
// Verify the specific alertUp is triggered
alertUp, err = hub.FindFirstRecordByFilter("alerts", "id={:id}", dbx.Params{"id": alertUp.Id})
assert.NoError(t, err)
assert.True(t, alertUp.GetBool("triggered"), "Alert should be triggered")
// Verify we have two unresolved alert history records
alertHistoryCount, err := hub.CountRecords("alerts_history", dbx.HashExp{"resolved": ""})
assert.NoError(t, err)
assert.EqualValues(t, 2, alertHistoryCount, "Should have exactly two unresolved alert history records")
err = alerts.ResolveStatusAlerts(hub)
assert.NoError(t, err)
// Verify alertUp is not triggered after resolving
alertUp, err = hub.FindFirstRecordByFilter("alerts", "id={:id}", dbx.Params{"id": alertUp.Id})
assert.NoError(t, err)
assert.False(t, alertUp.GetBool("triggered"), "Alert should not be triggered after resolving")
// Verify alertDown is still triggered
alertDown, err = hub.FindFirstRecordByFilter("alerts", "id={:id}", dbx.Params{"id": alertDown.Id})
assert.NoError(t, err)
assert.True(t, alertDown.GetBool("triggered"), "Alert should still be triggered after resolving")
// Verify we have one unresolved alert history record
alertHistoryCount, err = hub.CountRecords("alerts_history", dbx.HashExp{"resolved": ""})
assert.NoError(t, err)
assert.EqualValues(t, 1, alertHistoryCount, "Should have exactly one unresolved alert history record")
}

View File

@@ -1,6 +1,3 @@
//go:build testing
// +build testing
package alerts
import (
@@ -56,7 +53,3 @@ func (am *AlertManager) ForceExpirePendingAlerts() {
return true
})
}
func ResolveStatusAlerts(app core.App) error {
return resolveStatusAlerts(app)
}

View File

@@ -1,25 +0,0 @@
FROM --platform=$BUILDPLATFORM golang:alpine AS builder
WORKDIR /app
COPY ../go.mod ../go.sum ./
RUN go mod download
# Copy source files
COPY . ./
# Build
ARG TARGETOS TARGETARCH
RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags "-w -s" -o /agent ./internal/cmd/agent
# --------------------------
# Final image
# Note: must cap_add: [CAP_PERFMON] and mount /dev/dri/ as volume
# --------------------------
FROM alpine:edge
COPY --from=builder /agent /agent
RUN apk add --no-cache -X https://dl-cdn.alpinelinux.org/alpine/edge/testing igt-gpu-tools
ENTRYPOINT ["/agent"]

View File

@@ -2,18 +2,15 @@ FROM --platform=$BUILDPLATFORM golang:alpine AS builder
WORKDIR /app
COPY ../go.mod ../go.sum ./
RUN go mod download
# Copy source files
COPY . ./
COPY go.mod go.sum ./
# RUN go mod download
COPY *.go ./
COPY cmd ./cmd
COPY internal ./internal
# Build
ARG TARGETOS TARGETARCH
RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags "-w -s" -o /agent ./internal/cmd/agent
RUN rm -rf /tmp/*
RUN CGO_ENABLED=0 GOGC=75 GOOS=$TARGETOS GOARCH=$TARGETARCH go build -ldflags "-w -s" -o /agent ./cmd/agent
# --------------------------
# Final image: GPU-enabled agent with nvidia-smi
@@ -21,7 +18,4 @@ RUN rm -rf /tmp/*
FROM nvidia/cuda:12.2.2-base-ubuntu22.04
COPY --from=builder /agent /agent
# this is so we don't need to create the /tmp directory in the scratch container
COPY --from=builder /tmp /tmp
ENTRYPOINT ["/agent"]

View File

@@ -6,7 +6,6 @@ import (
"time"
"github.com/henrygd/beszel/internal/entities/container"
"github.com/henrygd/beszel/internal/entities/systemd"
)
type Stats struct {
@@ -39,22 +38,19 @@ type Stats struct {
Bandwidth [2]uint64 `json:"b,omitzero" cbor:"26,keyasint,omitzero"` // [sent bytes, recv bytes]
MaxBandwidth [2]uint64 `json:"bm,omitzero" cbor:"27,keyasint,omitzero"` // [sent bytes, recv bytes]
// TODO: remove other load fields in future release in favor of load avg array
LoadAvg [3]float64 `json:"la,omitempty" cbor:"28,keyasint"`
Battery [2]uint8 `json:"bat,omitzero" cbor:"29,keyasint,omitzero"` // [percent, charge state, current]
MaxMem float64 `json:"mm,omitempty" cbor:"30,keyasint,omitempty"`
NetworkInterfaces map[string][4]uint64 `json:"ni,omitempty" cbor:"31,keyasint,omitempty"` // [upload bytes, download bytes, total upload, total download]
LoadAvg [3]float64 `json:"la,omitempty" cbor:"28,keyasint"`
Battery [2]uint8 `json:"bat,omitzero" cbor:"29,keyasint,omitzero"` // [percent, charge state, current]
MaxMem float64 `json:"mm,omitempty" cbor:"30,keyasint,omitempty"`
}
type GPUData struct {
Name string `json:"n" cbor:"0,keyasint"`
Temperature float64 `json:"-"`
MemoryUsed float64 `json:"mu,omitempty,omitzero" cbor:"1,keyasint,omitempty,omitzero"`
MemoryTotal float64 `json:"mt,omitempty,omitzero" cbor:"2,keyasint,omitempty,omitzero"`
Usage float64 `json:"u" cbor:"3,keyasint,omitempty"`
Power float64 `json:"p,omitempty" cbor:"4,keyasint,omitempty"`
Count float64 `json:"-"`
Engines map[string]float64 `json:"e,omitempty" cbor:"5,keyasint,omitempty"`
PowerPkg float64 `json:"pp,omitempty" cbor:"6,keyasint,omitempty"`
Name string `json:"n" cbor:"0,keyasint"`
Temperature float64 `json:"-"`
MemoryUsed float64 `json:"mu,omitempty" cbor:"1,keyasint,omitempty"`
MemoryTotal float64 `json:"mt,omitempty" cbor:"2,keyasint,omitempty"`
Usage float64 `json:"u" cbor:"3,keyasint"`
Power float64 `json:"p,omitempty" cbor:"4,keyasint,omitempty"`
Count float64 `json:"-"`
}
type FsStats struct {
@@ -87,14 +83,6 @@ const (
Freebsd
)
type ConnectionType = uint8
const (
ConnectionTypeNone ConnectionType = iota
ConnectionTypeSSH
ConnectionTypeWebSocket
)
type Info struct {
Hostname string `json:"h" cbor:"0,keyasint"`
KernelVersion string `json:"k,omitempty" cbor:"1,keyasint,omitempty"`
@@ -116,14 +104,12 @@ type Info struct {
LoadAvg15 float64 `json:"l15,omitempty" cbor:"17,keyasint,omitempty"`
BandwidthBytes uint64 `json:"bb" cbor:"18,keyasint"`
// TODO: remove load fields in future release in favor of load avg array
LoadAvg [3]float64 `json:"la,omitempty" cbor:"19,keyasint"`
ConnectionType ConnectionType `json:"ct,omitempty" cbor:"20,keyasint,omitempty,omitzero"`
LoadAvg [3]float64 `json:"la,omitempty" cbor:"19,keyasint"`
}
// Final data structure to return to the hub
type CombinedData struct {
Stats Stats `json:"stats" cbor:"0,keyasint"`
Info Info `json:"info" cbor:"1,keyasint"`
Containers []*container.Stats `json:"container" cbor:"2,keyasint"`
SystemdServices []*systemd.Service `json:"systemd,omitempty" cbor:"3,keyasint,omitempty"`
Stats Stats `json:"stats" cbor:"0,keyasint"`
Info Info `json:"info" cbor:"1,keyasint"`
Containers []*container.Stats `json:"container" cbor:"2,keyasint"`
}

View File

@@ -1,34 +0,0 @@
package systemd
import (
"runtime"
"time"
)
// Service represents a single systemd service with its stats.
type Service struct {
Name string `json:"n" cbor:"0,keyasint"`
Status string `json:"s" cbor:"1,keyasint"`
Cpu float64 `json:"c" cbor:"2,keyasint"`
Mem float64 `json:"m" cbor:"3,keyasint"`
PrevCpuUsage uint64 `json:"-"`
PrevReadTime time.Time `json:"-"`
}
// CalculateCPUPercent calculates the CPU usage percentage for the service.
func (s *Service) CalculateCPUPercent(cpuUsage uint64) {
if s.PrevReadTime.IsZero() {
s.Cpu = 0
} else {
duration := time.Since(s.PrevReadTime).Nanoseconds()
if duration > 0 {
coreCount := int64(runtime.NumCPU())
duration *= coreCount
cpuPercent := float64(cpuUsage-s.PrevCpuUsage) / float64(duration)
s.Cpu = cpuPercent * 100
}
}
s.PrevCpuUsage = cpuUsage
s.PrevReadTime = time.Now()
}

View File

@@ -175,31 +175,35 @@ func (h *Hub) registerCronJobs(_ *core.ServeEvent) error {
// custom middlewares
func (h *Hub) registerMiddlewares(se *core.ServeEvent) {
// authorizes request with user matching the provided email
authorizeRequestWithEmail := func(e *core.RequestEvent, email string) (err error) {
if e.Auth != nil || email == "" {
return e.Next()
}
isAuthRefresh := e.Request.URL.Path == "/api/collections/users/auth-refresh" && e.Request.Method == http.MethodPost
e.Auth, err = e.App.FindFirstRecordByData("users", "email", email)
if err != nil || !isAuthRefresh {
return e.Next()
}
// auth refresh endpoint, make sure token is set in header
token, _ := e.Auth.NewAuthToken()
e.Request.Header.Set("Authorization", token)
return e.Next()
}
// authenticate with trusted header
if autoLogin, _ := GetEnv("AUTO_LOGIN"); autoLogin != "" {
se.Router.BindFunc(func(e *core.RequestEvent) error {
return authorizeRequestWithEmail(e, autoLogin)
})
}
// authenticate with trusted header
if trustedHeader, _ := GetEnv("TRUSTED_AUTH_HEADER"); trustedHeader != "" {
se.Router.BindFunc(func(e *core.RequestEvent) error {
return authorizeRequestWithEmail(e, e.Request.Header.Get(trustedHeader))
if e.Auth != nil {
return e.Next()
}
trustedEmail := e.Request.Header.Get(trustedHeader)
if trustedEmail == "" {
return e.Next()
}
isAuthRefresh := e.Request.URL.Path == "/api/collections/users/auth-refresh" && e.Request.Method == http.MethodPost
if !isAuthRefresh {
authRecord, err := e.App.FindAuthRecordByEmail("users", trustedEmail)
if err == nil {
e.Auth = authRecord
}
return e.Next()
}
// if auth refresh endpoint, find user record directly and generate token
user, err := e.App.FindFirstRecordByData("users", "email", trustedEmail)
if err != nil {
return e.Next()
}
e.Auth = user
// need to set the authorization header for the client sdk to pick up the token
if token, err := user.NewAuthToken(); err == nil {
e.Request.Header.Set("Authorization", token)
}
return e.Next()
})
}
}

View File

@@ -712,60 +712,6 @@ func TestCreateUserEndpointAvailability(t *testing.T) {
})
}
func TestAutoLoginMiddleware(t *testing.T) {
var hubs []*beszelTests.TestHub
defer func() {
defer os.Unsetenv("AUTO_LOGIN")
for _, hub := range hubs {
hub.Cleanup()
}
}()
os.Setenv("AUTO_LOGIN", "user@test.com")
testAppFactory := func(t testing.TB) *pbTests.TestApp {
hub, _ := beszelTests.NewTestHub(t.TempDir())
hubs = append(hubs, hub)
hub.StartHub()
return hub.TestApp
}
scenarios := []beszelTests.ApiScenario{
{
Name: "GET /getkey - without auto login should fail",
Method: http.MethodGet,
URL: "/api/beszel/getkey",
ExpectedStatus: 401,
ExpectedContent: []string{"requires valid"},
TestAppFactory: testAppFactory,
},
{
Name: "GET /getkey - with auto login should fail if no matching user",
Method: http.MethodGet,
URL: "/api/beszel/getkey",
ExpectedStatus: 401,
ExpectedContent: []string{"requires valid"},
TestAppFactory: testAppFactory,
},
{
Name: "GET /getkey - with auto login should succeed",
Method: http.MethodGet,
URL: "/api/beszel/getkey",
ExpectedStatus: 200,
ExpectedContent: []string{"\"key\":", "\"v\":"},
TestAppFactory: testAppFactory,
BeforeTestFunc: func(t testing.TB, app *pbTests.TestApp, e *core.ServeEvent) {
beszelTests.CreateUser(app, "user@test.com", "password123")
},
},
}
for _, scenario := range scenarios {
scenario.Test(t)
}
}
func TestTrustedHeaderMiddleware(t *testing.T) {
var hubs []*beszelTests.TestHub

View File

@@ -161,20 +161,6 @@ func (sys *System) createRecords(data *system.CombinedData) (*core.Record, error
return nil, err
}
}
// add new systemd_stats record
if len(data.SystemdServices) > 0 {
systemdStatsCollection, err := hub.FindCachedCollectionByNameOrId("systemd_stats")
if err != nil {
return nil, err
}
systemdStatsRecord := core.NewRecord(systemdStatsCollection)
systemdStatsRecord.Set("system", systemRecord.Id)
systemdStatsRecord.Set("stats", data.SystemdServices)
systemdStatsRecord.Set("type", "1m")
if err := hub.SaveNoValidate(systemdStatsRecord); err != nil {
return nil, err
}
}
// update system record (do this last because it triggers alerts and we need above records to be inserted first)
systemRecord.Set("status", up)

View File

@@ -22,12 +22,6 @@ func Update(cmd *cobra.Command, _ []string) {
// Check if china-mirrors flag is set
useMirror, _ := cmd.Flags().GetBool("china-mirrors")
// Get the executable path before update
exePath, err := os.Executable()
if err != nil {
log.Fatal(err)
}
updated, err := ghupdate.Update(ghupdate.Config{
ArchiveExecutable: "beszel",
DataDir: dataDir,
@@ -41,8 +35,11 @@ func Update(cmd *cobra.Command, _ []string) {
}
// make sure the file is executable
if err := os.Chmod(exePath, 0755); err != nil {
fmt.Printf("Warning: failed to set executable permissions: %v\n", err)
exePath, err := os.Executable()
if err == nil {
if err := os.Chmod(exePath, 0755); err != nil {
fmt.Printf("Warning: failed to set executable permissions: %v\n", err)
}
}
// Try to restart the service if it's running

View File

@@ -520,96 +520,6 @@ func init() {
],
"system": false
},
{
"id": "systemd_stats_collection",
"listRule": "@request.auth.id != \"\"",
"viewRule": null,
"createRule": null,
"updateRule": null,
"deleteRule": null,
"name": "systemd_stats",
"type": "base",
"fields": [
{
"autogeneratePattern": "[a-z0-9]{15}",
"hidden": false,
"id": "text3208210256",
"max": 15,
"min": 15,
"name": "id",
"pattern": "^[a-z0-9]+$",
"presentable": false,
"primaryKey": true,
"required": true,
"system": true,
"type": "text"
},
{
"cascadeDelete": true,
"collectionId": "2hz5ncl8tizk5nx",
"hidden": false,
"id": "hutcu6ps",
"maxSelect": 1,
"minSelect": 0,
"name": "system",
"presentable": false,
"required": true,
"system": false,
"type": "relation"
},
{
"hidden": false,
"id": "r39hhnil",
"maxSize": 2000000,
"name": "stats",
"presentable": false,
"required": true,
"system": false,
"type": "json"
},
{
"hidden": false,
"id": "vo7iuj96",
"maxSelect": 1,
"name": "type",
"presentable": false,
"required": true,
"system": false,
"type": "select",
"values": [
"1m",
"10m",
"20m",
"120m",
"480m"
]
},
{
"hidden": false,
"id": "autodate2990389176",
"name": "created",
"onCreate": true,
"onUpdate": false,
"presentable": false,
"system": false,
"type": "autodate"
},
{
"hidden": false,
"id": "autodate3332085495",
"name": "updated",
"onCreate": true,
"onUpdate": true,
"presentable": false,
"system": false,
"type": "autodate"
}
],
"indexes": [
"CREATE INDEX ` + "`" + `idx_systemd_stats` + "`" + ` ON ` + "`" + `systemd_stats` + "`" + ` (\n ` + "`" + `system` + "`" + `,\n ` + "`" + `type` + "`" + `,\n ` + "`" + `created` + "`" + `\n)"
],
"system": false
},
{
"id": "4afacsdnlu8q8r2",
"listRule": "@request.auth.id != \"\" && user.id = @request.auth.id",

View File

@@ -1,50 +0,0 @@
package migrations
import (
"github.com/henrygd/beszel/internal/entities/system"
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
// This can be deleted after Nov 2025 or so
func init() {
m.Register(func(app core.App) error {
app.RunInTransaction(func(txApp core.App) error {
var systemIds []string
txApp.DB().NewQuery("SELECT id FROM systems").Column(&systemIds)
for _, systemId := range systemIds {
var statRecordIds []string
txApp.DB().NewQuery("SELECT id FROM system_stats WHERE system = {:system} AND created > {:created}").Bind(map[string]any{"system": systemId, "created": "2025-09-21"}).Column(&statRecordIds)
for _, statRecordId := range statRecordIds {
statRecord, err := txApp.FindRecordById("system_stats", statRecordId)
if err != nil {
return err
}
var systemStats system.Stats
err = statRecord.UnmarshalJSONField("stats", &systemStats)
if err != nil {
return err
}
// if mem buff cache is less than total mem, we don't need to fix it
if systemStats.MemBuffCache < systemStats.Mem {
continue
}
systemStats.MemBuffCache = 0
statRecord.Set("stats", systemStats)
err = txApp.SaveNoValidate(statRecord)
if err != nil {
return err
}
}
}
return nil
})
return nil
}, func(app core.App) error {
return nil
})
}

View File

@@ -225,19 +225,6 @@ func (rm *RecordManager) AverageSystemStats(db dbx.Builder, records RecordIds) *
sum.MaxBandwidth[0] = max(sum.MaxBandwidth[0], stats.MaxBandwidth[0], stats.Bandwidth[0])
sum.MaxBandwidth[1] = max(sum.MaxBandwidth[1], stats.MaxBandwidth[1], stats.Bandwidth[1])
// Accumulate network interfaces
if sum.NetworkInterfaces == nil {
sum.NetworkInterfaces = make(map[string][4]uint64, len(stats.NetworkInterfaces))
}
for key, value := range stats.NetworkInterfaces {
sum.NetworkInterfaces[key] = [4]uint64{
sum.NetworkInterfaces[key][0] + value[0],
sum.NetworkInterfaces[key][1] + value[1],
max(sum.NetworkInterfaces[key][2], value[2]),
max(sum.NetworkInterfaces[key][3], value[3]),
}
}
// Accumulate temperatures
if stats.Temperatures != nil {
if sum.Temperatures == nil {
@@ -284,16 +271,6 @@ func (rm *RecordManager) AverageSystemStats(db dbx.Builder, records RecordIds) *
gpu.Usage += value.Usage
gpu.Power += value.Power
gpu.Count += value.Count
if value.Engines != nil {
if gpu.Engines == nil {
gpu.Engines = make(map[string]float64, len(value.Engines))
}
for engineKey, engineValue := range value.Engines {
gpu.Engines[engineKey] += engineValue
}
}
sum.GPUData[id] = gpu
}
}
@@ -322,19 +299,6 @@ func (rm *RecordManager) AverageSystemStats(db dbx.Builder, records RecordIds) *
sum.Bandwidth[0] = sum.Bandwidth[0] / uint64(count)
sum.Bandwidth[1] = sum.Bandwidth[1] / uint64(count)
sum.Battery[0] = uint8(batterySum / int(count))
// Average network interfaces
if sum.NetworkInterfaces != nil {
for key := range sum.NetworkInterfaces {
sum.NetworkInterfaces[key] = [4]uint64{
sum.NetworkInterfaces[key][0] / uint64(count),
sum.NetworkInterfaces[key][1] / uint64(count),
sum.NetworkInterfaces[key][2],
sum.NetworkInterfaces[key][3],
}
}
}
// Average temperatures
if sum.Temperatures != nil && tempCount > 0 {
for key := range sum.Temperatures {
@@ -363,13 +327,6 @@ func (rm *RecordManager) AverageSystemStats(db dbx.Builder, records RecordIds) *
gpu.Usage = twoDecimals(gpu.Usage / count)
gpu.Power = twoDecimals(gpu.Power / count)
gpu.Count = twoDecimals(gpu.Count / count)
if gpu.Engines != nil {
for engineKey := range gpu.Engines {
gpu.Engines[engineKey] = twoDecimals(gpu.Engines[engineKey] / count)
}
}
sum.GPUData[id] = gpu
}
}

View File

@@ -175,7 +175,7 @@ func TestDeleteOldSystemStats(t *testing.T) {
}
// Run deletion
err = records.DeleteOldSystemStats(hub)
err = records.TestDeleteOldSystemStats(hub)
require.NoError(t, err)
// Verify results
@@ -268,7 +268,7 @@ func TestDeleteOldAlertsHistory(t *testing.T) {
assert.Equal(t, int64(tc.alertCount), countBefore, "Initial count should match")
// Run deletion
err = records.DeleteOldAlertsHistory(hub, tc.countToKeep, tc.countBeforeDeletion)
err = records.TestDeleteOldAlertsHistory(hub, tc.countToKeep, tc.countBeforeDeletion)
require.NoError(t, err)
// Count after deletion
@@ -332,7 +332,7 @@ func TestDeleteOldAlertsHistoryEdgeCases(t *testing.T) {
}
// Should not error and should not delete anything
err = records.DeleteOldAlertsHistory(hub, 10, 20)
err = records.TestDeleteOldAlertsHistory(hub, 10, 20)
require.NoError(t, err)
count, err := hub.CountRecords("alerts_history")
@@ -346,7 +346,7 @@ func TestDeleteOldAlertsHistoryEdgeCases(t *testing.T) {
require.NoError(t, err)
// Should not error with empty table
err = records.DeleteOldAlertsHistory(hub, 10, 20)
err = records.TestDeleteOldAlertsHistory(hub, 10, 20)
require.NoError(t, err)
})
}
@@ -376,7 +376,7 @@ func TestTwoDecimals(t *testing.T) {
}
for _, tc := range testCases {
result := records.TwoDecimals(tc.input)
result := records.TestTwoDecimals(tc.input)
assert.InDelta(t, tc.expected, result, 0.02, "twoDecimals(%f) should equal %f", tc.input, tc.expected)
}
}

View File

@@ -7,17 +7,17 @@ import (
"github.com/pocketbase/pocketbase/core"
)
// DeleteOldSystemStats exposes deleteOldSystemStats for testing
func DeleteOldSystemStats(app core.App) error {
// TestDeleteOldSystemStats exposes deleteOldSystemStats for testing
func TestDeleteOldSystemStats(app core.App) error {
return deleteOldSystemStats(app)
}
// DeleteOldAlertsHistory exposes deleteOldAlertsHistory for testing
func DeleteOldAlertsHistory(app core.App, countToKeep, countBeforeDeletion int) error {
// TestDeleteOldAlertsHistory exposes deleteOldAlertsHistory for testing
func TestDeleteOldAlertsHistory(app core.App, countToKeep, countBeforeDeletion int) error {
return deleteOldAlertsHistory(app, countToKeep, countBeforeDeletion)
}
// TwoDecimals exposes twoDecimals for testing
func TwoDecimals(value float64) float64 {
// TestTwoDecimals exposes twoDecimals for testing
func TestTwoDecimals(value float64) float64 {
return twoDecimals(value)
}

View File

@@ -17,10 +17,7 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true,
"correctness": {
"useUniqueElementIds": "off"
}
"recommended": true
}
},
"javascript": {
@@ -38,4 +35,4 @@
}
}
}
}
}

View File

@@ -1,12 +1,12 @@
{
"name": "beszel",
"version": "0.12.12",
"version": "0.12.7",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "beszel",
"version": "0.12.12",
"version": "0.12.7",
"dependencies": {
"@henrygd/queue": "^1.0.7",
"@henrygd/semaphore": "^0.0.2",
@@ -46,7 +46,6 @@
"valibot": "^0.42.1"
},
"devDependencies": {
"@biomejs/biome": "2.2.3",
"@lingui/cli": "^5.4.1",
"@lingui/swc-plugin": "^5.6.1",
"@lingui/vite-plugin": "^5.4.1",
@@ -69,7 +68,7 @@
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
"integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
"devOptional": true,
"dev": true,
"license": "Apache-2.0",
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
@@ -83,7 +82,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.27.1.tgz",
"integrity": "sha512-cjQ7ZlQ0Mv3b47hABuTevyTuYN4i+loJKGeV9flcCgIK37cCXRh+L1bd3iBHlynerhQ7BhCkn2BPbQUL+rGqFg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-validator-identifier": "^7.27.1",
@@ -98,7 +97,7 @@
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/compat-data/-/compat-data-7.28.0.tgz",
"integrity": "sha512-60X7qkglvrap8mn1lh2ebxXdZYtUcpd7gsmy9kLaBJ4i/WdY8PqTSdxyA8qraikqKQK5C1KRBKXqznrVapyNaw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -108,7 +107,7 @@
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.28.3.tgz",
"integrity": "sha512-yDBHV9kQNcr2/sUr9jghVyz9C3Y5G2zUM2H2lo+9mKv4sFgbA8s8Z9t8D1jiTkGoO/NoIfKMyKWr4s6CN23ZwQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@ampproject/remapping": "^2.2.0",
@@ -139,7 +138,7 @@
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.28.3.tgz",
"integrity": "sha512-3lSpxGgvnmZznmBkCRnVREPUFJv2wrv9iAoFDvADJc0ypmdOxdUtcLeBgBJ6zE0PMeTKnxeQzyk0xTBq4Ep7zw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/parser": "^7.28.3",
@@ -156,7 +155,7 @@
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/helper-compilation-targets/-/helper-compilation-targets-7.27.2.tgz",
"integrity": "sha512-2+1thGUUWWjLTYTHZWK1n8Yga0ijBz1XAhUXcKy81rd5g6yh7hGqMp45v7cadSbEHc9G3OTv45SyneRN3ps4DQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/compat-data": "^7.27.2",
@@ -173,7 +172,7 @@
"version": "7.28.0",
"resolved": "https://registry.npmjs.org/@babel/helper-globals/-/helper-globals-7.28.0.tgz",
"integrity": "sha512-+W6cISkXFa1jXsDEdYA8HeevQT/FULhxzR99pxphltZcVaugps53THCeiWA8SguxxpSp3gKPiuYfSWopkLQ4hw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -183,7 +182,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.27.1.tgz",
"integrity": "sha512-0gSFWUPNXNopqtIPQvlD5WgXYI5GY2kP2cCvoT8kczjbfcfuIljTbcWrulD1CIPIX2gt1wghbDy08yE1p+/r3w==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/traverse": "^7.27.1",
@@ -197,7 +196,7 @@
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.28.3.tgz",
"integrity": "sha512-gytXUbs8k2sXS9PnQptz5o0QnpLL51SwASIORY6XaBKF88nsOT0Zw9szLqlSGQDP/4TljBAD5y98p2U1fqkdsw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-module-imports": "^7.27.1",
@@ -215,7 +214,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
"integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -225,7 +224,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz",
"integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -235,7 +234,7 @@
"version": "7.27.1",
"resolved": "https://registry.npmjs.org/@babel/helper-validator-option/-/helper-validator-option-7.27.1.tgz",
"integrity": "sha512-YvjJow9FxbhFFKDSuFnVCe2WxXk1zWc22fFePVNEaWJEu8IrZVlda6N0uHwzZrUM1il7NC9Mlp4MaJYbYd9JSg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -245,7 +244,7 @@
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.28.3.tgz",
"integrity": "sha512-PTNtvUQihsAsDHMOP5pfobP8C6CM4JWXmP8DrEIt46c3r2bf87Ua1zoqevsMo9g+tWDwgWrFP5EIxuBx5RudAw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/template": "^7.27.2",
@@ -259,7 +258,7 @@
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz",
"integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/types": "^7.28.2"
@@ -287,7 +286,7 @@
"version": "7.27.2",
"resolved": "https://registry.npmjs.org/@babel/template/-/template-7.27.2.tgz",
"integrity": "sha512-LPDZ85aEJyYSd18/DkjNh4/y1ntkE5KwUHWTiqgRxruuZL2F1yuHligVHLvcHY2vMHXttKFpJn6LwfI7cw7ODw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
@@ -302,7 +301,7 @@
"version": "7.28.3",
"resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.28.3.tgz",
"integrity": "sha512-7w4kZYHneL3A6NP2nxzHvT3HCZ7puDZZjFMqDpBPECub79sTtSO5CGXDkKrTQq8ksAwfD/XI2MRFX23njdDaIQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.27.1",
@@ -321,7 +320,7 @@
"version": "7.28.2",
"resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz",
"integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/helper-string-parser": "^7.27.1",
@@ -331,169 +330,6 @@
"node": ">=6.9.0"
}
},
"node_modules/@biomejs/biome": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-2.2.3.tgz",
"integrity": "sha512-9w0uMTvPrIdvUrxazZ42Ib7t8Y2yoGLKLdNne93RLICmaHw7mcLv4PPb5LvZLJF3141gQHiCColOh/v6VWlWmg==",
"dev": true,
"license": "MIT OR Apache-2.0",
"bin": {
"biome": "bin/biome"
},
"engines": {
"node": ">=14.21.3"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/biome"
},
"optionalDependencies": {
"@biomejs/cli-darwin-arm64": "2.2.3",
"@biomejs/cli-darwin-x64": "2.2.3",
"@biomejs/cli-linux-arm64": "2.2.3",
"@biomejs/cli-linux-arm64-musl": "2.2.3",
"@biomejs/cli-linux-x64": "2.2.3",
"@biomejs/cli-linux-x64-musl": "2.2.3",
"@biomejs/cli-win32-arm64": "2.2.3",
"@biomejs/cli-win32-x64": "2.2.3"
}
},
"node_modules/@biomejs/cli-darwin-arm64": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-2.2.3.tgz",
"integrity": "sha512-OrqQVBpadB5eqzinXN4+Q6honBz+tTlKVCsbEuEpljK8ASSItzIRZUA02mTikl3H/1nO2BMPFiJ0nkEZNy3B1w==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-darwin-x64": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-2.2.3.tgz",
"integrity": "sha512-OCdBpb1TmyfsTgBAM1kPMXyYKTohQ48WpiN9tkt9xvU6gKVKHY4oVwteBebiOqyfyzCNaSiuKIPjmHjUZ2ZNMg==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"darwin"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-2.2.3.tgz",
"integrity": "sha512-g/Uta2DqYpECxG+vUmTAmUKlVhnGEcY7DXWgKP8ruLRa8Si1QHsWknPY3B/wCo0KgYiFIOAZ9hjsHfNb9L85+g==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-arm64-musl": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-2.2.3.tgz",
"integrity": "sha512-q3w9jJ6JFPZPeqyvwwPeaiS/6NEszZ+pXKF+IczNo8Xj6fsii45a4gEEicKyKIytalV+s829ACZujQlXAiVLBQ==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-2.2.3.tgz",
"integrity": "sha512-LEtyYL1fJsvw35CxrbQ0gZoxOG3oZsAjzfRdvRBRHxOpQ91Q5doRVjvWW/wepgSdgk5hlaNzfeqpyGmfSD0Eyw==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-linux-x64-musl": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-2.2.3.tgz",
"integrity": "sha512-y76Dn4vkP1sMRGPFlNc+OTETBhGPJ90jY3il6jAfur8XWrYBQV3swZ1Jo0R2g+JpOeeoA0cOwM7mJG6svDz79w==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"linux"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-arm64": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-2.2.3.tgz",
"integrity": "sha512-Ms9zFYzjcJK7LV+AOMYnjN3pV3xL8Prxf9aWdDVL74onLn5kcvZ1ZMQswE5XHtnd/r/0bnUd928Rpbs14BzVmA==",
"cpu": [
"arm64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@biomejs/cli-win32-x64": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-2.2.3.tgz",
"integrity": "sha512-gvCpewE7mBwBIpqk1YrUqNR4mCiyJm6UI3YWQQXkedSSEwzRdodRpaKhbdbHw1/hmTWOVXQ+Eih5Qctf4TCVOQ==",
"cpu": [
"x64"
],
"dev": true,
"license": "MIT OR Apache-2.0",
"optional": true,
"os": [
"win32"
],
"engines": {
"node": ">=14.21.3"
}
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.25.6",
"resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.6.tgz",
@@ -1020,7 +856,7 @@
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/@jest/schemas/-/schemas-29.6.3.tgz",
"integrity": "sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@sinclair/typebox": "^0.27.8"
@@ -1033,7 +869,7 @@
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/@jest/types/-/types-29.6.3.tgz",
"integrity": "sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@jest/schemas": "^29.6.3",
@@ -1051,7 +887,7 @@
"version": "0.3.13",
"resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
"integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/sourcemap-codec": "^1.5.0",
@@ -1073,7 +909,7 @@
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
"integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.0.0"
@@ -1083,14 +919,14 @@
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
"integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/@jridgewell/trace-mapping": {
"version": "0.3.30",
"resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz",
"integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@jridgewell/resolve-uri": "^3.1.0",
@@ -1111,7 +947,7 @@
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/@lingui/babel-plugin-lingui-macro/-/babel-plugin-lingui-macro-5.4.1.tgz",
"integrity": "sha512-9IO+PDvdneY8OCI8zvI1oDXpzryTMtyRv7uq9O0U1mFCvIPVd5dWQKQDu/CpgpYAc2+JG/izn5PNl9xzPc6ckw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/core": "^7.20.12",
@@ -1331,7 +1167,7 @@
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/@lingui/conf/-/conf-5.4.1.tgz",
"integrity": "sha512-aDkj/bMSr/mCL8Nr1TS52v0GLCuVa4YqtRz+WvUCFZw/ovVInX0hKq1TClx/bSlhu60FzB/CbclxFMBw8aLVUg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/runtime": "^7.20.13",
@@ -2750,7 +2586,7 @@
"version": "0.27.8",
"resolved": "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.27.8.tgz",
"integrity": "sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/@swc/core": {
@@ -3420,14 +3256,14 @@
"version": "2.0.6",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz",
"integrity": "sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/@types/istanbul-lib-report": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/@types/istanbul-lib-report/-/istanbul-lib-report-3.0.3.tgz",
"integrity": "sha512-NQn7AHQnk/RSLOxrBbGyJM/aVQ+pjj5HCgasFxc0K/KhoATfQ/47AyUl15I2yBUpihjmas+a+VJBOqecrFH+uA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-coverage": "*"
@@ -3437,7 +3273,7 @@
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/@types/istanbul-reports/-/istanbul-reports-3.0.4.tgz",
"integrity": "sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@types/istanbul-lib-report": "*"
@@ -3447,7 +3283,7 @@
"version": "24.3.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.0.tgz",
"integrity": "sha512-aPTXCrfwnDLj4VvXrm+UUCQjNEvJgNA8s5F1cvwQU+3KNltTOkBm1j30uNLyqqPNe7gE3KFzImYoZEfLhp4Yow==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"undici-types": "~7.10.0"
@@ -3457,7 +3293,7 @@
"version": "19.1.11",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.11.tgz",
"integrity": "sha512-lr3jdBw/BGj49Eps7EvqlUaoeA0xpj3pc0RoJkHpYaCHkVK7i28dKyImLQb3JVlqs3aYSXf7qYuWOW/fgZnTXQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.0.2"
@@ -3467,7 +3303,7 @@
"version": "19.1.7",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.7.tgz",
"integrity": "sha512-i5ZzwYpqjmrKenzkoLM2Ibzt6mAsM7pxB6BCIouEVVmgiqaMj1TjaK7hnA36hbW5aZv20kx7Lw6hWzPWg0Rurw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "^19.0.0"
@@ -3477,7 +3313,7 @@
"version": "17.0.33",
"resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.33.tgz",
"integrity": "sha512-WpxBCKWPLr4xSsHgz511rFJAM+wS28w2zEO1QDNY5zM/S8ok70NNfztH0xwhqKyaK0OHCbN98LDAZuy1ctxDkA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@types/yargs-parser": "*"
@@ -3487,7 +3323,7 @@
"version": "21.0.3",
"resolved": "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.3.tgz",
"integrity": "sha512-I4q9QU9MQv4oEOz4tAHJtNz1cwuLxn2F3xcc2iV5WdqLPpUnj30aUuxt1mAxYTG+oe8CZMV/+6rU4S4gRDzqtQ==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/@vitejs/plugin-react-swc": {
@@ -3524,7 +3360,7 @@
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"color-convert": "^2.0.1"
@@ -3567,7 +3403,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"devOptional": true,
"dev": true,
"license": "Python-2.0"
},
"node_modules/aria-hidden": {
@@ -3662,7 +3498,7 @@
"version": "4.25.1",
"resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.25.1.tgz",
"integrity": "sha512-KGj0KoOMXLpSNkkEI6Z6mShmQy0bc1I+T7K9N81k4WWMrfz+6fQ6es80B/YLAeRoKvjYE1YSHHOW1qe9xIVzHw==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "opencollective",
@@ -3733,7 +3569,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
"integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -3743,7 +3579,7 @@
"version": "6.3.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.3.0.tgz",
"integrity": "sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -3756,7 +3592,7 @@
"version": "1.0.30001727",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001727.tgz",
"integrity": "sha512-pB68nIHmbN6L/4C6MH1DokyR3bYqFwjaSs/sWDHGj4CTcFtQUQMuJftVwWkXq7mNWOybD3KhUv3oWHoGxgP14Q==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "opencollective",
@@ -3777,7 +3613,7 @@
"version": "4.1.2",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
"integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"ansi-styles": "^4.1.0",
@@ -3889,7 +3725,7 @@
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"color-name": "~1.1.4"
@@ -3902,7 +3738,7 @@
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/colors": {
@@ -3919,14 +3755,14 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-2.0.0.tgz",
"integrity": "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/cosmiconfig": {
"version": "8.3.6",
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-8.3.6.tgz",
"integrity": "sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"import-fresh": "^3.3.0",
@@ -4106,7 +3942,7 @@
"version": "4.4.1",
"resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
"integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"ms": "^2.1.3"
@@ -4176,7 +4012,7 @@
"version": "1.5.182",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.182.tgz",
"integrity": "sha512-Lv65Btwv9W4J9pyODI6EWpdnhfvrve/us5h1WspW8B2Fb0366REPtY3hX7ounk1CkV/TBjWCEvCBBbYbmV0qCA==",
"devOptional": true,
"dev": true,
"license": "ISC"
},
"node_modules/emoji-regex": {
@@ -4204,7 +4040,7 @@
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"is-arrayish": "^0.2.1"
@@ -4273,7 +4109,7 @@
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
"integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4361,7 +4197,7 @@
"version": "1.0.0-beta.2",
"resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz",
"integrity": "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6.9.0"
@@ -4387,7 +4223,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -4418,7 +4254,7 @@
"version": "3.3.1",
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
"integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"parent-module": "^1.0.0",
@@ -4461,7 +4297,7 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/is-binary-path": {
@@ -4554,7 +4390,7 @@
"version": "29.6.3",
"resolved": "https://registry.npmjs.org/jest-get-type/-/jest-get-type-29.6.3.tgz",
"integrity": "sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": "^14.15.0 || ^16.10.0 || >=18.0.0"
@@ -4564,7 +4400,7 @@
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/jest-validate/-/jest-validate-29.7.0.tgz",
"integrity": "sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@jest/types": "^29.6.3",
@@ -4582,7 +4418,7 @@
"version": "1.21.7",
"resolved": "https://registry.npmjs.org/jiti/-/jiti-1.21.7.tgz",
"integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==",
"devOptional": true,
"dev": true,
"license": "MIT",
"bin": {
"jiti": "bin/jiti.js"
@@ -4604,7 +4440,7 @@
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"argparse": "^2.0.1"
@@ -4617,7 +4453,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
"integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"bin": {
"jsesc": "bin/jsesc"
@@ -4630,14 +4466,14 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/json5": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz",
"integrity": "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"bin": {
"json5": "lib/cli.js"
@@ -4650,7 +4486,7 @@
"version": "3.1.0",
"resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
"integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
@@ -4899,7 +4735,7 @@
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/lodash": {
@@ -4948,7 +4784,7 @@
"version": "5.1.1",
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz",
"integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==",
"devOptional": true,
"dev": true,
"license": "ISC",
"dependencies": {
"yallist": "^3.0.2"
@@ -5059,7 +4895,7 @@
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
"integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/nanoid": {
@@ -5100,7 +4936,7 @@
"version": "2.0.19",
"resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz",
"integrity": "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/normalize-path": {
@@ -5196,7 +5032,7 @@
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
"integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"callsites": "^3.0.0"
@@ -5209,7 +5045,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@babel/code-frame": "^7.0.0",
@@ -5238,7 +5074,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
@@ -5248,7 +5084,7 @@
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
"integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
"devOptional": true,
"dev": true,
"license": "ISC"
},
"node_modules/picomatch": {
@@ -5310,7 +5146,7 @@
"version": "29.7.0",
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-29.7.0.tgz",
"integrity": "sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"@jest/schemas": "^29.6.3",
@@ -5325,7 +5161,7 @@
"version": "5.2.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=10"
@@ -5571,7 +5407,7 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
"integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
"devOptional": true,
"dev": true,
"license": "MIT",
"engines": {
"node": ">=4"
@@ -5669,7 +5505,7 @@
"version": "6.3.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
"integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"devOptional": true,
"dev": true,
"license": "ISC",
"bin": {
"semver": "bin/semver.js"
@@ -5852,7 +5688,7 @@
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"has-flag": "^4.0.0"
@@ -5927,14 +5763,14 @@
"license": "MIT"
},
"node_modules/tinyglobby": {
"version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"version": "0.2.14",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"fdir": "^6.5.0",
"picomatch": "^4.0.3"
"fdir": "^6.4.4",
"picomatch": "^4.0.2"
},
"engines": {
"node": ">=12.0.0"
@@ -5986,7 +5822,7 @@
"version": "5.9.2",
"resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz",
"integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==",
"devOptional": true,
"dev": true,
"license": "Apache-2.0",
"bin": {
"tsc": "bin/tsc",
@@ -6000,14 +5836,14 @@
"version": "7.10.0",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
"devOptional": true,
"dev": true,
"license": "MIT"
},
"node_modules/update-browserslist-db": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
"integrity": "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw==",
"devOptional": true,
"dev": true,
"funding": [
{
"type": "opencollective",
@@ -6121,9 +5957,9 @@
}
},
"node_modules/vite": {
"version": "7.1.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz",
"integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==",
"version": "7.1.3",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.1.3.tgz",
"integrity": "sha512-OOUi5zjkDxYrKhTV3V7iKsoS37VUM7v40+HuwEmcrsf11Cdx9y3DIr2Px6liIcZFwt3XSRpQvFpL3WVy7ApkGw==",
"dev": true,
"license": "MIT",
"dependencies": {
@@ -6132,7 +5968,7 @@
"picomatch": "^4.0.3",
"postcss": "^8.5.6",
"rollup": "^4.43.0",
"tinyglobby": "^0.2.15"
"tinyglobby": "^0.2.14"
},
"bin": {
"vite": "bin/vite.js"
@@ -6339,7 +6175,7 @@
"version": "3.1.1",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
"integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==",
"devOptional": true,
"dev": true,
"license": "ISC"
}
}

View File

@@ -1,7 +1,7 @@
{
"name": "beszel",
"private": true,
"version": "0.12.12",
"version": "0.12.7",
"type": "module",
"scripts": {
"dev": "vite --host",
@@ -76,4 +76,4 @@
"optionalDependencies": {
"@esbuild/linux-arm64": "^0.21.5"
}
}
}

View File

@@ -1,9 +1,5 @@
import { t } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro"
import { useStore } from "@nanostores/react"
import { getPagePath } from "@nanostores/router"
import { ChevronDownIcon, ExternalLinkIcon, PlusIcon } from "lucide-react"
import { memo, useEffect, useRef, useState } from "react"
import { t } from "@lingui/core/macro"
import { Button } from "@/components/ui/button"
import {
Dialog,
@@ -14,30 +10,34 @@ import {
DialogTitle,
DialogTrigger,
} from "@/components/ui/dialog"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { isReadOnlyUser, pb } from "@/lib/api"
import { SystemStatus } from "@/lib/enums"
import { $publicKey } from "@/lib/stores"
import { cn, generateToken, tokenMap, useBrowserStorage } from "@/lib/utils"
import type { SystemRecord } from "@/types"
import { pb, isReadOnlyUser } from "@/lib/api"
import { useStore } from "@nanostores/react"
import { ChevronDownIcon, ExternalLinkIcon, PlusIcon } from "lucide-react"
import { memo, useEffect, useRef, useState } from "react"
import { $router, basePath, Link, navigate } from "./router"
import { SystemRecord } from "@/types"
import { SystemStatus } from "@/lib/enums"
import { AppleIcon, DockerIcon, TuxIcon, WindowsIcon } from "./ui/icons"
import { InputCopy } from "./ui/input-copy"
import { getPagePath } from "@nanostores/router"
import {
copyDockerCompose,
copyDockerRun,
copyLinuxCommand,
copyWindowsCommand,
type DropdownItem,
DropdownItem,
InstallDropdown,
} from "./install-dropdowns"
import { $router, basePath, Link, navigate } from "./router"
import { DropdownMenu, DropdownMenuTrigger } from "./ui/dropdown-menu"
import { AppleIcon, DockerIcon, FreeBsdIcon, TuxIcon, WindowsIcon } from "./ui/icons"
import { InputCopy } from "./ui/input-copy"
export function AddSystemButton({ className }: { className?: string }) {
const [open, setOpen] = useState(false)
const opened = useRef(false)
let opened = useRef(false)
if (open) {
opened.current = true
}
@@ -253,12 +253,6 @@ export const SystemDialog = ({ setOpen, system }: { setOpen: (open: boolean) =>
copyWindowsCommand(isUnixSocket ? hostValue : port.current?.value, publicKey, token),
icons: [WindowsIcon],
},
{
text: t({ message: "FreeBSD command", context: "Button to copy install command" }),
onClick: async () =>
copyLinuxCommand(isUnixSocket ? hostValue : port.current?.value, publicKey, token),
icons: [FreeBsdIcon],
},
{
text: t`Manual setup instructions`,
url: "https://beszel.dev/guide/agent-installation#binary",

View File

@@ -1,11 +1,11 @@
import { t } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro"
import type { ColumnDef } from "@tanstack/react-table"
import { Badge } from "@/components/ui/badge"
import { ColumnDef } from "@tanstack/react-table"
import { AlertsHistoryRecord } from "@/types"
import { Button } from "@/components/ui/button"
import { Badge } from "@/components/ui/badge"
import { formatShortDate, toFixedFloat, formatDuration, cn } from "@/lib/utils"
import { alertInfo } from "@/lib/alerts"
import { cn, formatDuration, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { AlertsHistoryRecord } from "@/types"
import { Trans } from "@lingui/react/macro"
import { t } from "@lingui/core/macro"
export const alertsHistoryColumns: ColumnDef<AlertsHistoryRecord>[] = [
{
@@ -38,7 +38,7 @@ export const alertsHistoryColumns: ColumnDef<AlertsHistoryRecord>[] = [
</Button>
),
cell: ({ getValue, row }) => {
const name = getValue() as string
let name = getValue() as string
const info = alertInfo[row.original.name]
const Icon = info?.icon

View File

@@ -1,13 +1,13 @@
import { t } from "@lingui/core/macro"
import { useStore } from "@nanostores/react"
import { BellIcon } from "lucide-react"
import { memo, useMemo, useState } from "react"
import { Button } from "@/components/ui/button"
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
import { useStore } from "@nanostores/react"
import { $alerts } from "@/lib/stores"
import { BellIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import type { SystemRecord } from "@/types"
import { Button } from "@/components/ui/button"
import { SystemRecord } from "@/types"
import { AlertDialogContent } from "./alerts-sheet"
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
export default memo(function AlertsButton({ system }: { system: SystemRecord }) {
const [opened, setOpened] = useState(false)

View File

@@ -1,20 +1,21 @@
import { t } from "@lingui/core/macro"
import { Plural, Trans } from "@lingui/react/macro"
import { useStore } from "@nanostores/react"
import { getPagePath } from "@nanostores/router"
import { GlobeIcon, ServerIcon } from "lucide-react"
import { lazy, memo, Suspense, useMemo, useState } from "react"
import { $router, Link } from "@/components/router"
import { Checkbox } from "@/components/ui/checkbox"
import { DialogDescription, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { Switch } from "@/components/ui/switch"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { toast } from "@/components/ui/use-toast"
import { alertInfo } from "@/lib/alerts"
import { pb } from "@/lib/api"
import { Trans, Plural } from "@lingui/react/macro"
import { $alerts, $systems } from "@/lib/stores"
import { cn, debounce } from "@/lib/utils"
import type { AlertInfo, AlertRecord, SystemRecord } from "@/types"
import { alertInfo } from "@/lib/alerts"
import { Switch } from "@/components/ui/switch"
import { AlertInfo, AlertRecord, SystemRecord } from "@/types"
import { lazy, memo, Suspense, useMemo, useState } from "react"
import { toast } from "@/components/ui/use-toast"
import { useStore } from "@nanostores/react"
import { getPagePath } from "@nanostores/router"
import { Checkbox } from "@/components/ui/checkbox"
import { DialogTitle, DialogDescription } from "@/components/ui/dialog"
import { Tabs, TabsList, TabsTrigger, TabsContent } from "@/components/ui/tabs"
import { ServerIcon, GlobeIcon } from "lucide-react"
import { $router, Link } from "@/components/router"
import { DialogHeader } from "@/components/ui/dialog"
import { pb } from "@/lib/api"
const Slider = lazy(() => import("@/components/ui/slider"))
@@ -171,7 +172,7 @@ export function AlertContent({
const [checked, setChecked] = useState(global ? false : !!alert)
const [min, setMin] = useState(alert?.min || 10)
const [value, setValue] = useState(alert?.value || (singleDescription ? 0 : (alertData.start ?? 80)))
const [value, setValue] = useState(alert?.value || (singleDescription ? 0 : alertData.start ?? 80))
const Icon = alertData.icon

View File

@@ -1,16 +1,9 @@
import { useMemo } from "react"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
xAxis,
} from "@/components/ui/chart"
import { chartMargin, cn, formatShortDate } from "@/lib/utils"
import type { ChartData, SystemStatsRecord } from "@/types"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { cn, formatShortDate, chartMargin } from "@/lib/utils"
import { useYAxisWidth } from "./hooks"
import { ChartData, SystemStatsRecord } from "@/types"
import { useMemo } from "react"
export type DataPoint = {
label: string
@@ -27,8 +20,6 @@ export default function AreaChartDefault({
contentFormatter,
dataPoints,
domain,
legend,
itemSorter,
}: // logRender = false,
{
chartData: ChartData
@@ -38,13 +29,10 @@ export default function AreaChartDefault({
contentFormatter: ({ value, payload }: { value: number; payload: SystemStatsRecord }) => string
dataPoints?: DataPoint[]
domain?: [number, number]
legend?: boolean
itemSorter?: (a: any, b: any) => number
// logRender?: boolean
}) {
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
// biome-ignore lint/correctness/useExhaustiveDependencies: ignore
return useMemo(() => {
if (chartData.systemStats.length === 0) {
return null
@@ -75,8 +63,6 @@ export default function AreaChartDefault({
<ChartTooltip
animationEasing="ease-out"
animationDuration={150}
// @ts-expect-error
itemSorter={itemSorter}
content={
<ChartTooltipContent
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
@@ -84,14 +70,11 @@ export default function AreaChartDefault({
/>
}
/>
{dataPoints?.map((dataPoint) => {
let { color } = dataPoint
if (typeof color === "number") {
color = `var(--chart-${color})`
}
{dataPoints?.map((dataPoint, i) => {
const color = `var(--chart-${dataPoint.color})`
return (
<Area
key={dataPoint.label}
key={i}
dataKey={dataPoint.dataKey}
name={dataPoint.label}
type="monotoneX"
@@ -102,7 +85,7 @@ export default function AreaChartDefault({
/>
)
})}
{legend && <ChartLegend content={<ChartLegendContent />} />}
{/* <ChartLegend content={<ChartLegendContent />} /> */}
</AreaChart>
</ChartContainer>
</div>

View File

@@ -1,9 +1,9 @@
import { useStore } from "@nanostores/react"
import { HistoryIcon } from "lucide-react"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { $chartTime } from "@/lib/stores"
import { chartTimeData, cn } from "@/lib/utils"
import type { ChartTimes } from "@/types"
import { ChartTimes } from "@/types"
import { useStore } from "@nanostores/react"
import { HistoryIcon } from "lucide-react"
export default function ChartTimeSelect({ className }: { className?: string }) {
const chartTime = useStore($chartTime)

View File

@@ -1,13 +1,13 @@
// import Spinner from '../spinner'
import { useStore } from "@nanostores/react"
import { memo, useMemo } from "react"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { type ChartConfig, ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { ChartType, Unit } from "@/lib/enums"
import { memo, useMemo } from "react"
import { cn, formatShortDate, chartMargin, toFixedFloat, formatBytes, decimalString } from "@/lib/utils"
// import Spinner from '../spinner'
import { useStore } from "@nanostores/react"
import { $containerFilter, $userSettings } from "@/lib/stores"
import { chartMargin, cn, decimalString, formatBytes, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { ChartData } from "@/types"
import { Separator } from "../ui/separator"
import { ChartType, Unit } from "@/lib/enums"
import { useYAxisWidth } from "./hooks"
export default memo(function ContainerChart({

View File

@@ -1,10 +1,10 @@
import { useLingui } from "@lingui/react/macro"
import { memo } from "react"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { cn, formatShortDate, decimalString, chartMargin, formatBytes, toFixedFloat } from "@/lib/utils"
import { ChartData } from "@/types"
import { memo } from "react"
import { useLingui } from "@lingui/react/macro"
import { Unit } from "@/lib/enums"
import { chartMargin, cn, decimalString, formatBytes, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { ChartData } from "@/types"
import { useYAxisWidth } from "./hooks"
export default memo(function DiskChart({

View File

@@ -1,5 +1,5 @@
import { memo, useMemo } from "react"
import { CartesianGrid, Line, LineChart, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
@@ -8,59 +8,48 @@ import {
ChartTooltipContent,
xAxis,
} from "@/components/ui/chart"
import { chartMargin, cn, decimalString, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { ChartData, GPUData } from "@/types"
import { cn, formatShortDate, toFixedFloat, decimalString, chartMargin } from "@/lib/utils"
import { ChartData } from "@/types"
import { memo, useMemo } from "react"
import { useYAxisWidth } from "./hooks"
import type { DataPoint } from "./line-chart"
export default memo(function GpuPowerChart({ chartData }: { chartData: ChartData }) {
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
const packageKey = " package"
const { gpuData, dataPoints } = useMemo(() => {
const dataPoints = [] as DataPoint[]
const gpuData = [] as Record<string, GPUData | string>[]
const addedKeys = new Map<string, number>()
const addKey = (key: string, value: number) => {
addedKeys.set(key, (addedKeys.get(key) ?? 0) + value)
}
for (const stats of chartData.systemStats) {
const gpus = stats.stats?.g ?? {}
const data = { created: stats.created } as Record<string, GPUData | string>
for (const id in gpus) {
const gpu = gpus[id] as GPUData
data[gpu.n] = gpu
addKey(gpu.n, gpu.p ?? 0)
if (gpu.pp) {
data[`${gpu.n}${packageKey}`] = gpu
addKey(`${gpu.n}${packageKey}`, gpu.pp ?? 0)
}
}
gpuData.push(data)
}
const sortedKeys = Array.from(addedKeys.entries())
.sort(([, a], [, b]) => b - a)
.map(([key]) => key)
for (let i = 0; i < sortedKeys.length; i++) {
const id = sortedKeys[i]
dataPoints.push({
label: id,
dataKey: (gpuData: Record<string, GPUData>) => {
return id.endsWith(packageKey) ? (gpuData[id]?.pp ?? 0) : (gpuData[id]?.p ?? 0)
},
color: `hsl(${226 + (((i * 360) / addedKeys.size) % 360)}, 65%, 52%)`,
})
}
return { gpuData, dataPoints }
}, [chartData])
if (chartData.systemStats.length === 0) {
return null
}
/** Format temperature data for chart and assign colors */
const newChartData = useMemo(() => {
const newChartData = { data: [], colors: {} } as {
data: Record<string, number | string>[]
colors: Record<string, string>
}
const powerSums = {} as Record<string, number>
for (let data of chartData.systemStats) {
let newData = { created: data.created } as Record<string, number | string>
for (let gpu of Object.values(data.stats?.g ?? {})) {
if (gpu.p) {
const name = gpu.n
newData[name] = gpu.p
powerSums[name] = (powerSums[name] ?? 0) + newData[name]
}
}
newChartData.data.push(newData)
}
const keys = Object.keys(powerSums).sort((a, b) => powerSums[b] - powerSums[a])
for (let key of keys) {
newChartData.colors[key] = `hsl(${((keys.indexOf(key) * 360) / keys.length) % 360}, 60%, 55%)`
}
return newChartData
}, [chartData])
const colors = Object.keys(newChartData.colors)
// console.log('rendered at', new Date())
return (
<div>
<ChartContainer
@@ -68,7 +57,7 @@ export default memo(function GpuPowerChart({ chartData }: { chartData: ChartData
"opacity-100": yAxisWidth,
})}
>
<LineChart accessibilityLayer data={gpuData} margin={chartMargin}>
<LineChart accessibilityLayer data={newChartData.data} margin={chartMargin}>
<CartesianGrid vertical={false} />
<YAxis
direction="ltr"
@@ -78,7 +67,7 @@ export default memo(function GpuPowerChart({ chartData }: { chartData: ChartData
width={yAxisWidth}
tickFormatter={(value) => {
const val = toFixedFloat(value, 2)
return updateYAxisWidth(`${val}W`)
return updateYAxisWidth(val + "W")
}}
tickLine={false}
axisLine={false}
@@ -87,29 +76,29 @@ export default memo(function GpuPowerChart({ chartData }: { chartData: ChartData
<ChartTooltip
animationEasing="ease-out"
animationDuration={150}
// @ts-expect-error
// @ts-ignore
itemSorter={(a, b) => b.value - a.value}
content={
<ChartTooltipContent
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
contentFormatter={(item) => `${decimalString(item.value)}W`}
contentFormatter={(item) => decimalString(item.value) + "W"}
// indicator="line"
/>
}
/>
{dataPoints.map((dataPoint) => (
{colors.map((key) => (
<Line
key={dataPoint.label}
dataKey={dataPoint.dataKey}
name={dataPoint.label}
key={key}
dataKey={key}
name={key}
type="monotoneX"
dot={false}
strokeWidth={1.5}
stroke={dataPoint.color as string}
stroke={newChartData.colors[key]}
isAnimationActive={false}
/>
))}
{dataPoints.length > 1 && <ChartLegend content={<ChartLegendContent />} />}
{colors.length > 1 && <ChartLegend content={<ChartLegendContent />} />}
</LineChart>
</ChartContainer>
</div>

View File

@@ -1,6 +1,6 @@
import { useMemo, useState } from "react"
import type { ChartConfig } from "@/components/ui/chart"
import type { ChartData, SystemStats, SystemStatsRecord } from "@/types"
import { ChartConfig } from "@/components/ui/chart"
import { ChartData } from "@/types"
/** Chart configurations for CPU, memory, and network usage charts */
export interface ContainerChartConfigs {
@@ -105,21 +105,3 @@ export function useYAxisWidth() {
}
return { yAxisWidth, updateYAxisWidth }
}
// Assures consistent colors for network interfaces
export function useNetworkInterfaces(interfaces: SystemStats["ni"]) {
const keys = Object.keys(interfaces ?? {})
const sortedKeys = keys.sort((a, b) => (interfaces?.[b]?.[3] ?? 0) - (interfaces?.[a]?.[3] ?? 0))
return {
length: sortedKeys.length,
data: (index = 3) => {
return sortedKeys.map((key) => ({
label: key,
dataKey: ({ stats }: SystemStatsRecord) => stats?.ni?.[key]?.[index],
color: `hsl(${220 + (((sortedKeys.indexOf(key) * 360) / sortedKeys.length) % 360)}, 70%, 50%)`,
opacity: 0.3,
}))
},
}
}

View File

@@ -1,110 +0,0 @@
import { useMemo } from "react"
import { CartesianGrid, Line, LineChart, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
ChartLegendContent,
ChartTooltip,
ChartTooltipContent,
xAxis,
} from "@/components/ui/chart"
import { chartMargin, cn, formatShortDate } from "@/lib/utils"
import type { ChartData, SystemStatsRecord } from "@/types"
import { useYAxisWidth } from "./hooks"
export type DataPoint = {
label: string
dataKey: (data: SystemStatsRecord) => number | undefined
color: number | string
}
export default function LineChartDefault({
chartData,
max,
maxToggled,
tickFormatter,
contentFormatter,
dataPoints,
domain,
legend,
itemSorter,
}: // logRender = false,
{
chartData: ChartData
max?: number
maxToggled?: boolean
tickFormatter: (value: number, index: number) => string
contentFormatter: ({ value, payload }: { value: number; payload: SystemStatsRecord }) => string
dataPoints?: DataPoint[]
domain?: [number, number]
legend?: boolean
itemSorter?: (a: any, b: any) => number
// logRender?: boolean
}) {
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
// biome-ignore lint/correctness/useExhaustiveDependencies: ignore
return useMemo(() => {
if (chartData.systemStats.length === 0) {
return null
}
// if (logRender) {
// console.log("Rendered at", new Date())
// }
return (
<div>
<ChartContainer
className={cn("h-full w-full absolute aspect-auto bg-card opacity-0 transition-opacity", {
"opacity-100": yAxisWidth,
})}
>
<LineChart accessibilityLayer data={chartData.systemStats} margin={chartMargin}>
<CartesianGrid vertical={false} />
<YAxis
direction="ltr"
orientation={chartData.orientation}
className="tracking-tighter"
width={yAxisWidth}
domain={domain ?? [0, max ?? "auto"]}
tickFormatter={(value, index) => updateYAxisWidth(tickFormatter(value, index))}
tickLine={false}
axisLine={false}
/>
{xAxis(chartData)}
<ChartTooltip
animationEasing="ease-out"
animationDuration={150}
// @ts-expect-error
itemSorter={itemSorter}
content={
<ChartTooltipContent
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
contentFormatter={contentFormatter}
/>
}
/>
{dataPoints?.map((dataPoint) => {
let { color } = dataPoint
if (typeof color === "number") {
color = `var(--chart-${color})`
}
return (
<Line
key={dataPoint.label}
dataKey={dataPoint.dataKey}
name={dataPoint.label}
type="monotoneX"
dot={false}
strokeWidth={1.5}
stroke={color}
isAnimationActive={false}
/>
)
})}
{legend && <ChartLegend content={<ChartLegendContent />} />}
</LineChart>
</ChartContainer>
</div>
)
}, [chartData.systemStats.at(-1), yAxisWidth, maxToggled])
}

View File

@@ -1,6 +1,5 @@
import { t } from "@lingui/core/macro"
import { memo } from "react"
import { CartesianGrid, Line, LineChart, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
@@ -9,8 +8,10 @@ import {
ChartTooltipContent,
xAxis,
} from "@/components/ui/chart"
import { chartMargin, cn, decimalString, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { ChartData, SystemStats } from "@/types"
import { cn, formatShortDate, toFixedFloat, decimalString, chartMargin } from "@/lib/utils"
import { ChartData, SystemStats } from "@/types"
import { memo } from "react"
import { t } from "@lingui/core/macro"
import { useYAxisWidth } from "./hooks"
export default memo(function LoadAverageChart({ chartData }: { chartData: ChartData }) {
@@ -59,7 +60,7 @@ export default memo(function LoadAverageChart({ chartData }: { chartData: ChartD
<ChartTooltip
animationEasing="ease-out"
animationDuration={150}
// @ts-expect-error
// @ts-ignore
// itemSorter={(a, b) => b.value - a.value}
content={
<ChartTooltipContent

View File

@@ -1,10 +1,10 @@
import { useLingui } from "@lingui/react/macro"
import { memo } from "react"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { cn, decimalString, formatShortDate, chartMargin, formatBytes, toFixedFloat } from "@/lib/utils"
import { memo } from "react"
import { ChartData } from "@/types"
import { useLingui } from "@lingui/react/macro"
import { Unit } from "@/lib/enums"
import { chartMargin, cn, decimalString, formatBytes, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { ChartData } from "@/types"
import { useYAxisWidth } from "./hooks"
export default memo(function MemChart({ chartData, showMax }: { chartData: ChartData; showMax: boolean }) {
@@ -53,7 +53,7 @@ export default memo(function MemChart({ chartData, showMax }: { chartData: Chart
animationDuration={150}
content={
<ChartTooltipContent
// @ts-expect-error
// @ts-ignore
itemSorter={(a, b) => a.order - b.order}
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
contentFormatter={({ value }) => {

View File

@@ -1,11 +1,12 @@
import { t } from "@lingui/core/macro"
import { useStore } from "@nanostores/react"
import { memo } from "react"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import { cn, formatShortDate, decimalString, chartMargin, formatBytes, toFixedFloat } from "@/lib/utils"
import { ChartData } from "@/types"
import { memo } from "react"
import { $userSettings } from "@/lib/stores"
import { chartMargin, cn, decimalString, formatBytes, formatShortDate, toFixedFloat } from "@/lib/utils"
import type { ChartData } from "@/types"
import { useStore } from "@nanostores/react"
import { useYAxisWidth } from "./hooks"
export default memo(function SwapChart({ chartData }: { chartData: ChartData }) {

View File

@@ -1,195 +0,0 @@
import { SystemdService } from "@/types";
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Trans } from "@lingui/react/macro";
import { memo, useMemo, useState } from "react";
import { Button } from "@/components/ui/button";
import { ChevronDownIcon, ChevronsUpDownIcon, XIcon } from "lucide-react";
import { cn } from "@/lib/utils";
import { Input } from "@/components/ui/input";
interface SystemdServicesTableProps {
services: SystemdService[];
}
type SortKey = "name" | "status" | "cpu" | "mem";
const statusPriority: { [key: string]: number } = {
failed: 1,
activating: 2,
active: 3,
deactivating: 4,
inactive: 5,
};
const getStatusColor = (status: string) => {
switch (status) {
case 'active':
return 'text-green-500';
case 'failed':
return 'text-red-500';
case 'activating':
case 'reloading':
return 'text-blue-500';
case 'inactive':
case 'deactivating':
return 'text-gray-500';
default:
return '';
}
};
const getStatusDotColor = (status: string) => {
switch (status) {
case 'active':
return 'bg-green-500';
case 'failed':
return 'bg-red-500';
case 'activating':
case 'reloading':
return 'bg-blue-500';
case 'inactive':
case 'deactivating':
return 'bg-gray-500';
default:
return 'bg-gray-400';
}
};
export default memo(function SystemdServicesTable({ services }: SystemdServicesTableProps) {
const [isExpanded, setIsExpanded] = useState(false);
const [filter, setFilter] = useState("");
const [sortKey, setSortKey] = useState<SortKey>("status");
const [sortAsc, setSortAsc] = useState(true);
const handleSort = (key: SortKey) => {
if (sortKey === key) {
setSortAsc(!sortAsc);
} else {
setSortKey(key);
setSortAsc(true);
}
};
const sortedServices = useMemo(() => {
return [...services].sort((a, b) => {
let compare = 0;
switch (sortKey) {
case "name":
compare = a.n.localeCompare(b.n);
break;
case "status":
const priorityA = statusPriority[a.s] || 99;
const priorityB = statusPriority[b.s] || 99;
compare = priorityA - priorityB;
if (compare === 0) {
compare = a.n.localeCompare(b.n);
}
break;
case "cpu":
compare = (a.c ?? 0) - (b.c ?? 0);
break;
case "mem":
compare = (a.m ?? 0) - (b.m ?? 0);
break;
}
return sortAsc ? compare : -compare;
});
}, [services, sortKey, sortAsc]);
const failedServices = useMemo(() => sortedServices.filter(s => s.s === 'failed'), [sortedServices]);
const activeServicesCount = useMemo(() => services.filter(s => s.s === 'active').length, [services]);
const filteredServices = useMemo(() => {
if (!filter) {
return sortedServices;
}
return sortedServices.filter(service => service.n.toLowerCase().includes(filter.toLowerCase()));
}, [sortedServices, filter]);
const servicesToShow = isExpanded ? filteredServices : failedServices;
const summary = (
<span className="text-sm text-muted-foreground ml-2">
({failedServices.length} <Trans>failed</Trans>, {activeServicesCount} <Trans>active</Trans>)
</span>
);
const SortableHeader = ({ sortKey: key, children }: { sortKey: SortKey, children: React.ReactNode }) => (
<TableHead onClick={() => handleSort(key)} className="cursor-pointer">
<div className="flex items-center gap-1">
{children}
<ChevronsUpDownIcon className="h-3 w-3" />
</div>
</TableHead>
);
return (
<div>
<div className="flex justify-between items-center mb-2">
<h3 className="text-lg font-semibold">
<Trans>Systemd Services</Trans> {summary}
</h3>
{isExpanded && (
<div className="relative max-w-xs">
<Input
placeholder="Filter services..."
value={filter}
onChange={(e) => setFilter(e.target.value)}
className="ps-4 pe-8"
/>
{filter && (
<Button
type="button"
variant="ghost"
size="icon"
aria-label="Clear"
className="absolute right-1 top-1/2 -translate-y-1/2 h-7 w-7 text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100"
onClick={() => setFilter("")}
>
<XIcon className="h-4 w-4" />
</Button>
)}
</div>
)}
</div>
<div className="rounded-md border">
<Table>
<TableHeader>
<TableRow>
<SortableHeader sortKey="name"><Trans>Service</Trans></SortableHeader>
<SortableHeader sortKey="status"><Trans>Status</Trans></SortableHeader>
<SortableHeader sortKey="cpu"><Trans>CPU Usage</Trans></SortableHeader>
<SortableHeader sortKey="mem"><Trans>Memory</Trans></SortableHeader>
</TableRow>
</TableHeader>
<TableBody>
{servicesToShow.map((service) => (
<TableRow key={service.n}>
<TableCell className="font-medium">{service.n}</TableCell>
<TableCell className={cn("flex items-center gap-2", getStatusColor(service.s))}>
<span className={cn("h-2 w-2 rounded-full", getStatusDotColor(service.s))} />
{service.s}
</TableCell>
<TableCell>{(service.c ?? 0).toFixed(2)}%</TableCell>
<TableCell>{(service.m ?? 0).toFixed(2)} MB</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</div>
{failedServices.length === 0 && !isExpanded && (
<div className="text-center py-4 text-muted-foreground">
<Trans>No failed services.</Trans>
</div>
)}
<div className="flex justify-center mt-2">
<Button variant="ghost" onClick={() => setIsExpanded(!isExpanded)} className="flex items-center gap-1">
<span>
{isExpanded ? <Trans>Show less</Trans> : <Trans>Show all</Trans>} ({services.length})
</span>
<ChevronDownIcon className={cn("h-4 w-4 transition-transform", isExpanded && "rotate-180")} />
</Button>
</div>
</div>
);
})

View File

@@ -1,6 +1,5 @@
import { useStore } from "@nanostores/react"
import { memo, useMemo } from "react"
import { CartesianGrid, Line, LineChart, YAxis } from "recharts"
import {
ChartContainer,
ChartLegend,
@@ -9,9 +8,11 @@ import {
ChartTooltipContent,
xAxis,
} from "@/components/ui/chart"
import { cn, formatShortDate, toFixedFloat, chartMargin, formatTemperature, decimalString } from "@/lib/utils"
import { ChartData } from "@/types"
import { memo, useMemo } from "react"
import { $temperatureFilter, $userSettings } from "@/lib/stores"
import { chartMargin, cn, decimalString, formatShortDate, formatTemperature, toFixedFloat } from "@/lib/utils"
import type { ChartData } from "@/types"
import { useStore } from "@nanostores/react"
import { useYAxisWidth } from "./hooks"
export default memo(function TemperatureChart({ chartData }: { chartData: ChartData }) {
@@ -30,18 +31,18 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
colors: Record<string, string>
}
const tempSums = {} as Record<string, number>
for (const data of chartData.systemStats) {
const newData = { created: data.created } as Record<string, number | string>
const keys = Object.keys(data.stats?.t ?? {})
for (let data of chartData.systemStats) {
let newData = { created: data.created } as Record<string, number | string>
let keys = Object.keys(data.stats?.t ?? {})
for (let i = 0; i < keys.length; i++) {
const key = keys[i]
let key = keys[i]
newData[key] = data.stats.t![key]
tempSums[key] = (tempSums[key] ?? 0) + newData[key]
}
newChartData.data.push(newData)
}
const keys = Object.keys(tempSums).sort((a, b) => tempSums[b] - tempSums[a])
for (const key of keys) {
for (let key of keys) {
newChartData.colors[key] = `hsl(${((keys.indexOf(key) * 360) / keys.length) % 360}, 60%, 55%)`
}
return newChartData
@@ -77,7 +78,7 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
<ChartTooltip
animationEasing="ease-out"
animationDuration={150}
// @ts-expect-error
// @ts-ignore
itemSorter={(a, b) => b.value - a.value}
content={
<ChartTooltipContent
@@ -92,7 +93,7 @@ export default memo(function TemperatureChart({ chartData }: { chartData: ChartD
/>
{colors.map((key) => {
const filtered = filter && !key.toLowerCase().includes(filter.toLowerCase())
const strokeOpacity = filtered ? 0.1 : 1
let strokeOpacity = filtered ? 0.1 : 1
return (
<Line
key={key}

View File

@@ -1,7 +1,3 @@
import { t } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro"
import { getPagePath } from "@nanostores/router"
import { DialogDescription } from "@radix-ui/react-dialog"
import {
AlertOctagonIcon,
BookIcon,
@@ -14,7 +10,7 @@ import {
SettingsIcon,
UsersIcon,
} from "lucide-react"
import { memo, useEffect, useMemo } from "react"
import {
CommandDialog,
CommandEmpty,
@@ -25,10 +21,15 @@ import {
CommandSeparator,
CommandShortcut,
} from "@/components/ui/command"
import { isAdmin } from "@/lib/api"
import { memo, useEffect, useMemo } from "react"
import { $systems } from "@/lib/stores"
import { getHostDisplayValue, listen } from "@/lib/utils"
import { $router, basePath, navigate, prependBasePath } from "./router"
import { Trans } from "@lingui/react/macro"
import { t } from "@lingui/core/macro"
import { getPagePath } from "@nanostores/router"
import { DialogDescription } from "@radix-ui/react-dialog"
import { isAdmin } from "@/lib/api"
export default memo(function CommandPalette({ open, setOpen }: { open: boolean; setOpen: (open: boolean) => void }) {
useEffect(() => {

View File

@@ -1,8 +1,8 @@
import { Trans } from "@lingui/react/macro"
import { Trans } from "@lingui/react/macro";
import { useEffect, useMemo, useRef } from "react"
import { $copyContent } from "@/lib/stores"
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from "./ui/dialog"
import { Textarea } from "./ui/textarea"
import { $copyContent } from "@/lib/stores"
export default function CopyToClipboard({ content }: { content: string }) {
return (

View File

@@ -1,7 +1,7 @@
import { i18n } from "@lingui/core"
import { memo } from "react"
import { copyToClipboard, getHubURL } from "@/lib/utils"
import { DropdownMenuContent, DropdownMenuItem } from "./ui/dropdown-menu"
import { copyToClipboard, getHubURL } from "@/lib/utils"
import { i18n } from "@lingui/core"
// const isbeta = beszel.hub_version.includes("beta")
// const imagetag = isbeta ? ":edge" : ""

View File

@@ -1,10 +1,11 @@
import { useLingui } from "@lingui/react/macro"
import { LanguagesIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { dynamicActivate } from "@/lib/i18n"
import languages from "@/lib/languages"
import { cn } from "@/lib/utils"
import { useLingui } from "@lingui/react/macro"
import { dynamicActivate } from "@/lib/i18n"
export function LangToggle() {
const { i18n } = useLingui()

View File

@@ -1,19 +1,19 @@
import { t } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro"
import { getPagePath } from "@nanostores/router"
import { KeyIcon, LoaderCircle, LockIcon, LogInIcon, MailIcon } from "lucide-react"
import type { AuthMethodsList, AuthProviderInfo, OAuth2AuthConfig } from "pocketbase"
import { useCallback, useEffect, useState } from "react"
import * as v from "valibot"
import { cn } from "@/lib/utils"
import { buttonVariants } from "@/components/ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "@/components/ui/dialog"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { pb } from "@/lib/api"
import { KeyIcon, LoaderCircle, LockIcon, LogInIcon, MailIcon } from "lucide-react"
import { $authenticated } from "@/lib/stores"
import { cn } from "@/lib/utils"
import { $router, Link, prependBasePath } from "../router"
import * as v from "valibot"
import { toast } from "../ui/use-toast"
import { Dialog, DialogContent, DialogTrigger, DialogHeader, DialogTitle } from "@/components/ui/dialog"
import { useCallback, useEffect, useState } from "react"
import { AuthMethodsList, AuthProviderInfo, OAuth2AuthConfig } from "pocketbase"
import { $router, Link, prependBasePath } from "../router"
import { getPagePath } from "@nanostores/router"
import { pb } from "@/lib/api"
import { OtpInputForm } from "./otp-forms"
const honeypot = v.literal("")
@@ -83,9 +83,9 @@ export function UserAuthForm({
const result = v.safeParse(Schema, data)
if (!result.success) {
console.log(result)
const errors = {}
let errors = {}
for (const issue of result.issues) {
// @ts-expect-error
// @ts-ignore
errors[issue.path[0].key] = issue.message
}
setErrors(errors)
@@ -96,7 +96,7 @@ export function UserAuthForm({
if (isFirstRun) {
// check that passwords match
if (password !== passwordConfirm) {
const msg = "Passwords do not match"
let msg = "Passwords do not match"
setErrors({ passwordConfirm: msg })
return
}

View File

@@ -1,14 +1,15 @@
import { t } from "@lingui/core/macro"
import { Trans } from "@lingui/react/macro"
import { t } from "@lingui/core/macro"
import { LoaderCircle, MailIcon, SendHorizonalIcon } from "lucide-react"
import { useCallback, useState } from "react"
import { pb } from "@/lib/api"
import { cn } from "@/lib/utils"
import { buttonVariants } from "../ui/button"
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogTrigger } from "../ui/dialog"
import { Input } from "../ui/input"
import { Label } from "../ui/label"
import { useCallback, useState } from "react"
import { toast } from "../ui/use-toast"
import { buttonVariants } from "../ui/button"
import { cn } from "@/lib/utils"
import { Dialog, DialogHeader } from "../ui/dialog"
import { DialogContent, DialogTrigger, DialogTitle } from "../ui/dialog"
import { pb } from "@/lib/api"
const showLoginFaliedToast = () => {
toast({

View File

@@ -1,14 +1,14 @@
import { t } from "@lingui/core/macro"
import { useStore } from "@nanostores/react"
import type { AuthMethodsList } from "pocketbase"
import { useEffect, useMemo, useState } from "react"
import { UserAuthForm } from "@/components/login/auth-form"
import { pb } from "@/lib/api"
import { Logo } from "../logo"
import { ModeToggle } from "../mode-toggle"
import { $router } from "../router"
import { useTheme } from "../theme-provider"
import { useEffect, useMemo, useState } from "react"
import { useStore } from "@nanostores/react"
import ForgotPassword from "./forgot-pass-form"
import { $router } from "../router"
import { AuthMethodsList } from "pocketbase"
import { useTheme } from "../theme-provider"
import { pb } from "@/lib/api"
import { ModeToggle } from "../mode-toggle"
import { OtpRequestForm } from "./otp-forms"
export default function () {
@@ -53,7 +53,7 @@ export default function () {
<div className="min-h-svh grid items-center py-12">
<div
className="grid gap-5 w-full px-4 mx-auto"
// @ts-expect-error
// @ts-ignore
style={{ maxWidth: "21.5em", "--border": theme == "light" ? "hsl(30, 8%, 70%)" : "hsl(220, 3%, 25%)" }}
>
<div className="absolute top-3 right-3">

View File

@@ -1,15 +1,15 @@
import { Trans } from "@lingui/react/macro"
import { LoaderCircle, MailIcon, SendHorizonalIcon } from "lucide-react"
import { useCallback, useState } from "react"
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/otp"
import { pb } from "@/lib/api"
import { $authenticated } from "@/lib/stores"
import { InputOTP, InputOTPGroup, InputOTPSlot } from "@/components/ui/otp"
import { Trans } from "@lingui/react/macro"
import { showLoginFaliedToast } from "./auth-form"
import { cn } from "@/lib/utils"
import { $router } from "../router"
import { MailIcon, LoaderCircle, SendHorizonalIcon } from "lucide-react"
import { Label } from "../ui/label"
import { buttonVariants } from "../ui/button"
import { Input } from "../ui/input"
import { Label } from "../ui/label"
import { showLoginFaliedToast } from "./auth-form"
import { $router } from "../router"
export function OtpInputForm({ otpId, mfaId }: { otpId: string; mfaId: string }) {
const [value, setValue] = useState("")

View File

@@ -1,7 +1,8 @@
import { t } from "@lingui/core/macro"
import { MoonStarIcon, SunIcon } from "lucide-react"
import { useTheme } from "@/components/theme-provider"
import { Button } from "@/components/ui/button"
import { useTheme } from "@/components/theme-provider"
export function ModeToggle() {
const { theme, setTheme } = useTheme()

View File

@@ -1,5 +1,6 @@
import { Trans } from "@lingui/react/macro"
import { getPagePath } from "@nanostores/router"
import { useState, lazy, Suspense } from "react"
import { Button, buttonVariants } from "@/components/ui/button"
import {
DatabaseBackupIcon,
LogOutIcon,
@@ -10,24 +11,23 @@ import {
UserIcon,
UsersIcon,
} from "lucide-react"
import { lazy, Suspense, useState } from "react"
import { Button, buttonVariants } from "@/components/ui/button"
import { $router, basePath, Link, prependBasePath } from "./router"
import { LangToggle } from "./lang-toggle"
import { ModeToggle } from "./mode-toggle"
import { Logo } from "./logo"
import { cn, runOnce } from "@/lib/utils"
import { isReadOnlyUser, isAdmin, logOut, pb } from "@/lib/api"
import {
DropdownMenu,
DropdownMenuTrigger,
DropdownMenuContent,
DropdownMenuGroup,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuSeparator,
DropdownMenuTrigger,
DropdownMenuGroup,
DropdownMenuItem,
} from "@/components/ui/dropdown-menu"
import { isAdmin, isReadOnlyUser, logOut, pb } from "@/lib/api"
import { cn, runOnce } from "@/lib/utils"
import { AddSystemButton } from "./add-system"
import { LangToggle } from "./lang-toggle"
import { Logo } from "./logo"
import { ModeToggle } from "./mode-toggle"
import { $router, basePath, Link, prependBasePath } from "./router"
import { getPagePath } from "@nanostores/router"
const CommandPalette = lazy(() => import("./command-palette"))

View File

@@ -23,7 +23,7 @@ export const prependBasePath = (path: string) => (basePath + path).replaceAll("/
// prepend base path to routes
for (const route in routes) {
// @ts-expect-error need as const above to get nanostores to parse types properly
// @ts-ignore need as const above to get nanostores to parse types properly
routes[route] = prependBasePath(routes[route])
}

View File

@@ -3,7 +3,6 @@ import { Trans, useLingui } from "@lingui/react/macro"
import { redirectPage } from "@nanostores/router"
import {
CopyIcon,
ExternalLinkIcon,
FingerprintIcon,
KeyIcon,
MoreHorizontalIcon,
@@ -29,7 +28,7 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { AppleIcon, DockerIcon, FreeBsdIcon, TuxIcon, WindowsIcon } from "@/components/ui/icons"
import { AppleIcon, DockerIcon, TuxIcon, WindowsIcon } from "@/components/ui/icons"
import { Separator } from "@/components/ui/separator"
import { Switch } from "@/components/ui/switch"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
@@ -151,7 +150,6 @@ const SectionUniversalToken = memo(() => {
setIsLoading(false)
}
// biome-ignore lint/correctness/useExhaustiveDependencies: only on mount
useEffect(() => {
updateToken()
}, [])
@@ -223,16 +221,6 @@ const ActionsButtonUniversalToken = memo(({ token, checked }: { token: string; c
onClick: () => copyWindowsCommand(port, publicKey, token),
icons: [WindowsIcon],
},
{
text: t({ message: "FreeBSD command", context: "Button to copy install command" }),
onClick: () => copyLinuxCommand(port, publicKey, token),
icons: [FreeBsdIcon],
},
{
text: t`Manual setup instructions`,
url: "https://beszel.dev/guide/agent-installation#binary",
icons: [ExternalLinkIcon],
},
]
return (
<div className="flex items-center gap-2">
@@ -303,8 +291,8 @@ const SectionTable = memo(({ fingerprints = [] }: { fingerprints: FingerprintRec
</tr>
</TableHeader>
<TableBody className="whitespace-pre">
{fingerprints.map((fingerprint) => (
<TableRow key={fingerprint.id}>
{fingerprints.map((fingerprint, i) => (
<TableRow key={i}>
<TableCell className="font-medium ps-5 py-2 max-w-60 truncate">
{fingerprint.expand.system.name}
</TableCell>
@@ -329,10 +317,10 @@ async function updateFingerprint(fingerprint: FingerprintRecord, rotateToken = f
fingerprint: "",
token: rotateToken ? generateToken() : fingerprint.token,
})
} catch (error: unknown) {
} catch (error: any) {
toast({
title: t`Error`,
description: (error as Error).message,
description: error.message,
})
}
}

View File

@@ -3,15 +3,7 @@ import { Plural, Trans, useLingui } from "@lingui/react/macro"
import { useStore } from "@nanostores/react"
import { getPagePath } from "@nanostores/router"
import { timeTicks } from "d3-time"
import {
ChevronRightSquareIcon,
ClockArrowUp,
CpuIcon,
GlobeIcon,
LayoutGridIcon,
MonitorIcon,
XIcon,
} from "lucide-react"
import { ClockArrowUp, CpuIcon, GlobeIcon, LayoutGridIcon, MonitorIcon, XIcon } from "lucide-react"
import { subscribeKeys } from "nanostores"
import React, { type JSX, memo, useCallback, useEffect, useMemo, useRef, useState } from "react"
import AreaChartDefault from "@/components/charts/area-chart"
@@ -24,7 +16,7 @@ import MemChart from "@/components/charts/mem-chart"
import SwapChart from "@/components/charts/swap-chart"
import TemperatureChart from "@/components/charts/temperature-chart"
import { getPbTimestamp, pb } from "@/lib/api"
import { ChartType, ConnectionType, connectionTypeLabels, Os, SystemStatus, Unit } from "@/lib/enums"
import { ChartType, Os, SystemStatus, Unit } from "@/lib/enums"
import { batteryStateTranslations } from "@/lib/i18n"
import {
$allSystemsByName,
@@ -49,20 +41,17 @@ import {
toFixedFloat,
useBrowserStorage,
} from "@/lib/utils"
import type { ChartData, ChartTimes, ContainerStatsRecord, GPUData, SystemRecord, SystemStatsRecord, SystemdStatsRecord } from "@/types"
import type { ChartData, ChartTimes, ContainerStatsRecord, GPUData, SystemRecord, SystemStatsRecord } from "@/types"
import ChartTimeSelect from "../charts/chart-time-select"
import { $router, navigate } from "../router"
import Spinner from "../spinner"
import { Button } from "../ui/button"
import { Card, CardDescription, CardHeader, CardTitle } from "../ui/card"
import { AppleIcon, ChartAverage, ChartMax, FreeBsdIcon, Rows, TuxIcon, WebSocketIcon, WindowsIcon } from "../ui/icons"
import { AppleIcon, ChartAverage, ChartMax, FreeBsdIcon, Rows, TuxIcon, WindowsIcon } from "../ui/icons"
import { Input } from "../ui/input"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../ui/select"
import { Separator } from "../ui/separator"
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "../ui/tooltip"
import NetworkSheet from "./system/network-sheet"
import LineChartDefault from "../charts/line-chart"
import SystemdServicesTable from "../charts/systemd-services-table"
type ChartTimeData = {
time: number
@@ -96,7 +85,7 @@ function getTimeData(chartTime: ChartTimes, lastCreated: number) {
}
// add empty values between records to make gaps if interval is too large
function addValues<T extends SystemStatsRecord | ContainerStatsRecord | SystemdStatsRecord>(
function addEmptyValues<T extends SystemStatsRecord | ContainerStatsRecord>(
prevRecords: T[],
newRecords: T[],
expectedInterval: number
@@ -120,7 +109,7 @@ function addValues<T extends SystemStatsRecord | ContainerStatsRecord | SystemdS
return modifiedRecords
}
async function getStats<T extends SystemStatsRecord | ContainerStatsRecord | SystemdStatsRecord>(
async function getStats<T extends SystemStatsRecord | ContainerStatsRecord>(
collection: string,
system: SystemRecord,
chartTime: ChartTimes
@@ -140,7 +129,7 @@ async function getStats<T extends SystemStatsRecord | ContainerStatsRecord | Sys
function dockerOrPodman(str: string, system: SystemRecord) {
if (system.info.p) {
return str.replace("docker", "podman").replace("Docker", "Podman")
str = str.replace("docker", "podman").replace("Docker", "Podman")
}
return str
}
@@ -154,7 +143,6 @@ export default memo(function SystemDetail({ name }: { name: string }) {
const [grid, setGrid] = useBrowserStorage("grid", true)
const [system, setSystem] = useState({} as SystemRecord)
const [systemStats, setSystemStats] = useState([] as SystemStatsRecord[])
const [systemdStats, setSystemdStats] = useState([] as SystemdStatsRecord[])
const [containerData, setContainerData] = useState([] as ChartData["containerData"])
const netCardRef = useRef<HTMLDivElement>(null)
const persistChartTime = useRef(false)
@@ -173,7 +161,6 @@ export default memo(function SystemDetail({ name }: { name: string }) {
}
persistChartTime.current = false
setSystemStats([])
setSystemdStats([])
setContainerData([])
setContainerFilterBar(null)
$containerFilter.set("")
@@ -238,8 +225,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
Promise.allSettled([
getStats<SystemStatsRecord>("system_stats", system, chartTime),
getStats<ContainerStatsRecord>("container_stats", system, chartTime),
getStats<SystemdStatsRecord>("systemd_stats", system, chartTime),
]).then(([systemStats, containerStats, systemdStats]) => {
]).then(([systemStats, containerStats]) => {
// loading: false
setChartLoading(false)
@@ -248,29 +234,18 @@ export default memo(function SystemDetail({ name }: { name: string }) {
const ss_cache_key = `${system.id}_${chartTime}_system_stats`
let systemData = (cache.get(ss_cache_key) || []) as SystemStatsRecord[]
if (systemStats.status === "fulfilled" && systemStats.value.length) {
systemData = systemData.concat(addValues(systemData, systemStats.value, expectedInterval))
systemData = systemData.concat(addEmptyValues(systemData, systemStats.value, expectedInterval))
if (systemData.length > 120) {
systemData = systemData.slice(-100)
}
cache.set(ss_cache_key, systemData)
}
setSystemStats(systemData)
// make new systemd stats
const sds_cache_key = `${system.id}_${chartTime}_systemd_stats`
let systemdData = (cache.get(sds_cache_key) || []) as SystemdStatsRecord[]
if (systemdStats.status === "fulfilled" && systemdStats.value.length) {
systemdData = systemdData.concat(addValues(systemdData, systemdStats.value, expectedInterval))
if (systemdData.length > 120) {
systemdData = systemdData.slice(-100)
}
cache.set(sds_cache_key, systemdData)
}
setSystemdStats(systemdData)
// make new container stats
const cs_cache_key = `${system.id}_${chartTime}_container_stats`
let containerData = (cache.get(cs_cache_key) || []) as ContainerStatsRecord[]
if (containerStats.status === "fulfilled" && containerStats.value.length) {
containerData = containerData.concat(addValues(containerData, containerStats.value, expectedInterval))
containerData = containerData.concat(addEmptyValues(containerData, containerStats.value, expectedInterval))
if (containerData.length > 120) {
containerData = containerData.slice(-100)
}
@@ -413,8 +388,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
const dataEmpty = !chartLoading && chartData.systemStats.length === 0
const lastGpuVals = Object.values(systemStats.at(-1)?.stats.g ?? {})
const hasGpuData = lastGpuVals.length > 0
const hasGpuPowerData = lastGpuVals.some((gpu) => gpu.p !== undefined || gpu.pp !== undefined)
const hasGpuEnginesData = lastGpuVals.some((gpu) => gpu.e !== undefined)
const hasGpuPowerData = lastGpuVals.some((gpu) => gpu.p !== undefined)
let translatedStatus: string = system.status
if (system.status === SystemStatus.Up) {
@@ -432,44 +406,25 @@ export default memo(function SystemDetail({ name }: { name: string }) {
<div>
<h1 className="text-[1.6rem] font-semibold mb-1.5">{system.name}</h1>
<div className="flex flex-wrap items-center gap-3 gap-y-2 text-sm opacity-90">
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<div className="capitalize flex gap-2 items-center">
<span className={cn("relative flex h-3 w-3")}>
{system.status === SystemStatus.Up && (
<span
className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
style={{ animationDuration: "1.5s" }}
></span>
)}
<span
className={cn("relative inline-flex rounded-full h-3 w-3", {
"bg-green-500": system.status === SystemStatus.Up,
"bg-red-500": system.status === SystemStatus.Down,
"bg-primary/40": system.status === SystemStatus.Paused,
"bg-yellow-500": system.status === SystemStatus.Pending,
})}
></span>
</span>
{translatedStatus}
</div>
</TooltipTrigger>
{system.info.ct && (
<TooltipContent>
<div className="flex gap-1 items-center">
{system.info.ct === ConnectionType.WebSocket ? (
<WebSocketIcon className="size-4" />
) : (
<ChevronRightSquareIcon className="size-4" strokeWidth={2} />
)}
{connectionTypeLabels[system.info.ct as ConnectionType]}
</div>
</TooltipContent>
<div className="capitalize flex gap-2 items-center">
<span className={cn("relative flex h-3 w-3")}>
{system.status === SystemStatus.Up && (
<span
className="animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"
style={{ animationDuration: "1.5s" }}
></span>
)}
</Tooltip>
</TooltipProvider>
<span
className={cn("relative inline-flex rounded-full h-3 w-3", {
"bg-green-500": system.status === SystemStatus.Up,
"bg-red-500": system.status === SystemStatus.Down,
"bg-primary/40": system.status === SystemStatus.Paused,
"bg-yellow-500": system.status === SystemStatus.Pending,
})}
></span>
</span>
{translatedStatus}
</div>
{systemInfo.map(({ value, label, Icon, hide }) => {
if (hide || !value) {
return null
@@ -609,13 +564,13 @@ export default memo(function SystemDetail({ name }: { name: string }) {
dataPoints={[
{
label: t({ message: "Write", comment: "Disk write" }),
dataKey: ({ stats }: SystemStatsRecord) => (showMax ? stats?.dwm : stats?.dw),
dataKey: ({ stats }) => (showMax ? stats?.dwm : stats?.dw),
color: 3,
opacity: 0.3,
},
{
label: t({ message: "Read", comment: "Disk read" }),
dataKey: ({ stats }: SystemStatsRecord) => (showMax ? stats?.drm : stats?.dr),
dataKey: ({ stats }) => (showMax ? stats?.drm : stats?.dr),
color: 1,
opacity: 0.3,
},
@@ -635,12 +590,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
empty={dataEmpty}
grid={grid}
title={t`Bandwidth`}
cornerEl={
<div className="flex gap-2">
{maxValSelect}
<NetworkSheet chartData={chartData} dataEmpty={dataEmpty} grid={grid} maxValues={maxValues} />
</div>
}
cornerEl={maxValSelect}
description={t`Network traffic of public interfaces`}
>
<AreaChartDefault
@@ -650,7 +600,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
{
label: t`Sent`,
// use bytes if available, otherwise multiply old MB (can remove in future)
dataKey(data: SystemStatsRecord) {
dataKey(data) {
if (showMax) {
return data?.stats?.bm?.[0] ?? (data?.stats?.nsm ?? 0) * 1024 * 1024
}
@@ -661,7 +611,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
},
{
label: t`Received`,
dataKey(data: SystemStatsRecord) {
dataKey(data) {
if (showMax) {
return data?.stats?.bm?.[1] ?? (data?.stats?.nrm ?? 0) * 1024 * 1024
}
@@ -670,9 +620,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
color: 2,
opacity: 0.2,
},
]
// try to place the lesser number in front for better visibility
.sort(() => (systemStats.at(-1)?.stats.b?.[1] ?? 0) - (systemStats.at(-1)?.stats.b?.[0] ?? 0))}
]}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, true, userSettings.unitNet, false)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
@@ -726,7 +674,6 @@ export default memo(function SystemDetail({ name }: { name: string }) {
grid={grid}
title={t`Load Average`}
description={t`System load averages over time`}
legend={true}
>
<LoadAverageChart chartData={chartData} />
</ChartCard>
@@ -740,7 +687,6 @@ export default memo(function SystemDetail({ name }: { name: string }) {
title={t`Temperature`}
description={t`Temperatures of system sensors`}
cornerEl={<FilterBar store={$temperatureFilter} />}
legend={Object.keys(systemStats.at(-1)?.stats.t ?? {}).length < 12}
>
<TemperatureChart chartData={chartData} />
</ChartCard>
@@ -774,6 +720,7 @@ export default memo(function SystemDetail({ name }: { name: string }) {
/>
</ChartCard>
)}
{/* GPU power draw chart */}
{hasGpuPowerData && (
<ChartCard
@@ -787,26 +734,14 @@ export default memo(function SystemDetail({ name }: { name: string }) {
)}
</div>
{/* Non-power GPU charts */}
{/* GPU charts */}
{hasGpuData && (
<div className="grid xl:grid-cols-2 gap-4">
{hasGpuEnginesData && (
<ChartCard
legend={true}
empty={dataEmpty}
grid={grid}
title={t`GPU Engines`}
description={t`Average utilization of GPU engines`}
>
<GpuEnginesChart chartData={chartData} />
</ChartCard>
)}
{Object.keys(systemStats.at(-1)?.stats.g ?? {}).map((id) => {
const gpu = systemStats.at(-1)?.stats.g?.[id] as GPUData
return (
<div key={id} className="contents">
<ChartCard
className="!col-span-1"
empty={dataEmpty}
grid={grid}
title={`${gpu.n} ${t`Usage`}`}
@@ -826,54 +761,39 @@ export default memo(function SystemDetail({ name }: { name: string }) {
contentFormatter={({ value }) => `${decimalString(value)}%`}
/>
</ChartCard>
{(gpu.mt ?? 0) > 0 && (
<ChartCard
empty={dataEmpty}
grid={grid}
title={`${gpu.n} VRAM`}
description={t`Precise utilization at the recorded time`}
>
<AreaChartDefault
chartData={chartData}
dataPoints={[
{
label: t`Usage`,
dataKey: ({ stats }) => stats?.g?.[id]?.mu ?? 0,
color: 2,
opacity: 0.25,
},
]}
max={gpu.mt}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
return `${decimalString(convertedValue)} ${unit}`
}}
/>
</ChartCard>
)}
<ChartCard
empty={dataEmpty}
grid={grid}
title={`${gpu.n} VRAM`}
description={t`Precise utilization at the recorded time`}
>
<AreaChartDefault
chartData={chartData}
dataPoints={[
{
label: t`Usage`,
dataKey: ({ stats }) => stats?.g?.[id]?.mu ?? 0,
color: 2,
opacity: 0.25,
},
]}
max={gpu.mt}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, Unit.Bytes, true)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, Unit.Bytes, true)
return `${decimalString(convertedValue)} ${unit}`
}}
/>
</ChartCard>
</div>
)
})}
</div>
)}
{/* systemd services table */}
{(systemdStats.at(-1)?.stats?.length ?? 0) > 0 && (
<Card className="col-span-full">
<CardHeader className="pb-5 pt-4 gap-1 relative max-sm:py-3 max-sm:px-4">
<CardTitle className="text-xl sm:text-2xl"><Trans>Systemd Services</Trans></CardTitle>
</CardHeader>
<div className="px-4 pb-4">
<SystemdServicesTable services={systemdStats.at(-1)!.stats!} />
</div>
</Card>
)}
{/* extra filesystem charts */}
{Object.keys(systemStats.at(-1)?.stats.efs ?? {}).length > 0 && (
<div className="grid xl:grid-cols-2 gap-4">
@@ -939,47 +859,27 @@ export default memo(function SystemDetail({ name }: { name: string }) {
)
})
function GpuEnginesChart({ chartData }: { chartData: ChartData }) {
const dataPoints = []
const engines = Object.keys(chartData.systemStats?.at(-1)?.stats.g?.[0]?.e ?? {}).sort()
for (const engine of engines) {
dataPoints.push({
label: engine,
dataKey: ({ stats }: SystemStatsRecord) => stats?.g?.[0]?.e?.[engine] ?? 0,
color: `hsl(${140 + (((engines.indexOf(engine) * 360) / engines.length) % 360)}, 65%, 52%)`,
opacity: 0.35,
})
}
return (
<LineChartDefault
legend={true}
chartData={chartData}
dataPoints={dataPoints}
tickFormatter={(val) => `${toFixedFloat(val, 2)}%`}
contentFormatter={({ value }) => `${decimalString(value)}%`}
/>
)
}
function FilterBar({ store = $containerFilter }: { store?: typeof $containerFilter }) {
const containerFilter = useStore(store)
const { t } = useLingui()
const inputRef = useRef<HTMLInputElement>(null)
const debouncedStoreSet = useMemo(() => debounce((value: string) => store.set(value), 80), [store])
const debouncedStoreSet = useMemo(() => debounce((value: string) => store.set(value), 150), [store])
const handleChange = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => debouncedStoreSet(e.target.value),
(e: React.ChangeEvent<HTMLInputElement>) => {
const value = e.target.value
if (inputRef.current) {
inputRef.current.value = value
}
debouncedStoreSet(value)
},
[debouncedStoreSet]
)
return (
<>
<Input
placeholder={t`Filter...`}
className="ps-4 pe-8 w-full sm:w-44"
onChange={handleChange}
value={containerFilter}
/>
<Input placeholder={t`Filter...`} className="ps-4 pe-8" onChange={handleChange} ref={inputRef} />
{containerFilter && (
<Button
type="button"
@@ -987,7 +887,12 @@ function FilterBar({ store = $containerFilter }: { store?: typeof $containerFilt
size="icon"
aria-label="Clear"
className="absolute right-1 top-1/2 -translate-y-1/2 h-7 w-7 text-gray-500 hover:text-gray-900 dark:text-gray-400 dark:hover:text-gray-100"
onClick={() => store.set("")}
onClick={() => {
if (inputRef.current) {
inputRef.current.value = ""
}
store.set("")
}}
>
<XIcon className="h-4 w-4" />
</Button>
@@ -1000,7 +905,7 @@ const SelectAvgMax = memo(({ max }: { max: boolean }) => {
const Icon = max ? ChartMax : ChartAverage
return (
<Select value={max ? "max" : "avg"} onValueChange={(e) => $maxValues.set(e === "max")}>
<SelectTrigger className="relative ps-10 pe-5 w-full sm:w-44">
<SelectTrigger className="relative ps-10 pe-5">
<Icon className="h-4 w-4 absolute start-4 top-1/2 -translate-y-1/2 opacity-85" />
<SelectValue />
</SelectTrigger>
@@ -1016,15 +921,13 @@ const SelectAvgMax = memo(({ max }: { max: boolean }) => {
)
})
export function ChartCard({
function ChartCard({
title,
description,
children,
grid,
empty,
cornerEl,
legend,
className,
}: {
title: string
description: string
@@ -1032,22 +935,17 @@ export function ChartCard({
grid?: boolean
empty?: boolean
cornerEl?: JSX.Element | null
legend?: boolean
className?: string
}) {
const { isIntersecting, ref } = useIntersectionObserver()
return (
<Card
className={cn("pb-2 sm:pb-4 odd:last-of-type:col-span-full min-h-full", { "col-span-full": !grid }, className)}
ref={ref}
>
<Card className={cn("pb-2 sm:pb-4 odd:last-of-type:col-span-full", { "col-span-full": !grid })} ref={ref}>
<CardHeader className="pb-5 pt-4 gap-1 relative max-sm:py-3 max-sm:px-4">
<CardTitle className="text-xl sm:text-2xl">{title}</CardTitle>
<CardDescription>{description}</CardDescription>
{cornerEl && <div className="py-1 grid sm:justify-end sm:absolute sm:top-3.5 sm:end-3.5">{cornerEl}</div>}
{cornerEl && <div className="relative py-1 block sm:w-44 sm:absolute sm:top-3.5 sm:end-3.5">{cornerEl}</div>}
</CardHeader>
<div className={cn("ps-0 w-[calc(100%-1.5em)] relative group", legend ? "h-54 md:h-56" : "h-48 md:h-52")}>
<div className="ps-0 w-[calc(100%-1.5em)] h-48 md:h-52 relative group">
{
<Spinner
msg={empty ? t`Waiting for enough records to display` : undefined}

View File

@@ -1,156 +0,0 @@
import { t } from "@lingui/core/macro"
import { useStore } from "@nanostores/react"
import { MoreHorizontalIcon } from "lucide-react"
import { memo, useRef, useState } from "react"
import AreaChartDefault from "@/components/charts/area-chart"
import ChartTimeSelect from "@/components/charts/chart-time-select"
import { useNetworkInterfaces } from "@/components/charts/hooks"
import { Button } from "@/components/ui/button"
import { Sheet, SheetContent, SheetTrigger } from "@/components/ui/sheet"
import { DialogTitle } from "@/components/ui/dialog"
import { $userSettings } from "@/lib/stores"
import { decimalString, formatBytes, toFixedFloat } from "@/lib/utils"
import type { ChartData } from "@/types"
import { ChartCard } from "../system"
export default memo(function NetworkSheet({
chartData,
dataEmpty,
grid,
maxValues,
}: {
chartData: ChartData
dataEmpty: boolean
grid: boolean
maxValues: boolean
}) {
const [netInterfacesOpen, setNetInterfacesOpen] = useState(false)
const userSettings = useStore($userSettings)
const netInterfaces = useNetworkInterfaces(chartData.systemStats.at(-1)?.stats?.ni ?? {})
const showNetLegend = netInterfaces.length > 0 && netInterfaces.length < 15
const hasOpened = useRef(false)
if (netInterfacesOpen && !hasOpened.current) {
hasOpened.current = true
}
if (!netInterfaces.length) {
return null
}
return (
<Sheet open={netInterfacesOpen} onOpenChange={setNetInterfacesOpen}>
<DialogTitle className="sr-only">{t`Network traffic of public interfaces`}</DialogTitle>
<SheetTrigger asChild>
<Button
title={t`View more`}
variant="outline"
size="icon"
className="shrink-0 max-sm:absolute max-sm:top-3 max-sm:end-3"
>
<MoreHorizontalIcon />
</Button>
</SheetTrigger>
{hasOpened.current && (
<SheetContent aria-describedby={undefined} className="overflow-auto w-200 !max-w-full p-4 sm:p-6">
<ChartTimeSelect className="w-[calc(100%-2em)]" />
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Download`}
description={t`Network traffic of public interfaces`}
legend={showNetLegend}
className="min-h-auto"
>
<AreaChartDefault
chartData={chartData}
maxToggled={maxValues}
itemSorter={(a, b) => b.value - a.value}
dataPoints={netInterfaces.data(1)}
legend={showNetLegend}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, true, userSettings.unitNet, false)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitNet, false)
return `${decimalString(convertedValue, convertedValue >= 100 ? 1 : 2)} ${unit}`
}}
/>
</ChartCard>
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Upload`}
description={t`Network traffic of public interfaces`}
legend={showNetLegend}
className="min-h-auto"
>
<AreaChartDefault
chartData={chartData}
maxToggled={maxValues}
itemSorter={(a, b) => b.value - a.value}
legend={showNetLegend}
dataPoints={netInterfaces.data(0)}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, true, userSettings.unitNet, false)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, true, userSettings.unitNet, false)
return `${decimalString(convertedValue, convertedValue >= 100 ? 1 : 2)} ${unit}`
}}
/>
</ChartCard>
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Cumulative Download`}
description={t`Total data received for each interface`}
legend={showNetLegend}
className="min-h-auto"
>
<AreaChartDefault
chartData={chartData}
legend={showNetLegend}
dataPoints={netInterfaces.data(3)}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, userSettings.unitNet, false)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, userSettings.unitNet, false)
return `${decimalString(convertedValue, convertedValue >= 100 ? 1 : 2)} ${unit}`
}}
/>
</ChartCard>
<ChartCard
empty={dataEmpty}
grid={grid}
title={t`Cumulative Upload`}
description={t`Total data sent for each interface`}
legend={showNetLegend}
className="min-h-auto"
>
<AreaChartDefault
chartData={chartData}
legend={showNetLegend}
dataPoints={netInterfaces.data(2)}
tickFormatter={(val) => {
const { value, unit } = formatBytes(val, false, userSettings.unitNet, false)
return `${toFixedFloat(value, value >= 10 ? 0 : 1)} ${unit}`
}}
contentFormatter={({ value }) => {
const { value: convertedValue, unit } = formatBytes(value, false, userSettings.unitNet, false)
return `${decimalString(convertedValue, convertedValue >= 100 ? 1 : 2)} ${unit}`
}}
/>
</ChartCard>
</SheetContent>
)}
</Sheet>
)
})

View File

@@ -1,5 +1,5 @@
import { LoaderCircleIcon } from "lucide-react"
import { cn } from "@/lib/utils"
import { LoaderCircleIcon } from "lucide-react"
export default function ({ msg, className }: { msg?: string; className?: string }) {
return (

View File

@@ -1,18 +1,11 @@
import { t } from "@lingui/core/macro"
import { Trans, useLingui } from "@lingui/react/macro"
import { useStore } from "@nanostores/react"
import { getPagePath } from "@nanostores/router"
import type { CellContext, ColumnDef, HeaderContext } from "@tanstack/react-table"
import type { ClassValue } from "clsx"
import type { SystemRecord, SystemStats, SystemStatsRecord, SystemdService, SystemdStatsRecord } from "@/types"
import { SystemRecord } from "@/types"
import { CellContext, ColumnDef, HeaderContext } from "@tanstack/react-table"
import { ClassValue } from "clsx"
import {
ArrowUpDownIcon,
ChevronRightSquareIcon,
CheckIcon,
CopyIcon,
CpuIcon,
HardDriveIcon,
ListChecks,
MemoryStickIcon,
MoreHorizontalIcon,
PauseCircleIcon,
@@ -22,10 +15,7 @@ import {
Trash2Icon,
WifiIcon,
} from "lucide-react"
import { memo, useMemo, useRef, useState } from "react"
import { isReadOnlyUser, pb } from "@/lib/api"
import { ConnectionType, connectionTypeLabels, MeterState, SystemStatus } from "@/lib/enums"
import { $longestSystemNameLen, $userSettings } from "@/lib/stores"
import { Button } from "../ui/button"
import {
cn,
copyToClipboard,
@@ -35,11 +25,24 @@ import {
getMeterState,
parseSemVer,
} from "@/lib/utils"
import { SystemDialog } from "../add-system"
import AlertButton from "../alerts/alert-button"
import { $router, Link } from "../router"
import { EthernetIcon, GpuIcon, HourglassIcon, ThermometerIcon } from "../ui/icons"
import { useStore } from "@nanostores/react"
import { $longestSystemNameLen, $userSettings } from "@/lib/stores"
import { Trans, useLingui } from "@lingui/react/macro"
import { useMemo, useRef, useState } from "react"
import { memo } from "react"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../ui/dropdown-menu"
import AlertButton from "../alerts/alert-button"
import { Dialog } from "../ui/dialog"
import { SystemDialog } from "../add-system"
import { AlertDialog } from "../ui/alert-dialog"
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
@@ -48,16 +51,12 @@ import {
AlertDialogHeader,
AlertDialogTitle,
} from "../ui/alert-dialog"
import { Button, buttonVariants } from "../ui/button"
import { Dialog } from "../ui/dialog"
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "../ui/dropdown-menu"
import { EthernetIcon, GpuIcon, HourglassIcon, ThermometerIcon, WebSocketIcon } from "../ui/icons"
import { buttonVariants } from "../ui/button"
import { t } from "@lingui/core/macro"
import { MeterState, SystemStatus } from "@/lib/enums"
import { $router, Link } from "../router"
import { getPagePath } from "@nanostores/router"
import { isReadOnlyUser, pb } from "@/lib/api"
const STATUS_COLORS = {
[SystemStatus.Up]: "bg-green-500",
@@ -274,46 +273,24 @@ export default function SystemsTableColumns(viewMode: "table" | "grid"): ColumnD
return null
}
const system = info.row.original
const color = {
"text-green-500": version === globalThis.BESZEL.HUB_VERSION,
"text-yellow-500": version !== globalThis.BESZEL.HUB_VERSION,
"text-red-500": system.status !== SystemStatus.Up,
}
return (
<Link
href={getPagePath($router, "system", { name: system.name })}
className={cn(
"flex gap-1.5 items-center md:pe-5 tabular-nums relative z-10",
viewMode === "table" && "ps-0.5"
)}
tabIndex={-1}
title={connectionTypeLabels[system.info.ct as ConnectionType]}
role="none"
>
{system.info.ct === ConnectionType.WebSocket && (
<WebSocketIcon className={cn("size-3 pointer-events-none", color)} />
)}
{system.info.ct === ConnectionType.SSH && (
<ChevronRightSquareIcon className={cn("size-3 pointer-events-none", color)} />
)}
{!system.info.ct && <IndicatorDot system={system} className={cn(color, "bg-current mx-0.5")} />}
<span className={cn("flex gap-1.5 items-center md:pe-5 tabular-nums", viewMode === "table" && "ps-0.5")}>
<IndicatorDot
system={system}
className={
(system.status !== SystemStatus.Up && STATUS_COLORS[SystemStatus.Paused]) ||
(version === globalThis.BESZEL.HUB_VERSION && STATUS_COLORS[SystemStatus.Up]) ||
STATUS_COLORS[SystemStatus.Pending]
}
/>
<span className="truncate max-w-14">{info.getValue() as string}</span>
</Link>
</span>
)
},
},
{
id: "systemd",
name: () => t`Services`,
size: 50,
Icon: ListChecks,
hideSort: true,
header: sortableHeader,
cell: ({ row }) => <SystemdCell systemId={row.original.id} />,
},
{
id: "actions",
// @ts-expect-error
// @ts-ignore
name: () => t({ message: "Actions", comment: "Table column" }),
size: 50,
cell: ({ row }) => (
@@ -328,13 +305,12 @@ export default function SystemsTableColumns(viewMode: "table" | "grid"): ColumnD
function sortableHeader(context: HeaderContext<SystemRecord, unknown>) {
const { column } = context
// @ts-expect-error
// @ts-ignore
const { Icon, hideSort, name }: { Icon: React.ElementType; name: () => string; hideSort: boolean } = column.columnDef
const isSorted = column.getIsSorted()
return (
<Button
variant="ghost"
className={cn("h-9 px-3 flex duration-50", isSorted && "bg-accent/70 light:bg-accent text-accent-foreground/90")}
className="h-9 px-3 flex"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
{Icon && <Icon className="me-2 size-4" />}
@@ -374,50 +350,10 @@ export function IndicatorDot({ system, className }: { system: SystemRecord; clas
)
}
const SystemdCell = ({ systemId }: { systemId: string }) => {
const [stats, setStats] = useState<SystemdService[] | null>(null);
useEffect(() => {
const fetchStats = async () => {
try {
const record = await pb.collection("systemd_stats").getFirstListItem<SystemdStatsRecord>(`system="${systemId}"`, {
sort: "-created",
});
setStats(record.stats);
} catch (error) {
// Handle case where no stats are found
setStats(null);
}
};
fetchStats();
}, [systemId]);
if (!stats) {
return <span className="text-muted-foreground">-</span>;
}
const failed = stats.filter(s => s.s === 'failed').length;
if (failed > 0) {
return (
<div className="tabular-nums text-red-500">
{failed}
</div>
);
}
return (
<div className="text-green-500 flex items-center justify-center">
<CheckIcon className="size-4" />
</div>
);
};
export const ActionsButton = memo(({ system }: { system: SystemRecord }) => {
const [deleteOpen, setDeleteOpen] = useState(false)
const [editOpen, setEditOpen] = useState(false)
const editOpened = useRef(false)
let editOpened = useRef(false)
const { t } = useLingui()
const { id, status, host, name } = system

View File

@@ -1,31 +1,17 @@
import { Trans, useLingui } from "@lingui/react/macro"
import { useStore } from "@nanostores/react"
import { getPagePath } from "@nanostores/router"
import {
type ColumnDef,
type ColumnFiltersState,
flexRender,
getCoreRowModel,
ColumnDef,
ColumnFiltersState,
getFilteredRowModel,
SortingState,
getSortedRowModel,
type Row,
type SortingState,
type Table as TableType,
flexRender,
VisibilityState,
getCoreRowModel,
useReactTable,
type VisibilityState,
Row,
Table as TableType,
} from "@tanstack/react-table"
import { useVirtualizer, type VirtualItem } from "@tanstack/react-virtual"
import {
ArrowDownIcon,
ArrowUpDownIcon,
ArrowUpIcon,
EyeIcon,
FilterIcon,
LayoutGridIcon,
LayoutListIcon,
Settings2Icon,
} from "lucide-react"
import { memo, useEffect, useMemo, useRef, useState } from "react"
import { TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Button } from "@/components/ui/button"
import {
DropdownMenu,
@@ -38,16 +24,30 @@ import {
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import { Input } from "@/components/ui/input"
import { TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { SystemStatus } from "@/lib/enums"
import { $downSystems, $pausedSystems, $systems, $upSystems } from "@/lib/stores"
import { SystemRecord } from "@/types"
import {
ArrowUpDownIcon,
LayoutGridIcon,
LayoutListIcon,
ArrowDownIcon,
ArrowUpIcon,
Settings2Icon,
EyeIcon,
FilterIcon,
} from "lucide-react"
import { memo, useEffect, useMemo, useRef, useState } from "react"
import { $pausedSystems, $downSystems, $upSystems, $systems } from "@/lib/stores"
import { useStore } from "@nanostores/react"
import { cn, runOnce, useBrowserStorage } from "@/lib/utils"
import type { SystemRecord } from "@/types"
import AlertButton from "../alerts/alert-button"
import { $router, Link } from "../router"
import { useLingui, Trans } from "@lingui/react/macro"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"
import { Input } from "@/components/ui/input"
import { getPagePath } from "@nanostores/router"
import SystemsTableColumns, { ActionsButton, IndicatorDot } from "./systems-table-columns"
import AlertButton from "../alerts/alert-button"
import { SystemStatus } from "@/lib/enums"
import { useVirtualizer, VirtualItem } from "@tanstack/react-virtual"
type ViewMode = "table" | "grid"
type StatusFilter = "all" | SystemRecord["status"]
@@ -309,121 +309,128 @@ export default function SystemsTable() {
)
}
const AllSystemsTable = memo(
({ table, rows, colLength }: { table: TableType<SystemRecord>; rows: Row<SystemRecord>[]; colLength: number }) => {
// The virtualizer will need a reference to the scrollable container element
const scrollRef = useRef<HTMLDivElement>(null)
const AllSystemsTable = memo(function ({
table,
rows,
colLength,
}: {
table: TableType<SystemRecord>
rows: Row<SystemRecord>[]
colLength: number
}) {
// The virtualizer will need a reference to the scrollable container element
const scrollRef = useRef<HTMLDivElement>(null)
const virtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({
count: rows.length,
estimateSize: () => (rows.length > 10 ? 56 : 60),
getScrollElement: () => scrollRef.current,
overscan: 5,
})
const virtualRows = virtualizer.getVirtualItems()
const virtualizer = useVirtualizer<HTMLDivElement, HTMLTableRowElement>({
count: rows.length,
estimateSize: () => (rows.length > 10 ? 56 : 60),
getScrollElement: () => scrollRef.current,
overscan: 5,
})
const virtualRows = virtualizer.getVirtualItems()
const paddingTop = Math.max(0, virtualRows[0]?.start ?? 0 - virtualizer.options.scrollMargin)
const paddingBottom = Math.max(0, virtualizer.getTotalSize() - (virtualRows[virtualRows.length - 1]?.end ?? 0))
const paddingTop = Math.max(0, virtualRows[0]?.start ?? 0 - virtualizer.options.scrollMargin)
const paddingBottom = Math.max(0, virtualizer.getTotalSize() - (virtualRows[virtualRows.length - 1]?.end ?? 0))
return (
<div
className={cn(
"h-min max-h-[calc(100dvh-17rem)] max-w-full relative overflow-auto border rounded-md",
// don't set min height if there are less than 2 rows, do set if we need to display the empty state
(!rows.length || rows.length > 2) && "min-h-50"
)}
ref={scrollRef}
>
{/* add header height to table size */}
<div style={{ height: `${virtualizer.getTotalSize() + 50}px`, paddingTop, paddingBottom }}>
<table className="text-sm w-full h-full">
<SystemsTableHead table={table} />
<TableBody onMouseEnter={preloadSystemDetail}>
{rows.length ? (
virtualRows.map((virtualRow) => {
const row = rows[virtualRow.index] as Row<SystemRecord>
return (
<SystemTableRow
key={row.id}
row={row}
virtualRow={virtualRow}
length={rows.length}
colLength={colLength}
/>
)
})
) : (
<TableRow>
<TableCell colSpan={colLength} className="h-37 text-center pointer-events-none">
<Trans>No systems found.</Trans>
</TableCell>
</TableRow>
)}
</TableBody>
</table>
</div>
</div>
)
}
)
function SystemsTableHead({ table }: { table: TableType<SystemRecord> }) {
const { t } = useLingui()
return (
<TableHeader className="sticky top-0 z-50 w-full border-b-2">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead className="px-1.5" key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
)
})}
</tr>
))}
</TableHeader>
<div
className={cn(
"h-min max-h-[calc(100dvh-17rem)] max-w-full relative overflow-auto border rounded-md",
// don't set min height if there are less than 2 rows, do set if we need to display the empty state
(!rows.length || rows.length > 2) && "min-h-50"
)}
ref={scrollRef}
>
{/* add header height to table size */}
<div style={{ height: `${virtualizer.getTotalSize() + 50}px`, paddingTop, paddingBottom }}>
<table className="text-sm w-full h-full">
<SystemsTableHead table={table} colLength={colLength} />
<TableBody onMouseEnter={preloadSystemDetail}>
{rows.length ? (
virtualRows.map((virtualRow) => {
const row = rows[virtualRow.index] as Row<SystemRecord>
return (
<SystemTableRow
key={row.id}
row={row}
virtualRow={virtualRow}
length={rows.length}
colLength={colLength}
/>
)
})
) : (
<TableRow>
<TableCell colSpan={colLength} className="h-37 text-center pointer-events-none">
<Trans>No systems found.</Trans>
</TableCell>
</TableRow>
)}
</TableBody>
</table>
</div>
</div>
)
})
function SystemsTableHead({ table, colLength }: { table: TableType<SystemRecord>; colLength: number }) {
const { i18n } = useLingui()
return useMemo(() => {
return (
<TableHeader className="sticky top-0 z-20 w-full border-b-2">
{table.getHeaderGroups().map((headerGroup) => (
<tr key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead className="px-1.5" key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
)
})}
</tr>
))}
</TableHeader>
)
}, [i18n.locale, colLength])
}
const SystemTableRow = memo(
({
row,
virtualRow,
colLength,
}: {
row: Row<SystemRecord>
virtualRow: VirtualItem
length: number
colLength: number
}) => {
const system = row.original
const { t } = useLingui()
return useMemo(() => {
return (
<TableRow
// data-state={row.getIsSelected() && "selected"}
className={cn("cursor-pointer transition-opacity relative safari:transform-3d", {
"opacity-50": system.status === SystemStatus.Paused,
})}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
style={{
width: cell.column.getSize(),
height: virtualRow.size,
}}
className="py-0"
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
)
}, [system, system.status, colLength, t])
}
)
const SystemTableRow = memo(function ({
row,
virtualRow,
colLength,
}: {
row: Row<SystemRecord>
virtualRow: VirtualItem
length: number
colLength: number
}) {
const system = row.original
const { t } = useLingui()
return useMemo(() => {
return (
<TableRow
// data-state={row.getIsSelected() && "selected"}
className={cn("cursor-pointer transition-opacity relative safari:transform-3d", {
"opacity-50": system.status === SystemStatus.Paused,
})}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
style={{
width: cell.column.getSize(),
height: virtualRow.size,
}}
className="py-0"
>
{flexRender(cell.column.columnDef.cell, cell.getContext())}
</TableCell>
))}
</TableRow>
)
}, [system, system.status, colLength, t])
})
const SystemCard = memo(
({ row, table, colLength }: { row: Row<SystemRecord>; table: TableType<SystemRecord>; colLength: number }) => {
@@ -464,7 +471,7 @@ const SystemCard = memo(
if (!column.getIsVisible() || column.id === "system" || column.id === "actions") return null
const cell = row.getAllCells().find((cell) => cell.column.id === column.id)
if (!cell) return null
// @ts-expect-error
// @ts-ignore
const { Icon, name } = column.columnDef as ColumnDef<SystemRecord, unknown>
return (
<>

View File

@@ -130,12 +130,3 @@ export function HourglassIcon(props: SVGProps<SVGSVGElement>) {
</svg>
)
}
export function WebSocketIcon(props: SVGProps<SVGSVGElement>) {
return (
<svg viewBox="0 0 256 193" {...props} fill="currentColor">
<title>WebSocket</title>
<path d="M192 145h32V68l-36-35-22 22 26 27zm32 16H113l-26-27 11-11 22 22h45l-44-45 11-11 44 44V88l-21-22 11-11-55-55H0l32 32h65l24 23-34 34-24-23V48H32v31l55 55-23 22 36 36h156z" />
</svg>
)
}

View File

@@ -53,11 +53,3 @@ export enum HourFormat {
"12h" = "12h",
"24h" = "24h",
}
/** Connection type */
export enum ConnectionType {
SSH = 1,
WebSocket,
}
export const connectionTypeLabels = ["", "SSH", "WebSocket"] as const

View File

@@ -1,4 +1,3 @@
/** biome-ignore-all lint/suspicious/noAssignInExpressions: it's fine :) */
import type { PreinitializedMapStore } from "nanostores"
import { pb, verifyAuth } from "@/lib/api"
import {
@@ -17,10 +16,9 @@ const COLLECTION = pb.collection<SystemRecord>("systems")
const FIELDS_DEFAULT = "id,name,host,port,info,status"
/** Maximum system name length for display purposes */
const MAX_SYSTEM_NAME_LENGTH = 22
const MAX_SYSTEM_NAME_LENGTH = 20
let initialized = false
// biome-ignore lint/suspicious/noConfusingVoidType: typescript rocks
let unsub: (() => void) | undefined | void
/** Initialize the systems manager and set up listeners */
@@ -106,37 +104,20 @@ async function fetchSystems(): Promise<SystemRecord[]> {
}
}
/** Makes sure the system has valid info object and throws if not */
function validateSystemInfo(system: SystemRecord) {
if (!("cpu" in system.info)) {
throw new Error(`${system.name} has no CPU info`)
}
}
/** Add system to both name and ID stores */
export function add(system: SystemRecord) {
try {
validateSystemInfo(system)
$allSystemsByName.setKey(system.name, system)
$allSystemsById.setKey(system.id, system)
} catch (error) {
console.error(error)
}
$allSystemsByName.setKey(system.name, system)
$allSystemsById.setKey(system.id, system)
}
/** Update system in stores */
export function update(system: SystemRecord) {
try {
validateSystemInfo(system)
// if name changed, make sure old name is removed from the name store
const oldName = $allSystemsById.get()[system.id]?.name
if (oldName !== system.name) {
$allSystemsByName.setKey(oldName, undefined as unknown as SystemRecord)
}
add(system)
} catch (error) {
console.error(error)
// if name changed, make sure old name is removed from the name store
const oldName = $allSystemsById.get()[system.id]?.name
if (oldName !== system.name) {
$allSystemsByName.setKey(oldName, undefined as any)
}
add(system)
}
/** Remove system from stores */
@@ -151,7 +132,7 @@ export function remove(system: SystemRecord) {
/** Remove system from specific store */
function removeFromStore(system: SystemRecord, store: PreinitializedMapStore<Record<string, SystemRecord>>) {
const key = store === $allSystemsByName ? system.name : system.id
store.setKey(key, undefined as unknown as SystemRecord)
store.setKey(key, undefined as any)
}
/** Action functions for subscription */

View File

@@ -1,7 +1,6 @@
import { t } from "@lingui/core/macro"
import { type ClassValue, clsx } from "clsx"
import { timeDay, timeHour } from "d3-time"
import { listenKeys } from "nanostores"
import { useEffect, useState } from "react"
import { twMerge } from "tailwind-merge"
import { prependBasePath } from "@/components/router"
@@ -9,6 +8,7 @@ import { toast } from "@/components/ui/use-toast"
import type { ChartTimeData, FingerprintRecord, SemVer, SystemRecord } from "@/types"
import { HourFormat, MeterState, Unit } from "./enums"
import { $copyContent, $userSettings } from "./stores"
import { listenKeys } from "nanostores"
export const FAVICON_DEFAULT = "favicon.svg"
export const FAVICON_GREEN = "favicon-green.svg"
@@ -179,8 +179,8 @@ export function formatTemperature(celsius: number, unit?: Unit): { value: number
if (!unit) {
unit = $userSettings.get().unitTemp || Unit.Celsius
}
// biome-ignore lint/suspicious/noDoubleEquals: need loose equality check due to form data being strings
if (unit == Unit.Fahrenheit) {
// need loose equality check due to form data being strings
if (unit === Unit.Fahrenheit) {
return {
value: celsius * 1.8 + 32,
unit: "°F",
@@ -202,8 +202,8 @@ export function formatBytes(
// Convert MB to bytes if isMegabytes is true
if (isMegabytes) size *= 1024 * 1024
// biome-ignore lint/suspicious/noDoubleEquals: need loose equality check due to form data being strings
if (unit == Unit.Bits) {
// need loose equality check due to form data being strings
if (unit === Unit.Bits) {
const bits = size * 8
const suffix = perSecond ? "ps" : ""
if (bits < 1000) return { value: bits, unit: `b${suffix}` }

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: ar\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Arabic\n"
"Plural-Forms: nplurals=6; plural=(n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: ar\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# يوم} other {# أيام}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# ساعة} other {# ساعات}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# دقيقة} few {# دقائق} many {# دقيقة} other {# دقيقة}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# دقيقة} few {# دقائق} many {# دقيقة} ot
msgid "{0} of {1} row(s) selected."
msgstr "تم تحديد {0} من {1} صف"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} يوم} other {{countString} أيام}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} ساعة} other {{countString} ساعات}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} دقيقة} few {{countString} دقائق} many {{countString} دقيقة} other {{countString} دقيقة}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ساعة"
@@ -48,6 +45,10 @@ msgstr "1 ساعة"
msgid "1 min"
msgstr "دقيقة واحدة"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 دقيقة"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 أسبوع"
@@ -85,10 +86,14 @@ msgstr "إجراءات"
msgid "Active"
msgstr "نشط"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "التنبيهات النشطة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "الحالة النشطة"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "إضافة <0>نظام</0>"
@@ -109,11 +114,19 @@ msgstr "إضافة رابط"
msgid "Adjust display options for charts."
msgstr "تعديل خيارات العرض للرسوم البيانية."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "تعديل عرض التخطيط الرئيسي"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "مسؤول"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "بعد"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "وكيل"
@@ -129,7 +142,15 @@ msgstr "سجل التنبيهات"
msgid "Alerts"
msgstr "التنبيهات"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "جميع الحاويات"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "عرض النطاق الترددي"
msgid "Battery"
msgstr "البطارية"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "أصبح نشطًا"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "أصبح غير نشط"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "قبل"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "يدعم بيزيل بروتوكول OpenID Connect والعديد من مزوّدي المصادقة عبر بروتوكول OAuth2."
@@ -208,6 +241,10 @@ msgstr "ثنائي"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "بت (كيلوبت/ثانية، ميجابت/ثانية، جيجابت/ثانية)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "حالة التمهيد"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "بايت (كيلوبايت/ثانية، ميجابايت/ثانية، ج
msgid "Cache / Buffers"
msgstr "ذاكرة التخزين المؤقت / المخازن المؤقتة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "يمكن إعادة التحميل"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "يمكن البدء"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "يمكن الإيقاف"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "إلغاء"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "القدرات"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "السعة"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "تحذير - فقدان محتمل للبيانات"
@@ -263,6 +320,14 @@ msgstr "تحقق من السجلات لمزيد من التفاصيل."
msgid "Check your notification service"
msgstr "تحقق من خدمة الإشعارات الخاصة بك"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "انقر على حاوية لعرض مزيد من المعلومات."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "انقر على جهاز لعرض مزيد من المعلومات."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "انقر على نظام لعرض مزيد من المعلومات."
@@ -285,7 +350,11 @@ msgstr "هيئ التنبيهات الواردة"
msgid "Confirm password"
msgstr "تأكيد كلمة المرور"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "التعارضات"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "الاتصال مقطوع"
@@ -344,12 +413,31 @@ msgstr "انسخ محتوى <0>docker-compose.yml</0> للوكيل أدناه،
msgid "Copy YAML"
msgstr "نسخ YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "المعالج"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "نوى المعالج"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "ذروة المعالج"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "وقت المعالج"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "تفصيل وقت المعالج"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "استخدام وحدة المعالجة المركزية"
@@ -380,8 +468,12 @@ msgstr "الرفع التراكمي"
msgid "Current state"
msgstr "الحالة الحالية"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "الدورات"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "لوحة التحكم"
@@ -398,6 +490,18 @@ msgstr "حذف"
msgid "Delete fingerprint"
msgstr "حذف البصمة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "الوصف"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "التفاصيل"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "الجهاز"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "إدخال/إخراج الشبكة للدوكر"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "التوثيق"
@@ -498,20 +603,29 @@ msgstr "أدخل كلمة المرور لمرة واحدة الخاصة بك."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "خطأ"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "يتجاوز {0}{1} في آخر {2, plural, one {# دقيقة} other {# دقائق}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "معرف العملية الرئيسي للتنفيذ"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "سيتم حذف الأنظمة الحالية غير المعرفة في <0>config.yml</0>. يرجى عمل نسخ احتياطية بانتظام."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "خرج نشطًا"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "تصدير"
@@ -528,6 +642,14 @@ msgstr "تصدير تكوين الأنظمة الحالية الخاصة بك."
msgid "Fahrenheit (°F)"
msgstr "فهرنهايت (°ف)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "فشل"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "السمات الفاشلة:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "فشل في المصادقة"
@@ -545,8 +667,16 @@ msgstr "فشل في إرسال إشعار الاختبار"
msgid "Failed to update alert"
msgstr "فشل في تحديث التنبيه"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "فشل: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "تصفية..."
@@ -555,6 +685,10 @@ msgstr "تصفية..."
msgid "Fingerprint"
msgstr "البصمة"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "البرمجيات الثابتة"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "لمدة <0>{min}</0> {min, plural, one {دقيقة} other {دقائق}}"
@@ -588,10 +722,18 @@ msgstr "محركات GPU"
msgid "GPU Power Draw"
msgstr "استهلاك طاقة وحدة معالجة الرسوميات"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "استخدام وحدة معالجة الرسوميات"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "شبكة"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "الصحة"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "خاملة"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "إذا فقدت كلمة المرور لحساب المسؤول الخاص بك، يمكنك إعادة تعيينها باستخدام الأمر التالي."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "صورة"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "عنوان البريد الإشباكي غير صالح."
@@ -628,6 +775,19 @@ msgstr "اللغة"
msgid "Layout"
msgstr "التخطيط"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "عرض التخطيط"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "دورة الحياة"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "الحد"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "متوسط التحميل"
@@ -649,6 +809,14 @@ msgstr "متوسط التحميل 5 دقائق"
msgid "Load Avg"
msgstr "متوسط التحميل"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "حالة التحميل"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "جاري التحميل..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "تسجيل الخروج"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "فشل محاولة تسجيل الدخول"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "السجلات"
@@ -671,6 +840,10 @@ msgstr "السجلات"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "هل تبحث عن مكان لإنشاء التنبيهات؟ انقر على أيقونات الجرس <0/> في جدول الأنظمة."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "معرف العملية الرئيسي"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "إدارة تفضيلات العرض والإشعارات."
@@ -685,10 +858,22 @@ msgstr "تعليمات الإعداد اليدوي"
msgid "Max 1 min"
msgstr "الحد الأقصى دقيقة"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "الذاكرة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "حد الذاكرة"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "ذروة الذاكرة"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "استخدام الذاكرة"
msgid "Memory usage of docker containers"
msgstr "استخدام الذاكرة لحاويات دوكر"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "الموديل"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "الاسم"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "الشبكة"
@@ -723,14 +916,30 @@ msgstr "حركة مرور الشبكة للواجهات العامة"
msgid "Network unit"
msgstr "وحدة الشبكة"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "لا"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "لم يتم العثور على نتائج."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "لا توجد نتائج."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "لا توجد سمات S.M.A.R.T. متاحة لهذا الجهاز."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "فتح القائمة"
msgid "Or continue with"
msgstr "أو المتابعة باستخدام"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "أخرى"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "الكتابة فوق التنبيهات الحالية"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "صفحة"
@@ -811,6 +1025,15 @@ msgstr "متوقف مؤقتا"
msgid "Paused ({pausedSystemsLength})"
msgstr "متوقف مؤقتا ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "متوسط الاستخدام لكل نواة"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "النسبة المئوية للوقت المقضي في كل حالة"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "يرجى <0>تكوين خادم SMTP</0> لضمان تسليم التنبيهات."
@@ -848,6 +1071,11 @@ msgstr "يرجى تسجيل الدخول إلى حسابك"
msgid "Port"
msgstr "المنفذ"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "تشغيل الطاقة"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "الاستخدام الدقيق في الوقت المسجل"
msgid "Preferred Language"
msgstr "اللغة المفضلة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "تم بدء العملية"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "قراءة"
msgid "Received"
msgstr "تم الاستلام"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "تحديث"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "العلاقات"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "طلب كلمة مرور لمرة واحدة"
@@ -880,6 +1121,14 @@ msgstr "طلب كلمة مرور لمرة واحدة"
msgid "Request OTP"
msgstr "طلب OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "مطلوب من قبل"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "يتطلب"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "إعادة تعيين كلمة المرور"
@@ -890,10 +1139,19 @@ msgstr "إعادة تعيين كلمة المرور"
msgid "Resolved"
msgstr "تم حلها"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "إعادة التشغيل"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "استئناف"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "الجذر"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "تدوير الرمز المميز"
@@ -902,6 +1160,18 @@ msgstr "تدوير الرمز المميز"
msgid "Rows per page"
msgstr "صفوف لكل صفحة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "مقاييس وقت التشغيل"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "تفاصيل S.M.A.R.T."
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "اختبار S.M.A.R.T. الذاتي"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "احفظ العنوان باستخدام مفتاح الإدخال أو الفاصلة. اتركه فارغًا لتعطيل إشعارات البريد الإشباكي."
@@ -931,6 +1201,18 @@ msgstr "راجع <0>إعدادات الإشعارات</0> لتكوين كيفي
msgid "Sent"
msgstr "تم الإرسال"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "الرقم التسلسلي"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "تفاصيل الخدمة"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "الخدمات"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "تعيين عتبات النسبة المئوية لألوان العداد."
@@ -960,14 +1242,22 @@ msgstr "الترتيب حسب"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "الحالة"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "الحالة"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "الحالة الفرعية"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "مساحة التبديل المستخدمة من قبل النظام"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "استخدام التبديل"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "النظام"
msgid "System load averages over time"
msgstr "متوسط تحميل النظام مع مرور الوقت"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "خدمات systemd"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "الأنظمة"
@@ -999,7 +1294,12 @@ msgstr "يمكن إدارة الأنظمة في ملف <0>config.yml</0> داخ
msgid "Table"
msgstr "جدول"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "المهام"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "درجة الحرارة"
@@ -1081,6 +1381,11 @@ msgstr "تسمح الرموز المميزة للوكلاء بالاتصال و
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "تُستخدم الرموز المميزة والبصمات للمصادقة على اتصالات WebSocket إلى المحور."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "الإجمالي"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "إجمالي البيانات المستلمة لكل واجهة"
@@ -1089,6 +1394,19 @@ msgstr "إجمالي البيانات المستلمة لكل واجهة"
msgid "Total data sent for each interface"
msgstr "إجمالي البيانات المرسلة لكل واجهة"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "الإجمالي: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "تم التفعيل بواسطة"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "المحفزات"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز متوسط التحميل لمدة دقيقة واحدة عتبة معينة"
@@ -1113,6 +1431,10 @@ msgstr "يتم التفعيل عندما يتجاوز الجمع بين الصع
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام وحدة المعالجة المركزية عتبة معينة"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام وحدة معالجة الرسوميات عتبة معينة"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام الذاكرة عتبة معينة"
@@ -1125,6 +1447,14 @@ msgstr "يتم التفعيل عندما يتغير الحالة بين التش
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام أي قرص عتبة معينة"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "النوع"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "ملف الوحدة"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "رمز مميز عالمي"
msgid "Unknown"
msgstr "غير معروفة"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "غير محدود"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "قيد التشغيل"
msgid "Up ({upSystemsLength})"
msgstr "قيد التشغيل ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "تم التحديث"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "يتم التحديث كل 10 دقائق."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "رفع"
@@ -1162,6 +1506,7 @@ msgstr "مدة التشغيل"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "الاستخدام"
@@ -1187,6 +1532,7 @@ msgstr "القيمة"
msgid "View"
msgstr "عرض"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "عرض المزيد"
@@ -1207,6 +1553,10 @@ msgstr "في انتظار وجود سجلات كافية للعرض"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "هل تريد مساعدتنا في تحسين ترجماتنا؟ تحقق من <0>Crowdin</0> لمزيد من التفاصيل."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "يريد"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "تحذير (%)"
@@ -1243,6 +1593,13 @@ msgstr "تكوين YAML"
msgid "YAML Configuration"
msgstr "تكوين YAML"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "نعم"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "تم تحديث إعدادات المستخدم الخاصة بك."

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: bg\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Bulgarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: bg\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# ден} other {# дни}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# час} other {# часа}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# минута} few {# минути} many {# минути} other {# минути}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# минута} few {# минути} many {# минут
msgid "{0} of {1} row(s) selected."
msgstr "{0} от {1} селектирани."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} ден} other {{countString} дни}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} час} other {{countString} часа}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} минута} few {{countString} минути} many {{countString} минути} other {{countString} минути}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 час"
@@ -48,6 +45,10 @@ msgstr "1 час"
msgid "1 min"
msgstr "1 минута"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 минута"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 седмица"
@@ -85,10 +86,14 @@ msgstr "Действия"
msgid "Active"
msgstr "Активен"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Активни тревоги"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Активно състояние"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Добави <0>Система</0>"
@@ -109,11 +114,19 @@ msgstr "Добави URL"
msgid "Adjust display options for charts."
msgstr "Настрой опциите за показване на диаграмите."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Настройка ширината на основния макет"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Администратор"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "След"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Агент"
@@ -129,7 +142,15 @@ msgstr "История на нотификациите"
msgid "Alerts"
msgstr "Тревоги"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Всички контейнери"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "Bandwidth на мрежата"
msgid "Battery"
msgstr "Батерия"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Стана активен"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Стана неактивен"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Преди"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel поддържа OpenID Connect и много други OAuth2 доставчици за удостоверяване."
@@ -208,6 +241,10 @@ msgstr "Двоичен код"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Бита (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Състояние при зареждане"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "Байта (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "Кеш / Буфери"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Може да се презареди"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Може да се стартира"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Може да се спре"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Откажи"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Възможности"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Капацитет"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Внимание - възможност за загуба на данни"
@@ -263,6 +320,14 @@ msgstr "Провери log-овете за повече информация."
msgid "Check your notification service"
msgstr "Провери услугата си за удостоверяване"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Кликнете върху контейнер, за да видите повече информация."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Кликнете върху устройство, за да видите повече информация."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Кликнете върху система, за да видите повече информация."
@@ -285,7 +350,11 @@ msgstr "Настрой как получаваш нотификации за т
msgid "Confirm password"
msgstr "Потвърди парола"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Конфликти"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "Връзката е прекъсната"
@@ -344,12 +413,31 @@ msgstr "Копирайте съдържанието на<0>docker-compose.yml</0
msgid "Copy YAML"
msgstr "Копирай YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "Процесор"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "CPU ядра"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "Пик на CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "Време на CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Разбивка на времето на CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Употреба на процесор"
@@ -380,8 +468,12 @@ msgstr "Кумулативно качване"
msgid "Current state"
msgstr "Текущо състояние"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Цикли"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Табло"
@@ -398,6 +490,18 @@ msgstr "Изтрий"
msgid "Delete fingerprint"
msgstr "Изтрий пръстов отпечатък"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Описание"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Подробности"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Устройство"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Мрежов I/O използван от docker"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Документация"
@@ -498,20 +603,29 @@ msgstr "Въведете Вашата еднократна парола."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Грешка"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Надвишава {0}{1} в последните {2, plural, one {# минута} other {# минути}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Съществуващи системи които не са дефинирани в <0>config.yml</0> ще бъдат изтрити. Моля прави чести архиви."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Излезе активно"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Експортиране"
@@ -528,6 +642,14 @@ msgstr "Експортирай конфигурацията на системи
msgid "Fahrenheit (°F)"
msgstr "Фаренхайт (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Неуспешно"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Неуспешни атрибути:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Неуспешно удостоверяване"
@@ -545,8 +667,16 @@ msgstr "Неуспешно изпрати тестова нотификация"
msgid "Failed to update alert"
msgstr "Неуспешно обнови тревога"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Неуспешни: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Филтрирай..."
@@ -555,6 +685,10 @@ msgstr "Филтрирай..."
msgid "Fingerprint"
msgstr "Пръстов отпечатък"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Фърмуер"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "За <0>{min}</0> {min, plural, one {минута} other {минути}}"
@@ -588,10 +722,18 @@ msgstr "GPU двигатели"
msgid "GPU Power Draw"
msgstr "Консумация на ток от графична карта"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "Употреба на GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Мрежово"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Здраве"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Неактивна"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Ако си загубил паролата до администраторския акаунт, можеш да я нулираш със следващата команда."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Образ"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Невалиден имейл адрес."
@@ -628,6 +775,19 @@ msgstr "Език"
msgid "Layout"
msgstr "Подреждане"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Ширина на макета"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Жизнен цикъл"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "лимит"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Средно натоварване"
@@ -649,6 +809,14 @@ msgstr "Средно натоварване 5 минути"
msgid "Load Avg"
msgstr "Средно натоварване"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Състояние на зареждане"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Зареждане..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Изход"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Неуспешен опит за вход"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Логове"
@@ -671,6 +840,10 @@ msgstr "Логове"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Търсиш къде да създадеш тревоги? Натисни емотиконата за звънец <0/> в таблицата за системи."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Управление на предпочитанията за показване и уведомяване."
@@ -685,10 +858,22 @@ msgstr "Инструкции за ръчна настройка"
msgid "Max 1 min"
msgstr "Максимум 1 минута"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Памет"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Лимит на памет"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Пик на памет"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Употреба на паметта"
msgid "Memory usage of docker containers"
msgstr "Използването на памет от docker контейнерите"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Модел"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Име"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Мрежа"
@@ -723,14 +916,30 @@ msgstr "Мрежов трафик на публични интерфейси"
msgid "Network unit"
msgstr "Единица за измерване на скорост"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Не"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Няма намерени резултати."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Няма резултати."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Няма налични S.M.A.R.T. атрибути за това устройство."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "Отвори менюто"
msgid "Or continue with"
msgstr "Или продължи с"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Други"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Презапиши съществуващи тревоги"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Страница"
@@ -811,6 +1025,15 @@ msgstr "На пауза"
msgid "Paused ({pausedSystemsLength})"
msgstr "На пауза ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Средно използване на ядро"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Процент време, прекарано във всяко състояние"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Моля <0>конфигурурай SMTP сървър</0> за да се подсигуриш, че тревогите са доставени."
@@ -848,6 +1071,11 @@ msgstr "Моля влез в акаунта ти"
msgid "Port"
msgstr "Порт"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Включване"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "Точно използване в записаното време"
msgid "Preferred Language"
msgstr "Предпочитан език"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Процесът стартира"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Прочети"
msgid "Received"
msgstr "Получени"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Опресни"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Връзки"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Заявка за еднократна парола"
@@ -880,6 +1121,14 @@ msgstr "Заявка за еднократна парола"
msgid "Request OTP"
msgstr "Заявка OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Изисква се от"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Изисква"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Нулиране на парола"
@@ -890,10 +1139,19 @@ msgstr "Нулиране на парола"
msgid "Resolved"
msgstr "Решен"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Рестартирания"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Възобнови"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Корен"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Пресъздаване на идентификатора"
@@ -902,6 +1160,18 @@ msgstr "Пресъздаване на идентификатора"
msgid "Rows per page"
msgstr "Редове на страница"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Метрики на изпълнение"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "S.M.A.R.T. Детайли"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T. Самотест"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Запази адреса с enter или запетая. Остави празно за да изключиш нотификациите чрез имейл."
@@ -931,6 +1201,18 @@ msgstr "Виж <0>настройките за нотификациите</0> з
msgid "Sent"
msgstr "Изпратени"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Сериен номер"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Детайли на услугата"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Услуги"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Задайте процентни прагове за цветовете на измервателните уреди."
@@ -960,14 +1242,22 @@ msgstr "Сортиране по"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Състояние"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Статус"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Подсъстояние"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Изполван swap от системата"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Използване на swap"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "Система"
msgid "System load averages over time"
msgstr "Средно натоварване на системата във времето"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Услуги на systemd"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Системи"
@@ -999,7 +1294,12 @@ msgstr "Системите могат да бъдат управлявани в
msgid "Table"
msgstr "Таблица"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Задачи"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Температура"
@@ -1081,6 +1381,11 @@ msgstr "Токените позволяват на агентите да се с
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Токените и пръстовите отпечатъци се използват за удостоверяване на WebSocket връзките към концентратора."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Общо"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Общо получени данни за всеки интерфейс"
@@ -1089,6 +1394,19 @@ msgstr "Общо получени данни за всеки интерфейс"
msgid "Total data sent for each interface"
msgstr "Общо изпратени данни за всеки интерфейс"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Общо: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Активиран от"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Активатори"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Задейства се, когато употребата на паметта за 1 минута надвиши зададен праг"
@@ -1113,6 +1431,10 @@ msgstr "Задейства се, когато комбинираното кач
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Задейства се, когато употребата на процесора надвиши зададен праг"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr ""
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Задейства се, когато употребата на паметта надвиши зададен праг"
@@ -1125,6 +1447,14 @@ msgstr "Задейства се, когато статуса превключв
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Задейства се, когато употребата на някой диск надивши зададен праг"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Тип"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Файл на единица"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "Универсален тоукън"
msgid "Unknown"
msgstr "Неизвестна"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Неограничено"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "Нагоре"
msgid "Up ({upSystemsLength})"
msgstr "Нагоре ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Актуализирано"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Актуализира се на всеки 10 минути."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Качване"
@@ -1162,6 +1506,7 @@ msgstr "Време на работа"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Употреба"
@@ -1187,6 +1532,7 @@ msgstr "Стойност"
msgid "View"
msgstr "Изглед"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Виж повече"
@@ -1207,6 +1553,10 @@ msgstr "Изчаква се за достатъчно записи за пока
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Искаш да помогнеш да направиш преводите още по-добри? Провери нашия <0>Crowdin</0> за повече детайли."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Иска"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Предупреждение (%)"
@@ -1243,6 +1593,13 @@ msgstr "YAML конфигурация"
msgid "YAML Configuration"
msgstr "YAML конфигурация"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Да"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Настройките за потребителя ти са обновени."

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: cs\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Czech\n"
"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 3;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: cs\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# den} few {# dny} other {# dní}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# Hodina} few {# Hodiny} many {# Hodin} other {# Hodin}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# minuta} few {# minuty} many {# minut} other {# minut}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# minuta} few {# minuty} many {# minut} other {# minut}
msgid "{0} of {1} row(s) selected."
msgstr "{0} z {1} vybraných řádků."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} den} few {{countString} dny} other {{countString} dní}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} Hodina} few {{countString} Hodiny} many {{countString} Hodin} other {{countString} Hodin}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hodina"
@@ -46,7 +43,11 @@ msgstr "1 hodina"
#. Load average
#: src/components/charts/load-average-chart.tsx
msgid "1 min"
msgstr "1 min"
msgstr ""
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 minuta"
#: src/lib/utils.ts
msgid "1 week"
@@ -59,7 +60,7 @@ msgstr "12 hodin"
#. Load average
#: src/components/charts/load-average-chart.tsx
msgid "15 min"
msgstr "15 min"
msgstr ""
#: src/lib/utils.ts
msgid "24 hours"
@@ -72,7 +73,7 @@ msgstr "30 dní"
#. Load average
#: src/components/charts/load-average-chart.tsx
msgid "5 min"
msgstr "5 min"
msgstr ""
#. Table column
#: src/components/routes/settings/tokens-fingerprints.tsx
@@ -85,10 +86,14 @@ msgstr "Akce"
msgid "Active"
msgstr "Aktivní"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Aktivní výstrahy"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Aktivní stav"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Přidat <0>Systém</0>"
@@ -109,14 +114,22 @@ msgstr "Přidat URL"
msgid "Adjust display options for charts."
msgstr "Upravit možnosti zobrazení pro grafy."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Upravit šířku hlavního rozvržení"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
msgstr "Administrátor"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Po"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
@@ -129,7 +142,15 @@ msgstr "Historie upozornění"
msgid "Alerts"
msgstr "Výstrahy"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Všechny kontejnery"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "Přenos"
msgid "Battery"
msgstr "Baterie"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Stal se aktivním"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Stal se neaktivním"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Před"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel podporuje OpenID Connect a mnoho poskytovatelů OAuth2 ověřování."
@@ -201,27 +234,51 @@ msgstr "Beszel používá <0>Shoutrrr</0> k integraci s populárními notifikač
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binary"
msgstr "Binární"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Bits (Kbps, Mbps, Gbps)"
msgstr "Bity (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Stav zavádění"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
msgstr "Bytes (KB/s, MB/s, GB/s)"
msgstr "Byty (KB/s, MB/s, GB/s)"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / vyrovnávací paměť"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Může znovu načíst"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Může spustit"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Může zastavit"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Zrušit"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Schopnosti"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Kapacita"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Upozornění - možná ztráta dat"
@@ -263,6 +320,14 @@ msgstr "Pro více informací zkontrolujte logy."
msgid "Check your notification service"
msgstr "Zkontrolujte službu upozornění"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Klikněte na kontejner pro zobrazení dalších informací."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Klikněte na zařízení pro zobrazení dalších informací."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Klikněte na systém pro zobrazení více informací."
@@ -285,7 +350,11 @@ msgstr "Konfigurace způsobu přijímání upozornění."
msgid "Confirm password"
msgstr "Potvrdit heslo"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Konflikty"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "Připojení je nedostupné"
@@ -344,12 +413,31 @@ msgstr "Zkopírujte obsah <0>docker-compose.yml</0> pro agenta níže nebo autom
msgid "Copy YAML"
msgstr "Kopírovat YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "Procesor"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "CPU jádra"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "Špička CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "Čas CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Rozdělení času CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Využití procesoru"
@@ -380,8 +468,12 @@ msgstr "Kumulativní odeslání"
msgid "Current state"
msgstr "Aktuální stav"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Cykly"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Přehled"
@@ -398,6 +490,18 @@ msgstr "Odstranit"
msgid "Delete fingerprint"
msgstr "Smazat identifikátor"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Popis"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr ""
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Zařízení"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -405,11 +509,11 @@ msgstr "Vybíjení"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Disk"
msgstr "Disk"
msgstr ""
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Disk unit"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Síťové I/O Dockeru"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Dokumentace"
@@ -470,7 +575,7 @@ msgstr "Upravit"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/otp-forms.tsx
msgid "Email"
msgstr "Email"
msgstr "E-mail"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
@@ -498,23 +603,32 @@ msgstr "Zadejte Vaše jednorázové heslo."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Chyba"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Překračuje {0}{1} za {2, plural, one {poslední # minutu} few {poslední # minuty} other {posledních # minut}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "Hlavní PID spuštění"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Stávající systémy, které nejsou definovány v <0>config.yml</0>, budou odstraněny. Provádějte pravidelné zálohování."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Ukončeno aktivně"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Export"
msgstr "Exportovat"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
@@ -528,6 +642,14 @@ msgstr "Exportovat aktuální konfiguraci systémů."
msgid "Fahrenheit (°F)"
msgstr "Fahrenheita (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Selhalo"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Neúspěšné atributy:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Ověření se nezdařilo"
@@ -545,8 +667,16 @@ msgstr "Nepodařilo se odeslat testovací oznámení"
msgid "Failed to update alert"
msgstr "Nepodařilo se aktualizovat upozornění"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Neúspěšné: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filtr..."
@@ -555,6 +685,10 @@ msgstr "Filtr..."
msgid "Fingerprint"
msgstr "Otisk"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr ""
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Za <0>{min}</0> {min, plural, one {minutu} few {minuty} other {minut}}"
@@ -588,10 +722,18 @@ msgstr "GPU enginy"
msgid "GPU Power Draw"
msgstr "Spotřeba energie GPU"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "Využití GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Mřížka"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Zdraví"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Neaktivní"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Pokud jste ztratili heslo k vašemu účtu správce, můžete jej obnovit pomocí následujícího příkazu."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Obraz"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Neplatná e-mailová adresa."
@@ -618,7 +765,7 @@ msgstr "Neplatná e-mailová adresa."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
msgstr "Jádro"
#: src/components/routes/settings/general.tsx
msgid "Language"
@@ -628,6 +775,19 @@ msgstr "Jazyk"
msgid "Layout"
msgstr "Rozvržení"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Šířka rozvržení"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Životní cyklus"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Průměrné vytížení"
@@ -649,6 +809,14 @@ msgstr "Průměrná zátěž 5m"
msgid "Load Avg"
msgstr "Prům. zatížení"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Stav načtení"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Načítání..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Odhlásit"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Pokus o přihlášení selhal"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Logy"
@@ -671,6 +840,10 @@ msgstr "Logy"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Hledáte místo kde vytvářet upozornění? Klikněte na ikonu zvonku <0/> v systémové tabulce."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "Hlavní PID"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Správa nastavení zobrazení a oznámení."
@@ -685,10 +858,22 @@ msgstr "Pokyny k manuálnímu nastavení"
msgid "Max 1 min"
msgstr "Max. 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Paměť"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Limit paměti"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Špička paměti"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Využití paměti"
msgid "Memory usage of docker containers"
msgstr "Využití paměti docker kontejnerů"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr ""
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Název"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Síť"
@@ -723,14 +916,30 @@ msgstr "Síťový provoz veřejných rozhraní"
msgid "Network unit"
msgstr "Síťová jednotka"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Ne"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Nenalezeny žádné výskyty."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Žádné výsledky."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Pro toto zařízení nejsou k dispozici žádné atributy S.M.A.R.T."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "Otevřít menu"
msgid "Or continue with"
msgstr "Nebo pokračujte s"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Jiné"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Přepsat existující upozornění"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Stránka"
@@ -811,6 +1025,15 @@ msgstr "Pozastaveno"
msgid "Paused ({pausedSystemsLength})"
msgstr "Pozastaveno ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Průměrné využití na jádro"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Procento času strávěného v každém stavu"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "<0>nakonfigurujte SMTP server</0> pro zajištění toho, aby byla upozornění doručena."
@@ -846,7 +1069,12 @@ msgstr "Přihlaste se prosím k vašemu účtu"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
msgstr ""
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Zapnutí"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
@@ -857,6 +1085,10 @@ msgstr "Přesné využití v zaznamenaném čase"
msgid "Preferred Language"
msgstr "Upřednostňovaný jazyk"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Proces spuštěn"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Číst"
msgid "Received"
msgstr "Přijato"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Aktualizovat"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Vztahy"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Požádat o jednorázové heslo"
@@ -880,6 +1121,14 @@ msgstr "Požádat o jednorázové heslo"
msgid "Request OTP"
msgstr "Požádat OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Vyžadováno službou"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Vyžaduje"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Obnovit heslo"
@@ -890,10 +1139,19 @@ msgstr "Obnovit heslo"
msgid "Resolved"
msgstr "Vyřešeno"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Restarty"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Pokračovat"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Kořenový"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Změnit token"
@@ -902,6 +1160,18 @@ msgstr "Změnit token"
msgid "Rows per page"
msgstr "Řádků na stránku"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Metriky běhu"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "S.M.A.R.T. Detaily"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T. Vlastní test"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Adresu uložte pomocí klávesy enter nebo čárky. Pro deaktivaci e-mailových oznámení ponechte prázdné pole."
@@ -931,6 +1201,18 @@ msgstr "Podívejte se na <0>nastavení upozornění</0> pro nastavení toho, jak
msgid "Sent"
msgstr "Odeslat"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Sériové číslo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Detaily služby"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Služby"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Nastavte procentuální prahové hodnoty pro barvy měřičů."
@@ -960,14 +1242,22 @@ msgstr "Seřadit podle"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stav"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Stav"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Podstav"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap prostor využívaný systémem"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Swap využití"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "Systém"
msgid "System load averages over time"
msgstr "Průměry zatížení systému v průběhu času"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Služby systemd"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systémy"
@@ -999,7 +1294,12 @@ msgstr "Systémy lze spravovat v souboru <0>config.yml</0> uvnitř datového adr
msgid "Table"
msgstr "Tabulka"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Úlohy"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Teplota"
@@ -1019,7 +1319,7 @@ msgstr "Teploty systémových senzorů"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
msgstr "Testovat <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
@@ -1065,7 +1365,7 @@ msgstr "Přepnout motiv"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Token"
msgstr "Token"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
@@ -1081,6 +1381,11 @@ msgstr "Tokeny umožňují agentům připojení a registraci. Otisky jsou stabil
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Tokeny a otisky slouží k ověření připojení WebSocket k uzlu."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Celkem"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Celkový přijatý objem dat pro každé rozhraní"
@@ -1089,6 +1394,19 @@ msgstr "Celkový přijatý objem dat pro každé rozhraní"
msgid "Total data sent for each interface"
msgstr "Celkový odeslaný objem dat pro každé rozhraní"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Celkem: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Spuštěno službou"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Spouštěče"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Spustí se, když využití paměti během 1 minuty překročí prahovou hodnotu"
@@ -1113,6 +1431,10 @@ msgstr "Spustí se, když kombinace up/down překročí prahovou hodnotu"
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Spustí se, když využití procesoru překročí prahovou hodnotu"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Spustí se, když využití GPU překročí prahovou hodnotu"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Spustí se, když využití paměti překročí prahovou hodnotu"
@@ -1125,6 +1447,14 @@ msgstr "Spouští se, když se změní dostupnost"
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Spustí se, když využití disku překročí prahovou hodnotu"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Typ"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Soubor jednotky"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "Univerzální token"
msgid "Unknown"
msgstr "Neznámá"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Neomezeno"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "Funkční"
msgid "Up ({upSystemsLength})"
msgstr "Funkční ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Aktualizováno"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Aktualizováno každých 10 minut."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Odeslání"
@@ -1162,6 +1506,7 @@ msgstr "Doba provozu"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Využití"
@@ -1187,6 +1532,7 @@ msgstr "Hodnota"
msgid "View"
msgstr "Zobrazení"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Zobrazit více"
@@ -1207,6 +1553,10 @@ msgstr "Čeká se na dostatek záznamů k zobrazení"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Chcete nám pomoci s našimi překlady ještě lépe? Podívejte se na <0>Crowdin</0> pro více informací."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Chce"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Varování (%)"
@@ -1243,6 +1593,13 @@ msgstr "YAML konfigurace"
msgid "YAML Configuration"
msgstr "YAML konfigurace"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Ano"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše uživatelská nastavení byla aktualizována."

File diff suppressed because it is too large Load Diff

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: de\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: German\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: de\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# Tag} other {# Tage}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# Stunde} other {# Stunden}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# Minute} other {# Minuten}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# Minute} other {# Minuten}}"
msgid "{0} of {1} row(s) selected."
msgstr "{0} von {1} Zeile(n) ausgewählt."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} Tag} other {{countString} Tage}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} Stunde} other {{countString} Stunden}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} Minute} other {{countString} Minuten}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 Stunde"
@@ -48,6 +45,10 @@ msgstr "1 Stunde"
msgid "1 min"
msgstr "1 Min"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 Minute"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 Woche"
@@ -85,10 +86,14 @@ msgstr "Aktionen"
msgid "Active"
msgstr "Aktiv"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Aktive Warnungen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Aktiver Zustand"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>System</0> hinzufügen"
@@ -109,11 +114,19 @@ msgstr "URL hinzufügen"
msgid "Adjust display options for charts."
msgstr "Anzeigeoptionen für Diagramme anpassen."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Breite des Hauptlayouts anpassen"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Nach"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
@@ -122,14 +135,22 @@ msgstr "Agent"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/settings/layout.tsx
msgid "Alert History"
msgstr "Alarm-Verlauf"
msgstr "Warnungsverlauf"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alerts-sheet.tsx
msgid "Alerts"
msgstr "Warnungen"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Alle Container"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "Bandbreite"
msgid "Battery"
msgstr "Batterie"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Wurde aktiv"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Wurde inaktiv"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Vor"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel unterstützt OpenID Connect und viele OAuth2-Authentifizierungsanbieter."
@@ -208,6 +241,10 @@ msgstr "Binär"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Bits (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Boot-Zustand"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "Bytes (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "Cache / Puffer"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Kann neu laden"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Kann starten"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Kann stoppen"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Abbrechen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Fähigkeiten"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Kapazität"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Vorsicht - potenzieller Datenverlust"
@@ -263,6 +320,14 @@ msgstr "Überprüfe die Protokolle für weitere Details."
msgid "Check your notification service"
msgstr "Überprüfe deinen Benachrichtigungsdienst"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Klicke auf einen Container, um weitere Informationen zu sehen."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Klicke auf ein Gerät, um weitere Informationen zu sehen."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Klicke auf ein System, um weitere Informationen zu sehen."
@@ -285,7 +350,11 @@ msgstr "Konfiguriere, wie du Warnbenachrichtigungen erhältst."
msgid "Confirm password"
msgstr "Passwort bestätigen"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Konflikte"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "Verbindung unterbrochen"
@@ -334,22 +403,41 @@ msgstr "Text kopieren"
#: src/components/add-system.tsx
msgid "Copy the installation command for the agent below, or register agents automatically with a <0>universal token</0>."
msgstr "Kopieren Sie den Installationsbefehl für den Agent unten oder registrieren Sie Agents automatisch mit einem <0>universellen Token</0>."
msgstr "Kopiere den Installationsbefehl für den Agent unten oder registriere Agents automatisch mit einem <0>universellen Token</0>."
#: src/components/add-system.tsx
msgid "Copy the<0>docker-compose.yml</0> content for the agent below, or register agents automatically with a <1>universal token</1>."
msgstr "Kopieren Sie den<0>docker-compose.yml</0> Inhalt für den Agent unten oder registrieren Sie Agents automatisch mit einem <1>universellen Token</1>."
msgstr "Kopiere den<0>docker-compose.yml</0> Inhalt für den Agent unten oder registriere Agents automatisch mit einem <1>universellen Token</1>."
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Copy YAML"
msgstr "YAML kopieren"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "CPU-Kerne"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "CPU-Spitze"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "CPU-Zeit"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "CPU-Zeit-Aufschlüsselung"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "CPU-Auslastung"
@@ -380,8 +468,12 @@ msgstr "Kumulativer Upload"
msgid "Current state"
msgstr "Aktueller Zustand"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Zyklen"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Dashboard"
@@ -398,6 +490,18 @@ msgstr "Löschen"
msgid "Delete fingerprint"
msgstr "Fingerabdruck löschen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Beschreibung"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Details"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Gerät"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Docker-Netzwerk-I/O"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Dokumentation"
@@ -455,7 +560,7 @@ msgstr "Offline ({downSystemsLength})"
#: src/components/routes/system/network-sheet.tsx
msgid "Download"
msgstr "Download"
msgstr "Herunterladen"
#: src/components/alerts-history-columns.tsx
msgid "Duration"
@@ -498,20 +603,29 @@ msgstr "Geben Sie Ihr Einmalpasswort ein."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Fehler"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Überschreitet {0}{1} in den letzten {2, plural, one {# Minute} other {# Minuten}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "Ausführungs-Haupt-PID"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Bestehende Systeme, die nicht in der <0>config.yml</0> definiert sind, werden gelöscht. Bitte mache regelmäßige Backups."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Beendet aktiv"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Exportieren"
@@ -528,6 +642,14 @@ msgstr "Exportiere die aktuelle Systemkonfiguration."
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Fehlgeschlagen"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Fehlgeschlagene Attribute:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Authentifizierung fehlgeschlagen"
@@ -545,8 +667,16 @@ msgstr "Testbenachrichtigung konnte nicht gesendet werden"
msgid "Failed to update alert"
msgstr "Warnung konnte nicht aktualisiert werden"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Fehlgeschlagen: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filter..."
@@ -555,6 +685,10 @@ msgstr "Filter..."
msgid "Fingerprint"
msgstr "Fingerabdruck"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firm­ware"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Für <0>{min}</0> {min, plural, one {Minute} other {Minuten}}"
@@ -588,10 +722,18 @@ msgstr "GPU-Engines"
msgid "GPU Power Draw"
msgstr "GPU-Leistungsaufnahme"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "GPU-Auslastung"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Raster"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Gesundheit"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Untätig"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Wenn du das Passwort für dein Administratorkonto verloren hast, kannst du es mit dem folgenden Befehl zurücksetzen."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Image"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ungültige E-Mail-Adresse."
@@ -628,6 +775,19 @@ msgstr "Sprache"
msgid "Layout"
msgstr "Anordnung"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Layoutbreite"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Lebenszyklus"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "Limit"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Durchschnittliche Systemlast"
@@ -649,6 +809,14 @@ msgstr "Durchschnittliche Systemlast 5 Min"
msgid "Load Avg"
msgstr "Systemlast"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Ladezustand"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Lädt..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Abmelden"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Anmeldeversuch fehlgeschlagen"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Protokolle"
@@ -671,6 +840,10 @@ msgstr "Protokolle"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Du möchtest neue Warnungen erstellen? Klicke dafür auf die Glocken-<0/>-Symbole in der Systemtabelle."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "Haupt-PID"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Anzeige- und Benachrichtigungseinstellungen verwalten."
@@ -685,10 +858,22 @@ msgstr "Anleitung zur manuellen Einrichtung"
msgid "Max 1 min"
msgstr "Max 1 Min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Arbeitsspeicher"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Arbeitsspeicherlimit"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Arbeitsspeicher-Spitze"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Arbeitsspeichernutzung"
msgid "Memory usage of docker containers"
msgstr "Arbeitsspeichernutzung der Docker-Container"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Modell"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Name"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Netz"
@@ -723,14 +916,30 @@ msgstr "Netzwerkverkehr der öffentlichen Schnittstellen"
msgid "Network unit"
msgstr "Netzwerkeinheit"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Nein"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Keine Ergebnisse gefunden."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Keine Ergebnisse."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Für dieses Gerät sind keine S.M.A.R.T.-Attribute verfügbar."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "Menü öffnen"
msgid "Or continue with"
msgstr "Oder fortfahren mit"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Andere"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Bestehende Warnungen überschreiben"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Seite"
@@ -811,6 +1025,15 @@ msgstr "Pausiert"
msgid "Paused ({pausedSystemsLength})"
msgstr "Pausiert ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Durchschnittliche Auslastung pro Kern"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Prozentsatz der Zeit in jedem Zustand"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Bitte <0>konfiguriere einen SMTP-Server</0>, um sicherzustellen, dass Warnungen zugestellt werden."
@@ -848,6 +1071,11 @@ msgstr "Bitte melde dich bei deinem Konto an"
msgid "Port"
msgstr "Port"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Eingeschaltet"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,10 +1085,14 @@ msgstr "Genaue Nutzung zum aufgezeichneten Zeitpunkt"
msgid "Preferred Language"
msgstr "Bevorzugte Sprache"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Prozess gestartet"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Schlüssel"
msgstr "Öffentlicher Schlüssel"
#. Disk read
#: src/components/routes/system.tsx
@@ -872,6 +1104,15 @@ msgstr "Lesen"
msgid "Received"
msgstr "Empfangen"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Aktualisieren"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Beziehungen"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Einmalpasswort anfordern"
@@ -880,6 +1121,14 @@ msgstr "Einmalpasswort anfordern"
msgid "Request OTP"
msgstr "OTP anfordern"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Benötigt von"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Benötigt"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Passwort zurücksetzen"
@@ -890,10 +1139,19 @@ msgstr "Passwort zurücksetzen"
msgid "Resolved"
msgstr "Gelöst"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Neustarts"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Fortsetzen"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Token rotieren"
@@ -902,6 +1160,18 @@ msgstr "Token rotieren"
msgid "Rows per page"
msgstr "Zeilen pro Seite"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Laufzeitmetriken"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "S.M.A.R.T.-Details"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T.-Selbsttest"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Adresse mit der Enter-Taste oder Komma speichern. Leer lassen, um E-Mail-Benachrichtigungen zu deaktivieren."
@@ -913,7 +1183,7 @@ msgstr "Einstellungen speichern"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "System sichern"
msgstr "System speichern"
#: src/components/navbar.tsx
msgid "Search"
@@ -931,6 +1201,18 @@ msgstr "Siehe <0>Benachrichtigungseinstellungen</0>, um zu konfigurieren, wie du
msgid "Sent"
msgstr "Gesendet"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Seriennummer"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Servicedetails"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Dienste"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Prozentuale Schwellenwerte für Zählerfarben festlegen."
@@ -960,14 +1242,22 @@ msgstr "Sortieren nach"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Status"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Status"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Unterzustand"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Vom System genutzter Swap-Speicher"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Swap-Nutzung"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "System"
msgid "System load averages over time"
msgstr "Systemlastdurchschnitt im Zeitverlauf"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Systemd-Dienste"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systeme"
@@ -999,7 +1294,12 @@ msgstr "Systeme können in einer <0>config.yml</0>-Datei im Datenverzeichnis ver
msgid "Table"
msgstr "Tabelle"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Aufgaben"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Temperatur"
@@ -1081,13 +1381,31 @@ msgstr "Tokens ermöglichen es Agents, sich zu verbinden und zu registrieren. Fi
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Tokens und Fingerabdrücke werden verwendet, um WebSocket-Verbindungen zum Hub zu authentifizieren."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Gesamt"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Gesamtdatenmenge für jede Schnittstelle empfangen"
msgstr "Empfangene Gesamtdatenmenge je Schnittstelle "
#: src/components/routes/system/network-sheet.tsx
msgid "Total data sent for each interface"
msgstr "Gesamtdatenmenge für jede Schnittstelle gesendet"
msgstr "Gesendete Gesamtdatenmenge je Schnittstelle"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Gesamt: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Ausgelöst von"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Trigger"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
@@ -1107,12 +1425,16 @@ msgstr "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet"
#: src/lib/alerts.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Löst aus, wenn die kombinierte Auf-/Abwärtsbewegung einen Schwellenwert überschreitet"
msgstr "Löst aus, wenn die kombinierte Up- und Downloadrate einen Schwellenwert überschreitet"
#: src/lib/alerts.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Löst aus, wenn die CPU-Auslastung einen Schwellenwert überschreitet"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Löst aus, wenn die GPU-Auslastung einen Schwellenwert überschreitet"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Löst aus, wenn die Arbeitsspeichernutzung einen Schwellenwert überschreitet"
@@ -1125,6 +1447,14 @@ msgstr "Löst aus, wenn der Status zwischen online und offline wechselt"
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Löst aus, wenn die Nutzung einer Festplatte einen Schwellenwert überschreitet"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Typ"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Unit-Datei"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "Universeller Token"
msgid "Unknown"
msgstr "Unbekannt"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Unbegrenzt"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,9 +1485,18 @@ msgstr "aktiv"
msgid "Up ({upSystemsLength})"
msgstr "aktiv ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Aktualisiert"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Alle 10 Minuten aktualisiert."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Upload"
msgstr "Hochladen"
#: src/components/routes/system.tsx
msgid "Uptime"
@@ -1162,6 +1506,7 @@ msgstr "Betriebszeit"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Nutzung"
@@ -1187,6 +1532,7 @@ msgstr "Wert"
msgid "View"
msgstr "Ansicht"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Mehr anzeigen"
@@ -1207,6 +1553,10 @@ msgstr "Warten auf genügend Datensätze zur Anzeige"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Möchtest du uns helfen, unsere Übersetzungen noch besser zu machen? Schau dir <0>Crowdin</0> für weitere Details an."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Möchte"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Warnung (%)"
@@ -1243,6 +1593,13 @@ msgstr "YAML-Konfiguration"
msgid "YAML Configuration"
msgstr "YAML-Konfiguration"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Deine Benutzereinstellungen wurden aktualisiert."

File diff suppressed because it is too large Load Diff

View File

@@ -75,10 +75,6 @@ msgstr "5 min"
msgid "Actions"
msgstr "Actions"
#: src/components/charts/systemd-services-table.tsx
msgid "active"
msgstr "active"
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Active"
@@ -172,10 +168,6 @@ msgstr "Average system-wide CPU utilization"
msgid "Average utilization of {0}"
msgstr "Average utilization of {0}"
#: src/components/routes/system.tsx
msgid "Average utilization of GPU engines"
msgstr "Average utilization of GPU engines"
#: src/components/command-palette.tsx
#: src/components/navbar.tsx
msgid "Backups"
@@ -347,7 +339,6 @@ msgstr "Copy YAML"
msgid "CPU"
msgstr "CPU"
#: src/components/charts/systemd-services-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
@@ -367,14 +358,6 @@ msgstr "Created"
msgid "Critical (%)"
msgstr "Critical (%)"
#: src/components/routes/system/network-sheet.tsx
msgid "Cumulative Download"
msgstr "Cumulative Download"
#: src/components/routes/system/network-sheet.tsx
msgid "Cumulative Upload"
msgstr "Cumulative Upload"
#. Context: Battery state
#: src/components/routes/system.tsx
msgid "Current state"
@@ -453,10 +436,6 @@ msgstr "Down"
msgid "Down ({downSystemsLength})"
msgstr "Down ({downSystemsLength})"
#: src/components/routes/system/network-sheet.tsx
msgid "Download"
msgstr "Download"
#: src/components/alerts-history-columns.tsx
msgid "Duration"
msgstr "Duration"
@@ -468,7 +447,6 @@ msgstr "Edit"
#: src/components/login/auth-form.tsx
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/otp-forms.tsx
msgid "Email"
msgstr "Email"
@@ -489,10 +467,6 @@ msgstr "Enter email address to reset password"
msgid "Enter email address..."
msgstr "Enter email address..."
#: src/components/login/otp-forms.tsx
msgid "Enter your one-time password."
msgstr "Enter your one-time password."
#: src/components/login/auth-form.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/settings/config-yaml.tsx
@@ -528,10 +502,6 @@ msgstr "Export your current systems configuration."
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
#: src/components/charts/systemd-services-table.tsx
msgid "failed"
msgstr "failed"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Failed to authenticate"
@@ -567,12 +537,6 @@ msgstr "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgid "Forgot password?"
msgstr "Forgot password?"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
msgid "FreeBSD command"
msgstr "FreeBSD command"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Full"
@@ -584,10 +548,6 @@ msgstr "Full"
msgid "General"
msgstr "General"
#: src/components/routes/system.tsx
msgid "GPU Engines"
msgstr "GPU Engines"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU Power Draw"
@@ -680,7 +640,6 @@ msgid "Manage display and notification preferences."
msgstr "Manage display and notification preferences."
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Manual setup instructions"
msgstr "Manual setup instructions"
@@ -689,7 +648,6 @@ msgstr "Manual setup instructions"
msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/charts/systemd-services-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Memory"
@@ -717,9 +675,6 @@ msgid "Network traffic of docker containers"
msgstr "Network traffic of docker containers"
#: src/components/routes/system.tsx
#: src/components/routes/system/network-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "Network traffic of public interfaces"
msgstr "Network traffic of public interfaces"
@@ -728,10 +683,6 @@ msgstr "Network traffic of public interfaces"
msgid "Network unit"
msgstr "Network unit"
#: src/components/charts/systemd-services-table.tsx
msgid "No failed services."
msgstr "No failed services."
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "No results found."
@@ -759,10 +710,6 @@ msgstr "OAuth 2 / OIDC support"
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "On each restart, systems in the database will be updated to match the systems defined in the file."
#: src/components/login/auth-form.tsx
msgid "One-time password"
msgstr "One-time password"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -881,14 +828,6 @@ msgstr "Read"
msgid "Received"
msgstr "Received"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Request a one-time password"
#: src/components/login/otp-forms.tsx
msgid "Request OTP"
msgstr "Request OTP"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Reset Password"
@@ -940,18 +879,14 @@ msgstr "See <0>notification settings</0> to configure how you receive alerts."
msgid "Sent"
msgstr "Sent"
#: src/components/charts/systemd-services-table.tsx
msgid "Service"
msgstr "Service"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Services"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Set percentage thresholds for meter colors."
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Sets the default time range for charts when a system is viewed."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
@@ -963,14 +898,6 @@ msgstr "Settings"
msgid "Settings saved"
msgstr "Settings saved"
#: src/components/charts/systemd-services-table.tsx
msgid "Show all"
msgstr "Show all"
#: src/components/charts/systemd-services-table.tsx
msgid "Show less"
msgstr "Show less"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Sign in"
@@ -988,7 +915,6 @@ msgstr "Sort By"
msgid "State"
msgstr "State"
#: src/components/charts/systemd-services-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
@@ -1013,11 +939,6 @@ msgstr "System"
msgid "System load averages over time"
msgstr "System load averages over time"
#: src/components/charts/systemd-services-table.tsx
#: src/components/routes/system.tsx
msgid "Systemd Services"
msgstr "Systemd Services"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systems"
@@ -1076,10 +997,6 @@ msgstr "Throughput of {extraFsName}"
msgid "Throughput of root filesystem"
msgstr "Throughput of root filesystem"
#: src/components/routes/settings/general.tsx
msgid "Time format"
msgstr "Time format"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "To email(s)"
@@ -1112,14 +1029,6 @@ msgstr "Tokens allow agents to connect and register. Fingerprints are stable ide
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Total data received for each interface"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data sent for each interface"
msgstr "Total data sent for each interface"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Triggers when 1 minute load average exceeds a threshold"
@@ -1181,10 +1090,6 @@ msgstr "Up"
msgid "Up ({upSystemsLength})"
msgstr "Up ({upSystemsLength})"
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Upload"
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Uptime"
@@ -1218,10 +1123,6 @@ msgstr "Value"
msgid "View"
msgstr "View"
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "View more"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "View your 200 most recent alerts."
msgstr "View your 200 most recent alerts."

File diff suppressed because it is too large Load Diff

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: fa\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Persian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: fa\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# روز} other {# روز}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# ساعت} other {# ساعت}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# دقیقه} few {# دقیقه} many {# دقیقه} other {# دقیقه}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# دقیقه} few {# دقیقه} many {# دقیقه} ot
msgid "{0} of {1} row(s) selected."
msgstr "{0} از {1} ردیف انتخاب شده است."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} روز} other {{countString} روز}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} ساعت} other {{countString} ساعت}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} دقیقه} few {{countString} دقیقه} many {{countString} دقیقه} other {{countString} دقیقه}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "۱ ساعت"
@@ -48,6 +45,10 @@ msgstr "۱ ساعت"
msgid "1 min"
msgstr "۱ دقیقه"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 دقیقه"
#: src/lib/utils.ts
msgid "1 week"
msgstr "۱ هفته"
@@ -85,10 +86,14 @@ msgstr "عملیات"
msgid "Active"
msgstr "فعال"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr " هشدارهای فعال"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "وضعیت فعال"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "افزودن <0>سیستم</0>"
@@ -109,11 +114,19 @@ msgstr "افزودن آدرس اینترنتی"
msgid "Adjust display options for charts."
msgstr "تنظیم گزینه‌های نمایش برای نمودارها."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "تنظیم عرض چیدمان اصلی"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "مدیر"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "بعد از"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "عامل"
@@ -129,7 +142,15 @@ msgstr "تاریخچه هشدارها"
msgid "Alerts"
msgstr "هشدارها"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "همه کانتینرها"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "پهنای باند"
msgid "Battery"
msgstr "باتری"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "فعال شد"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "غیرفعال شد"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "قبل از"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "بِزل از OpenID Connect و بسیاری از ارائه‌دهندگان احراز هویت OAuth2 پشتیبانی می‌کند."
@@ -208,6 +241,10 @@ msgstr "دودویی"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "بیت (کیلوبیت بر ثانیه، مگابیت بر ثانیه، گیگابیت بر ثانیه)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "وضعیت بوت"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "بایت (کیلوبایت بر ثانیه، مگابایت بر ثان
msgid "Cache / Buffers"
msgstr "حافظه پنهان / بافرها"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "می‌تواند بارگذاری مجدد شود"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "می‌تواند شروع شود"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "می‌تواند متوقف شود"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "لغو"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "قابلیت‌ها"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "ظرفیت"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "احتیاط - احتمال از دست رفتن داده‌ها"
@@ -263,6 +320,14 @@ msgstr "برای جزئیات بیشتر، لاگ‌ها را بررسی کنی
msgid "Check your notification service"
msgstr "سرویس اطلاع‌رسانی خود را بررسی کنید"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "برای مشاهده اطلاعات بیشتر روی کانتینر کلیک کنید."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "برای مشاهده اطلاعات بیشتر روی دستگاه کلیک کنید."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "برای مشاهده اطلاعات بیشتر روی یک سیستم کلیک کنید."
@@ -285,7 +350,11 @@ msgstr "نحوه دریافت هشدارهای اطلاع‌رسانی را پی
msgid "Confirm password"
msgstr "تأیید رمز عبور"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "تعارض‌ها"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "اتصال قطع است"
@@ -344,12 +413,31 @@ msgstr "محتوای <0>docker-compose.yml</0> عامل زیر را کپی کن
msgid "Copy YAML"
msgstr "کپی YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "پردازنده"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "هسته‌های CPU"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "حداکثر CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "زمان CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "تجزیه زمان CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "میزان استفاده از پردازنده"
@@ -380,8 +468,12 @@ msgstr "آپلود تجمعی"
msgid "Current state"
msgstr "وضعیت فعلی"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "چرخه‌ها"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "داشبورد"
@@ -398,6 +490,18 @@ msgstr "حذف"
msgid "Delete fingerprint"
msgstr "حذف اثر انگشت"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "توضیحات"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "جزئیات"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "دستگاه"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "ورودی/خروجی شبکه داکر"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "مستندات"
@@ -498,20 +603,29 @@ msgstr "رمز عبور یک‌بار مصرف خود را وارد کنید."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "خطا"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "در {2, plural, one {# دقیقه} other {# دقیقه}} گذشته از {0}{1} بیشتر است"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "سیستم‌های موجود که در <0>config.yml</0> تعریف نشده‌اند حذف خواهند شد. لطفاً به طور منظم پشتیبان‌گیری کنید."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "خروج فعال"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "خروجی گرفتن"
@@ -528,6 +642,14 @@ msgstr "پیکربندی سیستم‌های فعلی خود را خارج کن
msgid "Fahrenheit (°F)"
msgstr "فارنهایت (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "ناموفق"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "ویژگی‌های ناموفق:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "احراز هویت ناموفق بود"
@@ -545,8 +667,16 @@ msgstr "ارسال اعلان آزمایشی ناموفق بود"
msgid "Failed to update alert"
msgstr "به‌روزرسانی هشدار ناموفق بود"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "ناموفق: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "فیلتر..."
@@ -555,6 +685,10 @@ msgstr "فیلتر..."
msgid "Fingerprint"
msgstr "اثر انگشت"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "فرم‌ویر"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "برای <0>{min}</0> {min, plural, one {دقیقه} other {دقیقه}}"
@@ -588,10 +722,18 @@ msgstr "موتورهای GPU"
msgid "GPU Power Draw"
msgstr "مصرف برق پردازنده گرافیکی"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "میزان استفاده از GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "جدول"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "سلامتی"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "بیکار"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "اگر رمز عبور حساب مدیر خود را گم کرده‌اید، می‌توانید آن را با استفاده از دستور زیر بازنشانی کنید."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "تصویر"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "آدرس ایمیل نامعتبر است."
@@ -628,6 +775,19 @@ msgstr "زبان"
msgid "Layout"
msgstr "طرح‌بندی"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "عرض چیدمان"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "چرخه حیات"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "میانگین بار"
@@ -649,6 +809,14 @@ msgstr "میانگین بار ۵ دقیقه"
msgid "Load Avg"
msgstr "میانگین بار"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "وضعیت بارگذاری"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "در حال بارگذاری..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "خروج"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "تلاش برای ورود ناموفق بود"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "لاگ‌ها"
@@ -671,6 +840,10 @@ msgstr "لاگ‌ها"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "به دنبال جایی برای ایجاد هشدار هستید؟ روی آیکون‌های زنگ <0/> در جدول سیستم‌ها کلیک کنید."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "مدیریت تنظیمات نمایش و اعلان‌ها."
@@ -685,10 +858,22 @@ msgstr "دستورالعمل‌های راه‌اندازی دستی"
msgid "Max 1 min"
msgstr "حداکثر ۱ دقیقه"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "حافظه"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "محدودیت حافظه"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "حداکثر حافظه"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "میزان استفاده از حافظه"
msgid "Memory usage of docker containers"
msgstr "میزان استفاده از حافظه کانتینرهای داکر"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "مدل"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "نام"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "شبکه"
@@ -723,14 +916,30 @@ msgstr "ترافیک شبکه رابط‌های عمومی"
msgid "Network unit"
msgstr "واحد شبکه"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "خیر"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "هیچ نتیجه‌ای یافت نشد."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "نتیجه‌ای یافت نشد."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "هیچ ویژگی S.M.A.R.T برای این دستگاه موجود نیست."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "باز کردن منو"
msgid "Or continue with"
msgstr "یا ادامه با"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "سایر"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "بازنویسی هشدارهای موجود"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "صفحه"
@@ -811,6 +1025,15 @@ msgstr "مکث شده"
msgid "Paused ({pausedSystemsLength})"
msgstr "مکث شده ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "میانگین استفاده در هر هسته"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "درصد زمان صرف شده در هر حالت"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "لطفاً برای اطمینان از تحویل هشدارها، یک <0>سرور SMTP پیکربندی کنید</0>."
@@ -848,6 +1071,11 @@ msgstr "لطفاً به حساب کاربری خود وارد شوید"
msgid "Port"
msgstr "پورت"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "روشن کردن"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "میزان دقیق استفاده در زمان ثبت شده"
msgid "Preferred Language"
msgstr "زبان ترجیحی"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "فرآیند شروع شد"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "خواندن"
msgid "Received"
msgstr "دریافت شد"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "تازه‌سازی"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "روابط"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "درخواست رمز عبور یک‌بار مصرف"
@@ -880,6 +1121,14 @@ msgstr "درخواست رمز عبور یک‌بار مصرف"
msgid "Request OTP"
msgstr "درخواست OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "مورد نیاز توسط"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "نیازمند"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "بازنشانی رمز عبور"
@@ -890,10 +1139,19 @@ msgstr "بازنشانی رمز عبور"
msgid "Resolved"
msgstr "حل شده"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "راه‌اندازی مجدد"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "ادامه"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "چرخش توکن"
@@ -902,6 +1160,18 @@ msgstr "چرخش توکن"
msgid "Rows per page"
msgstr "ردیف در هر صفحه"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "معیارهای زمان اجرا"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "جزئیات S.M.A.R.T"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "تست خود S.M.A.R.T"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "آدرس را با استفاده از کلید Enter یا کاما ذخیره کنید. برای غیرفعال کردن اعلان‌های ایمیلی، خالی بگذارید."
@@ -931,6 +1201,18 @@ msgstr "برای پیکربندی نحوه دریافت هشدارها، به <0
msgid "Sent"
msgstr "ارسال شد"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "شماره سریال"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "جزئیات سرویس"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "سرویس‌ها"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "آستانه های درصدی را برای رنگ های متر تنظیم کنید."
@@ -960,14 +1242,22 @@ msgstr "مرتب‌سازی بر اساس"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "وضعیت"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "وضعیت"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "وضعیت فرعی"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "فضای Swap استفاده شده توسط سیستم"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "میزان استفاده از Swap"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "سیستم"
msgid "System load averages over time"
msgstr "میانگین بار سیستم در طول زمان"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr ""
#: src/components/navbar.tsx
msgid "Systems"
msgstr "سیستم‌ها"
@@ -999,7 +1294,12 @@ msgstr "سیستم‌ها ممکن است در یک فایل <0>config.yml</0>
msgid "Table"
msgstr "جدول"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "وظایف"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "دما"
@@ -1081,6 +1381,11 @@ msgstr "توکن‌ها به عامل‌ها اجازه اتصال و ثبت‌
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "توکن‌ها و اثرات انگشت برای احراز هویت اتصالات WebSocket به هاب استفاده می‌شوند."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "کل"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "داده‌های کل دریافت شده برای هر رابط"
@@ -1089,6 +1394,19 @@ msgstr "داده‌های کل دریافت شده برای هر رابط"
msgid "Total data sent for each interface"
msgstr "داده‌های کل ارسال شده برای هر رابط"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "کل: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "فعال شده توسط"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "محرک‌ها"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "هنگامی که میانگین بار ۱ دقیقه‌ای از یک آستانه فراتر رود، فعال می‌شود"
@@ -1113,6 +1431,10 @@ msgstr "هنگامی که مجموع بالا/پایین از یک آستانه
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "هنگامی که میزان استفاده از CPU از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "هنگامی که میزان استفاده از GPU از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "هنگامی که میزان استفاده از حافظه از یک آستانه فراتر رود، فعال می‌شود"
@@ -1125,6 +1447,14 @@ msgstr "هنگامی که وضعیت بین بالا و پایین تغییر م
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "هنگامی که استفاده از هر دیسکی از یک آستانه فراتر رود، فعال می‌شود"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "نوع"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr ""
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "توکن جهانی"
msgid "Unknown"
msgstr "ناشناخته"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "نامحدود"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "فعال"
msgid "Up ({upSystemsLength})"
msgstr "فعال ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "به‌روزرسانی شد"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "هر ۱۰ دقیقه به‌روزرسانی می‌شود."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "آپلود"
@@ -1162,6 +1506,7 @@ msgstr "آپتایم"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "میزان استفاده"
@@ -1187,6 +1532,7 @@ msgstr "مقدار"
msgid "View"
msgstr "مشاهده"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "مشاهده بیشتر"
@@ -1207,6 +1553,10 @@ msgstr "در انتظار رکوردهای کافی برای نمایش"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "می‌خواهید به ما کمک کنید تا ترجمه‌های خود را بهتر کنیم؟ برای جزئیات بیشتر به <0>Crowdin</0> مراجعه کنید."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "می‌خواهد"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "هشدار (%)"
@@ -1243,6 +1593,13 @@ msgstr "پیکربندی YAML"
msgid "YAML Configuration"
msgstr "پیکربندی YAML"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "بله"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "تنظیمات کاربری شما به‌روزرسانی شد."

View File

@@ -8,35 +8,32 @@ msgstr ""
"Language: fr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: French\n"
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: fr\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# jour} other {# jours}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# heure} other {# heures}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr ""
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "{0} of {1} row(s) selected."
msgstr "{0} sur {1} ligne(s) sélectionnée(s)."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} jour} other {{countString} jours}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} heure} other {{countString} heures}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr ""
#: src/lib/utils.ts
@@ -46,7 +43,11 @@ msgstr "1 heure"
#. Load average
#: src/components/charts/load-average-chart.tsx
msgid "1 min"
msgstr ""
msgstr "1 min"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 minute"
#: src/lib/utils.ts
msgid "1 week"
@@ -59,7 +60,7 @@ msgstr "12 heures"
#. Load average
#: src/components/charts/load-average-chart.tsx
msgid "15 min"
msgstr ""
msgstr "15 min"
#: src/lib/utils.ts
msgid "24 hours"
@@ -72,7 +73,7 @@ msgstr "30 jours"
#. Load average
#: src/components/charts/load-average-chart.tsx
msgid "5 min"
msgstr ""
msgstr "5 min"
#. Table column
#: src/components/routes/settings/tokens-fingerprints.tsx
@@ -83,12 +84,16 @@ msgstr "Actions"
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Active"
msgstr ""
msgstr "Active"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Alertes actives"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "État actif"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Ajouter <0>un Système</0>"
@@ -109,11 +114,19 @@ msgstr "Ajouter lURL"
msgid "Adjust display options for charts."
msgstr "Ajuster les options d'affichage pour les graphiques."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Ajuster la largeur de la mise en page principale"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Après"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
@@ -122,14 +135,22 @@ msgstr "Agent"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/settings/layout.tsx
msgid "Alert History"
msgstr ""
msgstr "Historique des alertes"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alerts-sheet.tsx
msgid "Alerts"
msgstr "Alertes"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Tous les conteneurs"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -141,7 +162,7 @@ msgstr "Êtes-vous sûr de vouloir supprimer {name} ?"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Are you sure?"
msgstr ""
msgstr "Êtes-vous sûr ?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
@@ -191,6 +212,18 @@ msgstr "Bande passante"
msgid "Battery"
msgstr "Batterie"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Devenu actif"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Devenu inactif"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Avant"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel prend en charge OpenID Connect et de nombreux fournisseurs d'authentification OAuth2."
@@ -206,33 +239,57 @@ msgstr "Binaire"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr ""
msgstr "Bits (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "État de démarrage"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
msgstr ""
msgstr "Bytes (KB/s, MB/s, GB/s)"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Tampons"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Peut recharger"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Peut démarrer"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Peut arrêter"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Annuler"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Capacités"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Capacité"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Attention - perte de données potentielle"
#: src/components/routes/settings/general.tsx
msgid "Celsius (°C)"
msgstr ""
msgstr "Celsius (°C)"
#: src/components/routes/settings/general.tsx
msgid "Change display units for metrics."
msgstr ""
msgstr "Ajuster les unités d'affichage pour les métriques."
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
@@ -263,9 +320,17 @@ msgstr "Vérifiez les journaux pour plus de détails."
msgid "Check your notification service"
msgstr "Vérifiez votre service de notification"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Cliquez sur un conteneur pour voir plus d'informations."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Cliquez sur un appareil pour voir plus d'informations."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr ""
msgstr "Cliquez sur un système pour voir plus d'informations."
#: src/components/ui/input-copy.tsx
msgid "Click to copy"
@@ -285,9 +350,13 @@ msgstr "Configurez comment vous recevez les notifications d'alerte."
msgid "Confirm password"
msgstr "Confirmer le mot de passe"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Conflits"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr ""
msgstr "Connexion interrompue"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -344,12 +413,31 @@ msgstr "Copiez le contenu du<0>docker-compose.yml</0> pour l'agent ci-dessous, o
msgid "Copy YAML"
msgstr "Copier YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "Cœurs CPU"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "Pic CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "Temps CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Répartition du temps CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Utilisation du CPU"
@@ -361,7 +449,7 @@ msgstr "Créer un compte"
#. Context: date created
#: src/components/alerts-history-columns.tsx
msgid "Created"
msgstr ""
msgstr "Date de création"
#: src/components/routes/settings/general.tsx
msgid "Critical (%)"
@@ -380,8 +468,12 @@ msgstr "Téléversement cumulatif"
msgid "Current state"
msgstr "État actuel"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Cycles"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Tableau de bord"
@@ -398,6 +490,18 @@ msgstr "Supprimer"
msgid "Delete fingerprint"
msgstr "Supprimer l'empreinte"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr ""
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Détail"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Appareil"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -413,7 +517,7 @@ msgstr "Entrée/Sortie disque"
#: src/components/routes/settings/general.tsx
msgid "Disk unit"
msgstr ""
msgstr "Unité disque"
#: src/components/charts/disk-chart.tsx
#: src/components/routes/system.tsx
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Entrée/Sortie réseau Docker"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Documentation"
@@ -451,7 +556,7 @@ msgstr "Injoignable"
#: src/components/systems-table/systems-table.tsx
msgid "Down ({downSystemsLength})"
msgstr ""
msgstr "Injoignable ({downSystemsLength})"
#: src/components/routes/system/network-sheet.tsx
msgid "Download"
@@ -459,7 +564,7 @@ msgstr "Télécharger"
#: src/components/alerts-history-columns.tsx
msgid "Duration"
msgstr ""
msgstr "Durée"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -498,23 +603,32 @@ msgstr "Entrez votre mot de passe à usage unique."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Erreur"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Dépasse {0}{1} dans {2, plural, one {la dernière # minute} other {les dernières # minutes}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "PID principal d'exécution"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Les systèmes existants non définis dans <0>config.yml</0> seront supprimés. Veuillez faire des sauvegardes régulières."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Sorti actif"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr ""
msgstr "Exporter"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
@@ -526,7 +640,15 @@ msgstr "Exportez la configuration actuelle de vos systèmes."
#: src/components/routes/settings/general.tsx
msgid "Fahrenheit (°F)"
msgstr ""
msgstr "Fahrenheit (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Échoué"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Attributs défaillants :"
#: src/lib/api.ts
msgid "Failed to authenticate"
@@ -545,15 +667,27 @@ msgstr "Échec de l'envoi de la notification de test"
msgid "Failed to update alert"
msgstr "Échec de la mise à jour de l'alerte"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Échec : {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filtrer..."
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Fingerprint"
msgstr ""
msgstr "Empreinte"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Micrologiciel"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
@@ -588,10 +722,18 @@ msgstr "Moteurs GPU"
msgid "GPU Power Draw"
msgstr "Consommation du GPU"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "Utilisation GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Grille"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Santé"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Inactive"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Si vous avez perdu le mot de passe de votre compte administrateur, vous pouvez le réinitialiser en utilisant la commande suivante."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Image"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Adresse email invalide."
@@ -628,26 +775,47 @@ msgstr "Langue"
msgid "Layout"
msgstr "Disposition"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Largeur de la mise en page"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Cycle de vie"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "limite"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr ""
msgstr "Charge moyenne"
#: src/lib/alerts.ts
msgid "Load Average 15m"
msgstr ""
msgstr "Charge moyenne 15m"
#: src/lib/alerts.ts
msgid "Load Average 1m"
msgstr ""
msgstr "Charge moyenne 1m"
#: src/lib/alerts.ts
msgid "Load Average 5m"
msgstr ""
msgstr "Charge moyenne 5m"
#. Short label for load average
#: src/components/systems-table/systems-table-columns.tsx
msgid "Load Avg"
msgstr ""
msgstr "Charge moy."
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "État de charge"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Chargement..."
#: src/components/navbar.tsx
msgid "Log Out"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Échec de la tentative de connexion"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Journaux"
@@ -671,6 +840,10 @@ msgstr "Journaux"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Vous cherchez plutôt où créer des alertes ? Cliquez sur les icônes de cloche <0/> dans le tableau des systèmes."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "PID principal"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Gérer les préférences d'affichage et de notification."
@@ -685,10 +858,22 @@ msgstr "Guide pour une installation manuelle"
msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Mémoire"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Limite mémoire"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Pic mémoire"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Utilisation de la mémoire"
msgid "Memory usage of docker containers"
msgstr "Utilisation de la mémoire des conteneurs Docker"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Modèle"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Nom"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Net"
@@ -721,15 +914,31 @@ msgstr "Trafic réseau des interfaces publiques"
#. Context: Bytes or bits
#: src/components/routes/settings/general.tsx
msgid "Network unit"
msgstr ""
msgstr "Unité réseau"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Non"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Aucun résultat trouvé."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr ""
msgstr "Aucun résultat."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Aucun attribut S.M.A.R.T. disponible pour cet appareil."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
@@ -764,10 +973,15 @@ msgstr "Ouvrir le menu"
msgid "Or continue with"
msgstr "Ou continuer avec"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Autre"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Écraser les alertes existantes"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Page"
@@ -776,7 +990,7 @@ msgstr "Page"
#. placeholder {1}: table.getPageCount()
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Page {0} of {1}"
msgstr ""
msgstr "Page {0} sur {1}"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
@@ -809,7 +1023,16 @@ msgstr "En pause"
#: src/components/systems-table/systems-table.tsx
msgid "Paused ({pausedSystemsLength})"
msgstr ""
msgstr "Mis en pause ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Utilisation moyenne par cœur"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Pourcentage de temps passé dans chaque état"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
@@ -848,6 +1071,11 @@ msgstr "Veuillez vous connecter à votre compte"
msgid "Port"
msgstr "Port"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Allumage"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "Utilisation précise au moment enregistré"
msgid "Preferred Language"
msgstr "Langue préférée"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Processus démarré"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Lecture"
msgid "Received"
msgstr "Reçu"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Actualiser"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Relations"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Demander un mot de passe à usage unique"
@@ -880,6 +1121,14 @@ msgstr "Demander un mot de passe à usage unique"
msgid "Request OTP"
msgstr "Demander OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Requis par"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Requiert"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Réinitialiser le mot de passe"
@@ -888,19 +1137,40 @@ msgstr "Réinitialiser le mot de passe"
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Resolved"
msgstr ""
msgstr "Résolu"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Redémarrages"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Reprendre"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr "Racine"
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Faire tourner le token"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Rows per page"
msgstr ""
msgstr "Lignes par page"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Métriques d'exécution"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "Détails S.M.A.R.T."
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "Auto-test S.M.A.R.T."
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
@@ -931,6 +1201,18 @@ msgstr "Voir les <0>paramètres de notification</0> pour configurer comment vous
msgid "Sent"
msgstr "Envoyé"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Numéro de série"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Détails du service"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Définir des seuils de pourcentage pour les couleurs des compteurs."
@@ -960,14 +1242,22 @@ msgstr "Trier par"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr ""
msgstr "État"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Statut"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Sous-état"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Espace Swap utilisé par le système"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Utilisation du swap"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -985,7 +1276,11 @@ msgstr "Système"
#: src/components/routes/system.tsx
msgid "System load averages over time"
msgstr ""
msgstr "Charges moyennes du système dans le temps"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Services systemd"
#: src/components/navbar.tsx
msgid "Systems"
@@ -999,7 +1294,12 @@ msgstr "Les systèmes peuvent être gérés dans un fichier <0>config.yml</0> à
msgid "Table"
msgstr "Tableau"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Tâches"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Temp."
@@ -1011,7 +1311,7 @@ msgstr "Température"
#: src/components/routes/settings/general.tsx
msgid "Temperature unit"
msgstr ""
msgstr "Unité de température"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
@@ -1035,7 +1335,7 @@ msgstr "Cette action ne peut pas être annulée. Cela supprimera définitivement
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "This will permanently delete all selected records from the database."
msgstr ""
msgstr "Ceci supprimera définitivement tous les enregistrements sélectionnés de la base de données."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
@@ -1065,7 +1365,7 @@ msgstr "Changer le thème"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Token"
msgstr ""
msgstr "Token"
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
@@ -1081,6 +1381,11 @@ msgstr "Les tokens permettent aux agents de se connecter et de s'enregistrer. Le
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Les tokens et les empreintes sont utilisés pour authentifier les connexions WebSocket vers le hub."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Total"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Données totales reçues pour chaque interface"
@@ -1089,17 +1394,30 @@ msgstr "Données totales reçues pour chaque interface"
msgid "Total data sent for each interface"
msgstr "Données totales envoyées pour chaque interface"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Total : {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Déclenché par"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Déclencheurs"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr ""
msgstr "Se déclenche lorsque la charge moyenne sur 1 minute dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when 15 minute load average exceeds a threshold"
msgstr ""
msgstr "Se déclenche lorsque la charge moyenne sur 15 minute dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when 5 minute load average exceeds a threshold"
msgstr ""
msgstr "Se déclenche lorsque la charge moyenne sur 5 minute dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when any sensor exceeds a threshold"
@@ -1113,6 +1431,10 @@ msgstr "Déclenchement lorsque le montant/descendant combinée dépasse un seuil
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation du CPU dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation du GPU dépasse un seuil"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation de la mémoire dépasse un seuil"
@@ -1125,10 +1447,18 @@ msgstr "Se déclenche lorsque le statut passe de \"Joignable\" à \"Injoignable\
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation de tout disque dépasse un seuil"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Type"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Fichier unité"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
msgstr ""
msgstr "Préférences des unités"
#: src/components/command-palette.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
@@ -1140,6 +1470,11 @@ msgstr "Token universel"
msgid "Unknown"
msgstr "Inconnue"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Illimité"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1148,7 +1483,16 @@ msgstr "Joignable"
#: src/components/systems-table/systems-table.tsx
msgid "Up ({upSystemsLength})"
msgstr ""
msgstr "Joignable ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Mis à jour"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Mis à jour toutes les 10 minutes."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
@@ -1162,6 +1506,7 @@ msgstr "Temps de fonctionnement"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Utilisation"
@@ -1181,19 +1526,20 @@ msgstr "Utilisateurs"
#: src/components/alerts-history-columns.tsx
msgid "Value"
msgstr ""
msgstr "Valeur"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Vue"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Voir plus"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "View your 200 most recent alerts."
msgstr ""
msgstr "Voir vos 200 dernières alertes."
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
@@ -1207,6 +1553,10 @@ msgstr "En attente de suffisamment d'enregistrements à afficher"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Vous voulez nous aider à améliorer nos traductions ? Consultez <0>Crowdin</0> pour plus de détails."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Souhaite"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Avertissement (%)"
@@ -1243,6 +1593,13 @@ msgstr "Configuration YAML"
msgid "YAML Configuration"
msgstr "Configuration YAML"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Oui"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vos paramètres utilisateur ont été mis à jour."

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -8,15 +8,15 @@ msgstr ""
"Language: is\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-09-22 23:10\n"
"Last-Translator: \n"
"Language-Team: Icelandic\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: is\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
@@ -80,10 +80,6 @@ msgstr ""
msgid "Actions"
msgstr "Aðgerðir"
#: src/components/charts/systemd-services-table.tsx
msgid "active"
msgstr ""
#: src/components/alerts-history-columns.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Active"
@@ -116,7 +112,7 @@ msgstr ""
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
@@ -205,7 +201,7 @@ msgstr "Beszel notar <0>Shoutrrr</0> til að tengjast vinsælum tilkynningaþjó
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binary"
msgstr ""
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
@@ -352,7 +348,6 @@ msgstr ""
msgid "CPU"
msgstr "Örgjörvi"
#: src/components/charts/systemd-services-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
@@ -533,10 +528,6 @@ msgstr ""
msgid "Fahrenheit (°F)"
msgstr ""
#: src/components/charts/systemd-services-table.tsx
msgid "failed"
msgstr ""
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Villa í auðkenningu"
@@ -581,7 +572,7 @@ msgstr ""
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Full"
msgstr "Full"
msgstr ""
#. Context: General settings
#: src/components/routes/settings/general.tsx
@@ -609,7 +600,7 @@ msgstr "Homebrew skipun"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
msgstr ""
#. Context: Battery state
#: src/lib/i18n.ts
@@ -694,7 +685,6 @@ msgstr ""
msgid "Max 1 min"
msgstr "Mest 1 mínúta"
#: src/components/charts/systemd-services-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Minni"
@@ -715,7 +705,7 @@ msgstr "Nafn"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Net"
msgstr ""
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
@@ -724,7 +714,6 @@ msgstr "Net traffík docker kerfa"
#: src/components/routes/system.tsx
#: src/components/routes/system/network-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "Network traffic of public interfaces"
msgstr ""
@@ -733,10 +722,6 @@ msgstr ""
msgid "Network unit"
msgstr ""
#: src/components/charts/systemd-services-table.tsx
msgid "No failed services."
msgstr ""
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Engar niðurstöður fundust."
@@ -860,7 +845,7 @@ msgstr "Vinsamlegast skráðu þig inn á aðganginn þinn"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
msgstr ""
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
@@ -943,14 +928,6 @@ msgstr ""
#: src/components/routes/system.tsx
msgid "Sent"
msgstr "Sent"
#: src/components/charts/systemd-services-table.tsx
msgid "Service"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr ""
#: src/components/routes/settings/general.tsx
@@ -968,14 +945,6 @@ msgstr "Stillingar"
msgid "Settings saved"
msgstr "Stillingar vistaðar"
#: src/components/charts/systemd-services-table.tsx
msgid "Show all"
msgstr ""
#: src/components/charts/systemd-services-table.tsx
msgid "Show less"
msgstr ""
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Innskrá"
@@ -993,7 +962,6 @@ msgstr "Raða eftir"
msgid "State"
msgstr ""
#: src/components/charts/systemd-services-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
@@ -1018,11 +986,6 @@ msgstr "Kerfi"
msgid "System load averages over time"
msgstr ""
#: src/components/charts/systemd-services-table.tsx
#: src/components/routes/system.tsx
msgid "Systemd Services"
msgstr ""
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Kerfi"
@@ -1282,3 +1245,4 @@ msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Notenda stillingar vistaðar."

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: it\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Italian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: it\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# giorno} other {# giorni}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# ora} other {# ore}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# minuto} other {# minuti}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# minuto} other {# minuti}}"
msgid "{0} of {1} row(s) selected."
msgstr "{0} di {1} righe selezionate."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} giorno} other {{countString} giorni}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} ora} other {{countString} ore}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuto} other {{countString} minuti}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ora"
@@ -48,6 +45,10 @@ msgstr "1 ora"
msgid "1 min"
msgstr "1 min"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 minuto"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 settimana"
@@ -85,10 +86,14 @@ msgstr "Azioni"
msgid "Active"
msgstr "Attivo"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Avvisi Attivi"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Stato attivo"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Aggiungi <0>Sistema</0>"
@@ -109,11 +114,19 @@ msgstr "Aggiungi URL"
msgid "Adjust display options for charts."
msgstr "Regola le opzioni di visualizzazione per i grafici."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Regola la larghezza del layout principale"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Amministratore"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Dopo"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agente"
@@ -129,7 +142,15 @@ msgstr "Cronologia Avvisi"
msgid "Alerts"
msgstr "Avvisi"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Tutti i contenitori"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "Larghezza di banda"
msgid "Battery"
msgstr "Batteria"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Diventato attivo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Diventato inattivo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Prima"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel supporta OpenID Connect e molti provider di autenticazione OAuth2."
@@ -208,6 +241,10 @@ msgstr "Binario"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Bit (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Stato di avvio"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "Byte (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "Cache / Buffer"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Può ricaricare"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Può avviare"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Può fermare"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Annulla"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Funzionalità"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Capacità"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Attenzione - possibile perdita di dati"
@@ -263,6 +320,14 @@ msgstr "Controlla i log per maggiori dettagli."
msgid "Check your notification service"
msgstr "Controlla il tuo servizio di notifica"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Fare clic su un contenitore per visualizzare ulteriori informazioni."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Fare clic su un dispositivo per visualizzare più informazioni."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Clicca su un sistema per visualizzare più informazioni."
@@ -285,7 +350,11 @@ msgstr "Configura come ricevere le notifiche di avviso."
msgid "Confirm password"
msgstr "Conferma password"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Conflitti"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "La connessione è interrotta"
@@ -344,12 +413,31 @@ msgstr "Copia il contenuto<0>docker-compose.yml</0> per l'agente qui sotto, o re
msgid "Copy YAML"
msgstr "Copia YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "Core CPU"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "Picco CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "Tempo CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Suddivisione tempo CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Utilizzo CPU"
@@ -380,8 +468,12 @@ msgstr "Upload cumulativo"
msgid "Current state"
msgstr "Stato attuale"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Cicli"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Cruscotto"
@@ -398,6 +490,18 @@ msgstr "Elimina"
msgid "Delete fingerprint"
msgstr "Elimina impronta digitale"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Descrizione"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Dettagli"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Dispositivo"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "I/O di Rete Docker"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Documentazione"
@@ -498,20 +603,29 @@ msgstr "Inserisci la tua password monouso."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Errore"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Supera {0}{1} negli ultimi {2, plural, one {# minuto} other {# minuti}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "PID principale exec"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "I sistemi esistenti non definiti in <0>config.yml</0> verranno eliminati. Si prega di effettuare backup regolari."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Uscito attivo"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Esporta"
@@ -528,6 +642,14 @@ msgstr "Esporta la configurazione attuale dei tuoi sistemi."
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Fallito"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Attributi falliti:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Autenticazione fallita"
@@ -545,8 +667,16 @@ msgstr "Invio della notifica di test fallito"
msgid "Failed to update alert"
msgstr "Aggiornamento dell'avviso fallito"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Fallito: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filtra..."
@@ -555,6 +685,10 @@ msgstr "Filtra..."
msgid "Fingerprint"
msgstr "Impronta digitale"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firmware"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Per <0>{min}</0> {min, plural, one {minuto} other {minuti}}"
@@ -588,10 +722,18 @@ msgstr "Motori GPU"
msgid "GPU Power Draw"
msgstr "Consumo della GPU"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "Utilizzo GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Griglia"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Stato"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Inattiva"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Se hai perso la password del tuo account amministratore, puoi reimpostarla utilizzando il seguente comando."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Immagine"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Indirizzo email non valido."
@@ -628,6 +775,19 @@ msgstr "Lingua"
msgid "Layout"
msgstr "Aspetto"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Larghezza del layout"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Ciclo di vita"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "limite"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Carico medio"
@@ -649,6 +809,14 @@ msgstr "Caricamento medio 5m"
msgid "Load Avg"
msgstr "Carico Medio"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Stato di caricamento"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Caricamento..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Disconnetti"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Tentativo di accesso fallito"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Log"
@@ -671,6 +840,10 @@ msgstr "Log"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Cerchi invece dove creare avvisi? Clicca sulle icone della campana <0/> nella tabella dei sistemi."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "PID principale"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Gestisci le preferenze di visualizzazione e notifica."
@@ -685,10 +858,22 @@ msgstr "Istruzioni di configurazione manuale"
msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Memoria"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Limite memoria"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Picco memoria"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Utilizzo Memoria"
msgid "Memory usage of docker containers"
msgstr "Utilizzo della memoria dei container Docker"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Modello"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Nome"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Rete"
@@ -723,14 +916,30 @@ msgstr "Traffico di rete delle interfacce pubbliche"
msgid "Network unit"
msgstr "Unità rete"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Nessun risultato trovato."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Nessun risultato."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Nessun attributo S.M.A.R.T. disponibile per questo dispositivo."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "Apri menu"
msgid "Or continue with"
msgstr "Oppure continua con"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Altro"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Sovrascrivi avvisi esistenti"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Pagina"
@@ -811,6 +1025,15 @@ msgstr "In pausa"
msgid "Paused ({pausedSystemsLength})"
msgstr "In pausa ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Utilizzo medio per core"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Percentuale di tempo trascorso in ogni stato"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Si prega di <0>configurare un server SMTP</0> per garantire la consegna degli avvisi."
@@ -848,6 +1071,11 @@ msgstr "Si prega di accedere al proprio account"
msgid "Port"
msgstr "Porta"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Accensione"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "Utilizzo preciso al momento registrato"
msgid "Preferred Language"
msgstr "Lingua Preferita"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Processo avviato"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Lettura"
msgid "Received"
msgstr "Ricevuto"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Aggiorna"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Relazioni"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Richiedi una password monouso"
@@ -880,6 +1121,14 @@ msgstr "Richiedi una password monouso"
msgid "Request OTP"
msgstr "Richiedi OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Richiesto da"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Richiede"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Reimposta Password"
@@ -890,10 +1139,19 @@ msgstr "Reimposta Password"
msgid "Resolved"
msgstr "Risolto"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Riavvii"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Riprendi"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Ruota token"
@@ -902,6 +1160,18 @@ msgstr "Ruota token"
msgid "Rows per page"
msgstr "Righe per pagina"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Metriche di runtime"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "Dettagli S.M.A.R.T."
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "Autotest S.M.A.R.T."
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Salva l'indirizzo usando il tasto invio o la virgola. Lascia vuoto per disabilitare le notifiche email."
@@ -931,6 +1201,18 @@ msgstr "Vedi <0>impostazioni di notifica</0> per configurare come ricevere gli a
msgid "Sent"
msgstr "Inviato"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Numero di serie"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Dettagli servizio"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Servizi"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Imposta le soglie percentuali per i colori dei contatori."
@@ -960,14 +1242,22 @@ msgstr "Ordina per"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stato"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Stato"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Sotto-stato"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Spazio di swap utilizzato dal sistema"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Utilizzo Swap"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "Sistema"
msgid "System load averages over time"
msgstr "Medie di carico del sistema nel tempo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Servizi Systemd"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemi"
@@ -999,7 +1294,12 @@ msgstr "I sistemi possono essere gestiti in un file <0>config.yml</0> all'intern
msgid "Table"
msgstr "Tabella"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Attività"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Temperatura"
@@ -1081,6 +1381,11 @@ msgstr "I token consentono agli agenti di connettersi e registrarsi. Le impronte
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "I token e le impronte digitali vengono utilizzati per autenticare le connessioni WebSocket all'hub."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Totale"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Dati totali ricevuti per ogni interfaccia"
@@ -1089,6 +1394,19 @@ msgstr "Dati totali ricevuti per ogni interfaccia"
msgid "Total data sent for each interface"
msgstr "Dati totali inviati per ogni interfaccia"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Totale: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Attivato da"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Trigger"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Si attiva quando la media di carico di 1 minuto supera una soglia"
@@ -1113,6 +1431,10 @@ msgstr "Attiva quando il combinato up/down supera una soglia"
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Attiva quando l'utilizzo della CPU supera una soglia"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Si attiva quando l'utilizzo della GPU supera una soglia"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Attiva quando l'utilizzo della memoria supera una soglia"
@@ -1125,6 +1447,14 @@ msgstr "Attiva quando lo stato passa tra up e down"
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Attiva quando l'utilizzo di un disco supera una soglia"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Tipo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "File unit"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "Token universale"
msgid "Unknown"
msgstr "Sconosciuta"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Illimitato"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "Attivo"
msgid "Up ({upSystemsLength})"
msgstr "Attivo ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Aggiornato"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Aggiornato ogni 10 minuti."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Carica"
@@ -1162,6 +1506,7 @@ msgstr "Tempo di attività"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Utilizzo"
@@ -1187,6 +1532,7 @@ msgstr "Valore"
msgid "View"
msgstr "Vista"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Visualizza altro"
@@ -1207,6 +1553,10 @@ msgstr "In attesa di abbastanza record da visualizzare"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Vuoi aiutarci a migliorare ulteriormente le nostre traduzioni? Dai un'occhiata a <0>Crowdin</0> per maggiori dettagli."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Desidera"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Avviso (%)"
@@ -1243,6 +1593,13 @@ msgstr "Configurazione YAML"
msgid "YAML Configuration"
msgstr "Configurazione YAML"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Sì"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Le impostazioni utente sono state aggiornate."

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: ja\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Japanese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: ja\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# 日} other {# 日}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# 時間} other {# 時間}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# 分} few {# 分} many {# 分} other {# 分}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# 分} few {# 分} many {# 分} other {# 分}}"
msgid "{0} of {1} row(s) selected."
msgstr "{1}行のうち{0}行が選択されました。"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 日} other {{countString} 日}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} 時間} other {{countString} 時間}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 分} few {{countString} 分} many {{countString} 分} other {{countString} 分}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1時間"
@@ -48,6 +45,10 @@ msgstr "1時間"
msgid "1 min"
msgstr "1分"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1分"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1週間"
@@ -85,10 +86,14 @@ msgstr "アクション"
msgid "Active"
msgstr "アクティブ"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "アクティブなアラート"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "アクティブ状態"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>システム</0>を追加"
@@ -109,11 +114,19 @@ msgstr "URLを追加"
msgid "Adjust display options for charts."
msgstr "チャートの表示オプションを調整します。"
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "メインレイアウトの幅を調整"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "管理者"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "後"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "エージェント"
@@ -129,7 +142,15 @@ msgstr "アラート履歴"
msgid "Alerts"
msgstr "アラート"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "すべてのコンテナ"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "帯域幅"
msgid "Battery"
msgstr "バッテリー"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "アクティブになった"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "非アクティブになった"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "前"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "BeszelはOpenID Connectと多くのOAuth2認証プロバイダーをサポートしています。"
@@ -208,6 +241,10 @@ msgstr "バイナリ"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "ビット (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "ブート状態"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "バイト (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "キャッシュ / バッファ"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "リロード可能"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "開始可能"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "停止可能"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "キャンセル"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "機能"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "容量"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "注意 - データ損失の可能性"
@@ -263,6 +320,14 @@ msgstr "詳細についてはログを確認してください。"
msgid "Check your notification service"
msgstr "通知サービスを確認してください"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "詳細情報を表示するにはコンテナをクリックしてください。"
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "詳細情報を表示するにはデバイスをクリックしてください。"
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "システムをクリックして詳細を表示します。"
@@ -285,7 +350,11 @@ msgstr "アラート通知の受信方法を設定します。"
msgid "Confirm password"
msgstr "パスワードを確認"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "競合"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "接続が切断されました"
@@ -344,12 +413,31 @@ msgstr "下記のエージェントの<0>docker-compose.yml</0>内容をコピ
msgid "Copy YAML"
msgstr "YAMLをコピー"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "CPU コア"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "CPUピーク"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "CPU時間"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "CPU 時間の内訳"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "CPU使用率"
@@ -380,8 +468,12 @@ msgstr "累積アップロード"
msgid "Current state"
msgstr "現在の状態"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "サイクル"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "ダッシュボード"
@@ -398,6 +490,18 @@ msgstr "削除"
msgid "Delete fingerprint"
msgstr "フィンガープリントを削除"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "説明"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "詳細"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "デバイス"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "DockerネットワークI/O"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "ドキュメント"
@@ -498,20 +603,29 @@ msgstr "ワンタイムパスワードを入力してください。"
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "エラー"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "過去{2, plural, one {# 分} other {# 分}}で{0}{1}を超えています"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "実行メインPID"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "<0>config.yml</0>に定義されていない既存のシステムは削除されます。定期的にバックアップを作成してください。"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "アクティブ状態で終了"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "エクスポート"
@@ -528,6 +642,14 @@ msgstr "現在のシステム設定をエクスポートします。"
msgid "Fahrenheit (°F)"
msgstr "華氏 (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "失敗"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "失敗した属性:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "認証に失敗しました"
@@ -545,8 +667,16 @@ msgstr "テスト通知の送信に失敗しました"
msgid "Failed to update alert"
msgstr "アラートの更新に失敗しました"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "失敗: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "フィルター..."
@@ -555,6 +685,10 @@ msgstr "フィルター..."
msgid "Fingerprint"
msgstr "フィンガープリント"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "ファームウェア"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "<0>{min}</0> {min, plural, one {分} other {分}}の間"
@@ -588,10 +722,18 @@ msgstr "GPUエンジン"
msgid "GPU Power Draw"
msgstr "GPUの消費電力"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "GPU使用率"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "グリッド"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "ヘルス"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "アイドル"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "管理者アカウントのパスワードを忘れた場合は、次のコマンドを使用してリセットできます。"
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "イメージ"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "無効なメールアドレスです。"
@@ -628,6 +775,19 @@ msgstr "言語"
msgid "Layout"
msgstr "レイアウト"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "レイアウト幅"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "ライフサイクル"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "制限"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "負荷平均"
@@ -649,6 +809,14 @@ msgstr "負荷平均 (5分)"
msgid "Load Avg"
msgstr "負荷平均"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "ロード状態"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "読み込み中..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "ログアウト"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "ログイン試行に失敗しました"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "ログ"
@@ -671,6 +840,10 @@ msgstr "ログ"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "アラートを作成する場所を探していますか?システムテーブルのベル<0/>アイコンをクリックしてください。"
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "メインPID"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "表示と通知の設定を管理します。"
@@ -685,10 +858,22 @@ msgstr "手動セットアップの手順"
msgid "Max 1 min"
msgstr "最大1分"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "メモリ"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "メモリ制限"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "メモリピーク"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "メモリ使用率"
msgid "Memory usage of docker containers"
msgstr "Dockerコンテナのメモリ使用率"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "モデル"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "名前"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "帯域"
@@ -723,14 +916,30 @@ msgstr "パブリックインターフェースのネットワークトラフィ
msgid "Network unit"
msgstr "ネットワーク単位"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "いいえ"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "結果が見つかりませんでした。"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "結果がありません。"
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "このデバイスのS.M.A.R.T.属性は利用できません。"
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "メニューを開く"
msgid "Or continue with"
msgstr "または、以下の方法でログイン"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "その他"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "既存のアラートを上書き"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "ページ"
@@ -811,6 +1025,15 @@ msgstr "一時停止中"
msgid "Paused ({pausedSystemsLength})"
msgstr "一時停止 ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "コアごとの平均使用率"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "各状態で費やした時間の割合"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "アラートが配信されるように<0>SMTPサーバーを設定</0>してください。"
@@ -848,6 +1071,11 @@ msgstr "アカウントにサインインしてください"
msgid "Port"
msgstr "ポート"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "電源オン"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "記録された時点での正確な利用"
msgid "Preferred Language"
msgstr "優先言語"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "プロセス開始"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "読み取り"
msgid "Received"
msgstr "受信"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "更新"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "関係"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "ワンタイムパスワードをリクエスト"
@@ -880,6 +1121,14 @@ msgstr "ワンタイムパスワードをリクエスト"
msgid "Request OTP"
msgstr "OTP をリクエスト"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "必要とされる"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "必要とする"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "パスワードをリセット"
@@ -890,10 +1139,19 @@ msgstr "パスワードをリセット"
msgid "Resolved"
msgstr "解決済み"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "再起動"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "再開"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "トークンをローテート"
@@ -902,6 +1160,18 @@ msgstr "トークンをローテート"
msgid "Rows per page"
msgstr "ページあたりの行数"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "ランタイムメトリクス"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "S.M.A.R.T.詳細"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T.セルフテスト"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Enterキーまたはカンマを使用してアドレスを保存します。空白のままにするとメール通知が無効になります。"
@@ -931,6 +1201,18 @@ msgstr "アラートの受信方法を設定するには<0>通知設定</0>を
msgid "Sent"
msgstr "送信"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "シリアル番号"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "サービス詳細"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "サービス"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "メーターの色を変更するしきい値(パーセンテージ)を設定します。"
@@ -960,14 +1242,22 @@ msgstr "並び替え基準"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "状態"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "ステータス"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "サブ状態"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "システムが使用するスワップ領域"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "スワップ使用量"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "システム"
msgid "System load averages over time"
msgstr "システムの負荷平均の推移"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Systemdサービス"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "システム"
@@ -999,7 +1294,12 @@ msgstr "システムはデータディレクトリ内の<0>config.yml</0>ファ
msgid "Table"
msgstr "テーブル"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "タスク"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "温度"
@@ -1081,6 +1381,11 @@ msgstr "トークンはエージェントの接続と登録を可能にします
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "トークンとフィンガープリントは、ハブへのWebSocket接続の認証に使用されます。"
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "総数"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "各インターフェースの総受信データ量"
@@ -1089,6 +1394,19 @@ msgstr "各インターフェースの総受信データ量"
msgid "Total data sent for each interface"
msgstr "各インターフェースの総送信データ量"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "合計: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "トリガー元"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "トリガー"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "1分間の負荷平均がしきい値を超えたときにトリガーされます"
@@ -1113,6 +1431,10 @@ msgstr "上り/下りの合計がしきい値を超えたときにトリガー
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "CPU使用率がしきい値を超えたときにトリガーされます"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "GPU使用率がしきい値を超えたときにトリガーされます"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "メモリ使用率がしきい値を超えたときにトリガーされます"
@@ -1125,6 +1447,14 @@ msgstr "ステータスが上から下に切り替わるときにトリガーさ
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "ディスクの使用量がしきい値を超えたときにトリガーされます"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "タイプ"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "ユニットファイル"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "ユニバーサルトークン"
msgid "Unknown"
msgstr "不明"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "無制限"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "正常"
msgid "Up ({upSystemsLength})"
msgstr "正常 ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "更新済み"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "10分ごとに更新されます。"
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "アップロード"
@@ -1162,6 +1506,7 @@ msgstr "稼働時間"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "使用量"
@@ -1187,6 +1532,7 @@ msgstr "値"
msgid "View"
msgstr "表示"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "もっと見る"
@@ -1207,6 +1553,10 @@ msgstr "表示するのに十分なレコードを待っています"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "翻訳をさらに良くするためにご協力をお願いします。詳細については<0>Crowdin</0>をご覧ください。"
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "要求"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "警告 (%)"
@@ -1243,6 +1593,13 @@ msgstr "YAML設定"
msgid "YAML Configuration"
msgstr "YAML設定"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "はい"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "ユーザー設定が更新されました。"

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: ko\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-09-23 02:45\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Korean\n"
"Plural-Forms: nplurals=1; plural=0;\n"
@@ -18,27 +18,24 @@ msgstr ""
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# 일} other {# 일}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# 시간} other {# 시간}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# 분} few {# 분} many {# 분} other {# 분}}"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "{0} of {1} row(s) selected."
msgstr "{1}개의 행 중 {0}개가 선택되었습니다."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} 일} other {{countString} 일}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} 시간} other {{countString} 시간}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} 분} few {{countString} 분} many {{countString} 분} other {{countString} 분}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1시간"
@@ -48,6 +45,10 @@ msgstr "1시간"
msgid "1 min"
msgstr "1분"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1분"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1주"
@@ -85,10 +86,14 @@ msgstr "작업"
msgid "Active"
msgstr "활성"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "활성화된 알림들"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "활성 상태"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>시스템</0> 추가"
@@ -109,11 +114,19 @@ msgstr "URL 추가"
msgid "Adjust display options for charts."
msgstr "차트 표시 옵션 변경."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "메인 레이아웃 너비 조정"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "관리자"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "이후"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "에이전트"
@@ -129,7 +142,15 @@ msgstr "알림 기록"
msgid "Alerts"
msgstr "알림"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "모든 컨테이너"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "대역폭"
msgid "Battery"
msgstr "배터리"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "활성화됨"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "비활성화됨"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "이전"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel은 OpenID Connect 및 많은 OAuth2 인증 제공자를 지원합니다."
@@ -208,6 +241,10 @@ msgstr "실행 파일"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "비트 (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "부팅 상태"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "바이트 (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "캐시 / 버퍼"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "재로드 가능"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "시작 가능"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "중지 가능"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "취소"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "권한"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "용량"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "주의 - 데이터 손실 가능성"
@@ -263,6 +320,14 @@ msgstr "자세한 내용은 로그를 확인하세요."
msgid "Check your notification service"
msgstr "알림 서비스를 확인하세요."
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "더 많은 정보를 보려면 컨테이너를 클릭하세요."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "더 많은 정보를 보려면 장치를 클릭하세요."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "더 많은 정보를 보려면 시스템을 클릭하세요."
@@ -285,7 +350,11 @@ msgstr "알림을 수신할 방법을 설정하세요."
msgid "Confirm password"
msgstr "비밀번호 확인"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "충돌"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "연결이 끊겼습니다"
@@ -344,12 +413,31 @@ msgstr "아래 에이전트의 <0>docker-compose.yml</0> 내용을 복사하거
msgid "Copy YAML"
msgstr "YAML 복사"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "CPU 코어"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "CPU 최대값"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "CPU 시간"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "CPU 시간 분배"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "CPU 사용량"
@@ -380,8 +468,12 @@ msgstr "누적 업로드"
msgid "Current state"
msgstr "현재 상태"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "사이클"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "대시보드"
@@ -398,6 +490,18 @@ msgstr "삭제"
msgid "Delete fingerprint"
msgstr "지문 삭제"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "설명"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "세부사항"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "장치"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Docker 네트워크 I/O"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "문서"
@@ -498,20 +603,29 @@ msgstr "OTP를 입력하세요."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "오류"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "마지막 {2, plural, one {# 분} other {# 분}} 동안 {0}{1} 초과"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr ""
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "<0>config.yml</0>에 정의되지 않은 기존 시스템은 삭제됩니다. 정기적으로 백업을 하세요."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "활성 종료됨"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "내보내기"
@@ -528,6 +642,14 @@ msgstr "현재 시스템 구성 내보내기"
msgid "Fahrenheit (°F)"
msgstr "화씨 (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "실패"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "실패한 속성:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "인증 실패"
@@ -545,8 +667,16 @@ msgstr "테스트 알림 전송 실패"
msgid "Failed to update alert"
msgstr "알림 수정 실패"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "실패: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "필터..."
@@ -555,6 +685,10 @@ msgstr "필터..."
msgid "Fingerprint"
msgstr "지문"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "펌웨어"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "<0>{min}</0> {min, plural, one {분} other {분}} 동안"
@@ -588,10 +722,18 @@ msgstr "GPU 엔진들"
msgid "GPU Power Draw"
msgstr "GPU 전원 사용량"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "GPU 사용량"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "그리드"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "상태"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "대기"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "관리자 계정의 비밀번호를 잃어버린 경우, 다음 명령어를 사용하여 재설정할 수 있습니다."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "이미지"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "잘못된 이메일 주소입니다."
@@ -628,6 +775,19 @@ msgstr "언어"
msgid "Layout"
msgstr "레이아웃"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "레이아웃 너비"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "생명주기"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "부하 평균"
@@ -649,6 +809,14 @@ msgstr "부하 평균 5분"
msgid "Load Avg"
msgstr "부하 평균"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "로드 상태"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "로딩 중..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "로그아웃"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "로그인 실패"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "로그"
@@ -671,6 +840,10 @@ msgstr "로그"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "알림을 생성하려 하시나요? 시스템 테이블의 종 <0/> 아이콘을 클릭하세요."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr ""
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "디스플레이 및 알림 설정"
@@ -685,10 +858,22 @@ msgstr "수동 설정 방법"
msgid "Max 1 min"
msgstr "1분간 최댓값"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "메모리"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "메모리 제한"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "메모리 최대값"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "메모리 사용량"
msgid "Memory usage of docker containers"
msgstr "Docker 컨테이너의 메모리 사용량"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "모델"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "이름"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "네트워크"
@@ -723,14 +916,30 @@ msgstr "공용 인터페이스의 네트워크 트래픽"
msgid "Network unit"
msgstr "네트워크 단위"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "아니오"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "결과가 없습니다."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "결과 없음."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "이 장치에 사용할 수 있는 S.M.A.R.T. 속성이 없습니다."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "메뉴 열기"
msgid "Or continue with"
msgstr "또는 아래 항목으로 진행하기"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "기타"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "기존 알림 덮어쓰기"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "페이지"
@@ -811,6 +1025,15 @@ msgstr "일시 정지됨"
msgid "Paused ({pausedSystemsLength})"
msgstr "일시 정지됨 ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "코어별 평균 사용률"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "각 상태에서 보낸 시간의 백분율"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "알림이 전달되도록 <0>SMTP 서버를 구성</0>하세요."
@@ -848,6 +1071,11 @@ msgstr "계정에 로그인하세요."
msgid "Port"
msgstr "포트"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "전원 켜기"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "기록된 시간의 정확한 사용량"
msgid "Preferred Language"
msgstr "선호 언어"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "프로세스 시작됨"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "읽기"
msgid "Received"
msgstr "수신됨"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "새로고침"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "관계"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "OTP 요청"
@@ -880,6 +1121,14 @@ msgstr "OTP 요청"
msgid "Request OTP"
msgstr "OTP 요청"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "필요한 대상"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "필요 항목"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "비밀번호 재설정"
@@ -890,10 +1139,19 @@ msgstr "비밀번호 재설정"
msgid "Resolved"
msgstr "해결됨"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "재시작 횟수"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "재개"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "토큰 회전"
@@ -902,6 +1160,18 @@ msgstr "토큰 회전"
msgid "Rows per page"
msgstr "페이지당 행 수"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "런타임 메트릭"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "S.M.A.R.T. 세부 정보"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T. 자체 테스트"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Enter 키 또는 쉼표를 사용하여 주소를 저장하세요. 이메일 알림을 비활성화하려면 비워 두세요."
@@ -931,6 +1201,18 @@ msgstr "알림을 받는 방법을 구성하려면 <0>알림 설정</0>을 참
msgid "Sent"
msgstr "보냄"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "시리얼 번호"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "서비스 세부 정보"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "서비스"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "그래프 미터 색상의 백분율 임계값을 설정합니다."
@@ -960,14 +1242,22 @@ msgstr "정렬 기준"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "상태"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "상태"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "하위 상태"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "시스템에서 사용된 스왑 공간"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "스왑 사용량"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "시스템"
msgid "System load averages over time"
msgstr "시간에 따른 시스템 부하 평균"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr ""
#: src/components/navbar.tsx
msgid "Systems"
msgstr "시스템"
@@ -999,7 +1294,12 @@ msgstr "시스템은 데이터 디렉토리 내의 <0>config.yml</0> 파일에
msgid "Table"
msgstr "표"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "작업"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "온도"
@@ -1081,6 +1381,11 @@ msgstr "토큰은 에이전트가 연결하고 등록할 수 있도록 합니다
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "토큰과 지문은 허브에 대한 WebSocket 연결을 인증하는 데 사용됩니다."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "총"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "각 인터페이스별 총합 다운로드 데이터량"
@@ -1089,6 +1394,19 @@ msgstr "각 인터페이스별 총합 다운로드 데이터량"
msgid "Total data sent for each interface"
msgstr "각 인터페이스별 총합 업로드 데이터량"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "총: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "트리거 대상"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "트리거"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "1분 부하 평균이 임계값을 초과하면 트리거됩니다."
@@ -1113,6 +1431,10 @@ msgstr "업로드와 다운로드 대역폭의 합이 임계값을 초과할 때
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "CPU 사용량이 임계값을 초과할 때 트리거됩니다."
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "GPU 사용량이 임계값을 초과할 때 트리거됩니다."
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "메모리 사용량이 임계값을 초과할 때 트리거됩니다."
@@ -1125,6 +1447,14 @@ msgstr "시스템의 전원이 켜지거나 꺼질때 트리거됩니다."
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "디스크 사용량이 임계값을 초과할 때 트리거됩니다."
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "유형"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr ""
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "범용 토큰"
msgid "Unknown"
msgstr "알 수 없음"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "무제한"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "온라인"
msgid "Up ({upSystemsLength})"
msgstr "온라인 ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "업데이트됨"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "10분마다 업데이트됩니다."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "업로드"
@@ -1162,6 +1506,7 @@ msgstr "가동 시간"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "사용량"
@@ -1187,6 +1532,7 @@ msgstr "값"
msgid "View"
msgstr "보기"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "더 보기"
@@ -1207,6 +1553,10 @@ msgstr "표시할 충분한 기록을 기다리는 중"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "번역을 개선하는데 도움을 주시겠습니까? 자세한 내용은 <0>Crowdin</0>을 확인해 주세요."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "요구 항목"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "경고 (%)"
@@ -1243,6 +1593,13 @@ msgstr "YAML 구성"
msgid "YAML Configuration"
msgstr "YAML 구성"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "예"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "사용자 설정이 업데이트되었습니다."

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: nl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Dutch\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: nl\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# dag} other {# dagen}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# uur} other {# uren}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# minuut} other {# minuten}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# minuut} other {# minuten}}"
msgid "{0} of {1} row(s) selected."
msgstr "{0} van de {1} rij(en) geselecteerd."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dag} other {{countString} dagen}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} uur} other {{countString} uren}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuut} other {{countString} minuten}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 uur"
@@ -48,9 +45,13 @@ msgstr "1 uur"
msgid "1 min"
msgstr "1 minuut"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 minuut"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 week"
msgstr ""
#: src/lib/utils.ts
msgid "12 hours"
@@ -85,10 +86,14 @@ msgstr "Acties"
msgid "Active"
msgstr "Actief"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Actieve waarschuwingen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Actieve status"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Voeg <0>Systeem</0> toe"
@@ -109,14 +114,22 @@ msgstr "Voeg URL toe"
msgid "Adjust display options for charts."
msgstr "Weergaveopties voor grafieken aanpassen."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Breedte van het hoofdlayout aanpassen"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Na"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
msgstr ""
#: src/components/command-palette.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
@@ -129,7 +142,15 @@ msgstr "Melding geschiedenis"
msgid "Alerts"
msgstr "Waarschuwingen"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Alle containers"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "Bandbreedte"
msgid "Battery"
msgstr "Batterij"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Actief geworden"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Inactief geworden"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Voor"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel ondersteunt OpenID Connect en vele OAuth2 authenticatieaanbieders."
@@ -206,29 +239,53 @@ msgstr "Binair"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Bits (Kbps, Mbps, Gbps)"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Opstartstatus"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
msgstr "Bytes (KB/s, MB/s, GB/s)"
msgstr ""
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffers"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Kan herladen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Kan starten"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Kan stoppen"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Annuleren"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Mogelijkheden"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Capaciteit"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Opgelet - potentieel gegevensverlies"
#: src/components/routes/settings/general.tsx
msgid "Celsius (°C)"
msgstr "Celsius (°C)"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Change display units for metrics."
@@ -263,6 +320,14 @@ msgstr "Controleer de logs voor meer details."
msgid "Check your notification service"
msgstr "Controleer je meldingsservice"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Klik op een container om meer informatie te zien."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Klik op een apparaat om meer informatie te bekijken."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Klik op een systeem om meer informatie te bekijken."
@@ -285,7 +350,11 @@ msgstr "Configureer hoe je waarschuwingsmeldingen ontvangt."
msgid "Confirm password"
msgstr "Bevestig wachtwoord"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Conflicten"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "Verbinding is niet actief"
@@ -344,12 +413,31 @@ msgstr "Kopieer de<0>docker-compose.yml</0> inhoud voor de agent hieronder, of r
msgid "Copy YAML"
msgstr "YAML kopiëren"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
msgstr ""
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "CPU-kernen"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "CPU-piek"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "CPU-tijd"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "CPU-tijdverdeling"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Processorgebruik"
@@ -380,10 +468,14 @@ msgstr "Cumulatieve upload"
msgid "Current state"
msgstr "Huidige status"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Cycli"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Dashboard"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Default time period"
@@ -398,6 +490,18 @@ msgstr "Verwijderen"
msgid "Delete fingerprint"
msgstr "Vingerafdruk verwijderen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Beschrijving"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr ""
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Apparaat"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Docker netwerk I/O"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Documentatie"
@@ -498,20 +603,29 @@ msgstr "Voer uw eenmalig wachtwoord in."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Fout"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Overschrijdt {0}{1} in de laatste {2, plural, one {# minuut} other {# minuten}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "Uitvoer hoofd-PID"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Bestaande systemen die niet gedefinieerd zijn in <0>config.yml</0> zullen worden verwijderd. Maak regelmatige backups."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Beëindigd actief"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Exporteren"
@@ -526,7 +640,15 @@ msgstr "Exporteer je huidige systeemconfiguratie."
#: src/components/routes/settings/general.tsx
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
msgstr ""
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Mislukt"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Mislukte kenmerken:"
#: src/lib/api.ts
msgid "Failed to authenticate"
@@ -545,16 +667,28 @@ msgstr "Versturen test notificatie mislukt"
msgid "Failed to update alert"
msgstr "Bijwerken waarschuwing mislukt"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Mislukt: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filter..."
msgstr "Filteren..."
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Fingerprint"
msgstr "Vingerafdruk"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr ""
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Voor <0>{min}</0> {min, plural, one {minuut} other {minuten}}"
@@ -588,10 +722,18 @@ msgstr "GPU-engines"
msgid "GPU Power Draw"
msgstr "GPU stroomverbruik"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "GPU-gebruik"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Raster"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Gezondheid"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Inactief"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Als je het wachtwoord voor je beheerdersaccount bent kwijtgeraakt, kan je het opnieuw instellen met behulp van de volgende opdracht."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr ""
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ongeldig e-mailadres."
@@ -618,7 +765,7 @@ msgstr "Ongeldig e-mailadres."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Language"
@@ -628,6 +775,19 @@ msgstr "Taal"
msgid "Layout"
msgstr "Indeling"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Layoutbreedte"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr ""
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Gemiddelde Belasting"
@@ -649,6 +809,14 @@ msgstr "Gemiddelde Belasting 5m"
msgid "Load Avg"
msgstr "Gem. Belasting"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Laadstatus"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Laden..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Afmelden"
@@ -663,14 +831,19 @@ msgid "Login attempt failed"
msgstr "Aanmelding mislukt"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Logs"
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Zoek je waar je meldingen kunt aanmaken? Klik op de bel <0/> in de systeemtabel."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "Hoofd-PID"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Weergave- en notificatievoorkeuren beheren."
@@ -683,12 +856,24 @@ msgstr "Handmatige installatie-instructies"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Max 1 min"
msgstr ""
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Geheugen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Geheugenlimiet"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Geheugenpiek"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,14 +883,22 @@ msgstr "Geheugengebruik"
msgid "Memory usage of docker containers"
msgstr "Geheugengebruik van docker containers"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr ""
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Naam"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Net"
msgstr "Netwerk"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
@@ -723,14 +916,30 @@ msgstr "Netwerkverkeer van publieke interfaces"
msgid "Network unit"
msgstr "Netwerk eenheid"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Nee"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Geen resultaten gevonden."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Geen resultaten."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Geen S.M.A.R.T. kenmerken beschikbaar voor dit apparaat."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -758,16 +967,21 @@ msgstr "Eenmalig wachtwoord"
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Open menu"
msgstr "Open menu"
msgstr "Menu openen"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Of ga verder met"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Overig"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Overschrijf bestaande waarschuwingen"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Pagina"
@@ -811,6 +1025,15 @@ msgstr "Gepauzeerd"
msgid "Paused ({pausedSystemsLength})"
msgstr "Gepauzeerd ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Gemiddeld gebruik per kern"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Percentage tijd besteed in elke status"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "<0>Configureer een SMTP-server </0> om ervoor te zorgen dat waarschuwingen worden afgeleverd."
@@ -848,6 +1071,11 @@ msgstr "Meld je aan bij je account"
msgid "Port"
msgstr "Poort"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Inschakelen"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "Nauwkeurig gebruik op de opgenomen tijd"
msgid "Preferred Language"
msgstr "Voorkeurstaal"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Proces gestart"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Lezen"
msgid "Received"
msgstr "Ontvangen"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Vernieuwen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Relaties"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Eenmalig wachtwoord aanvragen"
@@ -880,6 +1121,14 @@ msgstr "Eenmalig wachtwoord aanvragen"
msgid "Request OTP"
msgstr "OTP aanvragen"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Vereist door"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Vereist"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Wachtwoord resetten"
@@ -890,10 +1139,19 @@ msgstr "Wachtwoord resetten"
msgid "Resolved"
msgstr "Opgelost"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Herstarten"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Hervatten"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Roteer Token"
@@ -902,6 +1160,18 @@ msgstr "Roteer Token"
msgid "Rows per page"
msgstr "Rijen per pagina"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Runtime-metrieken"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "S.M.A.R.T.-details"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "S.M.A.R.T. Zelf-test"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Bewaar het adres met de enter-toets of komma. Laat leeg om e-mailmeldingen uit te schakelen."
@@ -931,6 +1201,18 @@ msgstr "Zie <0>notificatie-instellingen</0> om te configureren hoe je meldingen
msgid "Sent"
msgstr "Verzonden"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Serienummer"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Servicedetails"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr ""
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Stel percentagedrempels in voor meterkleuren."
@@ -960,13 +1242,21 @@ msgstr "Sorteren op"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Status"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Status"
msgstr ""
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Substatus"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Swap gebruik"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "Systeem"
msgid "System load averages over time"
msgstr "Gemiddelde systeembelasting na verloop van tijd"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Systemd-services"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systemen"
@@ -999,7 +1294,12 @@ msgstr "Systemen kunnen worden beheerd in een <0>config.yml</0> bestand in je da
msgid "Table"
msgstr "Tabel"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Taken"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Temperatuur"
@@ -1019,7 +1319,7 @@ msgstr "Temperatuur van systeem sensoren"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
@@ -1081,6 +1381,11 @@ msgstr "Tokens staan agenten toe om verbinding te maken met en te registreren. V
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Tokens en vingerafdrukken worden gebruikt om WebSocket verbindingen te verifiëren naar de hub."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Totaal"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Totaal ontvangen gegevens per interface"
@@ -1089,6 +1394,19 @@ msgstr "Totaal ontvangen gegevens per interface"
msgid "Total data sent for each interface"
msgstr "Totaal verzonden gegevens per interface"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Totaal: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Geactiveerd door"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr ""
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Triggert wanneer de gemiddelde belasting een drempelwaarde overschrijdt"
@@ -1113,6 +1431,10 @@ msgstr "Triggert wanneer de gecombineerde up/down een drempelwaarde overschrijdt
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Triggert wanneer het CPU-gebruik een drempelwaarde overschrijdt"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Triggert wanneer het GPU-gebruik een drempelwaarde overschrijdt"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Triggert wanneer het geheugengebruik een drempelwaarde overschrijdt"
@@ -1125,6 +1447,14 @@ msgstr "Triggert wanneer de status schakelt tussen up en down"
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Triggert wanneer het gebruik van een schijf een drempelwaarde overschrijdt"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Unit-bestand"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "Universele token"
msgid "Unknown"
msgstr "Onbekend"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Onbeperkt"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "Online"
msgid "Up ({upSystemsLength})"
msgstr "Online ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Bijgewerkt"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Elke 10 minuten bijgewerkt."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Uploaden"
@@ -1162,6 +1506,7 @@ msgstr "Actief"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Gebruik"
@@ -1187,6 +1532,7 @@ msgstr "Waarde"
msgid "View"
msgstr "Weergave"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Meer weergeven"
@@ -1207,6 +1553,10 @@ msgstr "Wachtend op genoeg records om weer te geven"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Wil je ons helpen onze vertalingen nog beter te maken? Bekijk <0>Crowdin</0> voor meer informatie."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Wil"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Waarschuwing (%)"
@@ -1243,6 +1593,13 @@ msgstr "YAML Configuratie"
msgid "YAML Configuration"
msgstr "YAML Configuratie"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Ja"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Je gebruikersinstellingen zijn bijgewerkt."

File diff suppressed because it is too large Load Diff

View File

@@ -8,7 +8,7 @@ msgstr ""
"Language: pl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-09-18 15:36\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Polish\n"
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
@@ -18,27 +18,24 @@ msgstr ""
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# dzień} few {# dni} many {# dni} other {# dni}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {godzinę} few {# godziny} many {# godzin} other {# godziny}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# minuta} few {# minuty} many {# minut} other {# minut}}"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "{0} of {1} row(s) selected."
msgstr "{0} z {1} wybranych wierszy."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dzień} few {{countString} dni} many {{countString} dni} other {{countString} dni}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {godzinę} few {{countString} godziny} many {{countString} godzin} other {{countString} godziny}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuta} few {{countString} minuty} many {{countString} minut} other {{countString} minut}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 godzina"
@@ -48,6 +45,10 @@ msgstr "1 godzina"
msgid "1 min"
msgstr "1 min"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 minuta"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 tydzień"
@@ -85,10 +86,14 @@ msgstr "Akcje"
msgid "Active"
msgstr "Aktywny"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Aktywne alerty"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Stan aktywny"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Dodaj <0>system</0>"
@@ -109,11 +114,19 @@ msgstr "Dodaj URL"
msgid "Adjust display options for charts."
msgstr "Dostosuj opcje wyświetlania wykresów."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Dostosuj szerokość głównego układu"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Po"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agent"
@@ -129,7 +142,15 @@ msgstr "Historia alertów"
msgid "Alerts"
msgstr "Alerty"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Wszystkie kontenery"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -191,6 +212,18 @@ msgstr "Przepustowość"
msgid "Battery"
msgstr "Bateria"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Stało się aktywnym"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Stało się nieaktywnym"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Przed"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel obsługuje OpenID Connect i wielu dostawców uwierzytelniania OAuth2."
@@ -208,6 +241,10 @@ msgstr "Plik binarny"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Bity (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Stan rozruchu"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "Bajty (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "Pamięć podręczna / Bufory"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Może przeładować"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Może uruchomić"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Może zatrzymać"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Anuluj"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Możliwości"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Pojemność"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Uwaga- potencjalna utrata danych."
@@ -263,6 +320,14 @@ msgstr "Sprawdź logi, aby uzyskać więcej informacji."
msgid "Check your notification service"
msgstr "Sprawdź swój serwis powiadomień"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Kliknij na kontener, aby wyświetlić więcej informacji."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Kliknij na urządzenie, aby wyświetlić więcej informacji."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Kliknij na system, aby zobaczyć więcej informacji."
@@ -285,7 +350,11 @@ msgstr "Skonfiguruj sposób otrzymywania powiadomień."
msgid "Confirm password"
msgstr "Potwierdź hasło"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Konflikty"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "Brak połączenia"
@@ -344,12 +413,31 @@ msgstr "Skopiuj poniżej zawartość pliku <0>docker-compose.yml</0> dla agenta
msgid "Copy YAML"
msgstr "Kopiuj YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "Procesor"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "Rdzenie CPU"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "Szczyt CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "Czas CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Podział czasu CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Użycie procesora"
@@ -380,8 +468,12 @@ msgstr "Wysyłanie skumulowane"
msgid "Current state"
msgstr "Aktualny stan"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Cykle"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Panel kontrolny"
@@ -398,6 +490,18 @@ msgstr "Usuń"
msgid "Delete fingerprint"
msgstr "Usuń odcisk palca"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Opis"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Szczegół"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Urządzenie"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "Sieć Docker I/O"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Dokumentacja"
@@ -498,20 +603,29 @@ msgstr "Wprowadź swoje jednorazowe hasło."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Błąd"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Przekracza {0}{1} w ciągu ostatnich {2, plural, one {# minuty} other {# minut}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "Główny PID wykonania"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Istniejące systemy, które nie są zdefiniowane w <0>config.yml</0>, zostaną usunięte. Proszę regularnie tworzyć kopie zapasowe."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Zakończono aktywnie"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Eksport"
@@ -528,6 +642,14 @@ msgstr "Eksportuj aktualną konfigurację systemów."
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Nieudane"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Nieudane atrybuty:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Błąd autoryzacji"
@@ -545,8 +667,16 @@ msgstr "Nie udało się wysłać testowego powiadomienia"
msgid "Failed to update alert"
msgstr "Nie udało się zaktualizować powiadomienia"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Nieudane: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filtruj..."
@@ -555,6 +685,10 @@ msgstr "Filtruj..."
msgid "Fingerprint"
msgstr "Odcisk palca"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Oprogramowanie sprzętowe"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Na <0>{min}</0> {min, plural, one {minutę} other {minut}}"
@@ -588,10 +722,18 @@ msgstr "Silniki GPU"
msgid "GPU Power Draw"
msgstr "Moc GPU"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "Użycie GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Siatka"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Zdrowie"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Bezczynna"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Jeśli utraciłeś hasło do swojego konta administratora, możesz je zresetować, używając następującego polecenia."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Obraz"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Nieprawidłowy adres e-mail."
@@ -628,6 +775,19 @@ msgstr "Język"
msgid "Layout"
msgstr "Układ"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Szerokość układu"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Cykl życia"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "limit"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Średnie obciążenie"
@@ -649,6 +809,14 @@ msgstr "Średnie obciążenie 5 m"
msgid "Load Avg"
msgstr "Śr. obciążenie"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Stan obciążenia"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Ładowanie..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Wyloguj"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Próba logowania nie powiodła się"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Logi"
@@ -671,6 +840,10 @@ msgstr "Logi"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Szukasz, gdzie utworzyć powiadomienia? Kliknij ikonę dzwonka <0/> w tabeli systemów."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "Główny PID"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Zarządzaj preferencjami wyświetlania i powiadomień."
@@ -685,10 +858,22 @@ msgstr "Instrukcja ręcznej konfiguracji"
msgid "Max 1 min"
msgstr "Maks. 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Pamięć"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Limit pamięci"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Szczyt pamięci"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Wykorzystanie pamięci"
msgid "Memory usage of docker containers"
msgstr "Użycie pamięci przez kontenery Docker."
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Model"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Nazwa"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Sieć"
@@ -723,14 +916,30 @@ msgstr "Ruch sieciowy interfejsów publicznych"
msgid "Network unit"
msgstr "Jednostka sieciowa"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Nie"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Brak wyników."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Brak wyników."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Brak dostępnych atrybutów S.M.A.R.T. dla tego urządzenia."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "Otwórz menu"
msgid "Or continue with"
msgstr "Lub kontynuuj z"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Inne"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Nadpisz istniejące alerty"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Strona"
@@ -811,6 +1025,15 @@ msgstr "Wstrzymane"
msgid "Paused ({pausedSystemsLength})"
msgstr "Wstrzymane ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Średnie wykorzystanie na rdzeń"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Procent czasu spędzonego w każdym stanie"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Proszę <0>skonfigurować serwer SMTP</0>, aby zapewnić dostarczanie powiadomień."
@@ -848,6 +1071,11 @@ msgstr "Zaloguj się na swoje konto"
msgid "Port"
msgstr "Port"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Włączony"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "Dokładne wykorzystanie w zarejestrowanym czasie"
msgid "Preferred Language"
msgstr "Preferowany język"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Proces uruchomiony"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Odczyt"
msgid "Received"
msgstr "Otrzymane"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Odśwież"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Relacje"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Zażądaj jednorazowego hasła"
@@ -880,6 +1121,14 @@ msgstr "Zażądaj jednorazowego hasła"
msgid "Request OTP"
msgstr "Zażądaj OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Wymagane przez"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Wymaga"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Resetuj hasło"
@@ -890,10 +1139,19 @@ msgstr "Resetuj hasło"
msgid "Resolved"
msgstr "Rozwiązany"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Ponowne uruchomienia"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Wznów"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Zmień token"
@@ -902,6 +1160,18 @@ msgstr "Zmień token"
msgid "Rows per page"
msgstr "Wiersze na stronę"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Metryki czasu wykonania"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "Szczegóły S.M.A.R.T."
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "Samodiagnostyka S.M.A.R.T."
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Zapisz adres, używając klawisza enter lub przecinka. Pozostaw puste, aby wyłączyć powiadomienia e-mail."
@@ -931,6 +1201,18 @@ msgstr "Zobacz <0>ustawienia powiadomień</0>, aby skonfigurować sposób, w jak
msgid "Sent"
msgstr "Wysłane"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Numer seryjny"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Szczegóły usługi"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Usługi"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Ustaw progi procentowe dla kolorów mierników."
@@ -960,14 +1242,22 @@ msgstr "Sortuj według"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Stan"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Status"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Stan podrzędny"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Pamięć wymiany używana przez system"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Użycie pamięci wymiany"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "System"
msgid "System load averages over time"
msgstr "Średnie obciążenie systemu w czasie"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Usługi systemd"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systemy"
@@ -999,7 +1294,12 @@ msgstr "Systemy mogą być zarządzane w pliku <0>config.yml</0> znajdującym si
msgid "Table"
msgstr "Tabela"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Zadania"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Temperatura"
@@ -1081,6 +1381,11 @@ msgstr "Tokeny umożliwiają agentom łączenie się i rejestrację. Odciski pal
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Tokeny i odciski palców (fingerprinty) służą do uwierzytelniania połączeń WebSocket z hubem."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Łącznie"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Całkowita ilość danych odebranych dla każdego interfejsu"
@@ -1089,6 +1394,19 @@ msgstr "Całkowita ilość danych odebranych dla każdego interfejsu"
msgid "Total data sent for each interface"
msgstr "Całkowita ilość danych wysłanych dla każdego interfejsu"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr "Łącznie: {0}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Wyzwalane przez"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Wyzwalacze"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Uruchamia się, gdy 1-minutowe średnie obciążenie systemu przekroczy ustawiony próg"
@@ -1113,6 +1431,10 @@ msgstr "Wyzwalane, gdy łączna wartość w górę/w dół przekroczy próg"
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Wyzwalane, gdy użycie procesora przekracza próg"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Wyzwalane, gdy użycie GPU przekroczy próg"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Wyzwalane, wykorzystanie pamięci przekroczy ustalony próg."
@@ -1125,6 +1447,14 @@ msgstr "Wyzwalane, gdy status przełącza się między stanem aktywnym a nieakty
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Wyzwalane, gdy wykorzystanie któregokolwiek dysku przekroczy ustalony próg"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Typ"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Plik jednostki"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,6 +1470,11 @@ msgstr "Uniwersalny token"
msgid "Unknown"
msgstr "Nieznana"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Bez limitu"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
@@ -1150,6 +1485,15 @@ msgstr "Działa"
msgid "Up ({upSystemsLength})"
msgstr "Działa ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Zaktualizowano"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Aktualizowane co 10 minut."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Wysyłanie"
@@ -1162,6 +1506,7 @@ msgstr "Czas pracy"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Wykorzystanie"
@@ -1187,6 +1532,7 @@ msgstr "Wartość"
msgid "View"
msgstr "Widok"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Zobacz więcej"
@@ -1207,6 +1553,10 @@ msgstr "Oczekiwanie na wystarczającą liczbę rekordów do wyświetlenia"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Chcesz pomóc nam uczynić nasze tłumaczenia jeszcze lepszymi? Sprawdź <0>Crowdin</0> po więcej szczegółów."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Wymaga"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Ostrzeżenie (%)"
@@ -1243,6 +1593,13 @@ msgstr "Konf. YAML"
msgid "YAML Configuration"
msgstr "Konfiguracja YAML"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Tak"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Twoje ustawienia użytkownika zostały zaktualizowane."

View File

@@ -8,30 +8,15 @@ msgstr ""
"Language: pt\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-08-28 23:21\n"
"PO-Revision-Date: 2025-11-14 22:51\n"
"Last-Translator: \n"
"Language-Team: Portuguese\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: pt-PT\n"
"X-Crowdin-File: /main/beszel/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 16\n"
#. placeholder {0}: Math.trunc(system.info?.u / 86400)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# day} other {# days}}"
msgstr "{0, plural, one {# dia} other {# dias}}"
#. placeholder {0}: Math.trunc(system.info.u / 3600)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# hour} other {# hours}}"
msgstr "{0, plural, one {# hora} other {# horas}}"
#. placeholder {0}: Math.trunc(system.info.u / 60)
#: src/components/routes/system.tsx
msgid "{0, plural, one {# minute} few {# minutes} many {# minutes} other {# minutes}}"
msgstr "{0, plural, one {# minuto} other {# minutos}}"
"X-Crowdin-File: /main/internal/site/src/locales/en/en.po\n"
"X-Crowdin-File-ID: 32\n"
#. placeholder {0}: table.getFilteredSelectedRowModel().rows.length
#. placeholder {1}: table.getFilteredRowModel().rows.length
@@ -39,6 +24,18 @@ msgstr "{0, plural, one {# minuto} other {# minutos}}"
msgid "{0} of {1} row(s) selected."
msgstr "{0} de {1} linha(s) selecionada(s)."
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} day} other {{countString} days}}"
msgstr "{count, plural, one {{countString} dia} other {{countString} dias}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} hour} other {{countString} hours}}"
msgstr "{count, plural, one {{countString} hora} other {{countString} horas}}"
#: src/lib/utils.ts
msgid "{count, plural, one {{countString} minute} few {{countString} minutes} many {{countString} minutes} other {{countString} minutes}}"
msgstr "{count, plural, one {{countString} minuto} other {{countString} minutos}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hora"
@@ -48,6 +45,10 @@ msgstr "1 hora"
msgid "1 min"
msgstr "1 min"
#: src/lib/utils.ts
msgid "1 minute"
msgstr "1 minuto"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 semana"
@@ -85,10 +86,14 @@ msgstr "Ações"
msgid "Active"
msgstr "Ativo"
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Active Alerts"
msgstr "Alertas Ativos"
#: src/components/systemd-table/systemd-table.tsx
msgid "Active state"
msgstr "Estado ativo"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Adicionar <0>Sistema</0>"
@@ -109,11 +114,19 @@ msgstr "Adicionar URL"
msgid "Adjust display options for charts."
msgstr "Ajustar opções de exibição para gráficos."
#: src/components/routes/settings/general.tsx
msgid "Adjust the width of the main layout"
msgstr "Ajustar a largura do layout principal"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systemd-table/systemd-table.tsx
msgid "After"
msgstr "Depois"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Agent"
msgstr "Agente"
@@ -129,7 +142,15 @@ msgstr "Histórico de alertas"
msgid "Alerts"
msgstr "Alertas"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/containers.tsx
msgid "All Containers"
msgstr "Todos os Contêineres"
#: src/components/alerts/alerts-sheet.tsx
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "All Systems"
@@ -180,7 +201,7 @@ msgstr "Utilização média dos motores GPU"
#: src/components/command-palette.tsx
#: src/components/navbar.tsx
msgid "Backups"
msgstr "Backups"
msgstr "Cópias de segurança"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
@@ -191,6 +212,18 @@ msgstr "Largura de Banda"
msgid "Battery"
msgstr "Bateria"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became active"
msgstr "Tornou-se ativo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Became inactive"
msgstr "Tornou-se inativo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Before"
msgstr "Antes"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel suporta OpenID Connect e muitos provedores de autenticação OAuth2."
@@ -208,6 +241,10 @@ msgstr "Binário"
msgid "Bits (Kbps, Mbps, Gbps)"
msgstr "Bits (Kbps, Mbps, Gbps)"
#: src/components/systemd-table/systemd-table.tsx
msgid "Boot state"
msgstr "Estado de inicialização"
#: src/components/routes/settings/general.tsx
#: src/components/routes/settings/general.tsx
msgid "Bytes (KB/s, MB/s, GB/s)"
@@ -217,11 +254,31 @@ msgstr "Bytes (KB/s, MB/s, GB/s)"
msgid "Cache / Buffers"
msgstr "Cache / Buffers"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can reload"
msgstr "Pode recarregar"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can start"
msgstr "Pode iniciar"
#: src/components/systemd-table/systemd-table.tsx
msgid "Can stop"
msgstr "Pode parar"
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Cancel"
msgstr "Cancelar"
#: src/components/systemd-table/systemd-table.tsx
msgid "Capabilities"
msgstr "Capacidades"
#: src/components/routes/system/smart-table.tsx
msgid "Capacity"
msgstr "Capacidade"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Cuidado - possível perda de dados"
@@ -263,6 +320,14 @@ msgstr "Verifique os logs para mais detalhes."
msgid "Check your notification service"
msgstr "Verifique seu serviço de notificação"
#: src/components/containers-table/containers-table.tsx
msgid "Click on a container to view more information."
msgstr "Clique num contentor para ver mais informações."
#: src/components/routes/system/smart-table.tsx
msgid "Click on a device to view more information."
msgstr "Clique em um dispositivo para ver mais informações."
#: src/components/systems-table/systems-table.tsx
msgid "Click on a system to view more information."
msgstr "Clique em um sistema para ver mais informações."
@@ -285,7 +350,11 @@ msgstr "Configure como você recebe notificações de alerta."
msgid "Confirm password"
msgstr "Confirmar senha"
#: src/components/routes/home.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Conflicts"
msgstr "Conflitos"
#: src/components/active-alerts.tsx
msgid "Connection is down"
msgstr "A conexão está inativa"
@@ -344,12 +413,31 @@ msgstr "Copie o conteúdo do <0>docker-compose.yml</0> do agente abaixo, ou regi
msgid "Copy YAML"
msgstr "Copiar YAML"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "CPU"
msgstr "CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Cores"
msgstr "Núcleos de CPU"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "CPU Peak"
msgstr "Pico de CPU"
#: src/components/systemd-table/systemd-table.tsx
msgid "CPU time"
msgstr "Tempo de CPU"
#: src/components/routes/system/cpu-sheet.tsx
msgid "CPU Time Breakdown"
msgstr "Distribuição do Tempo de CPU"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
#: src/lib/alerts.ts
msgid "CPU Usage"
msgstr "Uso de CPU"
@@ -380,8 +468,12 @@ msgstr "Upload cumulativo"
msgid "Current state"
msgstr "Estado atual"
#. Power Cycles
#: src/components/routes/system/smart-table.tsx
msgid "Cycles"
msgstr "Ciclos"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Painel"
@@ -398,6 +490,18 @@ msgstr "Excluir"
msgid "Delete fingerprint"
msgstr "Excluir impressão digital"
#: src/components/systemd-table/systemd-table.tsx
msgid "Description"
msgstr "Descrição"
#: src/components/containers-table/containers-table.tsx
msgid "Detail"
msgstr "Detalhe"
#: src/components/routes/system/smart-table.tsx
msgid "Device"
msgstr "Dispositivo"
#. Context: Battery state
#: src/lib/i18n.ts
msgid "Discharging"
@@ -438,6 +542,7 @@ msgid "Docker Network I/O"
msgstr "E/S de Rede do Docker"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Documentation"
msgstr "Documentação"
@@ -447,7 +552,7 @@ msgstr "Documentação"
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
msgid "Down"
msgstr "Desligado"
msgstr "Desligado"
#: src/components/systems-table/systems-table.tsx
msgid "Down ({downSystemsLength})"
@@ -498,20 +603,29 @@ msgstr "Insira a sua senha de uso único."
#: src/components/routes/settings/config-yaml.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Error"
msgstr "Erro"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
#: src/components/active-alerts.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Excede {0}{1} no último {2, plural, one {# minuto} other {# minutos}}"
#: src/components/systemd-table/systemd-table.tsx
msgid "Exec main PID"
msgstr "PID principal de execução"
#: src/components/routes/settings/config-yaml.tsx
msgid "Existing systems not defined in <0>config.yml</0> will be deleted. Please make regular backups."
msgstr "Sistemas existentes não definidos em <0>config.yml</0> serão excluídos. Faça backups regulares."
#: src/components/systemd-table/systemd-table.tsx
msgid "Exited active"
msgstr "Saiu ativo"
#: src/components/routes/settings/alerts-history-data-table.tsx
msgid "Export"
msgstr "Exportar"
@@ -528,6 +642,14 @@ msgstr "Exporte a configuração atual dos seus sistemas."
msgid "Fahrenheit (°F)"
msgstr "Fahrenheit (°F)"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Failed"
msgstr "Falhou"
#: src/components/routes/system/smart-table.tsx
msgid "Failed Attributes:"
msgstr "Atributos com Falha:"
#: src/lib/api.ts
msgid "Failed to authenticate"
msgstr "Falha na autenticação"
@@ -545,8 +667,16 @@ msgstr "Falha ao enviar notificação de teste"
msgid "Failed to update alert"
msgstr "Falha ao atualizar alerta"
#. placeholder {0}: statusTotals[ServiceStatus.Failed]
#: src/components/systemd-table/systemd-table.tsx
msgid "Failed: {0}"
msgstr "Falhou: {0}"
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Filter..."
msgstr "Filtrar..."
@@ -555,6 +685,10 @@ msgstr "Filtrar..."
msgid "Fingerprint"
msgstr "Impressão digital"
#: src/components/routes/system/smart-table.tsx
msgid "Firmware"
msgstr "Firmware"
#: src/components/alerts/alerts-sheet.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Por <0>{min}</0> {min, plural, one {minuto} other {minutos}}"
@@ -588,10 +722,18 @@ msgstr "Motores GPU"
msgid "GPU Power Draw"
msgstr "Consumo de Energia da GPU"
#: src/lib/alerts.ts
msgid "GPU Usage"
msgstr "Uso de GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Grade"
#: src/components/containers-table/containers-table-columns.tsx
msgid "Health"
msgstr "Saúde"
#: src/components/add-system.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
msgctxt "Button to copy install command"
@@ -611,6 +753,11 @@ msgstr "Inativa"
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Se você perdeu a senha da sua conta de administrador, pode redefini-la usando o seguinte comando."
#: src/components/containers-table/containers-table-columns.tsx
msgctxt "Docker image"
msgid "Image"
msgstr "Imagem"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Endereço de email inválido."
@@ -628,6 +775,19 @@ msgstr "Idioma"
msgid "Layout"
msgstr "Aspeto"
#: src/components/routes/settings/general.tsx
msgid "Layout width"
msgstr "Largura do layout"
#: src/components/systemd-table/systemd-table.tsx
msgid "Lifecycle"
msgstr "Ciclo de vida"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "limit"
msgstr "limite"
#: src/components/routes/system.tsx
msgid "Load Average"
msgstr "Carga Média"
@@ -649,6 +809,14 @@ msgstr "Carga média 5m"
msgid "Load Avg"
msgstr "Carga Média"
#: src/components/systemd-table/systemd-table.tsx
msgid "Load state"
msgstr "Estado de carga"
#: src/components/systemd-table/systemd-table.tsx
msgid "Loading..."
msgstr "Carregando..."
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Sair"
@@ -663,6 +831,7 @@ msgid "Login attempt failed"
msgstr "Tentativa de login falhou"
#: src/components/command-palette.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/navbar.tsx
msgid "Logs"
msgstr "Logs"
@@ -671,6 +840,10 @@ msgstr "Logs"
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Procurando onde criar alertas? Clique nos ícones de sino <0/> na tabela de sistemas."
#: src/components/systemd-table/systemd-table.tsx
msgid "Main PID"
msgstr "PID principal"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Gerenciar preferências de exibição e notificação."
@@ -685,10 +858,22 @@ msgstr "Instruções de configuração manual"
msgid "Max 1 min"
msgstr "Máx 1 min"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Memory"
msgstr "Memória"
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory limit"
msgstr "Limite de memória"
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Memory Peak"
msgstr "Pico de memória"
#: src/components/routes/system.tsx
#: src/lib/alerts.ts
msgid "Memory Usage"
@@ -698,11 +883,19 @@ msgstr "Uso de Memória"
msgid "Memory usage of docker containers"
msgstr "Uso de memória dos contêineres Docker"
#: src/components/routes/system/smart-table.tsx
msgid "Model"
msgstr "Modelo"
#: src/components/add-system.tsx
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Name"
msgstr "Nome"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Net"
msgstr "Rede"
@@ -723,14 +916,30 @@ msgstr "Tráfego de rede das interfaces públicas"
msgid "Network unit"
msgstr "Unidade de rede"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No"
msgstr "Não"
#: src/components/command-palette.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results found."
msgstr "Nenhum resultado encontrado."
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
#: src/components/routes/settings/alerts-history-data-table.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "No results."
msgstr "Sem resultados."
#: src/components/routes/system/smart-table.tsx
msgid "No S.M.A.R.T. attributes available for this device."
msgstr "Nenhum atributo S.M.A.R.T. disponível para este dispositivo."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
@@ -764,10 +973,15 @@ msgstr "Abrir menu"
msgid "Or continue with"
msgstr "Ou continue com"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Other"
msgstr "Outro"
#: src/components/alerts/alerts-sheet.tsx
msgid "Overwrite existing alerts"
msgstr "Sobrescrever alertas existentes"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Página"
@@ -811,6 +1025,15 @@ msgstr "Pausado"
msgid "Paused ({pausedSystemsLength})"
msgstr "Pausado ({pausedSystemsLength})"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Per-core average utilization"
msgstr "Utilização média por núcleo"
#: src/components/routes/system/cpu-sheet.tsx
msgid "Percentage of time spent in each state"
msgstr "Percentagem de tempo gasto em cada estado"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Por favor, <0>configure um servidor SMTP</0> para garantir que os alertas sejam entregues."
@@ -848,6 +1071,11 @@ msgstr "Por favor, entre na sua conta"
msgid "Port"
msgstr "Porta"
#. Power On Time
#: src/components/routes/system/smart-table.tsx
msgid "Power On"
msgstr "Ligado"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
@@ -857,6 +1085,10 @@ msgstr "Utilização precisa no momento registrado"
msgid "Preferred Language"
msgstr "Idioma Preferido"
#: src/components/systemd-table/systemd-table.tsx
msgid "Process started"
msgstr "Processo iniciado"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
@@ -872,6 +1104,15 @@ msgstr "Ler"
msgid "Received"
msgstr "Recebido"
#: src/components/containers-table/containers-table.tsx
#: src/components/containers-table/containers-table.tsx
msgid "Refresh"
msgstr "Atualizar"
#: src/components/systemd-table/systemd-table.tsx
msgid "Relationships"
msgstr "Relacionamentos"
#: src/components/login/login.tsx
msgid "Request a one-time password"
msgstr "Solicitar senha de uso único"
@@ -880,6 +1121,14 @@ msgstr "Solicitar senha de uso único"
msgid "Request OTP"
msgstr "Solicitar OTP"
#: src/components/systemd-table/systemd-table.tsx
msgid "Required by"
msgstr "Requerido por"
#: src/components/systemd-table/systemd-table.tsx
msgid "Requires"
msgstr "Requer"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Redefinir Senha"
@@ -890,10 +1139,19 @@ msgstr "Redefinir Senha"
msgid "Resolved"
msgstr "Resolvido"
#: src/components/systemd-table/systemd-table.tsx
msgid "Restarts"
msgstr "Reinícios"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Resume"
msgstr "Retomar"
#: src/components/systems-table/systems-table-columns.tsx
msgctxt "Root disk label"
msgid "Root"
msgstr ""
#: src/components/routes/settings/tokens-fingerprints.tsx
msgid "Rotate token"
msgstr "Rotacionar token"
@@ -902,6 +1160,18 @@ msgstr "Rotacionar token"
msgid "Rows per page"
msgstr "Linhas por página"
#: src/components/systemd-table/systemd-table.tsx
msgid "Runtime Metrics"
msgstr "Métricas de tempo de execução"
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Details"
msgstr "Detalhes S.M.A.R.T."
#: src/components/routes/system/smart-table.tsx
msgid "S.M.A.R.T. Self-Test"
msgstr "Auto-teste S.M.A.R.T."
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Salve o endereço usando a tecla enter ou vírgula. Deixe em branco para desativar notificações por email."
@@ -931,6 +1201,18 @@ msgstr "Veja <0>configurações de notificação</0> para configurar como você
msgid "Sent"
msgstr "Enviado"
#: src/components/routes/system/smart-table.tsx
msgid "Serial Number"
msgstr "Número de Série"
#: src/components/systemd-table/systemd-table.tsx
msgid "Service Details"
msgstr "Detalhes do serviço"
#: src/components/systems-table/systems-table-columns.tsx
msgid "Services"
msgstr "Serviços"
#: src/components/routes/settings/general.tsx
msgid "Set percentage thresholds for meter colors."
msgstr "Defina os limiares de porcentagem para as cores do medidor."
@@ -960,13 +1242,21 @@ msgstr "Ordenar Por"
#. Context: alert state (active or resolved)
#: src/components/alerts-history-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "State"
msgstr "Estado"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/system/smart-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systems-table/systems-table.tsx
#: src/lib/alerts.ts
msgid "Status"
msgstr "Status"
msgstr "Estado"
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Sub State"
msgstr "Subestado"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
@@ -977,6 +1267,7 @@ msgid "Swap Usage"
msgstr "Uso de Swap"
#: src/components/alerts-history-columns.tsx
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/routes/settings/tokens-fingerprints.tsx
#: src/components/systems-table/systems-table-columns.tsx
#: src/lib/alerts.ts
@@ -987,6 +1278,10 @@ msgstr "Sistema"
msgid "System load averages over time"
msgstr "Médias de carga do sistema ao longo do tempo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Systemd Services"
msgstr "Serviços Systemd"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemas"
@@ -999,7 +1294,12 @@ msgstr "Os sistemas podem ser gerenciados em um arquivo <0>config.yml</0> dentro
msgid "Table"
msgstr "Tabela"
#: src/components/systemd-table/systemd-table.tsx
msgid "Tasks"
msgstr "Tarefas"
#. Temperature label in systems table
#: src/components/routes/system/smart-table.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Temp"
msgstr "Temp"
@@ -1081,6 +1381,11 @@ msgstr "Os tokens permitem que os agentes se conectem e registrem. As impressõe
msgid "Tokens and fingerprints are used to authenticate WebSocket connections to the hub."
msgstr "Tokens e impressões digitais são usados para autenticar conexões WebSocket ao hub."
#: src/components/ui/chart.tsx
#: src/components/ui/chart.tsx
msgid "Total"
msgstr "Total"
#: src/components/routes/system/network-sheet.tsx
msgid "Total data received for each interface"
msgstr "Dados totais recebidos para cada interface"
@@ -1089,6 +1394,19 @@ msgstr "Dados totais recebidos para cada interface"
msgid "Total data sent for each interface"
msgstr "Dados totais enviados para cada interface"
#. placeholder {0}: data.length
#: src/components/systemd-table/systemd-table.tsx
msgid "Total: {0}"
msgstr ""
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggered by"
msgstr "Acionado por"
#: src/components/systemd-table/systemd-table.tsx
msgid "Triggers"
msgstr "Acionadores"
#: src/lib/alerts.ts
msgid "Triggers when 1 minute load average exceeds a threshold"
msgstr "Dispara quando a média de carga de 1 minuto excede um limite"
@@ -1113,6 +1431,10 @@ msgstr "Dispara quando a soma de subida/descida excede um limite"
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Dispara quando o uso de CPU excede um limite"
#: src/lib/alerts.ts
msgid "Triggers when GPU usage exceeds a threshold"
msgstr "Dispara quando o uso de GPU excede um limite"
#: src/lib/alerts.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Dispara quando o uso de memória excede um limite"
@@ -1125,6 +1447,14 @@ msgstr "Dispara quando o status alterna entre ativo e inativo"
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Dispara quando o uso de qualquer disco excede um limite"
#: src/components/routes/system/smart-table.tsx
msgid "Type"
msgstr "Tipo"
#: src/components/systemd-table/systemd-table.tsx
msgid "Unit file"
msgstr "Arquivo de unidade"
#. Temperature / network units
#: src/components/routes/settings/general.tsx
msgid "Unit preferences"
@@ -1140,16 +1470,30 @@ msgstr "Token universal"
msgid "Unknown"
msgstr "Desconhecida"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Unlimited"
msgstr "Ilimitado"
#. Context: System is up
#: src/components/routes/system.tsx
#: src/components/systems-table/systems-table-columns.tsx
msgid "Up"
msgstr "Ligado"
msgstr "Ligado"
#: src/components/systems-table/systems-table.tsx
msgid "Up ({upSystemsLength})"
msgstr "Ativo ({upSystemsLength})"
#: src/components/containers-table/containers-table-columns.tsx
#: src/components/systemd-table/systemd-table-columns.tsx
msgid "Updated"
msgstr "Atualizado"
#: src/components/systemd-table/systemd-table.tsx
msgid "Updated every 10 minutes."
msgstr "Atualizado a cada 10 minutos."
#: src/components/routes/system/network-sheet.tsx
msgid "Upload"
msgstr "Carregar"
@@ -1162,6 +1506,7 @@ msgstr "Tempo de Atividade"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/routes/system/cpu-sheet.tsx
msgid "Usage"
msgstr "Uso"
@@ -1187,6 +1532,7 @@ msgstr "Valor"
msgid "View"
msgstr "Visual"
#: src/components/routes/system/cpu-sheet.tsx
#: src/components/routes/system/network-sheet.tsx
msgid "View more"
msgstr "Ver mais"
@@ -1207,6 +1553,10 @@ msgstr "Aguardando registros suficientes para exibir"
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Quer nos ajudar a melhorar ainda mais nossas traduções? Confira <0>Crowdin</0> para mais detalhes."
#: src/components/systemd-table/systemd-table.tsx
msgid "Wants"
msgstr "Deseja"
#: src/components/routes/settings/general.tsx
msgid "Warning (%)"
msgstr "Aviso (%)"
@@ -1243,6 +1593,13 @@ msgstr "Configuração YAML"
msgid "YAML Configuration"
msgstr "Configuração YAML"
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
#: src/components/systemd-table/systemd-table.tsx
msgid "Yes"
msgstr "Sim"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "As configurações do seu usuário foram atualizadas."

File diff suppressed because it is too large Load Diff

Some files were not shown because too many files have changed in this diff Show More