Compare commits

...

797 Commits

Author SHA1 Message Date
hank
406b74d70f New translations en.po (Norwegian) 2026-01-17 07:51:47 -05:00
hank
35e254f84b New translations en.po (Russian) 2026-01-17 02:47:22 -05:00
hank
c96d9d9cdf New translations en.po (Polish) 2026-01-15 10:56:08 -05:00
hank
4acb763ac5 New translations en.po (Polish) 2026-01-15 09:49:55 -05:00
hank
ed027c9c37 New translations en.po (French) 2026-01-13 17:24:56 -05:00
hank
c4e847fd1a New translations en.po (Indonesian) 2026-01-12 16:37:34 -05:00
hank
6731b3b9f1 New translations en.po (Chinese Traditional, Hong Kong) 2026-01-11 17:21:15 -05:00
hank
2229ff8a72 New translations en.po (Croatian) 2026-01-11 17:21:14 -05:00
hank
f2579602b0 New translations en.po (Thai) 2026-01-11 17:21:13 -05:00
hank
f3b8be37fc New translations en.po (Persian) 2026-01-11 17:21:12 -05:00
hank
87a802e85f New translations en.po (Vietnamese) 2026-01-11 17:21:11 -05:00
hank
088dbb9933 New translations en.po (Chinese Simplified) 2026-01-11 17:21:10 -05:00
hank
442c1b2922 New translations en.po (Ukrainian) 2026-01-11 17:21:09 -05:00
hank
b443c8d680 New translations en.po (Turkish) 2026-01-11 17:21:08 -05:00
hank
552eaf4240 New translations en.po (Swedish) 2026-01-11 17:21:07 -05:00
hank
125f63603d New translations en.po (Serbian (Cyrillic)) 2026-01-11 17:21:06 -05:00
hank
69e1c3608c New translations en.po (Slovenian) 2026-01-11 17:21:05 -05:00
hank
e4c90c7855 New translations en.po (Russian) 2026-01-11 17:21:04 -05:00
hank
03e2de874a New translations en.po (Portuguese) 2026-01-11 17:21:03 -05:00
hank
9a0b666acc New translations en.po (Norwegian) 2026-01-11 17:21:02 -05:00
hank
de2f96ef2e New translations en.po (Korean) 2026-01-11 17:21:01 -05:00
hank
931eec842f New translations en.po (Japanese) 2026-01-11 17:21:00 -05:00
hank
f52cd6514e New translations en.po (Italian) 2026-01-11 17:20:59 -05:00
hank
b38d424770 New translations en.po (Hungarian) 2026-01-11 17:20:58 -05:00
hank
bd31c8f232 New translations en.po (Hebrew) 2026-01-11 17:20:57 -05:00
hank
254e210d97 New translations en.po (German) 2026-01-11 17:20:56 -05:00
hank
80cb847771 New translations en.po (Czech) 2026-01-11 17:20:55 -05:00
hank
e09e906248 New translations en.po (Bulgarian) 2026-01-11 17:20:54 -05:00
hank
7845d90ce7 New translations en.po (Chinese Traditional) 2026-01-11 17:20:53 -05:00
hank
5989f18cfb New translations en.po (Indonesian) 2026-01-11 17:20:52 -05:00
hank
5b675bddf8 New translations en.po (Polish) 2026-01-11 17:20:52 -05:00
hank
ad97cce189 New translations en.po (Dutch) 2026-01-11 17:20:51 -05:00
hank
789c9f166b New translations en.po (Danish) 2026-01-11 17:20:50 -05:00
hank
40c8696c0f New translations en.po (Arabic) 2026-01-11 17:20:48 -05:00
hank
59cd27a9ec New translations en.po (Spanish) 2026-01-11 17:20:48 -05:00
hank
a59a2bb408 New translations en.po (French) 2026-01-11 17:20:47 -05:00
hank
1cabcc9ecb New translations en.po (Romanian) 2026-01-11 17:20:46 -05:00
hank
7f5a2be7fa New translations en.po (Chinese Traditional, Hong Kong) 2026-01-11 13:53:42 -05:00
hank
ee34919525 New translations en.po (Croatian) 2026-01-11 13:53:41 -05:00
hank
d58c4bfbf3 New translations en.po (Thai) 2026-01-11 13:53:40 -05:00
hank
c811cd2fd6 New translations en.po (Persian) 2026-01-11 13:53:39 -05:00
hank
8cf2678c9a New translations en.po (Vietnamese) 2026-01-11 13:53:38 -05:00
hank
5775e2a7e0 New translations en.po (Chinese Simplified) 2026-01-11 13:53:37 -05:00
hank
cfc9ac437f New translations en.po (Ukrainian) 2026-01-11 13:53:36 -05:00
hank
813c622ebf New translations en.po (Turkish) 2026-01-11 13:53:35 -05:00
hank
9048d645d0 New translations en.po (Swedish) 2026-01-11 13:53:34 -05:00
hank
2e247312aa New translations en.po (Serbian (Cyrillic)) 2026-01-11 13:53:33 -05:00
hank
9e1932394b New translations en.po (Slovenian) 2026-01-11 13:53:32 -05:00
hank
99f156d1d7 New translations en.po (Russian) 2026-01-11 13:53:31 -05:00
hank
10bda5d42d New translations en.po (Portuguese) 2026-01-11 13:53:30 -05:00
hank
5ec86f57b8 New translations en.po (Norwegian) 2026-01-11 13:53:29 -05:00
hank
51fa959ccf New translations en.po (Korean) 2026-01-11 13:53:28 -05:00
hank
9e50162063 New translations en.po (Japanese) 2026-01-11 13:53:27 -05:00
hank
6d13acd294 New translations en.po (Italian) 2026-01-11 13:53:26 -05:00
hank
3570ee8313 New translations en.po (Hungarian) 2026-01-11 13:53:25 -05:00
hank
c9e67ae7b8 New translations en.po (Hebrew) 2026-01-11 13:53:24 -05:00
hank
832e08ac3b New translations en.po (German) 2026-01-11 13:53:23 -05:00
hank
934e877616 New translations en.po (Czech) 2026-01-11 13:53:22 -05:00
hank
e8a8bab2db New translations en.po (Bulgarian) 2026-01-11 13:53:21 -05:00
hank
69645f33d5 New translations en.po (Chinese Traditional) 2026-01-11 13:53:20 -05:00
hank
8af100796a New translations en.po (Indonesian) 2026-01-11 13:53:19 -05:00
hank
eee6698e60 New translations en.po (Polish) 2026-01-11 13:53:18 -05:00
hank
fed9084e07 New translations en.po (Dutch) 2026-01-11 13:53:16 -05:00
hank
56ce1309c9 New translations en.po (Danish) 2026-01-11 13:53:15 -05:00
hank
ce7f096789 New translations en.po (Arabic) 2026-01-11 13:53:14 -05:00
hank
2656f6581a New translations en.po (Spanish) 2026-01-11 13:53:13 -05:00
hank
23055c2255 New translations en.po (French) 2026-01-11 13:53:12 -05:00
hank
e493b72c0f New translations en.po (Romanian) 2026-01-11 13:53:11 -05:00
hank
4b1c20820e New translations en.po (Chinese Traditional) 2026-01-10 12:34:34 -05:00
hank
7c74922760 New translations en.po (French) 2026-01-09 16:08:47 -05:00
hank
19fcce8952 New translations en.po (French) 2025-12-25 17:44:44 -05:00
hank
3d74c23098 New translations en.po (Arabic) 2025-12-25 14:15:27 -05:00
hank
d433962a41 New translations en.po (Indonesian) 2025-12-25 05:45:43 -05:00
hank
c1d94ac29f New translations en.po (Indonesian) 2025-12-25 04:22:51 -05:00
hank
9f4e56c9cf New translations en.po (Romanian) 2025-12-19 06:58:15 -05:00
hank
a3ebfbf37f New translations en.po (Romanian) 2025-12-19 05:55:07 -05:00
hank
cb90e96ae5 New translations en.po (Danish) 2025-12-19 05:55:06 -05:00
hank
25ed5d0d66 New translations en.po (Danish) 2025-12-19 03:46:19 -05:00
hank
3e5b91056e New translations en.po (Polish) 2025-12-18 14:21:36 -05:00
hank
dc79f24c06 New translations en.po (Thai) 2025-12-17 13:16:58 -05:00
hank
f9f5258b22 New translations en.po (Dutch) 2025-12-17 07:02:37 -05:00
hank
0b611cda57 New translations en.po (Dutch) 2025-12-17 05:18:18 -05:00
hank
74635e5763 New translations en.po (Spanish) 2025-12-14 04:39:12 -05:00
hank
8ce9088d9d New translations en.po (Serbian (Cyrillic)) 2025-12-08 13:22:54 -05:00
hank
b3331c00f8 New translations en.po (Chinese Traditional) 2025-12-08 10:28:57 -05:00
hank
d0559065c1 New translations en.po (Chinese Traditional) 2025-12-08 08:54:57 -05:00
hank
78f6006bdc New translations en.po (Serbian (Cyrillic)) 2025-12-05 15:24:47 -05:00
hank
436b42f4d1 New translations en.po (Swedish) 2025-12-05 15:24:42 -05:00
hank
16f7b30624 New translations en.po (Slovenian) 2025-12-05 15:24:41 -05:00
hank
9249256c9f New translations en.po (Portuguese) 2025-12-05 15:24:40 -05:00
hank
34163b8595 New translations en.po (Norwegian) 2025-12-05 15:24:38 -05:00
hank
a4731f9179 New translations en.po (German) 2025-12-05 15:24:34 -05:00
hank
9c74eccaf0 New translations en.po (Danish) 2025-12-05 15:24:33 -05:00
hank
4768adf440 New translations en.po (Czech) 2025-12-05 15:24:32 -05:00
hank
11ffb422e8 New translations en.po (French) 2025-12-05 15:24:29 -05:00
hank
bab02ad738 New translations en.po (Spanish) 2025-12-05 15:24:28 -05:00
hank
61faee2450 New translations en.po (Serbian (Cyrillic)) 2025-12-04 15:03:35 -05:00
hank
d0be54f47c New translations en.po (Chinese Traditional, Hong Kong) 2025-12-02 18:18:21 -05:00
hank
cc2be97055 New translations en.po (Croatian) 2025-12-02 18:18:20 -05:00
hank
2fc1565b75 New translations en.po (Persian) 2025-12-02 18:18:19 -05:00
hank
f5421eff3c New translations en.po (Indonesian) 2025-12-02 18:18:18 -05:00
hank
fc01ca1cad New translations en.po (Vietnamese) 2025-12-02 18:18:17 -05:00
hank
e2923126d2 New translations en.po (Chinese Simplified) 2025-12-02 18:18:16 -05:00
hank
972ce62ff5 New translations en.po (Ukrainian) 2025-12-02 18:18:15 -05:00
hank
05d9297ca3 New translations en.po (Turkish) 2025-12-02 18:18:14 -05:00
hank
ffc35b3c51 New translations en.po (Swedish) 2025-12-02 18:18:13 -05:00
hank
a547de8bf0 New translations en.po (Slovenian) 2025-12-02 18:18:12 -05:00
hank
d8d1a89256 New translations en.po (Portuguese) 2025-12-02 18:18:11 -05:00
hank
c29ba1c353 New translations en.po (Polish) 2025-12-02 18:18:10 -05:00
hank
474d860929 New translations en.po (Norwegian) 2025-12-02 18:18:09 -05:00
hank
fb57a57e77 New translations en.po (Dutch) 2025-12-02 18:18:08 -05:00
hank
02e5a8e9fc New translations en.po (Korean) 2025-12-02 18:18:07 -05:00
hank
c0f6f64aa7 New translations en.po (Japanese) 2025-12-02 18:18:06 -05:00
hank
3077ed045d New translations en.po (Hungarian) 2025-12-02 18:18:05 -05:00
hank
f7b62a2868 New translations en.po (Hebrew) 2025-12-02 18:18:04 -05:00
hank
5daa0d3576 New translations en.po (German) 2025-12-02 18:18:03 -05:00
hank
a6b9fa2aa9 New translations en.po (Danish) 2025-12-02 18:18:02 -05:00
hank
5195e6d675 New translations en.po (Czech) 2025-12-02 18:18:01 -05:00
hank
93e71dcf30 New translations en.po (Bulgarian) 2025-12-02 18:18:00 -05:00
hank
826227f3af New translations en.po (Arabic) 2025-12-02 18:17:59 -05:00
hank
cfe8645c18 New translations en.po (French) 2025-12-02 18:17:58 -05:00
hank
681184b444 New translations en.po (Romanian) 2025-12-02 18:17:56 -05:00
hank
6d759cbe9f New translations en.po (Spanish) 2025-12-02 18:17:55 -05:00
hank
75480f66fa New translations en.po (Russian) 2025-12-02 18:17:55 -05:00
hank
416c237ef3 New translations en.po (Italian) 2025-12-02 18:17:53 -05:00
hank
ff64ac7a37 New translations en.po (Chinese Traditional) 2025-12-02 18:17:52 -05:00
hank
555f668b54 New translations en.po (Spanish) 2025-12-01 18:32:58 -05:00
hank
0dedc634a7 New translations en.po (Russian) 2025-12-01 18:32:57 -05:00
hank
5500e45951 New translations en.po (Chinese Traditional) 2025-12-01 18:32:56 -05:00
hank
e7574a927f New translations en.po (Chinese Traditional) 2025-11-22 06:14:37 -05:00
hank
83fbaa7a3f New translations en.po (Chinese Traditional) 2025-11-22 00:56:30 -05:00
hank
cf3efa1f9f New translations en.po (Chinese Traditional) 2025-11-21 22:50:27 -05:00
hank
24093e33a9 New translations en.po (Russian) 2025-11-21 18:15:30 -05:00
hank
075fad1da4 New translations en.po (Italian) 2025-11-20 11:58:14 -05:00
hank
a35631415a New translations en.po (Polish) 2025-11-17 11:53:50 -05:00
hank
8e99d67174 New translations en.po (Spanish) 2025-11-15 03:26:28 -05:00
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
hank
8db87e5497 Update Crowdin configuration file 2025-09-11 12:45:43 -04:00
henrygd
e601a0d564 add TRUSTED_AUTH_HEADER for auth forwarding (#399) 2025-09-10 21:26:59 -04:00
Fankesyooni
07491108cd new zh-CN translations (#1160) 2025-09-10 13:34:17 -04:00
henrygd
42ab17de1f move i18n.yml to project root 2025-09-10 13:30:42 -04:00
henrygd
2d14174f61 update i18n.yml 2025-09-10 13:28:06 -04:00
henrygd
a19ccc9263 comments 2025-09-09 17:13:15 -04:00
henrygd
956880aa59 improve container filtering performance
- also a few instances of autoformat
2025-09-09 16:59:16 -04:00
henrygd
b2b54db409 update makefile with proper site src path 2025-09-09 15:41:15 -04:00
henrygd
32d5188eef path updates after reorganization 2025-09-09 13:53:36 -04:00
henrygd
46dab7f531 fix gitignore after reorganization 2025-09-09 13:51:46 -04:00
henrygd
c898a9ebbc update /src to /internal 2025-09-09 13:35:34 -04:00
henrygd
8a13b05c20 rename /src to /internal (sorry i'll fix the prs) 2025-09-09 13:29:07 -04:00
henrygd
86ea23fe39 refactor install-agent.sh for freebsd
- Updated paths for FreeBSD installation, changing default directories from /opt/beszel-agent to /usr/local/etc/beszel-agent and /usr/local/sbin.
- Introduced conditional path setting based on the operating system.
- Updated cron job creation to use /etc/cron.d
2025-09-08 19:46:39 -04:00
henrygd
a284dd74dd add time format (12h, 24h) settings (#424)
- Some biome formatting :/
- Changed chartTime update to use listenkeys
2025-09-08 17:12:43 -04:00
Alexander Mnich
6a0075291c [FIX] OpenWRT auto update (#1155)
* switch to root crontab for OpenWRT auto update

* fix: OpenWRT auto update restart condition
2025-09-08 16:50:39 -04:00
henrygd
f542bc70a1 add biome and apply selected formatting / fixes 2025-09-08 15:22:04 -04:00
henrygd
270e59d9ea add support for otp and mfa 2025-09-07 20:46:34 -04:00
henrygd
0d97a604f8 rename main.go to beszel.go 2025-09-07 17:34:56 -04:00
henrygd
f6078fc232 fix govulncheck workflow 2025-09-07 16:52:46 -04:00
henrygd
6f5d95031c update project structure
- move agent to /agent
- change /beszel to /src
- update workflows and docker builds
2025-09-07 16:42:15 -04:00
henrygd
4e26defdca update imports for gh package name 2025-09-07 14:48:39 -04:00
Ayman Nedjmeddine
cda8fa7efd Rename Go module to github.com/henrygd/beszel 2025-09-07 14:29:56 -04:00
henrygd
fd050f2a8f revert to previous version behavior of setting hub.appURL (#1148)
- remove fallback that sets appUrl to settings.Meta.AppURL
- prefer using current browser URL in generated config if APP_URL not set
2025-09-07 14:10:47 -04:00
henrygd
e53d41dcec refactor: launch web url for dev server + css update 2025-09-07 14:10:34 -04:00
Sasha Blue
a1eb15dabb Adding openwrt restart procedure after updating the agent automatically (#1151) 2025-09-07 13:25:23 -04:00
henrygd
eb4bdafbea add freebsd support to agent install script / update command (#39) 2025-09-05 19:15:21 -04:00
Alexander Mnich
fea2330534 fix: avoid goreleaser truthy evaluation (#1146)
Goreleaser performs truthy evaluation on templates. As .Env.IS_FORK is a string the env variable containing a non empty-string already evaluated to true.
2025-09-05 17:25:57 -04:00
henrygd
5e37469ea9 0.12.7 release :) 2025-09-05 14:00:24 -04:00
henrygd
e027479bb1 make sure initial user is verfied when supplying user/pass 2025-09-05 14:00:21 -04:00
henrygd
1597e869c1 update translations 2025-09-05 13:53:17 -04:00
henrygd
862399d8ec update language files 2025-09-05 12:36:45 -04:00
henrygd
f6f85f8f9d Add USER_EMAIL and USER_PASSWORD env vars to set the email / pass of initial user (#1137) 2025-09-05 11:42:43 -04:00
Riedel, Max
e22d7ca801 fix: add nextSystemToken to deps of useEffect to generate a new token after system creation (#1142) 2025-09-05 11:00:32 -04:00
henrygd
c382c1d5f6 windows: make LHM opt-in with LHM=true (#1130) 2025-09-05 10:39:18 -04:00
henrygd
f7618ed6b0 update go version for vulcheck action 2025-09-04 19:17:44 -04:00
henrygd
d1295b7c50 alerts tests and small refactoring 2025-09-04 19:13:10 -04:00
henrygd
a162a54a58 bump go version and add keyword 2025-09-04 19:13:10 -04:00
henrygd
794db0ac6a make sure old names are removed in systemsbyname store 2025-09-04 19:13:10 -04:00
henrygd
e9fb9b856f install script: remove newlines from KEY (#1139) 2025-09-04 11:26:53 -04:00
Sven van Ginkel
66bca11d36 [Bug] Update install script to use crontab on Alpine (#1136)
* add cron

* update the install script
2025-09-03 23:10:38 -04:00
henrygd
86e87f0d47 refactor hub dev server
- moved html replacement functionality from vite to go
2025-09-01 22:16:57 -04:00
henrygd
fadfc5d81d refactor(hub): separate development and production server logic 2025-09-01 19:27:11 -04:00
henrygd
fc39ff1e4d add pflag to go deps 2025-09-01 19:24:26 -04:00
henrygd
82ccfc66e0 refactor: shared container charts config hook 2025-09-01 18:41:30 -04:00
henrygd
890bad1c39 refactor: improve runOnce with weakmap cache 2025-09-01 18:34:29 -04:00
henrygd
9c458885f1 refactor (hub): add systemsManager module
- Removed the `updateSystemList` function and replaced it with a more efficient system management approach using `systemsManager`.
- Updated the `App` component to initialize and subscribe to system updates through the new `systemsManager`.
- Refactored the `SystemsTable` and `SystemDetail` components to utilize the new state management for systems, improving performance and maintainability.
- Enhanced the `ActiveAlerts` component to fetch system names directly from the new state structure.
2025-09-01 17:29:33 -04:00
henrygd
d2aed0dc72 refactor: replace useLocalStorage with useBrowserStorage 2025-09-01 17:28:13 -04:00
Augustin ROLET
3dbcb5d7da Minor UI changes (#1110)
* ui: add devices count from #1078

* ux: save sortMode in localStorage from #1024

* fix: reload component when system switch to "up"

* ux: move running systems to desc field
2025-08-31 18:16:25 -04:00
Alexander Mnich
57a1a8b39e [Feature] improved support for mips and mipsle architectures (#1112)
* switch mipsle to softfloat

* feat: add support for mips
2025-08-30 15:50:15 -04:00
Alexander Mnich
ab81c04569 [Fix] fix GitHub workflow errors in forks (#1113)
* feat: do not run winget/homebrew/scoop release in fork

* fix: replaced deprecated goreleaser fields

https://goreleaser.com/deprecations/#archivesbuilds

* fix: push docker images only with access to the registry
2025-08-30 15:49:49 -04:00
henrygd
0c32be3bea 0.12.6 release :) 2025-08-29 17:24:45 -04:00
henrygd
81d43fbf6e refactor: small style improvements 2025-08-29 17:23:47 -04:00
henrygd
96f441de40 Virtualize All Systems table to improve performance with hundreds of systems (#1100)
- Also truncate long system names in tables and alerts sheet. (#1104)
2025-08-29 16:16:45 -04:00
henrygd
0e95caaee9 update command ui component 2025-08-29 15:04:26 -04:00
Sven van Ginkel
7697a12b42 fix alignment for metrics (#1109) 2025-08-29 14:00:17 -04:00
henrygd
94245a9ba4 fix update mirror and make opt-in with --china-mirrors (#1035) 2025-08-29 13:46:24 -04:00
henrygd
b084814aea auth form: fix border style and add theme toggle 2025-08-28 21:17:44 -04:00
Impact
cce74246ee Use older cuda image for increased compatibility (#1103) 2025-08-28 20:49:52 -04:00
henrygd
a3420b8c67 add max 1 min memory 2025-08-28 20:07:22 -04:00
henrygd
e1bb17ee9e update locale files 2025-08-28 18:23:40 -04:00
henrygd
52983f60b7 refactor: add api module and page preloading 2025-08-28 18:23:24 -04:00
henrygd
1f053fd85d update 2025-08-28 17:31:18 -04:00
Sven van Ginkel
a989d121d3 [Feature] Add Status Filtering to Systems Table (#927) 2025-08-28 17:30:44 -04:00
Sven van Ginkel
50d2406423 [Bug] Fix system table in Safari (#1092)
Co-authored-by: henrygd <hank@henrygd.me>
2025-08-28 12:07:27 -04:00
Sven van Ginkel
059d2d0a5b Add missing os.Chmod step to hub update command (#1093) 2025-08-27 13:00:03 -04:00
henrygd
621bef30b5 update changelog 2025-08-26 21:26:18 -04:00
henrygd
5f4d3dc730 0.12.5 release :) 2025-08-26 21:04:46 -04:00
henrygd
8fa9aece63 change long german translation 2025-08-26 20:50:35 -04:00
henrygd
2f1a022e2a refactor: use width for meters instead of scale 2025-08-26 20:49:31 -04:00
henrygd
4815cd29bc ghupdate: rename plugin struct 2025-08-26 18:41:42 -04:00
henrygd
e49bfaf5d7 downgrade gopsutil to fix freebsd bug (#1083) 2025-08-26 18:40:32 -04:00
henrygd
b13915b76f freebsd: fix battery-related bug (#1081) 2025-08-26 18:39:42 -04:00
henrygd
e2a57dc43b update tooltip component for tailwind 4 2025-08-26 16:16:38 -04:00
henrygd
7222224b40 add battery to supported metrics 2025-08-25 23:15:19 -04:00
henrygd
02ff475b84 improve language toggle selected style 2025-08-25 22:14:48 -04:00
henrygd
09cd8d0db9 add check for battery array length (#1076) 2025-08-25 21:34:34 -04:00
henrygd
36f1a0c53b update synctest.run to synctest.test 2025-08-25 21:25:19 -04:00
henrygd
0b0e94e045 remove pocketbase imports from ghupdate 2025-08-25 21:16:43 -04:00
henrygd
20ca6edf81 0.12.4 release :) 2025-08-25 20:23:38 -04:00
henrygd
1990f8c6df use mirror for asset download in update command (#1035) 2025-08-25 20:18:31 -04:00
henrygd
6e9dbf863f remove rhysd/go-github-selfupdate dependency 2025-08-25 20:05:02 -04:00
henrygd
fa921d77f1 update updater (#1009) 2025-08-25 20:04:23 -04:00
Sven van Ginkel
ff854d481d [Chore] Improve auto update mechanism (#1009) 2025-08-25 17:30:42 -04:00
henrygd
4ce491fe48 i18n: add default machine translations for new strings 2025-08-25 17:02:34 -04:00
henrygd
493bae7eb6 i18n: new battery strings 2025-08-25 16:46:15 -04:00
henrygd
ae5532aa36 new translations 2025-08-25 16:37:20 -04:00
NaNomicon
a1eae6413a New Vietnamese translations 2025-08-25 16:36:41 -04:00
henrygd
ee52bf1fbf New Polish translations by dymek37 2025-08-25 16:32:15 -04:00
Alex van Steenhoven
2ff0bd6b44 New Dutch translations 2025-08-25 16:30:57 -04:00
harupong
a385233b7d New Japanese translations 2025-08-25 16:28:02 -04:00
henrygd
f5648a415d New Italian translations by Tommaso Cavazza 2025-08-25 16:27:35 -04:00
Radoslav Mandev
556fb18953 New Bulgarian translations 2025-08-25 16:26:03 -04:00
henrygd
a482f78739 add changelog 2025-08-25 16:21:07 -04:00
henrygd
4a580ce972 tailwind 4 upgrade + update js deps 2025-08-25 16:12:15 -04:00
henrygd
e07558237f remove dropdown from theme mode toggle 2025-08-25 16:09:49 -04:00
henrygd
fb3c70a1bc update battery charge to include all batteries 2025-08-24 22:34:38 -04:00
henrygd
cba4d60895 improve chart legend alignment 2025-08-24 22:34:26 -04:00
henrygd
8b655ef2b9 add battery charge monitoring 2025-08-24 20:45:38 -04:00
henrygd
0188418055 update go deps 2025-08-24 19:57:40 -04:00
henrygd
72334c42d0 refactor: add @/lib/alerts 2025-08-24 19:57:28 -04:00
henrygd
0638ff3c21 refactor: add subscribe / unsubscribe to alertManager 2025-08-24 19:48:21 -04:00
henrygd
b64318d9e8 fix: frontend token generation in insecure contexts 2025-08-24 17:24:34 -04:00
henrygd
0f5b1b5157 refactor: replace status strings with systemstatus enum
- also small style changes after tailwind update
2025-08-23 20:35:18 -04:00
henrygd
3c4ae46f50 remove usememo return in add system dialog
- forgot to remove this before last commit. interferes with token display.
2025-08-22 20:27:12 -04:00
henrygd
c158b1aeeb move alerts ui to sheet component 2025-08-22 19:28:00 -04:00
henrygd
684d92c497 upgrade to tailwind 4 2025-08-22 18:06:19 -04:00
henrygd
bbd9595ec0 upgrade js dependencies (react 19) 2025-08-22 14:39:48 -04:00
henrygd
bbebb3e301 update Link component to support opening links in new tabs with ctrl/cmd key 2025-08-21 19:00:34 -04:00
henrygd
9d25181d1d use anchor tag for system table links 2025-08-21 18:44:38 -04:00
henrygd
7ba1f366ba remove batch api in favor of custom endpoint for alerts management (#1039, #1023) 2025-08-19 20:56:12 -04:00
henrygd
37c6b920f9 refactor: move useStore above possible return nulls 2025-08-19 20:20:47 -04:00
henrygd
49db81dac8 refactor: api router groups and auth handling
- require auth for `/api/beszel/getkey`
- Change `GET /api/beszel/send-test-notification` endpoint to `POST /api/beszel/test-notification`.
- add tests for API endpoints
2025-08-19 20:14:01 -04:00
henrygd
a9e90ec19c update resolveAlertHistoryRecord params to use alert ID directly 2025-08-19 19:56:51 -04:00
henrygd
2ad60507b7 small style updates 2025-08-19 19:48:25 -04:00
henrygd
12059ee3db refactor: js performance improvements 2025-08-06 22:21:48 -04:00
henrygd
de56544ca3 0.12.3 release :) 2025-08-03 22:10:51 -04:00
henrygd
065c7facb6 update language files 2025-08-03 22:10:25 -04:00
NickAss512
630c92c139 New Czech translations 2025-08-03 21:53:51 -04:00
henrygd
e11d452d91 separate agent dockerfiles 2025-08-03 21:14:43 -04:00
dalton-baker
99c7f7bd8a Add GPU-enabled build target in dockerfile_Agent (nvidia-smi support) (#898) 2025-08-03 13:31:26 -04:00
henrygd
8af3a0eb5b refactor: add getMeterState function 2025-08-02 23:44:07 -04:00
henrygd
5f7950b474 tweaks to custom meter percentages 2025-08-02 20:53:49 -04:00
Sven van Ginkel
df9e2dec28 [Feature] Add custom meter percentages (#942) 2025-08-02 17:58:52 -04:00
henrygd
a0f271545a refactoring (no functionality changes) 2025-08-02 17:04:38 -04:00
Bradley Varol
aa2bc9f118 fix systems table names wrapping (#1027) 2025-08-02 12:28:49 -04:00
henrygd
b22ae87022 disable winget auto pr and reactivate docker workflow 2025-08-01 21:15:37 -04:00
henrygd
79e79079bc fix goreleaser winget token field and temp disable docker workflow 2025-08-01 20:43:33 -04:00
henrygd
1811ebdee4 0.12.2 release :) 2025-08-01 20:36:29 -04:00
henrygd
137f3f3e24 update language files 2025-08-01 20:34:38 -04:00
Mikael Richardsson
ed1d1e77c0 Update Swedish translations 2025-08-01 20:29:02 -04:00
henrygd
8c36dd1caa windows: embed LibreHardwareMonitorLib for better sensors detection
- Updated GitHub Actions release workflow to set up .NET and build the LHM executable.
- Modified Makefile to include a conditional build step for the .NET executable on Windows.
2025-08-01 20:04:40 -04:00
hank
57bfe72486 Update readme.md 2025-07-31 19:43:08 -04:00
henrygd
75f66b0246 fix: handle missing docker group in debian postinstall script (#1012)
Check if docker group exists before attempting to add beszel user to it, preventing installation failure when Docker is not installed.
2025-07-30 19:09:10 -04:00
henrygd
ce93d54aa7 fix agent data directory resolution (#991) 2025-07-30 14:34:36 -04:00
henrygd
39dbe0eac5 ensure /etc/machine-id exists for persistent fingerprint in install-agent.sh 2025-07-30 14:25:41 -04:00
henrygd
7282044f80 improve memo deps for default area chart 2025-07-29 20:53:44 -04:00
henrygd
d77c37c0b0 winget upgrade: make sure service is stopped before updating package 2025-07-29 18:37:34 -04:00
Sven van Ginkel
e362cbbca5 Move copy button (#1010)
Thank you!
2025-07-28 19:20:37 -04:00
evrial
118544926b [Fix] OpenWrt agent install script (#1005)
* Update install-agent.sh

* Update install-agent.sh

* Update install-agent.sh
2025-07-28 14:56:31 -04:00
henrygd
d4bb0a0a30 fix: consolidate OpenWRT environment variables into single procd_set_param call 2025-07-27 18:51:26 -04:00
henrygd
fe5e35d1a9 agent install script: improve openwrt compatibility 2025-07-27 18:44:36 -04:00
henrygd
60a6ae2caa add winget token for goreleaser action 2025-07-25 20:13:31 -04:00
henrygd
80338d36aa release 0.12.1 :) 2025-07-25 19:23:53 -04:00
henrygd
f0d2c242e8 update language files 2025-07-25 19:19:49 -04:00
zoixc
559f83d99c Updated Russian translations 2025-07-25 19:14:08 -04:00
Kamil
d3a751ee6c Updated Polish translations 2025-07-25 19:13:18 -04:00
Sven van Ginkel
fb70a166fa Updated Dutch translations 2025-07-25 19:13:18 -04:00
Alberto Rizzi
c12457b707 Updated Italian translations 2025-07-25 19:08:03 -04:00
Lucas Pedro
3e53d73d56 Updated Portuguese translations 2025-07-25 19:03:45 -04:00
Mikki Alexander Mousing Sørensen
80338c5e98 Updated Danish translations 2025-07-25 19:01:34 -04:00
NickAss512
249cd8ad19 Updated Czech translations
Co-authored-by: Gear <88455107+GearCzech@users.noreply.github.com>
2025-07-25 19:01:34 -04:00
henrygd
ccdff46370 add TOKEN_FILE env var 2025-07-25 18:26:31 -04:00
henrygd
91679b5cc0 refactor load average handling (#982)
- Transitioned from individual load average fields (LoadAvg1, LoadAvg5,
LoadAvg15) to a single array (LoadAvg)
- Ensure load is displayed when all zero values.
2025-07-25 18:07:29 -04:00
henrygd
6953edf59e sort token / fingerprint table by system name 2025-07-25 15:53:40 -04:00
henrygd
b91c77ec92 make sure only 200 records are returned for alert history table 2025-07-25 15:43:19 -04:00
henrygd
3ac0b185d1 fix oidc icon display issue (#990) 2025-07-25 13:55:02 -04:00
henrygd
1e675cabb5 refactor agent data directory resolution (#991) 2025-07-25 13:37:23 -04:00
henrygd
5f44965c2c improve table formatting and fix #983
- should fix NaN display bug for dasboard cpu
- standardize decimals for dash meters
2025-07-25 00:29:08 -04:00
henrygd
f080929296 Update goreleaser configuration
- Removed the name field for brew.
- Enabled pull requests for winget.
2025-07-24 22:31:27 -04:00
henrygd
f055658eba update bun.lockb and package-lock.json 2025-07-24 20:03:19 -04:00
henrygd
e430c747fe 0.12.0 release :) 2025-07-24 19:51:51 -04:00
henrygd
ca62b1db36 update translations 2025-07-24 19:47:25 -04:00
henrygd
38569b7057 update install scripts for 0.12.0 release 2025-07-24 18:39:13 -04:00
henrygd
203244090f update alert history icon 2025-07-24 18:11:39 -04:00
henrygd
2bed722045 add windows upgrade scripts 2025-07-24 17:36:17 -04:00
henrygd
13f3a52760 remove beta scripts from copy/paste commands 2025-07-24 17:35:21 -04:00
henrygd
16b9827c70 bump migration name for 0.12.0 release 2025-07-24 17:35:06 -04:00
henrygd
0fc352d7fc update js deps 2025-07-23 19:51:19 -04:00
凉心
8a2bee11d4 Update viewport meta to prevent input zoom on iOS (#858)
- Prevents page zoom when tapping input fields on iPhone
2025-07-23 19:39:39 -04:00
henrygd
485f7d16ff add tests for agent/client.go and hub/ws/ws.go 2025-07-23 15:54:02 -04:00
henrygd
46fdc94cb8 improve bandwidth measurement precision + refactor default area chart 2025-07-23 15:52:02 -04:00
henrygd
261f7fb76c update go dependencies 2025-07-21 20:14:31 -04:00
henrygd
18d9258907 Alert history updates 2025-07-21 20:07:52 -04:00
Sven van Ginkel
9d7fb8ab80 [Feature] Add Alerts History page (#973)
* Add alert history

* refactor

* fix one colunm

* update migration

* add retention
2025-07-20 19:20:51 -04:00
henrygd
3730a78e5a update load avg display and include it in longer records 2025-07-16 21:24:42 -04:00
Sven van Ginkel
7cdd0907e8 [Feature][0.12.0-Beta] Enhance Load Average Display, Charting & Alert Grouping (#960)
* Add 1m load

* update alart dialog

* fix null data

* Remove omit zero

* change table and alert view
2025-07-16 16:03:26 -04:00
henrygd
3586f73f30 check for malformed sensor names on darwin (#796) 2025-07-16 14:56:13 -04:00
henrygd
752ccc6beb hide tokens page for readonly users 2025-07-16 14:41:23 -04:00
henrygd
f577476c81 clear systems from memory on logout (#970) 2025-07-16 14:39:15 -04:00
henrygd
49ae424698 refactor: consolidate fixedFloat funcs + remove trailing zeroes from y axis 2025-07-15 21:46:41 -04:00
henrygd
d4fd19522b fix races when loading user settings 2025-07-15 21:29:51 -04:00
henrygd
5c047e4afd Refactor unit preferences and update chart components
* Refactor user settings to use enum for unit preferences (temperature,
network, disk).
* Update chart components to utilize new unit formatting functions
* Remove deprecated conversion functions and streamline unit handling
across charts.
* Enhance settings page to allow user selection of unit preferences with
updated labels.
2025-07-15 18:57:37 -04:00
Anish Chanda
6576141f54 Adds display unit preference (#938)
* Adds temperature unit preference

* add unit preferences for networking

* adds options for MB/s and bps.

* supports disk throughput unit preferences
2025-07-14 14:46:13 -04:00
Sven van Ginkel
926e807020 [Chore] Fix CI labels (#964) 2025-07-14 14:03:56 -04:00
Sven van Ginkel
d91847c6c5 [Chrore] Improve Issue Templates with Categorization and Label Automation (#939)
* Update templates

* update script

* update labels

* add PR template

* update dropdown
2025-07-13 19:51:29 -04:00
Alexander Mnich
0abd88270c fix docker edge tag (#959) 2025-07-13 11:18:25 -04:00
henrygd
806c4e51c5 v0.12.0-beta2 release 2025-07-12 21:19:57 -04:00
henrygd
6520783fe9 small ui tweaks 2025-07-12 21:16:40 -04:00
henrygd
48c8a3a4a5 update package-lock.json 2025-07-12 21:06:01 -04:00
henrygd
e0c839f78c add skip_upload: auto to goreleaser homebrew config 2025-07-12 19:56:48 -04:00
NeMeow
1ba362bafe Add 5m and 10m load avg alerts and table values (#816)
Co-authored-by: henrygd <hank@henrygd.me>
2025-07-12 19:47:33 -04:00
henrygd
b5d55ead4a send websocket close message to agent 2025-07-12 18:49:40 -04:00
henrygd
4f879ccc66 Fix universal tokens registering multiple systems 2025-07-12 17:11:53 -04:00
henrygd
cd9e0f7b5b fix typo in install scripts 2025-07-10 15:10:44 -04:00
henrygd
780644eeae Update translations on tokens page 2025-07-08 21:32:16 -04:00
henrygd
71f081da20 add :edge image tag 2025-07-08 20:40:51 -04:00
henrygd
11c61bcf42 update translations for 0.12.0 beta 2025-07-08 19:28:30 -04:00
henrygd
402a1584d7 Add CBOR and agent initiated WebSocket connections (#51, #490, #646, #845, etc)
- Add version exchange between hub and agent.
- Introduce ConnectionManager for managing WebSocket and SSH connections.
- Implement fingerprint generation and storage in agent.
- Create expiry map package to store universal tokens.
- Update config.yml configuration to include tokens.
- Enhance system management with new methods for handling system states and alerts.
- Update front-end components to support token / fingerprint management features.
- Introduce utility functions for token generation and hub URL retrieval.

Co-authored-by: nhas <jordanatararimu@gmail.com>
2025-07-08 18:41:36 -04:00
henrygd
99d61a0193 update makefile and other tiny refactoring
- remove goccy/json dep
- add explicit types in gpu.go
2025-07-08 18:21:14 -04:00
henrygd
5ddb200a75 improve memory efficiency of records.go 2025-07-08 18:03:49 -04:00
henrygd
faa247dbda add agent data directory handling 2025-07-08 16:45:14 -04:00
henrygd
6d1cec3c42 new agent healthcheck to support non-ssh connections 2025-07-08 16:43:33 -04:00
henrygd
529df84273 make sure agent container has /tmp directory 2025-07-08 15:35:50 -04:00
henrygd
e0e21eedd6 update deps 2025-07-08 15:35:06 -04:00
henrygd
4356ffbe9b add install scripts for beta versions 2025-07-08 15:33:26 -04:00
henrygd
be1366b785 update docker workflow to clearly handle beta / rc tags 2025-07-08 15:28:23 -04:00
henrygd
3dc7e02ed0 exclude bond network interfaces by default 2025-07-08 15:27:33 -04:00
henrygd
d67d638a6b Refactor dockerManager
- Introduced a reusable buffer and JSON decoder in dockerManager for efficient decoding of Docker API responses.
- Adjusted network statistics calculations to ensure accurate data handling.
2025-07-08 15:27:01 -04:00
henrygd
7b36036455 add vulncheck workflow 2025-07-03 21:06:26 -04:00
Sven van Ginkel
1b58560acf Update MakeFile to serve outside local host (#934) 2025-06-27 21:41:16 -04:00
henrygd
1627c41f84 fix gpu name issue introduced in previous commit 2025-06-27 18:00:47 -04:00
henrygd
4395520a28 Probable fix for Jetson gpu issue (#895) 2025-06-26 22:11:48 -04:00
Alexander Mnich
8c52f30a71 add GITHUB_TOKEN fallback for goreleaser (#925)
adding the fallback to the GITHUB_TOKEN allows execution of goreleaser in a fork without additional configuration
2025-06-26 21:03:19 -04:00
SSU
46316ebffa fix(install): suppress scoop output to avoid nssm path pollution (#918)
Suppressed the output of “scoop install beszel-agent” to ensure the NSSM service path
contains only the executable location.

Closes #915

Co-authored-by: suseol <suseol@geosr.com>
2025-06-25 13:52:45 -04:00
henrygd
0b04f60b6c Add panic recovery for sensors.TemperaturesWithContext (#796) 2025-06-23 19:50:11 -04:00
HansAndreManfredson
20b822d072 Fix missing groups #892 (#893) 2025-06-17 16:08:32 -04:00
Tobias Gruetzmacher
ca7642cc91 Create service user as system user (#867) 2025-06-12 14:54:36 -04:00
henrygd
68009c85a5 Add ppc64le agent build (#682) 2025-05-28 18:47:47 -04:00
Leon Blakey
1c7c64c4aa Add user to docker group in Debian package (#847) 2025-05-28 14:49:19 -04:00
henrygd
b05966d30b add help section to readme 2025-05-26 15:49:24 -04:00
Nikolas Garofil
ea90f6a596 Update readme.md 2025-05-26 14:45:23 -04:00
henrygd
f1e43b2593 scale fractional temperature values to reasonable Celsius values (#688) 2025-05-26 01:08:03 -04:00
henrygd
748d18321d fix: windows paths when regular and admin install users differ (#739) 2025-05-26 00:51:44 -04:00
henrygd
ae84919c39 update windows install command to use bypass execution policy (#739) 2025-05-24 21:49:43 -04:00
henrygd
b23221702e Handle systemd nvidia rules automatically during agent installation 2025-05-21 17:24:54 -04:00
henrygd
4d5b096230 Improve 'add system' dropdown buttons 2025-05-09 22:31:47 -04:00
henrygd
7caf7d1b31 Clear system's active alerts when system is paused 2025-05-08 20:41:44 -04:00
henrygd
6107f52d07 Fix system path in notification urls 2025-05-08 19:06:19 -04:00
henrygd
f4fb7a89e5 Add tests for GetSSHKey and handle read errors on key file 2025-05-08 18:54:14 -04:00
henrygd
5439066f4d hub.MakeLink method to assure URLs are formatted properly (#805)
- Updated AlertManager to replace direct app references with a hub interface.
- Changed AlertManager.app to AlertManager.hub
- Add tests for MakeLink
2025-05-08 17:47:15 -04:00
henrygd
7c18f3d8b4 Add mipsle agent build (#802) 2025-05-07 20:11:48 -04:00
henrygd
63af81666b Refactor SSH configuration and key management
- Restrict to specific key exchanges / MACs / ciphers.
- Refactored GetSSHKey method to return an ssh.Signer instead of byte array.
- Added common package.

Co-authored-by: nhas <jordanatararimu@gmail.com>
2025-05-07 20:03:21 -04:00
henrygd
c0a6153a43 Update goreleaser configuration for beszel-agent to include restart delay and process type 2025-05-05 20:22:15 -04:00
henrygd
df334caca6 update install-agent.ps1 to support installing as admin (#797) 2025-05-05 20:21:37 -04:00
henrygd
ffb3ec0477 Fix broken link to notifications when using base path 2025-05-02 20:02:23 -04:00
henrygd
3a97edd0d5 add winget support to windows install script 2025-05-01 17:40:20 -04:00
henrygd
ab1d1c1273 Remove PrivateTmp setting from Systemd rules in install-agent.sh
Allows sharing socket in /tmp
2025-05-01 17:00:08 -04:00
henrygd
0fb39edae4 rename ssh imports in server.go 2025-04-30 18:09:25 -04:00
henrygd
3a977a8e1f goreleaser: update deprecated format field 2025-04-30 16:15:37 -04:00
henrygd
081979de24 Add winget configuration for beszel-agent 2025-04-30 15:00:26 -04:00
henrygd
23fe189797 Add SELinux context management to install-agent.sh (#788)
- Introduced functions to set and clean up SELinux contexts.
- Added SELinux context checks during the update process (systemd only).
- Updated the service execution command to use a dedicated update script.
2025-04-29 18:59:36 -04:00
henrygd
e9d429b9b8 Enhance service start check in install-agent.ps1
- Added logic to handle service start failures and check status with retries.
- Improved user feedback for service status during startup process.
2025-04-28 21:47:02 -04:00
henrygd
99202c85b6 re-enable docker image creation workflow 2025-04-28 21:16:32 -04:00
henrygd
d5c3d8f84e release 0.11.1 with new line so goreleaser doesn't fail :)
- Temp disable docker workflow bc image was already build
2025-04-28 20:57:27 -04:00
Alexander Mnich
8f442992e6 New German translations 2025-04-28 20:48:38 -04:00
henrygd
39820c8ac1 release 0.11.1 2025-04-28 20:38:24 -04:00
henrygd
0c8b10af99 Escape backslashes in windows agent install command (#785) 2025-04-28 20:37:25 -04:00
henrygd
8e072492b7 Skip checking Docker if DOCKER_HOST is set to an empty string 2025-04-28 20:23:54 -04:00
henrygd
88d6307ce0 Add FreeBSD icon 2025-04-28 19:37:00 -04:00
henrygd
2cc516f9e5 update readme and notifications link 2025-04-27 20:05:07 -04:00
299 changed files with 79279 additions and 32487 deletions

48
.dockerignore Normal file
View File

@@ -0,0 +1,48 @@
# Node.js dependencies
node_modules
internalsite/node_modules
# Go build artifacts and binaries
build
dist
*.exe
beszel-agent
beszel_data*
pb_data
data
temp
# Development and IDE files
.vscode
.idea*
*.swc
__debug_*
# Git and version control
.git
.gitignore
# Documentation and supplemental files
*.md
supplemental
freebsd-port
# Test files (exclude from production builds)
*_test.go
coverage
# Docker files
dockerfile_*
# Temporary files
*.tmp
*.bak
*.log
# OS specific files
.DS_Store
Thumbs.db
# .NET build artifacts
agent/lhm/obj
agent/lhm/bin

View File

@@ -1,8 +1,19 @@
name: 🐛 Bug report
description: Report a new bug or issue.
title: '[Bug]: '
labels: ['bug']
labels: ['bug', "needs confirmation"]
body:
- type: dropdown
id: component
attributes:
label: Component
description: Which part of Beszel is this about?
options:
- Hub
- Agent
- Hub & Agent
validations:
required: true
- type: markdown
attributes:
value: |
@@ -43,6 +54,39 @@ body:
3. Pour it into a cup.
validations:
required: true
- type: dropdown
id: category
attributes:
label: Category
description: Which category does this relate to most?
options:
- Metrics
- Charts & Visualization
- Settings & Configuration
- Notifications & Alerts
- Authentication
- Installation
- Performance
- UI / UX
- Other
validations:
required: true
- type: dropdown
id: metrics
attributes:
label: Affected Metrics
description: If applicable, which specific metric does this relate to most?
options:
- CPU
- Memory
- Storage
- Network
- Containers
- GPU
- Sensors
- Other
validations:
required: true
- type: input
id: system
attributes:
@@ -61,7 +105,6 @@ body:
id: install-method
attributes:
label: Installation method
default: 0
options:
- Docker
- Binary

View File

@@ -1,8 +1,19 @@
name: 🚀 Feature request
description: Request a new feature or change.
title: "[Feature]: "
labels: ["enhancement"]
labels: ["enhancement", "needs review"]
body:
- type: dropdown
id: component
attributes:
label: Component
description: Which part of Beszel is this about?
options:
- Hub
- Agent
- Hub & Agent
validations:
required: true
- type: markdown
attributes:
value: Before submitting, please search existing [issues](https://github.com/henrygd/beszel/issues) and [discussions](https://github.com/henrygd/beszel/discussions) (including closed).
@@ -11,8 +22,55 @@ body:
label: Describe the feature you would like to see
validations:
required: true
- type: textarea
id: motivation
attributes:
label: Motivation / Use Case
description: Why do you want this feature? What problem does it solve?
validations:
required: true
- type: textarea
attributes:
label: Describe how you would like to see this feature implemented
validations:
required: true
- type: textarea
id: logs
attributes:
label: Screenshots
description: Please attach any relevant screenshots, such as images from your current solution or similar implementations.
validations:
required: false
- type: dropdown
id: category
attributes:
label: Category
description: Which category does this relate to most?
options:
- Metrics
- Charts & Visualization
- Settings & Configuration
- Notifications & Alerts
- Authentication
- Installation
- Performance
- UI / UX
- Other
validations:
required: true
- type: dropdown
id: metrics
attributes:
label: Affected Metrics
description: If applicable, which specific metric does this relate to most?
options:
- CPU
- Memory
- Storage
- Network
- Containers
- GPU
- Sensors
- Other
validations:
required: true

33
.github/pull_request_template.md vendored Normal file
View File

@@ -0,0 +1,33 @@
## 📃 Description
A short description of the pull request changes should go here and the sections below should list in detail all changes. You can remove the sections you don't need.
## 📖 Documentation
Add a link to the PR for [documentation](https://github.com/henrygd/beszel-docs) changes.
## 🪵 Changelog
### Added
- one
- two
### ✏️ Changed
- one
- two
### 🔧 Fixed
- one
- two
### 🗑️ Removed
- one
- two
## 📷 Screenshots
If this PR has any UI/UX changes it's strongly suggested you add screenshots here.

View File

@@ -3,7 +3,7 @@ name: Make docker images
on:
push:
tags:
- 'v*'
- "v*"
jobs:
build:
@@ -13,29 +13,49 @@ jobs:
matrix:
include:
- image: henrygd/beszel
context: ./beszel
dockerfile: ./beszel/dockerfile_Hub
context: ./
dockerfile: ./internal/dockerfile_hub
registry: docker.io
username_secret: DOCKERHUB_USERNAME
password_secret: DOCKERHUB_TOKEN
- image: henrygd/beszel-agent
context: ./beszel
dockerfile: ./beszel/dockerfile_Agent
context: ./
dockerfile: ./internal/dockerfile_agent
registry: docker.io
username_secret: DOCKERHUB_USERNAME
password_secret: DOCKERHUB_TOKEN
- image: henrygd/beszel-agent-nvidia
context: ./
dockerfile: ./internal/dockerfile_agent_nvidia
platforms: linux/amd64
registry: docker.io
username_secret: DOCKERHUB_USERNAME
password_secret: DOCKERHUB_TOKEN
- image: ghcr.io/${{ github.repository }}/beszel
context: ./beszel
dockerfile: ./beszel/dockerfile_Hub
context: ./
dockerfile: ./internal/dockerfile_hub
registry: ghcr.io
username: ${{ github.actor }}
password_secret: GITHUB_TOKEN
- image: ghcr.io/${{ github.repository }}/beszel-agent
context: ./beszel
dockerfile: ./beszel/dockerfile_Agent
context: ./
dockerfile: ./internal/dockerfile_agent
registry: ghcr.io
username: ${{ github.actor }}
password_secret: GITHUB_TOKEN
- image: ghcr.io/${{ github.repository }}/beszel-agent-nvidia
context: ./
dockerfile: ./internal/dockerfile_agent_nvidia
platforms: linux/amd64
registry: ghcr.io
username: ${{ github.actor }}
password_secret: GITHUB_TOKEN
permissions:
contents: read
packages: write
@@ -48,10 +68,10 @@ jobs:
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install --no-save --cwd ./beszel/site
run: bun install --no-save --cwd ./internal/site
- name: Build site
run: bun run --cwd ./beszel/site build
run: bun run --cwd ./internal/site build
- name: Set up QEMU
uses: docker/setup-qemu-action@v3
@@ -65,6 +85,7 @@ jobs:
with:
images: ${{ matrix.image }}
tags: |
type=raw,value=edge
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
@@ -72,7 +93,9 @@ jobs:
# https://github.com/docker/login-action
- name: Login to Docker Hub
if: github.event_name != 'pull_request'
env:
password_secret_exists: ${{ secrets[matrix.password_secret] != '' && 'true' || 'false' }}
if: github.event_name != 'pull_request' && env.password_secret_exists == 'true'
uses: docker/login-action@v3
with:
username: ${{ matrix.username || secrets[matrix.username_secret] }}
@@ -84,9 +107,9 @@ jobs:
- name: Build and push Docker image
uses: docker/build-push-action@v5
with:
context: '${{ matrix.context }}'
context: "${{ matrix.context }}"
file: ${{ matrix.dockerfile }}
platforms: linux/amd64,linux/arm64,linux/arm/v7
push: ${{ github.ref_type == 'tag' }}
platforms: ${{ matrix.platforms || 'linux/amd64,linux/arm64,linux/arm/v7' }}
push: ${{ github.ref_type == 'tag' && secrets[matrix.password_secret] != '' }}
tags: ${{ steps.metadata.outputs.tags }}
labels: ${{ steps.metadata.outputs.labels }}

View File

@@ -0,0 +1,43 @@
name: 'Issue and PR Maintenance'
on:
schedule:
- cron: '0 0 * * *' # runs at midnight UTC
workflow_dispatch:
permissions:
issues: write
pull-requests: write
jobs:
close-stale:
name: Close Stale Issues
runs-on: ubuntu-24.04
steps:
- name: Close Stale Issues
uses: actions/stale@v9
with:
repo-token: ${{ secrets.GITHUB_TOKEN }}
# Messaging
stale-issue-message: >
👋 This issue has been automatically marked as stale due to inactivity.
If this issue is still relevant, please comment to keep it open.
Without activity, it will be closed in 7 days.
close-issue-message: >
🔒 This issue has been automatically closed due to prolonged inactivity.
Feel free to open a new issue if you have further questions or concerns.
# Timing
days-before-issue-stale: 14
days-before-issue-close: 7
# Labels
stale-issue-label: 'stale'
remove-stale-when-updated: true
only-issue-labels: 'awaiting-requester'
# Exemptions
exempt-assignees: true
exempt-milestones: true

View File

@@ -0,0 +1,82 @@
name: Label issues from dropdowns
on:
issues:
types: [opened]
jobs:
label_from_dropdown:
runs-on: ubuntu-latest
permissions:
issues: write
steps:
- name: Apply labels based on dropdown choices
uses: actions/github-script@v7
with:
script: |
const issueNumber = context.issue.number;
const owner = context.repo.owner;
const repo = context.repo.repo;
// Get the issue body
const body = context.payload.issue.body;
// Helper to find dropdown value in the body (assuming markdown format)
function extractSectionValue(heading) {
const regex = new RegExp(`### ${heading}\\s+([\\s\\S]*?)(?:\\n###|$)`, 'i');
const match = body.match(regex);
if (match) {
// Get the first non-empty line after the heading
const lines = match[1].split('\n').map(l => l.trim()).filter(Boolean);
return lines[0] || null;
}
return null;
}
// Extract dropdown selections
const category = extractSectionValue('Category');
const metrics = extractSectionValue('Affected Metrics');
const component = extractSectionValue('Component');
// Build labels to add
let labelsToAdd = [];
if (category) labelsToAdd.push(category);
if (metrics) labelsToAdd.push(metrics);
if (component) labelsToAdd.push(component);
// Get existing labels in the repo
const { data: existingLabels } = await github.rest.issues.listLabelsForRepo({
owner,
repo,
per_page: 100
});
const existingLabelNames = existingLabels.map(l => l.name);
// Find labels that need to be created
const labelsToCreate = labelsToAdd.filter(label => !existingLabelNames.includes(label));
// Create missing labels (with a default color)
for (const label of labelsToCreate) {
try {
await github.rest.issues.createLabel({
owner,
repo,
name: label,
color: 'ededed' // light gray, you can pick any hex color
});
} catch (e) {
// Ignore if label already exists (race condition), otherwise rethrow
if (!e || e.status !== 422) throw e;
}
}
// Now apply all labels (they all exist now)
if (labelsToAdd.length > 0) {
await github.rest.issues.addLabels({
owner,
repo,
issue_number: issueNumber,
labels: labelsToAdd
});
}

View File

@@ -3,7 +3,7 @@ name: Make release and binaries
on:
push:
tags:
- 'v*'
- "v*"
permissions:
contents: write
@@ -21,22 +21,34 @@ jobs:
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install --no-save --cwd ./beszel/site
run: bun install --no-save --cwd ./internal/site
- name: Build site
run: bun run --cwd ./beszel/site build
run: bun run --cwd ./internal/site build
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: '^1.22.1'
go-version: "^1.22.1"
- name: Set up .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: "9.0.x"
- name: Build .NET LHM executable for Windows sensors
run: |
dotnet build -c Release ./agent/lhm/beszel_lhm.csproj
shell: bash
- name: GoReleaser beszel
uses: goreleaser/goreleaser-action@v6
with:
workdir: ./beszel
workdir: ./
distribution: goreleaser
version: latest
args: release --clean
env:
GITHUB_TOKEN: ${{ secrets.TOKEN }}
GITHUB_TOKEN: ${{ secrets.TOKEN || secrets.GITHUB_TOKEN }}
WINGET_TOKEN: ${{ secrets.WINGET_TOKEN }}
IS_FORK: ${{ github.repository_owner != 'henrygd' }}

33
.github/workflows/vulncheck.yml vendored Normal file
View File

@@ -0,0 +1,33 @@
# https://github.com/minio/minio/blob/master/.github/workflows/vulncheck.yml
name: VulnCheck
on:
pull_request:
branches:
- main
push:
branches:
- main
permissions:
contents: read # to fetch code (actions/checkout)
jobs:
vulncheck:
name: VulnCheck
runs-on: ubuntu-latest
steps:
- name: Check out code into the Go module directory
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v5
with:
go-version: 1.25.x
# cached: false
- name: Get official govulncheck
run: go install golang.org/x/vuln/cmd/govulncheck@latest
shell: bash
- name: Run govulncheck
run: govulncheck -show verbose ./...
shell: bash

11
.gitignore vendored
View File

@@ -8,12 +8,15 @@ beszel_data
beszel_data*
dist
*.exe
beszel/cmd/hub/hub
beszel/cmd/agent/agent
internal/cmd/hub/hub
internal/cmd/agent/agent
node_modules
beszel/build
build
*timestamp*
.swc
beszel/site/src/locales/**/*.ts
internal/site/src/locales/**/*.ts
*.bak
__debug_*
agent/lhm/obj
agent/lhm/bin
dockerfile_agent_dev

View File

@@ -9,7 +9,7 @@ before:
builds:
- id: beszel
binary: beszel
main: cmd/hub/hub.go
main: internal/cmd/hub/hub.go
env:
- CGO_ENABLED=0
goos:
@@ -22,7 +22,7 @@ builds:
- id: beszel-agent
binary: beszel-agent
main: cmd/agent/agent.go
main: internal/cmd/agent/agent.go
env:
- CGO_ENABLED=0
goos:
@@ -37,11 +37,26 @@ builds:
- arm
- mips64
- riscv64
- mipsle
- mips
- ppc64le
gomips:
- hardfloat
- softfloat
ignore:
- goos: freebsd
goarch: arm
- goos: openbsd
goarch: arm
- goos: linux
goarch: mips64
gomips: softfloat
- goos: linux
goarch: mipsle
gomips: hardfloat
- goos: linux
goarch: mips
gomips: hardfloat
- goos: windows
goarch: arm
- goos: darwin
@@ -51,8 +66,8 @@ builds:
archives:
- id: beszel-agent
format: tar.gz
builds:
formats: [tar.gz]
ids:
- beszel-agent
name_template: >-
{{ .Binary }}_
@@ -60,11 +75,11 @@ archives:
{{- .Arch }}
format_overrides:
- goos: windows
format: zip
formats: [zip]
- id: beszel
format: tar.gz
builds:
formats: [tar.gz]
ids:
- beszel
name_template: >-
{{ .Binary }}_
@@ -83,36 +98,33 @@ nfpms:
API access.
maintainer: henrygd <hank@henrygd.me>
section: net
builds:
ids:
- beszel-agent
formats:
- deb
# don't think this is needed with CGO_ENABLED=0
# dependencies:
# - libc6
contents:
- src: ../supplemental/debian/beszel-agent.service
- src: ./supplemental/debian/beszel-agent.service
dst: lib/systemd/system/beszel-agent.service
packager: deb
- src: ../supplemental/debian/copyright
- src: ./supplemental/debian/copyright
dst: usr/share/doc/beszel-agent/copyright
packager: deb
- src: ../supplemental/debian/lintian-overrides
- src: ./supplemental/debian/lintian-overrides
dst: usr/share/lintian/overrides/beszel-agent
packager: deb
scripts:
postinstall: ../supplemental/debian/postinstall.sh
preremove: ../supplemental/debian/prerm.sh
postremove: ../supplemental/debian/postrm.sh
postinstall: ./supplemental/debian/postinstall.sh
preremove: ./supplemental/debian/prerm.sh
postremove: ./supplemental/debian/postrm.sh
deb:
predepends:
- adduser
- debconf
scripts:
templates: ../supplemental/debian/templates
templates: ./supplemental/debian/templates
# Currently broken due to a bug in goreleaser
# https://github.com/goreleaser/goreleaser/issues/5487
#config: ../supplemental/debian/config.sh
#config: ./supplemental/debian/config.sh
scoops:
- ids: [beszel-agent]
@@ -120,9 +132,10 @@ scoops:
repository:
owner: henrygd
name: beszel-scoops
homepage: 'https://beszel.dev'
description: 'Agent for Beszel, a lightweight server monitoring platform.'
homepage: "https://beszel.dev"
description: "Agent for Beszel, a lightweight server monitoring platform."
license: MIT
skip_upload: '{{ if eq (tolower .Env.IS_FORK) "true" }}true{{ else }}auto{{ end }}'
# # Needs choco installed, so doesn't build on linux / default gh workflow :(
# chocolateys:
@@ -153,9 +166,10 @@ brews:
repository:
owner: henrygd
name: homebrew-beszel
homepage: 'https://beszel.dev'
description: 'Agent for Beszel, a lightweight server monitoring platform.'
homepage: "https://beszel.dev"
description: "Agent for Beszel, a lightweight server monitoring platform."
license: MIT
skip_upload: '{{ if eq (tolower .Env.IS_FORK) "true" }}true{{ else }}auto{{ end }}'
extra_install: |
(bin/"beszel-agent-launcher").write <<~EOS
#!/bin/bash
@@ -172,6 +186,44 @@ brews:
log_path "#{Dir.home}/.cache/beszel/beszel-agent.log"
error_log_path "#{Dir.home}/.cache/beszel/beszel-agent.log"
keep_alive true
restart_delay 5
process_type :background
winget:
- ids: [beszel-agent]
name: beszel-agent
package_identifier: henrygd.beszel-agent
publisher: henrygd
license: MIT
license_url: "https://github.com/henrygd/beszel/blob/main/LICENSE"
copyright: "2025 henrygd"
homepage: "https://beszel.dev"
release_notes_url: "https://github.com/henrygd/beszel/releases/tag/v{{ .Version }}"
publisher_support_url: "https://github.com/henrygd/beszel/issues"
short_description: "Agent for Beszel, a lightweight server monitoring platform."
skip_upload: '{{ if eq (tolower .Env.IS_FORK) "true" }}true{{ else }}auto{{ end }}'
description: |
Beszel is a lightweight server monitoring platform that includes Docker
statistics, historical data, and alert functions. It has a friendly web
interface, simple configuration, and is ready to use out of the box.
It supports automatic backup, multi-user, OAuth authentication, and
API access.
tags:
- homelab
- monitoring
- self-hosted
repository:
owner: henrygd
name: beszel-winget
branch: henrygd.beszel-agent-{{ .Version }}
token: "{{ .Env.WINGET_TOKEN }}"
# pull_request:
# enabled: true
# draft: false
# base:
# owner: microsoft
# name: winget-pkgs
# branch: master
release:
draft: true
@@ -181,5 +233,5 @@ changelog:
sort: asc
filters:
exclude:
- '^docs:'
- '^test:'
- "^docs:"
- "^test:"

102
Makefile Normal file
View File

@@ -0,0 +1,102 @@
# Default OS/ARCH values
OS ?= $(shell go env GOOS)
ARCH ?= $(shell go env GOARCH)
# Skip building the web UI if true
SKIP_WEB ?= false
# Set executable extension based on target OS
EXE_EXT := $(if $(filter windows,$(OS)),.exe,)
.PHONY: tidy build-agent build-hub build-hub-dev build clean lint dev-server dev-agent dev-hub dev generate-locales
.DEFAULT_GOAL := build
clean:
go clean
rm -rf ./build
lint:
golangci-lint run
test: export GOEXPERIMENT=synctest
test:
go test -tags=testing ./...
tidy:
go mod tidy
build-web-ui:
@if command -v bun >/dev/null 2>&1; then \
bun install --cwd ./internal/site && \
bun run --cwd ./internal/site build; \
else \
npm install --prefix ./internal/site && \
npm run --prefix ./internal/site build; \
fi
# Conditional .NET build - only for Windows
build-dotnet-conditional:
@if [ "$(OS)" = "windows" ]; then \
echo "Building .NET executable for Windows..."; \
if command -v dotnet >/dev/null 2>&1; then \
rm -rf ./agent/lhm/bin; \
dotnet build -c Release ./agent/lhm/beszel_lhm.csproj; \
else \
echo "Error: dotnet not found. Install .NET SDK to build Windows agent."; \
exit 1; \
fi; \
fi
# Update build-agent to include conditional .NET build
build-agent: tidy build-dotnet-conditional
GOOS=$(OS) GOARCH=$(ARCH) go build -o ./build/beszel-agent_$(OS)_$(ARCH)$(EXE_EXT) -ldflags "-w -s" ./internal/cmd/agent
build-hub: tidy $(if $(filter false,$(SKIP_WEB)),build-web-ui)
GOOS=$(OS) GOARCH=$(ARCH) go build -o ./build/beszel_$(OS)_$(ARCH)$(EXE_EXT) -ldflags "-w -s" ./internal/cmd/hub
build-hub-dev: tidy
mkdir -p ./internal/site/dist && touch ./internal/site/dist/index.html
GOOS=$(OS) GOARCH=$(ARCH) go build -tags development -o ./build/beszel-dev_$(OS)_$(ARCH)$(EXE_EXT) -ldflags "-w -s" ./internal/cmd/hub
build: build-agent build-hub
generate-locales:
@if [ ! -f ./internal/site/src/locales/en/en.ts ]; then \
echo "Generating locales..."; \
command -v bun >/dev/null 2>&1 && cd ./internal/site && bun install && bun run sync || cd ./internal/site && npm install && npm run sync; \
fi
dev-server: generate-locales
cd ./internal/site
@if command -v bun >/dev/null 2>&1; then \
cd ./internal/site && bun run dev --host 0.0.0.0; \
else \
cd ./internal/site && npm run dev --host 0.0.0.0; \
fi
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/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
dev-agent:
@if command -v entr >/dev/null 2>&1; then \
find ./internal/cmd/agent/*.go ./agent/*.go | entr -r go run github.com/henrygd/beszel/internal/cmd/agent; \
else \
go run github.com/henrygd/beszel/internal/cmd/agent; \
fi
build-dotnet:
@if command -v dotnet >/dev/null 2>&1; then \
rm -rf ./agent/lhm/bin; \
dotnet build -c Release ./agent/lhm/beszel_lhm.csproj; \
else \
echo "dotnet not found"; \
fi
# KEY="..." make -j dev
dev: dev-server dev-hub dev-agent

185
agent/agent.go Normal file
View File

@@ -0,0 +1,185 @@
// Package agent implements the Beszel monitoring agent that collects and serves system metrics.
//
// The agent runs on monitored systems and communicates collected data
// to the Beszel hub for centralized monitoring and alerting.
package agent
import (
"crypto/sha256"
"encoding/hex"
"log/slog"
"os"
"path/filepath"
"strings"
"sync"
"time"
"github.com/gliderlabs/ssh"
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/shirou/gopsutil/v4/host"
gossh "golang.org/x/crypto/ssh"
)
type Agent struct {
sync.Mutex // Used to lock agent while collecting data
debug bool // true if LOG_LEVEL is set to debug
zfs bool // true if system has arcstats
memCalc string // Memory calculation formula
fsNames []string // List of filesystem device names being monitored
fsStats map[string]*system.FsStats // Keeps track of disk stats for each filesystem
netInterfaces map[string]struct{} // Stores all valid network interfaces
netIoStats system.NetIoStats // Keeps track of bandwidth usage
dockerManager *dockerManager // Manages Docker API requests
sensorConfig *SensorConfig // Sensors config
systemInfo system.Info // Host system info
gpuManager *GPUManager // Manages GPU data
cache *SessionCache // Cache for system stats based on primary session ID
connectionManager *ConnectionManager // Channel to signal connection events
server *ssh.Server // SSH server
dataDir string // Directory for persisting data
keys []gossh.PublicKey // SSH public keys
}
// NewAgent creates a new agent with the given data directory for persisting data.
// If the data directory is not set, it will attempt to find the optimal directory.
func NewAgent(dataDir ...string) (agent *Agent, err error) {
agent = &Agent{
fsStats: make(map[string]*system.FsStats),
cache: NewSessionCache(69 * time.Second),
}
agent.dataDir, err = getDataDir(dataDir...)
if err != nil {
slog.Warn("Data directory not found")
} else {
slog.Info("Data directory", "path", agent.dataDir)
}
agent.memCalc, _ = GetEnv("MEM_CALC")
agent.sensorConfig = agent.newSensorConfig()
// Set up slog with a log level determined by the LOG_LEVEL env var
if logLevelStr, exists := GetEnv("LOG_LEVEL"); exists {
switch strings.ToLower(logLevelStr) {
case "debug":
agent.debug = true
slog.SetLogLoggerLevel(slog.LevelDebug)
case "warn":
slog.SetLogLoggerLevel(slog.LevelWarn)
case "error":
slog.SetLogLoggerLevel(slog.LevelError)
}
}
slog.Debug(beszel.Version)
// initialize system info
agent.initializeSystemInfo()
// initialize connection manager
agent.connectionManager = newConnectionManager(agent)
// initialize disk info
agent.initializeDiskInfo()
// initialize net io stats
agent.initializeNetIoStats()
// initialize docker manager
agent.dockerManager = newDockerManager(agent)
// initialize GPU manager
if gm, err := NewGPUManager(); err != nil {
slog.Debug("GPU", "err", err)
} else {
agent.gpuManager = gm
}
// if debugging, print stats
if agent.debug {
slog.Debug("Stats", "data", agent.gatherStats(""))
}
return agent, nil
}
// GetEnv retrieves an environment variable with a "BESZEL_AGENT_" prefix, or falls back to the unprefixed key.
func GetEnv(key string) (value string, exists bool) {
if value, exists = os.LookupEnv("BESZEL_AGENT_" + key); exists {
return value, exists
}
// Fallback to the old unprefixed key
return os.LookupEnv(key)
}
func (a *Agent) gatherStats(sessionID string) *system.CombinedData {
a.Lock()
defer a.Unlock()
data, isCached := a.cache.Get(sessionID)
if isCached {
slog.Debug("Cached data", "session", sessionID)
return data
}
*data = system.CombinedData{
Stats: a.getSystemStats(),
Info: a.systemInfo,
}
slog.Debug("System data", "data", data)
if a.dockerManager != nil {
if containerStats, err := a.dockerManager.getDockerStats(); err == nil {
data.Containers = containerStats
slog.Debug("Containers", "data", data.Containers)
} else {
slog.Debug("Containers", "err", err)
}
}
data.Stats.ExtraFs = make(map[string]*system.FsStats)
for name, stats := range a.fsStats {
if !stats.Root && stats.DiskTotal > 0 {
data.Stats.ExtraFs[name] = stats
}
}
slog.Debug("Extra FS", "data", data.Stats.ExtraFs)
a.cache.Set(sessionID, data)
return data
}
// StartAgent initializes and starts the agent with optional WebSocket connection
func (a *Agent) Start(serverOptions ServerOptions) error {
a.keys = serverOptions.Keys
return a.connectionManager.Start(serverOptions)
}
func (a *Agent) getFingerprint() string {
// first look for a fingerprint in the data directory
if a.dataDir != "" {
if fp, err := os.ReadFile(filepath.Join(a.dataDir, "fingerprint")); err == nil {
return string(fp)
}
}
// if no fingerprint is found, generate one
fingerprint, err := host.HostID()
if err != nil || fingerprint == "" {
fingerprint = a.systemInfo.Hostname + a.systemInfo.CpuModel
}
// hash fingerprint
sum := sha256.Sum256([]byte(fingerprint))
fingerprint = hex.EncodeToString(sum[:24])
// save fingerprint to data directory
if a.dataDir != "" {
err = os.WriteFile(filepath.Join(a.dataDir, "fingerprint"), []byte(fingerprint), 0644)
if err != nil {
slog.Warn("Failed to save fingerprint", "err", err)
}
}
return fingerprint
}

View File

@@ -1,8 +1,9 @@
package agent
import (
"beszel/internal/entities/system"
"time"
"github.com/henrygd/beszel/internal/entities/system"
)
// Not thread safe since we only access from gatherStats which is already locked

View File

@@ -1,17 +1,21 @@
//go:build testing
// +build testing
package agent
import (
"beszel/internal/entities/system"
"testing"
"testing/synctest"
"time"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSessionCache_GetSet(t *testing.T) {
synctest.Run(func() {
synctest.Test(t, func(t *testing.T) {
cache := NewSessionCache(69 * time.Second)
testData := &system.CombinedData{

View File

@@ -0,0 +1,9 @@
//go:build testing
// +build testing
package agent
// TESTING ONLY: GetConnectionManager is a helper function to get the connection manager for testing.
func (a *Agent) GetConnectionManager() *ConnectionManager {
return a.connectionManager
}

53
agent/battery/battery.go Normal file
View File

@@ -0,0 +1,53 @@
//go:build !freebsd
// Package battery provides functions to check if the system has a battery and to get the battery stats.
package battery
import (
"errors"
"log/slog"
"github.com/distatus/battery"
)
var systemHasBattery = false
var haveCheckedBattery = false
// HasReadableBattery checks if the system has a battery and returns true if it does.
func HasReadableBattery() bool {
if haveCheckedBattery {
return systemHasBattery
}
haveCheckedBattery = true
bat, err := battery.Get(0)
if err == nil && bat != nil {
systemHasBattery = true
} else {
slog.Debug("No battery found", "err", err)
}
return systemHasBattery
}
// GetBatteryStats returns the current battery percent and charge state
func GetBatteryStats() (batteryPercent uint8, batteryState uint8, err error) {
if !systemHasBattery {
return batteryPercent, batteryState, errors.ErrUnsupported
}
batteries, err := battery.GetAll()
if err != nil || len(batteries) == 0 {
return batteryPercent, batteryState, err
}
totalCapacity := float64(0)
totalCharge := float64(0)
for _, bat := range batteries {
if bat.Design != 0 {
totalCapacity += bat.Design
} else {
totalCapacity += bat.Full
}
totalCharge += bat.Current
}
batteryPercent = uint8(totalCharge / totalCapacity * 100)
batteryState = uint8(batteries[0].State.Raw)
return batteryPercent, batteryState, nil
}

View File

@@ -0,0 +1,13 @@
//go:build freebsd
package battery
import "errors"
func HasReadableBattery() bool {
return false
}
func GetBatteryStats() (uint8, uint8, error) {
return 0, 0, errors.ErrUnsupported
}

266
agent/client.go Normal file
View File

@@ -0,0 +1,266 @@
package agent
import (
"crypto/tls"
"errors"
"fmt"
"log/slog"
"net"
"net/http"
"net/url"
"os"
"path"
"strings"
"time"
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/common"
"github.com/fxamacker/cbor/v2"
"github.com/lxzan/gws"
"golang.org/x/crypto/ssh"
)
const (
wsDeadline = 70 * time.Second
)
// WebSocketClient manages the WebSocket connection between the agent and hub.
// It handles authentication, message routing, and connection lifecycle management.
type WebSocketClient struct {
gws.BuiltinEventHandler
options *gws.ClientOption // WebSocket client configuration options
agent *Agent // Reference to the parent agent
Conn *gws.Conn // Active WebSocket connection
hubURL *url.URL // Parsed hub URL for connection
token string // Authentication token for hub registration
fingerprint string // System fingerprint for identification
hubRequest *common.HubRequest[cbor.RawMessage] // Reusable request structure for message parsing
lastConnectAttempt time.Time // Timestamp of last connection attempt
hubVerified bool // Whether the hub has been cryptographically verified
}
// newWebSocketClient creates a new WebSocket client for the given agent.
// It reads configuration from environment variables and validates the hub URL.
func newWebSocketClient(agent *Agent) (client *WebSocketClient, err error) {
hubURLStr, exists := GetEnv("HUB_URL")
if !exists {
return nil, errors.New("HUB_URL environment variable not set")
}
client = &WebSocketClient{}
client.hubURL, err = url.Parse(hubURLStr)
if err != nil {
return nil, errors.New("invalid hub URL")
}
// get registration token
client.token, err = getToken()
if err != nil {
return nil, err
}
client.agent = agent
client.hubRequest = &common.HubRequest[cbor.RawMessage]{}
client.fingerprint = agent.getFingerprint()
return client, nil
}
// getToken returns the token for the WebSocket client.
// It first checks the TOKEN environment variable, then the TOKEN_FILE environment variable.
// If neither is set, it returns an error.
func getToken() (string, error) {
// get token from env var
token, _ := GetEnv("TOKEN")
if token != "" {
return token, nil
}
// get token from file
tokenFile, _ := GetEnv("TOKEN_FILE")
if tokenFile == "" {
return "", errors.New("must set TOKEN or TOKEN_FILE")
}
tokenBytes, err := os.ReadFile(tokenFile)
if err != nil {
return "", err
}
return string(tokenBytes), nil
}
// getOptions returns the WebSocket client options, creating them if necessary.
// It configures the connection URL, TLS settings, and authentication headers.
func (client *WebSocketClient) getOptions() *gws.ClientOption {
if client.options != nil {
return client.options
}
// update the hub url to use websocket scheme and api path
if client.hubURL.Scheme == "https" {
client.hubURL.Scheme = "wss"
} else {
client.hubURL.Scheme = "ws"
}
client.hubURL.Path = path.Join(client.hubURL.Path, "api/beszel/agent-connect")
client.options = &gws.ClientOption{
Addr: client.hubURL.String(),
TlsConfig: &tls.Config{InsecureSkipVerify: true},
RequestHeader: http.Header{
"User-Agent": []string{getUserAgent()},
"X-Token": []string{client.token},
"X-Beszel": []string{beszel.Version},
},
}
return client.options
}
// Connect establishes a WebSocket connection to the hub.
// It closes any existing connection before attempting to reconnect.
func (client *WebSocketClient) Connect() (err error) {
client.lastConnectAttempt = time.Now()
// make sure previous connection is closed
client.Close()
client.Conn, _, err = gws.NewClient(client, client.getOptions())
if err != nil {
return err
}
go client.Conn.ReadLoop()
return nil
}
// OnOpen handles WebSocket connection establishment.
// It sets a deadline for the connection to prevent hanging.
func (client *WebSocketClient) OnOpen(conn *gws.Conn) {
conn.SetDeadline(time.Now().Add(wsDeadline))
}
// OnClose handles WebSocket connection closure.
// It logs the closure reason and notifies the connection manager.
func (client *WebSocketClient) OnClose(conn *gws.Conn, err error) {
slog.Warn("Connection closed", "err", strings.TrimPrefix(err.Error(), "gws: "))
client.agent.connectionManager.eventChan <- WebSocketDisconnect
}
// OnMessage handles incoming WebSocket messages from the hub.
// It decodes CBOR messages and routes them to appropriate handlers.
func (client *WebSocketClient) OnMessage(conn *gws.Conn, message *gws.Message) {
defer message.Close()
conn.SetDeadline(time.Now().Add(wsDeadline))
if message.Opcode != gws.OpcodeBinary {
return
}
if err := cbor.NewDecoder(message.Data).Decode(client.hubRequest); err != nil {
slog.Error("Error parsing message", "err", err)
return
}
if err := client.handleHubRequest(client.hubRequest); err != nil {
slog.Error("Error handling message", "err", err)
}
}
// OnPing handles WebSocket ping frames.
// It responds with a pong and updates the connection deadline.
func (client *WebSocketClient) OnPing(conn *gws.Conn, message []byte) {
conn.SetDeadline(time.Now().Add(wsDeadline))
conn.WritePong(message)
}
// handleAuthChallenge verifies the authenticity of the hub and returns the system's fingerprint.
func (client *WebSocketClient) handleAuthChallenge(msg *common.HubRequest[cbor.RawMessage]) (err error) {
var authRequest common.FingerprintRequest
if err := cbor.Unmarshal(msg.Data, &authRequest); err != nil {
return err
}
if err := client.verifySignature(authRequest.Signature); err != nil {
return err
}
client.hubVerified = true
client.agent.connectionManager.eventChan <- WebSocketConnect
response := &common.FingerprintResponse{
Fingerprint: client.fingerprint,
}
if authRequest.NeedSysInfo {
response.Hostname = client.agent.systemInfo.Hostname
serverAddr := client.agent.connectionManager.serverOptions.Addr
_, response.Port, _ = net.SplitHostPort(serverAddr)
}
return client.sendMessage(response)
}
// verifySignature verifies the signature of the token using the public keys.
func (client *WebSocketClient) verifySignature(signature []byte) (err error) {
for _, pubKey := range client.agent.keys {
sig := ssh.Signature{
Format: pubKey.Type(),
Blob: signature,
}
if err = pubKey.Verify([]byte(client.token), &sig); err == nil {
return nil
}
}
return errors.New("invalid signature - check KEY value")
}
// Close closes the WebSocket connection gracefully.
// This method is safe to call multiple times.
func (client *WebSocketClient) Close() {
if client.Conn != nil {
_ = client.Conn.WriteClose(1000, nil)
}
}
// handleHubRequest routes the request to the appropriate handler.
// It ensures the hub is verified before processing most requests.
func (client *WebSocketClient) handleHubRequest(msg *common.HubRequest[cbor.RawMessage]) error {
if !client.hubVerified && msg.Action != common.CheckFingerprint {
return errors.New("hub not verified")
}
switch msg.Action {
case common.GetData:
return client.sendSystemData()
case common.CheckFingerprint:
return client.handleAuthChallenge(msg)
}
return nil
}
// sendSystemData gathers and sends current system statistics to the hub.
func (client *WebSocketClient) sendSystemData() error {
sysStats := client.agent.gatherStats(client.token)
return client.sendMessage(sysStats)
}
// sendMessage encodes the given data to CBOR and sends it as a binary message over the WebSocket connection to the hub.
func (client *WebSocketClient) sendMessage(data any) error {
bytes, err := cbor.Marshal(data)
if err != nil {
return err
}
return client.Conn.WriteMessage(gws.OpcodeBinary, bytes)
}
// getUserAgent returns one of two User-Agent strings based on current time.
// This is used to avoid being blocked by Cloudflare or other anti-bot measures.
func getUserAgent() string {
const (
uaBase = "Mozilla/5.0 (%s) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
uaWindows = "Windows NT 11.0; Win64; x64"
uaMac = "Macintosh; Intel Mac OS X 14_0_0"
)
if time.Now().UnixNano()%2 == 0 {
return fmt.Sprintf(uaBase, uaWindows)
}
return fmt.Sprintf(uaBase, uaMac)
}

540
agent/client_test.go Normal file
View File

@@ -0,0 +1,540 @@
//go:build testing
// +build testing
package agent
import (
"crypto/ed25519"
"net/url"
"os"
"strings"
"testing"
"time"
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/common"
"github.com/fxamacker/cbor/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
)
// TestNewWebSocketClient tests WebSocket client creation
func TestNewWebSocketClient(t *testing.T) {
agent := createTestAgent(t)
testCases := []struct {
name string
hubURL string
token string
expectError bool
errorMsg string
}{
{
name: "valid configuration",
hubURL: "http://localhost:8080",
token: "test-token-123",
expectError: false,
},
{
name: "valid https URL",
hubURL: "https://hub.example.com",
token: "secure-token",
expectError: false,
},
{
name: "missing hub URL",
hubURL: "",
token: "test-token",
expectError: true,
errorMsg: "HUB_URL environment variable not set",
},
{
name: "invalid URL",
hubURL: "ht\ttp://invalid",
token: "test-token",
expectError: true,
errorMsg: "invalid hub URL",
},
{
name: "missing token",
hubURL: "http://localhost:8080",
token: "",
expectError: true,
errorMsg: "must set TOKEN or TOKEN_FILE",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Set up environment
if tc.hubURL != "" {
os.Setenv("BESZEL_AGENT_HUB_URL", tc.hubURL)
} else {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
}
if tc.token != "" {
os.Setenv("BESZEL_AGENT_TOKEN", tc.token)
} else {
os.Unsetenv("BESZEL_AGENT_TOKEN")
}
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
client, err := newWebSocketClient(agent)
if tc.expectError {
assert.Error(t, err)
if err != nil && tc.errorMsg != "" {
assert.Contains(t, err.Error(), tc.errorMsg)
}
assert.Nil(t, client)
} else {
require.NoError(t, err)
assert.NotNil(t, client)
assert.Equal(t, agent, client.agent)
assert.Equal(t, tc.token, client.token)
assert.Equal(t, tc.hubURL, client.hubURL.String())
assert.NotEmpty(t, client.fingerprint)
assert.NotNil(t, client.hubRequest)
}
})
}
}
// TestWebSocketClient_GetOptions tests WebSocket client options configuration
func TestWebSocketClient_GetOptions(t *testing.T) {
agent := createTestAgent(t)
testCases := []struct {
name string
inputURL string
expectedScheme string
expectedPath string
}{
{
name: "http to ws conversion",
inputURL: "http://localhost:8080",
expectedScheme: "ws",
expectedPath: "/api/beszel/agent-connect",
},
{
name: "https to wss conversion",
inputURL: "https://hub.example.com",
expectedScheme: "wss",
expectedPath: "/api/beszel/agent-connect",
},
{
name: "existing path preservation",
inputURL: "http://localhost:8080/custom/path",
expectedScheme: "ws",
expectedPath: "/custom/path/api/beszel/agent-connect",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Set up environment
os.Setenv("BESZEL_AGENT_HUB_URL", tc.inputURL)
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
client, err := newWebSocketClient(agent)
require.NoError(t, err)
options := client.getOptions()
// Parse the WebSocket URL
wsURL, err := url.Parse(options.Addr)
require.NoError(t, err)
assert.Equal(t, tc.expectedScheme, wsURL.Scheme)
assert.Equal(t, tc.expectedPath, wsURL.Path)
// Check headers
assert.Equal(t, "test-token", options.RequestHeader.Get("X-Token"))
assert.Equal(t, beszel.Version, options.RequestHeader.Get("X-Beszel"))
assert.Contains(t, options.RequestHeader.Get("User-Agent"), "Mozilla/5.0")
// Test options caching
options2 := client.getOptions()
assert.Same(t, options, options2, "Options should be cached")
})
}
}
// TestWebSocketClient_VerifySignature tests signature verification
func TestWebSocketClient_VerifySignature(t *testing.T) {
agent := createTestAgent(t)
// Generate test key pairs
_, goodPrivKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
goodPubKey, err := ssh.NewPublicKey(goodPrivKey.Public().(ed25519.PublicKey))
require.NoError(t, err)
_, badPrivKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
badPubKey, err := ssh.NewPublicKey(badPrivKey.Public().(ed25519.PublicKey))
require.NoError(t, err)
// Set up environment
os.Setenv("BESZEL_AGENT_HUB_URL", "http://localhost:8080")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
client, err := newWebSocketClient(agent)
require.NoError(t, err)
testCases := []struct {
name string
keys []ssh.PublicKey
token string
signWith ed25519.PrivateKey
expectError bool
}{
{
name: "valid signature with correct key",
keys: []ssh.PublicKey{goodPubKey},
token: "test-token",
signWith: goodPrivKey,
expectError: false,
},
{
name: "invalid signature with wrong key",
keys: []ssh.PublicKey{goodPubKey},
token: "test-token",
signWith: badPrivKey,
expectError: true,
},
{
name: "valid signature with multiple keys",
keys: []ssh.PublicKey{badPubKey, goodPubKey},
token: "test-token",
signWith: goodPrivKey,
expectError: false,
},
{
name: "no valid keys",
keys: []ssh.PublicKey{badPubKey},
token: "test-token",
signWith: goodPrivKey,
expectError: true,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
// Set up agent with test keys
agent.keys = tc.keys
client.token = tc.token
// Create signature
signature := ed25519.Sign(tc.signWith, []byte(tc.token))
err := client.verifySignature(signature)
if tc.expectError {
assert.Error(t, err)
assert.Contains(t, err.Error(), "invalid signature")
} else {
assert.NoError(t, err)
}
})
}
}
// TestWebSocketClient_HandleHubRequest tests hub request routing (basic verification logic)
func TestWebSocketClient_HandleHubRequest(t *testing.T) {
agent := createTestAgent(t)
// Set up environment
os.Setenv("BESZEL_AGENT_HUB_URL", "http://localhost:8080")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
client, err := newWebSocketClient(agent)
require.NoError(t, err)
testCases := []struct {
name string
action common.WebSocketAction
hubVerified bool
expectError bool
errorMsg string
}{
{
name: "CheckFingerprint without verification",
action: common.CheckFingerprint,
hubVerified: false,
expectError: false, // CheckFingerprint is allowed without verification
},
{
name: "GetData without verification",
action: common.GetData,
hubVerified: false,
expectError: true,
errorMsg: "hub not verified",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
client.hubVerified = tc.hubVerified
// Create minimal request
hubRequest := &common.HubRequest[cbor.RawMessage]{
Action: tc.action,
Data: cbor.RawMessage{},
}
err := client.handleHubRequest(hubRequest)
if tc.expectError {
assert.Error(t, err)
if tc.errorMsg != "" {
assert.Contains(t, err.Error(), tc.errorMsg)
}
} else {
// For CheckFingerprint, we expect a decode error since we're not providing valid data,
// but it shouldn't be the "hub not verified" error
if err != nil && tc.errorMsg != "" {
assert.NotContains(t, err.Error(), tc.errorMsg)
}
}
})
}
}
// TestWebSocketClient_GetUserAgent tests user agent generation
func TestGetUserAgent(t *testing.T) {
// Run multiple times to check both variants
userAgents := make(map[string]bool)
for range 20 {
ua := getUserAgent()
userAgents[ua] = true
// Check that it's a valid Mozilla user agent
assert.Contains(t, ua, "Mozilla/5.0")
assert.Contains(t, ua, "AppleWebKit/537.36")
assert.Contains(t, ua, "Chrome/124.0.0.0")
assert.Contains(t, ua, "Safari/537.36")
// Should contain either Windows or Mac
isWindows := strings.Contains(ua, "Windows NT 11.0")
isMac := strings.Contains(ua, "Macintosh; Intel Mac OS X 14_0_0")
assert.True(t, isWindows || isMac, "User agent should contain either Windows or Mac identifier")
}
// With enough iterations, we should see both variants
// though this might occasionally fail
if len(userAgents) == 1 {
t.Log("Note: Only one user agent variant was generated in this test run")
}
}
// TestWebSocketClient_Close tests connection closing
func TestWebSocketClient_Close(t *testing.T) {
agent := createTestAgent(t)
// Set up environment
os.Setenv("BESZEL_AGENT_HUB_URL", "http://localhost:8080")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
client, err := newWebSocketClient(agent)
require.NoError(t, err)
// Test closing with nil connection (should not panic)
assert.NotPanics(t, func() {
client.Close()
})
}
// TestWebSocketClient_ConnectRateLimit tests connection rate limiting
func TestWebSocketClient_ConnectRateLimit(t *testing.T) {
agent := createTestAgent(t)
// Set up environment
os.Setenv("BESZEL_AGENT_HUB_URL", "http://localhost:8080")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
client, err := newWebSocketClient(agent)
require.NoError(t, err)
// Set recent connection attempt
client.lastConnectAttempt = time.Now()
// Test that connection fails quickly due to rate limiting
// This won't actually connect but should fail fast
err = client.Connect()
assert.Error(t, err, "Connection should fail but not hang")
}
// TestGetToken tests the getToken function with various scenarios
func TestGetToken(t *testing.T) {
unsetEnvVars := func() {
os.Unsetenv("BESZEL_AGENT_TOKEN")
os.Unsetenv("TOKEN")
os.Unsetenv("BESZEL_AGENT_TOKEN_FILE")
os.Unsetenv("TOKEN_FILE")
}
t.Run("token from TOKEN environment variable", func(t *testing.T) {
unsetEnvVars()
// Set TOKEN env var
expectedToken := "test-token-from-env"
os.Setenv("TOKEN", expectedToken)
defer os.Unsetenv("TOKEN")
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, expectedToken, token)
})
t.Run("token from BESZEL_AGENT_TOKEN environment variable", func(t *testing.T) {
unsetEnvVars()
// Set BESZEL_AGENT_TOKEN env var (should take precedence)
expectedToken := "test-token-from-beszel-env"
os.Setenv("BESZEL_AGENT_TOKEN", expectedToken)
defer os.Unsetenv("BESZEL_AGENT_TOKEN")
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, expectedToken, token)
})
t.Run("token from TOKEN_FILE", func(t *testing.T) {
unsetEnvVars()
// Create a temporary token file
expectedToken := "test-token-from-file"
tokenFile, err := os.CreateTemp("", "token-test-*.txt")
require.NoError(t, err)
defer os.Remove(tokenFile.Name())
_, err = tokenFile.WriteString(expectedToken)
require.NoError(t, err)
tokenFile.Close()
// Set TOKEN_FILE env var
os.Setenv("TOKEN_FILE", tokenFile.Name())
defer os.Unsetenv("TOKEN_FILE")
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, expectedToken, token)
})
t.Run("token from BESZEL_AGENT_TOKEN_FILE", func(t *testing.T) {
unsetEnvVars()
// Create a temporary token file
expectedToken := "test-token-from-beszel-file"
tokenFile, err := os.CreateTemp("", "token-test-*.txt")
require.NoError(t, err)
defer os.Remove(tokenFile.Name())
_, err = tokenFile.WriteString(expectedToken)
require.NoError(t, err)
tokenFile.Close()
// Set BESZEL_AGENT_TOKEN_FILE env var (should take precedence)
os.Setenv("BESZEL_AGENT_TOKEN_FILE", tokenFile.Name())
defer os.Unsetenv("BESZEL_AGENT_TOKEN_FILE")
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, expectedToken, token)
})
t.Run("TOKEN takes precedence over TOKEN_FILE", func(t *testing.T) {
unsetEnvVars()
// Create a temporary token file
fileToken := "token-from-file"
tokenFile, err := os.CreateTemp("", "token-test-*.txt")
require.NoError(t, err)
defer os.Remove(tokenFile.Name())
_, err = tokenFile.WriteString(fileToken)
require.NoError(t, err)
tokenFile.Close()
// Set both TOKEN and TOKEN_FILE
envToken := "token-from-env"
os.Setenv("TOKEN", envToken)
os.Setenv("TOKEN_FILE", tokenFile.Name())
defer func() {
os.Unsetenv("TOKEN")
os.Unsetenv("TOKEN_FILE")
}()
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, envToken, token, "TOKEN should take precedence over TOKEN_FILE")
})
t.Run("error when neither TOKEN nor TOKEN_FILE is set", func(t *testing.T) {
unsetEnvVars()
token, err := getToken()
assert.Error(t, err)
assert.Equal(t, "", token)
assert.Contains(t, err.Error(), "must set TOKEN or TOKEN_FILE")
})
t.Run("error when TOKEN_FILE points to non-existent file", func(t *testing.T) {
unsetEnvVars()
// Set TOKEN_FILE to a non-existent file
os.Setenv("TOKEN_FILE", "/non/existent/file.txt")
defer os.Unsetenv("TOKEN_FILE")
token, err := getToken()
assert.Error(t, err)
assert.Equal(t, "", token)
assert.Contains(t, err.Error(), "no such file or directory")
})
t.Run("handles empty token file", func(t *testing.T) {
unsetEnvVars()
// Create an empty token file
tokenFile, err := os.CreateTemp("", "token-test-*.txt")
require.NoError(t, err)
defer os.Remove(tokenFile.Name())
tokenFile.Close()
// Set TOKEN_FILE env var
os.Setenv("TOKEN_FILE", tokenFile.Name())
defer os.Unsetenv("TOKEN_FILE")
token, err := getToken()
assert.NoError(t, err)
assert.Equal(t, "", token, "Empty file should return empty string")
})
}

221
agent/connection_manager.go Normal file
View File

@@ -0,0 +1,221 @@
package agent
import (
"errors"
"log/slog"
"os"
"os/signal"
"syscall"
"time"
"github.com/henrygd/beszel/agent/health"
)
// 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
}
// ConnectionState represents the current connection state of the agent.
type ConnectionState uint8
// ConnectionEvent represents connection-related events that can occur.
type ConnectionEvent uint8
// Connection states
const (
Disconnected ConnectionState = iota // No active connection
WebSocketConnected // Connected via WebSocket
SSHConnected // Connected via SSH
)
// Connection events
const (
WebSocketConnect ConnectionEvent = iota // WebSocket connection established
WebSocketDisconnect // WebSocket connection lost
SSHConnect // SSH connection established
SSHDisconnect // SSH connection lost
)
const wsTickerInterval = 10 * time.Second
// newConnectionManager creates a new connection manager for the given agent.
func newConnectionManager(agent *Agent) *ConnectionManager {
cm := &ConnectionManager{
agent: agent,
State: Disconnected,
}
return cm
}
// startWsTicker starts or resets the WebSocket connection attempt ticker.
func (c *ConnectionManager) startWsTicker() {
if c.wsTicker == nil {
c.wsTicker = time.NewTicker(wsTickerInterval)
} else {
c.wsTicker.Reset(wsTickerInterval)
}
}
// stopWsTicker stops the WebSocket connection attempt ticker.
func (c *ConnectionManager) stopWsTicker() {
if c.wsTicker != nil {
c.wsTicker.Stop()
}
}
// Start begins connection attempts and enters the main event loop.
// It handles connection events, periodic health updates, and graceful shutdown.
func (c *ConnectionManager) Start(serverOptions ServerOptions) error {
if c.eventChan != nil {
return errors.New("already started")
}
wsClient, err := newWebSocketClient(c.agent)
if err != nil {
slog.Warn("Error creating WebSocket client", "err", err)
}
c.wsClient = wsClient
c.serverOptions = serverOptions
c.eventChan = make(chan ConnectionEvent, 1)
// signal handling for shutdown
sigChan := make(chan os.Signal, 1)
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
c.startWsTicker()
c.connect()
// update health status immediately and every 90 seconds
_ = health.Update()
healthTicker := time.Tick(90 * time.Second)
for {
select {
case connectionEvent := <-c.eventChan:
c.handleEvent(connectionEvent)
case <-c.wsTicker.C:
_ = c.startWebSocketConnection()
case <-healthTicker:
_ = health.Update()
case <-sigChan:
slog.Info("Shutting down")
_ = c.agent.StopServer()
c.closeWebSocket()
return health.CleanUp()
}
}
}
// handleEvent processes connection events and updates the connection state accordingly.
func (c *ConnectionManager) handleEvent(event ConnectionEvent) {
switch event {
case WebSocketConnect:
c.handleStateChange(WebSocketConnected)
case SSHConnect:
c.handleStateChange(SSHConnected)
case WebSocketDisconnect:
if c.State == WebSocketConnected {
c.handleStateChange(Disconnected)
}
case SSHDisconnect:
if c.State == SSHConnected {
c.handleStateChange(Disconnected)
}
}
}
// handleStateChange updates the connection state and performs necessary actions
// based on the new state, including stopping services and initiating reconnections.
func (c *ConnectionManager) handleStateChange(newState ConnectionState) {
if c.State == newState {
return
}
c.State = newState
switch newState {
case WebSocketConnected:
slog.Info("WebSocket connected", "host", c.wsClient.hubURL.Host)
c.stopWsTicker()
_ = c.agent.StopServer()
c.isConnecting = false
case SSHConnected:
// stop new ws connection attempts
slog.Info("SSH connection established")
c.stopWsTicker()
c.isConnecting = false
case Disconnected:
if c.isConnecting {
// Already handling reconnection, avoid duplicate attempts
return
}
c.isConnecting = true
slog.Warn("Disconnected from hub")
// make sure old ws connection is closed
c.closeWebSocket()
// reconnect
go c.connect()
}
}
// connect handles the connection logic with proper delays and priority.
// It attempts WebSocket connection first, falling back to SSH server if needed.
func (c *ConnectionManager) connect() {
c.isConnecting = true
defer func() {
c.isConnecting = false
}()
if c.wsClient != nil && time.Since(c.wsClient.lastConnectAttempt) < 5*time.Second {
time.Sleep(5 * time.Second)
}
// Try WebSocket first, if it fails, start SSH server
err := c.startWebSocketConnection()
if err != nil && c.State == Disconnected {
c.startSSHServer()
c.startWsTicker()
}
}
// startWebSocketConnection attempts to establish a WebSocket connection to the hub.
func (c *ConnectionManager) startWebSocketConnection() error {
if c.State != Disconnected {
return errors.New("already connected")
}
if c.wsClient == nil {
return errors.New("WebSocket client not initialized")
}
if time.Since(c.wsClient.lastConnectAttempt) < 5*time.Second {
return errors.New("already connecting")
}
err := c.wsClient.Connect()
if err != nil {
slog.Warn("WebSocket connection failed", "err", err)
c.closeWebSocket()
}
return err
}
// startSSHServer starts the SSH server if the agent is currently disconnected.
func (c *ConnectionManager) startSSHServer() {
if c.State == Disconnected {
go c.agent.StartServer(c.serverOptions)
}
}
// closeWebSocket closes the WebSocket connection if it exists.
func (c *ConnectionManager) closeWebSocket() {
if c.wsClient != nil {
c.wsClient.Close()
}
}

View File

@@ -0,0 +1,315 @@
//go:build testing
// +build testing
package agent
import (
"crypto/ed25519"
"fmt"
"net"
"net/url"
"os"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
)
func createTestAgent(t *testing.T) *Agent {
dataDir := t.TempDir()
agent, err := NewAgent(dataDir)
require.NoError(t, err)
return agent
}
func createTestServerOptions(t *testing.T) ServerOptions {
// Generate test key pair
_, privKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
sshPubKey, err := ssh.NewPublicKey(privKey.Public().(ed25519.PublicKey))
require.NoError(t, err)
// Find available port
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err)
port := listener.Addr().(*net.TCPAddr).Port
listener.Close()
return ServerOptions{
Network: "tcp",
Addr: fmt.Sprintf("127.0.0.1:%d", port),
Keys: []ssh.PublicKey{sshPubKey},
}
}
// TestConnectionManager_NewConnectionManager tests connection manager creation
func TestConnectionManager_NewConnectionManager(t *testing.T) {
agent := createTestAgent(t)
cm := newConnectionManager(agent)
assert.NotNil(t, cm, "Connection manager should not be nil")
assert.Equal(t, agent, cm.agent, "Agent reference should be set")
assert.Equal(t, Disconnected, cm.State, "Initial state should be Disconnected")
assert.Nil(t, cm.eventChan, "Event channel should be nil initially")
assert.Nil(t, cm.wsClient, "WebSocket client should be nil initially")
assert.Nil(t, cm.wsTicker, "WebSocket ticker should be nil initially")
assert.False(t, cm.isConnecting, "isConnecting should be false initially")
}
// TestConnectionManager_StateTransitions tests basic state transitions
func TestConnectionManager_StateTransitions(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
initialState := cm.State
cm.wsClient = &WebSocketClient{
hubURL: &url.URL{
Host: "localhost:8080",
},
}
assert.NotNil(t, cm, "Connection manager should not be nil")
assert.Equal(t, Disconnected, initialState, "Initial state should be Disconnected")
// Test state transitions
cm.handleStateChange(WebSocketConnected)
assert.Equal(t, WebSocketConnected, cm.State, "State should change to WebSocketConnected")
cm.handleStateChange(SSHConnected)
assert.Equal(t, SSHConnected, cm.State, "State should change to SSHConnected")
cm.handleStateChange(Disconnected)
assert.Equal(t, Disconnected, cm.State, "State should change to Disconnected")
// Test that same state doesn't trigger changes
cm.State = WebSocketConnected
cm.handleStateChange(WebSocketConnected)
assert.Equal(t, WebSocketConnected, cm.State, "Same state should not trigger change")
}
// TestConnectionManager_EventHandling tests event handling logic
func TestConnectionManager_EventHandling(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
cm.wsClient = &WebSocketClient{
hubURL: &url.URL{
Host: "localhost:8080",
},
}
testCases := []struct {
name string
initialState ConnectionState
event ConnectionEvent
expectedState ConnectionState
}{
{
name: "WebSocket connect from disconnected",
initialState: Disconnected,
event: WebSocketConnect,
expectedState: WebSocketConnected,
},
{
name: "SSH connect from disconnected",
initialState: Disconnected,
event: SSHConnect,
expectedState: SSHConnected,
},
{
name: "WebSocket disconnect from connected",
initialState: WebSocketConnected,
event: WebSocketDisconnect,
expectedState: Disconnected,
},
{
name: "SSH disconnect from connected",
initialState: SSHConnected,
event: SSHDisconnect,
expectedState: Disconnected,
},
{
name: "WebSocket disconnect from SSH connected (no change)",
initialState: SSHConnected,
event: WebSocketDisconnect,
expectedState: SSHConnected,
},
{
name: "SSH disconnect from WebSocket connected (no change)",
initialState: WebSocketConnected,
event: SSHDisconnect,
expectedState: WebSocketConnected,
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
cm.State = tc.initialState
cm.handleEvent(tc.event)
assert.Equal(t, tc.expectedState, cm.State, "State should match expected after event")
})
}
}
// TestConnectionManager_TickerManagement tests WebSocket ticker management
func TestConnectionManager_TickerManagement(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
// Test starting ticker
cm.startWsTicker()
assert.NotNil(t, cm.wsTicker, "Ticker should be created")
// Test stopping ticker (should not panic)
assert.NotPanics(t, func() {
cm.stopWsTicker()
}, "Stopping ticker should not panic")
// Test stopping nil ticker (should not panic)
cm.wsTicker = nil
assert.NotPanics(t, func() {
cm.stopWsTicker()
}, "Stopping nil ticker should not panic")
// Test restarting ticker
cm.startWsTicker()
assert.NotNil(t, cm.wsTicker, "Ticker should be recreated")
// Test resetting existing ticker
firstTicker := cm.wsTicker
cm.startWsTicker()
assert.Equal(t, firstTicker, cm.wsTicker, "Same ticker instance should be reused")
cm.stopWsTicker()
}
// TestConnectionManager_WebSocketConnectionFlow tests WebSocket connection logic
func TestConnectionManager_WebSocketConnectionFlow(t *testing.T) {
if testing.Short() {
t.Skip("Skipping WebSocket connection test in short mode")
}
agent := createTestAgent(t)
cm := agent.connectionManager
// Test WebSocket connection without proper environment
err := cm.startWebSocketConnection()
assert.Error(t, err, "WebSocket connection should fail without proper environment")
assert.Equal(t, Disconnected, cm.State, "State should remain Disconnected after failed connection")
// Test with invalid URL
os.Setenv("BESZEL_AGENT_HUB_URL", "invalid-url")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
// Test with missing token
os.Setenv("BESZEL_AGENT_HUB_URL", "http://localhost:8080")
os.Unsetenv("BESZEL_AGENT_TOKEN")
_, err2 := newWebSocketClient(agent)
assert.Error(t, err2, "WebSocket client creation should fail without token")
}
// TestConnectionManager_ReconnectionLogic tests reconnection prevention logic
func TestConnectionManager_ReconnectionLogic(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
cm.eventChan = make(chan ConnectionEvent, 1)
// Test that isConnecting flag prevents duplicate reconnection attempts
// Start from connected state, then simulate disconnect
cm.State = WebSocketConnected
cm.isConnecting = false
// First disconnect should trigger reconnection logic
cm.handleStateChange(Disconnected)
assert.Equal(t, Disconnected, cm.State, "Should change to disconnected")
assert.True(t, cm.isConnecting, "Should set isConnecting flag")
}
// TestConnectionManager_ConnectWithRateLimit tests connection rate limiting
func TestConnectionManager_ConnectWithRateLimit(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
// Set up environment for WebSocket client creation
os.Setenv("BESZEL_AGENT_HUB_URL", "ws://localhost:8080")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
// Create WebSocket client
wsClient, err := newWebSocketClient(agent)
require.NoError(t, err)
cm.wsClient = wsClient
// Set recent connection attempt
cm.wsClient.lastConnectAttempt = time.Now()
// Test that connection is rate limited
err = cm.startWebSocketConnection()
assert.Error(t, err, "Should error due to rate limiting")
assert.Contains(t, err.Error(), "already connecting", "Error should indicate rate limiting")
// Test connection after rate limit expires
cm.wsClient.lastConnectAttempt = time.Now().Add(-10 * time.Second)
err = cm.startWebSocketConnection()
// This will fail due to no actual server, but should not be rate limited
assert.Error(t, err, "Connection should fail but not due to rate limiting")
assert.NotContains(t, err.Error(), "already connecting", "Error should not indicate rate limiting")
}
// TestConnectionManager_StartWithInvalidConfig tests starting with invalid configuration
func TestConnectionManager_StartWithInvalidConfig(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
serverOptions := createTestServerOptions(t)
// Test starting when already started
cm.eventChan = make(chan ConnectionEvent, 5)
err := cm.Start(serverOptions)
assert.Error(t, err, "Should error when starting already started connection manager")
}
// TestConnectionManager_CloseWebSocket tests WebSocket closing
func TestConnectionManager_CloseWebSocket(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
// Test closing when no WebSocket client exists
assert.NotPanics(t, func() {
cm.closeWebSocket()
}, "Should not panic when closing nil WebSocket client")
// Set up environment and create WebSocket client
os.Setenv("BESZEL_AGENT_HUB_URL", "ws://localhost:8080")
os.Setenv("BESZEL_AGENT_TOKEN", "test-token")
defer func() {
os.Unsetenv("BESZEL_AGENT_HUB_URL")
os.Unsetenv("BESZEL_AGENT_TOKEN")
}()
wsClient, err := newWebSocketClient(agent)
require.NoError(t, err)
cm.wsClient = wsClient
// Test closing when WebSocket client exists
assert.NotPanics(t, func() {
cm.closeWebSocket()
}, "Should not panic when closing WebSocket client")
}
// TestConnectionManager_ConnectFlow tests the connect method
func TestConnectionManager_ConnectFlow(t *testing.T) {
agent := createTestAgent(t)
cm := agent.connectionManager
// Test connect without WebSocket client
assert.NotPanics(t, func() {
cm.connect()
}, "Connect should not panic without WebSocket client")
}

117
agent/data_dir.go Normal file
View File

@@ -0,0 +1,117 @@
package agent
import (
"errors"
"fmt"
"os"
"path/filepath"
"runtime"
)
// getDataDir returns the path to the data directory for the agent and an error
// if the directory is not valid. Attempts to find the optimal data directory if
// no data directories are provided.
func getDataDir(dataDirs ...string) (string, error) {
if len(dataDirs) > 0 {
return testDataDirs(dataDirs)
}
dataDir, _ := GetEnv("DATA_DIR")
if dataDir != "" {
dataDirs = append(dataDirs, dataDir)
}
if runtime.GOOS == "windows" {
dataDirs = append(dataDirs,
filepath.Join(os.Getenv("APPDATA"), "beszel-agent"),
filepath.Join(os.Getenv("LOCALAPPDATA"), "beszel-agent"),
)
} else {
dataDirs = append(dataDirs, "/var/lib/beszel-agent")
if homeDir, err := os.UserHomeDir(); err == nil {
dataDirs = append(dataDirs, filepath.Join(homeDir, ".config", "beszel"))
}
}
return testDataDirs(dataDirs)
}
func testDataDirs(paths []string) (string, error) {
// first check if the directory exists and is writable
for _, path := range paths {
if valid, _ := isValidDataDir(path, false); valid {
return path, nil
}
}
// if the directory doesn't exist, try to create it
for _, path := range paths {
exists, _ := directoryExists(path)
if exists {
continue
}
if err := os.MkdirAll(path, 0755); err != nil {
continue
}
// Verify the created directory is actually writable
writable, _ := directoryIsWritable(path)
if !writable {
continue
}
return path, nil
}
return "", errors.New("data directory not found")
}
func isValidDataDir(path string, createIfNotExists bool) (bool, error) {
exists, err := directoryExists(path)
if err != nil {
return false, err
}
if !exists {
if !createIfNotExists {
return false, nil
}
if err = os.MkdirAll(path, 0755); err != nil {
return false, err
}
}
// Always check if the directory is writable
writable, err := directoryIsWritable(path)
if err != nil {
return false, err
}
return writable, nil
}
// directoryExists checks if a directory exists
func directoryExists(path string) (bool, error) {
// Check if directory exists
stat, err := os.Stat(path)
if err != nil {
if os.IsNotExist(err) {
return false, nil
}
return false, err
}
if !stat.IsDir() {
return false, fmt.Errorf("%s is not a directory", path)
}
return true, nil
}
// directoryIsWritable tests if a directory is writable by creating and removing a temporary file
func directoryIsWritable(path string) (bool, error) {
testFile := filepath.Join(path, ".write-test")
file, err := os.Create(testFile)
if err != nil {
return false, err
}
defer file.Close()
defer os.Remove(testFile)
return true, nil
}

263
agent/data_dir_test.go Normal file
View File

@@ -0,0 +1,263 @@
//go:build testing
// +build testing
package agent
import (
"os"
"path/filepath"
"runtime"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestGetDataDir(t *testing.T) {
// Test with explicit dataDir parameter
t.Run("explicit data dir", func(t *testing.T) {
tempDir := t.TempDir()
result, err := getDataDir(tempDir)
require.NoError(t, err)
assert.Equal(t, tempDir, result)
})
// Test with explicit non-existent dataDir that can be created
t.Run("explicit data dir - create new", func(t *testing.T) {
tempDir := t.TempDir()
newDir := filepath.Join(tempDir, "new-data-dir")
result, err := getDataDir(newDir)
require.NoError(t, err)
assert.Equal(t, newDir, result)
// Verify directory was created
stat, err := os.Stat(newDir)
require.NoError(t, err)
assert.True(t, stat.IsDir())
})
// Test with DATA_DIR environment variable
t.Run("DATA_DIR environment variable", func(t *testing.T) {
tempDir := t.TempDir()
// Set environment variable
oldValue := os.Getenv("DATA_DIR")
defer func() {
if oldValue == "" {
os.Unsetenv("BESZEL_AGENT_DATA_DIR")
} else {
os.Setenv("BESZEL_AGENT_DATA_DIR", oldValue)
}
}()
os.Setenv("BESZEL_AGENT_DATA_DIR", tempDir)
result, err := getDataDir()
require.NoError(t, err)
assert.Equal(t, tempDir, result)
})
// Test with invalid explicit dataDir
t.Run("invalid explicit data dir", func(t *testing.T) {
invalidPath := "/invalid/path/that/cannot/be/created"
_, err := getDataDir(invalidPath)
assert.Error(t, err)
})
// Test fallback behavior (empty dataDir, no env var)
t.Run("fallback to default directories", func(t *testing.T) {
// Clear DATA_DIR environment variable
oldValue := os.Getenv("DATA_DIR")
defer func() {
if oldValue == "" {
os.Unsetenv("DATA_DIR")
} else {
os.Setenv("DATA_DIR", oldValue)
}
}()
os.Unsetenv("DATA_DIR")
// This will try platform-specific defaults, which may or may not work
// We're mainly testing that it doesn't panic and returns some result
result, err := getDataDir()
// We don't assert success/failure here since it depends on system permissions
// Just verify we get a string result if no error
if err == nil {
assert.NotEmpty(t, result)
}
})
}
func TestTestDataDirs(t *testing.T) {
// Test with existing valid directory
t.Run("existing valid directory", func(t *testing.T) {
tempDir := t.TempDir()
result, err := testDataDirs([]string{tempDir})
require.NoError(t, err)
assert.Equal(t, tempDir, result)
})
// Test with multiple directories, first one valid
t.Run("multiple dirs - first valid", func(t *testing.T) {
tempDir := t.TempDir()
invalidDir := "/invalid/path"
result, err := testDataDirs([]string{tempDir, invalidDir})
require.NoError(t, err)
assert.Equal(t, tempDir, result)
})
// Test with multiple directories, second one valid
t.Run("multiple dirs - second valid", func(t *testing.T) {
tempDir := t.TempDir()
invalidDir := "/invalid/path"
result, err := testDataDirs([]string{invalidDir, tempDir})
require.NoError(t, err)
assert.Equal(t, tempDir, result)
})
// Test with non-existing directory that can be created
t.Run("create new directory", func(t *testing.T) {
tempDir := t.TempDir()
newDir := filepath.Join(tempDir, "new-dir")
result, err := testDataDirs([]string{newDir})
require.NoError(t, err)
assert.Equal(t, newDir, result)
// Verify directory was created
stat, err := os.Stat(newDir)
require.NoError(t, err)
assert.True(t, stat.IsDir())
})
// Test with no valid directories
t.Run("no valid directories", func(t *testing.T) {
invalidPaths := []string{"/invalid/path1", "/invalid/path2"}
_, err := testDataDirs(invalidPaths)
assert.Error(t, err)
assert.Contains(t, err.Error(), "data directory not found")
})
}
func TestIsValidDataDir(t *testing.T) {
// Test with existing directory
t.Run("existing directory", func(t *testing.T) {
tempDir := t.TempDir()
valid, err := isValidDataDir(tempDir, false)
require.NoError(t, err)
assert.True(t, valid)
})
// Test with non-existing directory, createIfNotExists=false
t.Run("non-existing dir - no create", func(t *testing.T) {
tempDir := t.TempDir()
nonExistentDir := filepath.Join(tempDir, "does-not-exist")
valid, err := isValidDataDir(nonExistentDir, false)
require.NoError(t, err)
assert.False(t, valid)
})
// Test with non-existing directory, createIfNotExists=true
t.Run("non-existing dir - create", func(t *testing.T) {
tempDir := t.TempDir()
newDir := filepath.Join(tempDir, "new-dir")
valid, err := isValidDataDir(newDir, true)
require.NoError(t, err)
assert.True(t, valid)
// Verify directory was created
stat, err := os.Stat(newDir)
require.NoError(t, err)
assert.True(t, stat.IsDir())
})
// Test with file instead of directory
t.Run("file instead of directory", func(t *testing.T) {
tempDir := t.TempDir()
tempFile := filepath.Join(tempDir, "testfile")
err := os.WriteFile(tempFile, []byte("test"), 0644)
require.NoError(t, err)
valid, err := isValidDataDir(tempFile, false)
assert.Error(t, err)
assert.False(t, valid)
assert.Contains(t, err.Error(), "is not a directory")
})
}
func TestDirectoryExists(t *testing.T) {
// Test with existing directory
t.Run("existing directory", func(t *testing.T) {
tempDir := t.TempDir()
exists, err := directoryExists(tempDir)
require.NoError(t, err)
assert.True(t, exists)
})
// Test with non-existing directory
t.Run("non-existing directory", func(t *testing.T) {
tempDir := t.TempDir()
nonExistentDir := filepath.Join(tempDir, "does-not-exist")
exists, err := directoryExists(nonExistentDir)
require.NoError(t, err)
assert.False(t, exists)
})
// Test with file instead of directory
t.Run("file instead of directory", func(t *testing.T) {
tempDir := t.TempDir()
tempFile := filepath.Join(tempDir, "testfile")
err := os.WriteFile(tempFile, []byte("test"), 0644)
require.NoError(t, err)
exists, err := directoryExists(tempFile)
assert.Error(t, err)
assert.False(t, exists)
assert.Contains(t, err.Error(), "is not a directory")
})
}
func TestDirectoryIsWritable(t *testing.T) {
// Test with writable directory
t.Run("writable directory", func(t *testing.T) {
tempDir := t.TempDir()
writable, err := directoryIsWritable(tempDir)
require.NoError(t, err)
assert.True(t, writable)
})
// Test with non-existing directory
t.Run("non-existing directory", func(t *testing.T) {
tempDir := t.TempDir()
nonExistentDir := filepath.Join(tempDir, "does-not-exist")
writable, err := directoryIsWritable(nonExistentDir)
assert.Error(t, err)
assert.False(t, writable)
})
// Test with non-writable directory (Unix-like systems only)
t.Run("non-writable directory", func(t *testing.T) {
if runtime.GOOS != "linux" && runtime.GOOS != "darwin" {
t.Skip("Skipping non-writable directory test on", runtime.GOOS)
}
tempDir := t.TempDir()
readOnlyDir := filepath.Join(tempDir, "readonly")
// Create the directory
err := os.Mkdir(readOnlyDir, 0755)
require.NoError(t, err)
// Make it read-only
err = os.Chmod(readOnlyDir, 0444)
require.NoError(t, err)
// Restore permissions after test for cleanup
defer func() {
os.Chmod(readOnlyDir, 0755)
}()
writable, err := directoryIsWritable(readOnlyDir)
assert.Error(t, err)
assert.False(t, writable)
})
}

View File

@@ -1,7 +1,6 @@
package agent
import (
"beszel/internal/entities/system"
"log/slog"
"os"
"path/filepath"
@@ -9,6 +8,8 @@ import (
"strings"
"time"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/shirou/gopsutil/v4/disk"
)

View File

@@ -1,7 +1,7 @@
package agent
import (
"beszel/internal/entities/container"
"bytes"
"context"
"encoding/json"
"fmt"
@@ -14,6 +14,8 @@ import (
"sync"
"time"
"github.com/henrygd/beszel/internal/entities/container"
"github.com/blang/semver"
)
@@ -27,6 +29,9 @@ type dockerManager struct {
validIds map[string]struct{} // Map of valid container ids, used to prune invalid containers from containerStatsMap
goodDockerVersion bool // Whether docker version is at least 25.0.0 (one-shot works correctly)
isWindows bool // Whether the Docker Engine API is running on Windows
buf *bytes.Buffer // Buffer to store and read response bodies
decoder *json.Decoder // Reusable JSON decoder that reads from buf
apiStats *container.ApiStats // Reusable API stats object
}
// userAgentRoundTripper is a custom http.RoundTripper that adds a User-Agent header to all requests
@@ -63,10 +68,9 @@ func (dm *dockerManager) getDockerStats() ([]*container.Stats, error) {
if err != nil {
return nil, err
}
defer resp.Body.Close()
dm.apiContainerList = dm.apiContainerList[:0]
if err := json.NewDecoder(resp.Body).Decode(&dm.apiContainerList); err != nil {
if err := dm.decode(resp, &dm.apiContainerList); err != nil {
return nil, err
}
@@ -83,7 +87,8 @@ func (dm *dockerManager) getDockerStats() ([]*container.Stats, error) {
var failedContainers []*container.ApiInfo
for _, ctr := range dm.apiContainerList {
for i := range dm.apiContainerList {
ctr := dm.apiContainerList[i]
ctr.IdShort = ctr.Id[:12]
dm.validIds[ctr.IdShort] = struct{}{}
// check if container is less than 1 minute old (possible restart)
@@ -111,7 +116,8 @@ func (dm *dockerManager) getDockerStats() ([]*container.Stats, error) {
// retry failed containers separately so we can run them in parallel (docker 24 bug)
if len(failedContainers) > 0 {
slog.Debug("Retrying failed containers", "count", len(failedContainers))
for _, ctr := range failedContainers {
for i := range failedContainers {
ctr := failedContainers[i]
dm.queue()
go func() {
defer dm.dequeue()
@@ -164,8 +170,13 @@ func (dm *dockerManager) updateContainerStats(ctr *container.ApiInfo) error {
stats.NetworkRecv = 0
// docker host container stats response
var res container.ApiStats
if err := json.NewDecoder(resp.Body).Decode(&res); err != nil {
// res := dm.getApiStats()
// defer dm.putApiStats(res)
//
res := dm.apiStats
res.Networks = nil
if err := dm.decode(resp, res); err != nil {
return err
}
@@ -173,9 +184,14 @@ func (dm *dockerManager) updateContainerStats(ctr *container.ApiInfo) error {
var usedMemory uint64
var cpuPct float64
// store current cpu stats
prevCpuContainer, prevCpuSystem := stats.CpuContainer, stats.CpuSystem
stats.CpuContainer = res.CPUStats.CPUUsage.TotalUsage
stats.CpuSystem = res.CPUStats.SystemUsage
if dm.isWindows {
usedMemory = res.MemoryStats.PrivateWorkingSet
cpuPct = res.CalculateCpuPercentWindows(stats.PrevCpu[0], stats.PrevRead)
cpuPct = res.CalculateCpuPercentWindows(prevCpuContainer, stats.PrevReadTime)
} else {
// check if container has valid data, otherwise may be in restart loop (#103)
if res.MemoryStats.Usage == 0 {
@@ -187,13 +203,12 @@ func (dm *dockerManager) updateContainerStats(ctr *container.ApiInfo) error {
}
usedMemory = res.MemoryStats.Usage - memCache
cpuPct = res.CalculateCpuPercentLinux(stats.PrevCpu)
cpuPct = res.CalculateCpuPercentLinux(prevCpuContainer, prevCpuSystem)
}
if cpuPct > 100 {
return fmt.Errorf("%s cpu pct greater than 100: %+v", name, cpuPct)
}
stats.PrevCpu = [2]uint64{res.CPUStats.CPUUsage.TotalUsage, res.CPUStats.SystemUsage}
// network
var total_sent, total_recv uint64
@@ -201,21 +216,25 @@ func (dm *dockerManager) updateContainerStats(ctr *container.ApiInfo) error {
total_sent += v.TxBytes
total_recv += v.RxBytes
}
var sent_delta, recv_delta float64
// prevent first run from sending all prev sent/recv bytes
if initialized {
secondsElapsed := time.Since(stats.PrevRead).Seconds()
sent_delta = float64(total_sent-stats.PrevNet.Sent) / secondsElapsed
recv_delta = float64(total_recv-stats.PrevNet.Recv) / secondsElapsed
var sent_delta, recv_delta uint64
millisecondsElapsed := uint64(time.Since(stats.PrevReadTime).Milliseconds())
if initialized && millisecondsElapsed > 0 {
// get bytes per second
sent_delta = (total_sent - stats.PrevNet.Sent) * 1000 / millisecondsElapsed
recv_delta = (total_recv - stats.PrevNet.Recv) * 1000 / millisecondsElapsed
// check for unrealistic network values (> 5GB/s)
if sent_delta > 5e9 || recv_delta > 5e9 {
slog.Warn("Bad network delta", "container", name)
sent_delta, recv_delta = 0, 0
}
}
stats.PrevNet.Sent = total_sent
stats.PrevNet.Recv = total_recv
stats.PrevNet.Sent, stats.PrevNet.Recv = total_sent, total_recv
stats.Cpu = twoDecimals(cpuPct)
stats.Mem = bytesToMegabytes(float64(usedMemory))
stats.NetworkSent = bytesToMegabytes(sent_delta)
stats.NetworkRecv = bytesToMegabytes(recv_delta)
stats.PrevRead = res.Read
stats.NetworkSent = bytesToMegabytes(float64(sent_delta))
stats.NetworkRecv = bytesToMegabytes(float64(recv_delta))
stats.PrevReadTime = res.Read
return nil
}
@@ -231,14 +250,16 @@ func (dm *dockerManager) deleteContainerStatsSync(id string) {
func newDockerManager(a *Agent) *dockerManager {
dockerHost, exists := GetEnv("DOCKER_HOST")
if exists {
slog.Info("DOCKER_HOST", "host", dockerHost)
// return nil if set to empty string
if dockerHost == "" {
return nil
}
} else {
dockerHost = getDockerHost()
}
parsedURL, err := url.Parse(dockerHost)
if err != nil {
slog.Error("Error parsing DOCKER_HOST", "err", err)
os.Exit(1)
}
@@ -286,6 +307,7 @@ func newDockerManager(a *Agent) *dockerManager {
containerStatsMap: make(map[string]*container.Stats),
sem: make(chan struct{}, 5),
apiContainerList: []*container.ApiInfo{},
apiStats: &container.ApiStats{},
}
// If using podman, return client
@@ -304,9 +326,8 @@ func newDockerManager(a *Agent) *dockerManager {
if err != nil {
return manager
}
defer resp.Body.Close()
if err := json.NewDecoder(resp.Body).Decode(&versionInfo); err != nil {
if err := manager.decode(resp, &versionInfo); err != nil {
return manager
}
@@ -320,6 +341,22 @@ func newDockerManager(a *Agent) *dockerManager {
return manager
}
// Decodes Docker API JSON response using a reusable buffer and decoder. Not thread safe.
func (dm *dockerManager) decode(resp *http.Response, d any) error {
if dm.buf == nil {
// initialize buffer with 256kb starting size
dm.buf = bytes.NewBuffer(make([]byte, 0, 1024*256))
dm.decoder = json.NewDecoder(dm.buf)
}
defer resp.Body.Close()
defer dm.buf.Reset()
_, err := dm.buf.ReadFrom(resp.Body)
if err != nil {
return err
}
return dm.decoder.Decode(d)
}
// Test docker / podman sockets and return if one exists
func getDockerHost() string {
scheme := "unix://"

View File

@@ -1,7 +1,6 @@
package agent
import (
"beszel/internal/entities/system"
"bufio"
"bytes"
"encoding/json"
@@ -13,29 +12,31 @@ import (
"sync"
"time"
"github.com/henrygd/beszel/internal/entities/system"
"golang.org/x/exp/slog"
)
const (
// Commands
nvidiaSmiCmd = "nvidia-smi"
rocmSmiCmd = "rocm-smi"
tegraStatsCmd = "tegrastats"
nvidiaSmiCmd string = "nvidia-smi"
rocmSmiCmd string = "rocm-smi"
tegraStatsCmd string = "tegrastats"
// Polling intervals
nvidiaSmiInterval = "4" // in seconds
tegraStatsInterval = "3700" // in milliseconds
rocmSmiInterval = 4300 * time.Millisecond
nvidiaSmiInterval string = "4" // in seconds
tegraStatsInterval string = "3700" // in milliseconds
rocmSmiInterval time.Duration = 4300 * time.Millisecond
// Command retry and timeout constants
retryWaitTime = 5 * time.Second
maxFailureRetries = 5
retryWaitTime time.Duration = 5 * time.Second
maxFailureRetries int = 5
cmdBufferSize = 10 * 1024
cmdBufferSize uint16 = 10 * 1024
// Unit Conversions
mebibytesInAMegabyte = 1.024 // nvidia-smi reports memory in MiB
milliwattsInAWatt = 1000.0 // tegrastats reports power in mW
mebibytesInAMegabyte float64 = 1.024 // nvidia-smi reports memory in MiB
milliwattsInAWatt float64 = 1000.0 // tegrastats reports power in mW
)
// GPUManager manages data collection for GPUs (either Nvidia or AMD)
@@ -243,21 +244,26 @@ 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 {
// sum the data
gpu.Temperature = twoDecimals(gpu.Temperature)
gpu.MemoryUsed = twoDecimals(gpu.MemoryUsed)
gpu.MemoryTotal = twoDecimals(gpu.MemoryTotal)
gpu.Usage = twoDecimals(gpu.Usage / gpu.Count)
gpu.Power = twoDecimals(gpu.Power / gpu.Count)
// reset the count
gpu.Count = 1
// dereference to avoid overwriting anything else
gpuCopy := *gpu
gpuAvg := *gpu
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.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 {
gpuCopy.Name = fmt.Sprintf("%s %s", gpu.Name, id)
gpuAvg.Name = fmt.Sprintf("%s %s", gpu.Name, id)
}
gpuData[id] = gpuCopy
gpuData[id] = gpuAvg
}
slog.Debug("GPU", "data", gpuData)
return gpuData

View File

@@ -4,12 +4,13 @@
package agent
import (
"beszel/internal/entities/system"
"os"
"path/filepath"
"testing"
"time"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -279,6 +280,19 @@ func TestParseJetsonData(t *testing.T) {
Count: 1,
},
},
{
name: "orin nano",
input: "06-18-2025 11:25:24 RAM 3452/7620MB (lfb 25x4MB) SWAP 1518/16384MB (cached 174MB) CPU [1%@1420,2%@1420,0%@1420,2%@1420,2%@729,1%@729] GR3D_FREQ 0% cpu@50.031C soc2@49.031C soc0@50C gpu@49.031C tj@50.25C soc1@50.25C VDD_IN 4824mW/4824mW VDD_CPU_GPU_CV 518mW/518mW VDD_SOC 1475mW/1475mW",
wantMetrics: &system.GPUData{
Name: "GPU",
MemoryUsed: 3452.0,
MemoryTotal: 7620.0,
Usage: 0.0,
Temperature: 50.25,
Power: 0.518,
Count: 1,
},
},
{
name: "missing temperature",
input: "11-14-2024 22:54:33 RAM 4300/30698MB GR3D_FREQ 45% VDD_GPU_SOC 2171mW",
@@ -318,44 +332,85 @@ func TestParseJetsonData(t *testing.T) {
}
func TestGetCurrentData(t *testing.T) {
gm := &GPUManager{
GpuDataMap: map[string]*system.GPUData{
"0": {
Name: "GPU1",
Temperature: 50,
MemoryUsed: 2048,
MemoryTotal: 4096,
Usage: 100, // 100 over 2 counts = 50 avg
Power: 200, // 200 over 2 counts = 100 avg
Count: 2,
t.Run("calculates averages and resets accumulators", func(t *testing.T) {
gm := &GPUManager{
GpuDataMap: map[string]*system.GPUData{
"0": {
Name: "GPU1",
Temperature: 50,
MemoryUsed: 2048,
MemoryTotal: 4096,
Usage: 100, // 100 over 2 counts = 50 avg
Power: 200, // 200 over 2 counts = 100 avg
Count: 2,
},
"1": {
Name: "GPU1",
Temperature: 60,
MemoryUsed: 3072,
MemoryTotal: 8192,
Usage: 30,
Power: 60,
Count: 1,
},
"2": {
Name: "GPU 2",
Temperature: 70,
MemoryUsed: 4096,
MemoryTotal: 8192,
Usage: 200,
Power: 400,
Count: 1,
},
},
"1": {
Name: "GPU1",
Temperature: 60,
MemoryUsed: 3072,
MemoryTotal: 8192,
Usage: 30,
Power: 60,
Count: 1,
}
result := gm.GetCurrentData()
// Verify name disambiguation
assert.Equal(t, "GPU1 0", result["0"].Name)
assert.Equal(t, "GPU1 1", result["1"].Name)
assert.Equal(t, "GPU 2", result["2"].Name)
// Check averaged values in the result
assert.InDelta(t, 50.0, result["0"].Usage, 0.01)
assert.InDelta(t, 100.0, result["0"].Power, 0.01)
assert.InDelta(t, 30.0, result["1"].Usage, 0.01)
assert.InDelta(t, 60.0, result["1"].Power, 0.01)
// Verify that accumulators in the original map are 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) {
gm := &GPUManager{
GpuDataMap: map[string]*system.GPUData{
"0": {
Name: "TestGPU",
Count: 0,
Usage: 0,
Power: 0,
},
},
},
}
}
result := gm.GetCurrentData()
var result map[string]system.GPUData
assert.NotPanics(t, func() {
result = gm.GetCurrentData()
})
// Verify name disambiguation
assert.Equal(t, "GPU1 0", result["0"].Name)
assert.Equal(t, "GPU1 1", result["1"].Name)
// Check that usage and power are 0
assert.Equal(t, 0.0, result["0"].Usage)
assert.Equal(t, 0.0, result["0"].Power)
// Check averaged values
assert.InDelta(t, 50.0, result["0"].Usage, 0.01)
assert.InDelta(t, 100.0, result["0"].Power, 0.01)
assert.InDelta(t, 30.0, result["1"].Usage, 0.01)
assert.InDelta(t, 60.0, result["1"].Power, 0.01)
// Verify reset counts
assert.Equal(t, float64(1), gm.GpuDataMap["0"].Count)
assert.Equal(t, float64(1), gm.GpuDataMap["1"].Count)
// Verify reset count
assert.Equal(t, float64(0), gm.GpuDataMap["0"].Count)
})
}
func TestDetectGPUs(t *testing.T) {
@@ -722,6 +777,18 @@ func TestAccumulation(t *testing.T) {
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 := 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.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)
}
})
}
}

43
agent/health/health.go Normal file
View File

@@ -0,0 +1,43 @@
// Package health provides functions to check and update the health of the agent.
// It uses a file in the temp directory to store the timestamp of the last connection attempt.
// If the timestamp is older than 90 seconds, the agent is considered unhealthy.
// NB: The agent must be started with the Start() method to be considered healthy.
package health
import (
"errors"
"log"
"os"
"path/filepath"
"time"
)
// healthFile is the path to the health file
var healthFile = filepath.Join(os.TempDir(), "beszel_health")
// Check checks if the agent is connected by checking the modification time of the health file
func Check() error {
fileInfo, err := os.Stat(healthFile)
if err != nil {
return err
}
if time.Since(fileInfo.ModTime()) > 91*time.Second {
log.Println("over 90 seconds since last connection")
return errors.New("unhealthy")
}
return nil
}
// Update updates the modification time of the health file
func Update() error {
file, err := os.Create(healthFile)
if err != nil {
return err
}
return file.Close()
}
// CleanUp removes the health file
func CleanUp() error {
return os.Remove(healthFile)
}

View File

@@ -0,0 +1,67 @@
//go:build testing
// +build testing
package health
import (
"os"
"path/filepath"
"testing"
"time"
"testing/synctest"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestHealth(t *testing.T) {
// Override healthFile to use a temporary directory for this test.
originalHealthFile := healthFile
tmpDir := t.TempDir()
healthFile = filepath.Join(tmpDir, "beszel_health_test")
defer func() { healthFile = originalHealthFile }()
t.Run("check with no health file", func(t *testing.T) {
err := Check()
require.Error(t, err)
assert.True(t, os.IsNotExist(err), "expected a file-not-exist error, but got: %v", err)
})
t.Run("update and check", func(t *testing.T) {
err := Update()
require.NoError(t, err, "Update() failed")
err = Check()
assert.NoError(t, err, "Check() failed immediately after Update()")
})
// This test uses synctest to simulate time passing.
// NOTE: This test requires GOEXPERIMENT=synctest to run.
t.Run("check with simulated time", func(t *testing.T) {
synctest.Test(t, func(t *testing.T) {
// Update the file to set the initial timestamp.
require.NoError(t, Update(), "Update() failed inside synctest")
// Set the mtime to the current fake time to align the file's timestamp with the simulated clock.
now := time.Now()
require.NoError(t, os.Chtimes(healthFile, now, now), "Chtimes failed")
// Wait a duration less than the threshold.
time.Sleep(89 * time.Second)
synctest.Wait()
// The check should still pass.
assert.NoError(t, Check(), "Check() failed after 89s")
// Wait for the total duration to exceed the threshold.
time.Sleep(5 * time.Second)
synctest.Wait()
// The check should now fail as unhealthy.
err := Check()
require.Error(t, err, "Check() should have failed after 91s")
assert.Equal(t, "unhealthy", err.Error(), "Check() returned wrong error")
})
})
}

80
agent/lhm/beszel_lhm.cs Normal file
View File

@@ -0,0 +1,80 @@
using System;
using System.Globalization;
using LibreHardwareMonitor.Hardware;
class Program
{
static void Main()
{
var computer = new Computer
{
IsCpuEnabled = true,
IsGpuEnabled = true,
IsMemoryEnabled = true,
IsMotherboardEnabled = true,
IsStorageEnabled = true,
// IsPsuEnabled = true,
// IsNetworkEnabled = true,
};
computer.Open();
var reader = Console.In;
var writer = Console.Out;
string line;
while ((line = reader.ReadLine()) != null)
{
if (line.Trim().Equals("getTemps", StringComparison.OrdinalIgnoreCase))
{
foreach (var hw in computer.Hardware)
{
// process main hardware sensors
ProcessSensors(hw, writer);
// process subhardware sensors
foreach (var subhardware in hw.SubHardware)
{
ProcessSensors(subhardware, writer);
}
}
// send empty line to signal end of sensor data
writer.WriteLine();
writer.Flush();
}
}
computer.Close();
}
static void ProcessSensors(IHardware hardware, System.IO.TextWriter writer)
{
var updated = false;
foreach (var sensor in hardware.Sensors)
{
var validTemp = sensor.SensorType == SensorType.Temperature && sensor.Value.HasValue;
if (!validTemp || sensor.Name.Contains("Distance"))
{
continue;
}
if (!updated)
{
hardware.Update();
updated = true;
}
var name = sensor.Name;
// if sensor.Name starts with "Temperature" replace with hardware.Identifier but retain the rest of the name.
// usually this is a number like Temperature 3
if (sensor.Name.StartsWith("Temperature"))
{
name = hardware.Identifier.ToString().Replace("/", "_").TrimStart('_') + sensor.Name.Substring(11);
}
// invariant culture assures the value is parsable as a float
var value = sensor.Value.Value.ToString("0.##", CultureInfo.InvariantCulture);
// write the name and value to the writer
writer.WriteLine($"{name}|{value}");
}
}
}

View File

@@ -0,0 +1,11 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net48</TargetFramework>
<Platforms>x64</Platforms>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="LibreHardwareMonitorLib" Version="0.9.4" />
</ItemGroup>
</Project>

View File

@@ -57,6 +57,7 @@ func (a *Agent) skipNetworkInterface(v psutilNet.IOCountersStat) bool {
strings.HasPrefix(v.Name, "docker"),
strings.HasPrefix(v.Name, "br-"),
strings.HasPrefix(v.Name, "veth"),
strings.HasPrefix(v.Name, "bond"),
v.BytesRecv == 0,
v.BytesSent == 0:
return true

View File

@@ -1,12 +1,16 @@
package agent
import (
"beszel/internal/entities/system"
"context"
"fmt"
"log/slog"
"path"
"runtime"
"strconv"
"strings"
"unicode/utf8"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/shirou/gopsutil/v4/common"
"github.com/shirou/gopsutil/v4/sensors"
@@ -30,6 +34,9 @@ func (a *Agent) newSensorConfig() *SensorConfig {
return a.newSensorConfigWithEnv(primarySensor, sysSensors, sensorsEnvVal, skipCollection)
}
// Matches sensors.TemperaturesWithContext to allow for panic recovery (gopsutil/issues/1832)
type getTempsFn func(ctx context.Context) ([]sensors.TemperatureStat, error)
// newSensorConfigWithEnv creates a SensorConfig with the provided environment variables
// sensorsSet indicates if the SENSORS environment variable was explicitly set (even to empty string)
func (a *Agent) newSensorConfigWithEnv(primarySensor, sysSensors, sensorsEnvVal string, skipCollection bool) *SensorConfig {
@@ -78,8 +85,18 @@ func (a *Agent) updateTemperatures(systemStats *system.Stats) {
// reset high temp
a.systemInfo.DashboardTemp = 0
// get sensor data
temps, _ := sensors.TemperaturesWithContext(a.sensorConfig.context)
temps, err := a.getTempsWithPanicRecovery(getSensorTemps)
if err != nil {
// retry once on panic (gopsutil/issues/1832)
temps, err = a.getTempsWithPanicRecovery(getSensorTemps)
if err != nil {
slog.Warn("Error updating temperatures", "err", err)
if len(systemStats.Temperatures) > 0 {
systemStats.Temperatures = make(map[string]float64)
}
return
}
}
slog.Debug("Temperature", "sensors", temps)
// return if no sensors
@@ -89,6 +106,15 @@ func (a *Agent) updateTemperatures(systemStats *system.Stats) {
systemStats.Temperatures = make(map[string]float64, len(temps))
for i, sensor := range temps {
// check for malformed strings on darwin (gopsutil/issues/1832)
if runtime.GOOS == "darwin" && !utf8.ValidString(sensor.SensorKey) {
continue
}
// scale temperature
if sensor.Temperature != 0 && sensor.Temperature < 1 {
sensor.Temperature = scaleTemperature(sensor.Temperature)
}
// skip if temperature is unreasonable
if sensor.Temperature <= 0 || sensor.Temperature >= 200 {
continue
@@ -103,15 +129,28 @@ func (a *Agent) updateTemperatures(systemStats *system.Stats) {
continue
}
// set dashboard temperature
if a.sensorConfig.primarySensor == "" {
switch a.sensorConfig.primarySensor {
case "":
a.systemInfo.DashboardTemp = max(a.systemInfo.DashboardTemp, sensor.Temperature)
} else if a.sensorConfig.primarySensor == sensorName {
case sensorName:
a.systemInfo.DashboardTemp = sensor.Temperature
}
systemStats.Temperatures[sensorName] = twoDecimals(sensor.Temperature)
}
}
// getTempsWithPanicRecovery wraps sensors.TemperaturesWithContext to recover from panics (gopsutil/issues/1832)
func (a *Agent) getTempsWithPanicRecovery(getTemps getTempsFn) (temps []sensors.TemperatureStat, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("panic: %v", r)
}
}()
// get sensor data (error ignored intentionally as it may be only with one sensor)
temps, _ = getTemps(a.sensorConfig.context)
return
}
// isValidSensor checks if a sensor is valid based on the sensor name and the sensor config
func isValidSensor(sensorName string, config *SensorConfig) bool {
// if no sensors configured, everything is valid
@@ -141,3 +180,19 @@ func isValidSensor(sensorName string, config *SensorConfig) bool {
return config.isBlacklist
}
// scaleTemperature scales temperatures in fractional values to reasonable Celsius values
func scaleTemperature(temp float64) float64 {
if temp > 1 {
return temp
}
scaled100 := temp * 100
scaled1000 := temp * 1000
if scaled100 >= 15 && scaled100 <= 95 {
return scaled100
} else if scaled1000 >= 15 && scaled1000 <= 95 {
return scaled1000
}
return scaled100
}

9
agent/sensors_default.go Normal file
View File

@@ -0,0 +1,9 @@
//go:build !windows
package agent
import (
"github.com/shirou/gopsutil/v4/sensors"
)
var getSensorTemps = sensors.TemperaturesWithContext

View File

@@ -5,10 +5,14 @@ package agent
import (
"context"
"fmt"
"os"
"testing"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/shirou/gopsutil/v4/common"
"github.com/shirou/gopsutil/v4/sensors"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@@ -372,3 +376,179 @@ func TestNewSensorConfig(t *testing.T) {
require.True(t, ok, "EnvMap should contain HostSysEnvKey")
assert.Equal(t, "/test/path", sysPath)
}
func TestScaleTemperature(t *testing.T) {
tests := []struct {
name string
input float64
expected float64
desc string
}{
// Normal temperatures (no scaling needed)
{"normal_cpu_temp", 45.0, 45.0, "Normal CPU temperature"},
{"normal_room_temp", 25.0, 25.0, "Normal room temperature"},
{"high_cpu_temp", 85.0, 85.0, "High CPU temperature"},
// Zero temperature
{"zero_temp", 0.0, 0.0, "Zero temperature"},
// Fractional values that should use 100x scaling
{"fractional_45c", 0.45, 45.0, "0.45 should become 45°C (100x)"},
{"fractional_25c", 0.25, 25.0, "0.25 should become 25°C (100x)"},
{"fractional_60c", 0.60, 60.0, "0.60 should become 60°C (100x)"},
{"fractional_75c", 0.75, 75.0, "0.75 should become 75°C (100x)"},
{"fractional_30c", 0.30, 30.0, "0.30 should become 30°C (100x)"},
// Fractional values that should use 1000x scaling
{"millifractional_45c", 0.045, 45.0, "0.045 should become 45°C (1000x)"},
{"millifractional_25c", 0.025, 25.0, "0.025 should become 25°C (1000x)"},
{"millifractional_60c", 0.060, 60.0, "0.060 should become 60°C (1000x)"},
{"millifractional_75c", 0.075, 75.0, "0.075 should become 75°C (1000x)"},
{"millifractional_35c", 0.035, 35.0, "0.035 should become 35°C (1000x)"},
// Edge cases - values outside reasonable range
{"very_low_fractional", 0.01, 1.0, "0.01 should default to 100x scaling (1°C)"},
{"very_high_fractional", 0.99, 99.0, "0.99 should default to 100x scaling (99°C)"},
{"extremely_low", 0.001, 0.1, "0.001 should default to 100x scaling (0.1°C)"},
// Boundary cases around the reasonable range (15-95°C)
{"boundary_low_100x", 0.15, 15.0, "0.15 should use 100x scaling (15°C)"},
{"boundary_high_100x", 0.95, 95.0, "0.95 should use 100x scaling (95°C)"},
{"boundary_low_1000x", 0.015, 15.0, "0.015 should use 1000x scaling (15°C)"},
{"boundary_high_1000x", 0.095, 95.0, "0.095 should use 1000x scaling (95°C)"},
// Values just outside reasonable range
{"just_below_range_100x", 0.14, 14.0, "0.14 should default to 100x (14°C)"},
{"just_above_range_100x", 0.96, 96.0, "0.96 should default to 100x (96°C)"},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result := scaleTemperature(tt.input)
assert.InDelta(t, tt.expected, result, 0.001,
"scaleTemperature(%v) = %v, expected %v (%s)",
tt.input, result, tt.expected, tt.desc)
})
}
}
func TestScaleTemperatureLogic(t *testing.T) {
// Test the logic flow for ambiguous cases
t.Run("prefers_100x_when_both_valid", func(t *testing.T) {
// 0.5 could be 50°C (100x) or 500°C (1000x)
// Should prefer 100x since it's tried first and is in range
result := scaleTemperature(0.5)
expected := 50.0
assert.InDelta(t, expected, result, 0.001,
"scaleTemperature(0.5) = %v, expected %v (should prefer 100x scaling)",
result, expected)
})
t.Run("uses_1000x_when_100x_too_low", func(t *testing.T) {
// 0.05 -> 5°C (100x, too low) or 50°C (1000x, in range)
// Should use 1000x since 100x is below reasonable range
result := scaleTemperature(0.05)
expected := 50.0
assert.InDelta(t, expected, result, 0.001,
"scaleTemperature(0.05) = %v, expected %v (should use 1000x scaling)",
result, expected)
})
t.Run("defaults_to_100x_when_both_invalid", func(t *testing.T) {
// 0.005 -> 0.5°C (100x, too low) or 5°C (1000x, too low)
// Should default to 100x scaling
result := scaleTemperature(0.005)
expected := 0.5
assert.InDelta(t, expected, result, 0.001,
"scaleTemperature(0.005) = %v, expected %v (should default to 100x)",
result, expected)
})
}
func TestGetTempsWithPanicRecovery(t *testing.T) {
agent := &Agent{
systemInfo: system.Info{},
sensorConfig: &SensorConfig{
context: context.Background(),
},
}
tests := []struct {
name string
getTempsFn getTempsFn
expectError bool
errorMsg string
}{
{
name: "successful_function_call",
getTempsFn: func(ctx context.Context) ([]sensors.TemperatureStat, error) {
return []sensors.TemperatureStat{
{SensorKey: "test_sensor", Temperature: 45.0},
}, nil
},
expectError: false,
},
{
name: "function_returns_error",
getTempsFn: func(ctx context.Context) ([]sensors.TemperatureStat, error) {
return []sensors.TemperatureStat{
{SensorKey: "test_sensor", Temperature: 45.0},
}, fmt.Errorf("sensor error")
},
expectError: false, // getTempsWithPanicRecovery ignores errors from the function
},
{
name: "function_panics_with_string",
getTempsFn: func(ctx context.Context) ([]sensors.TemperatureStat, error) {
panic("test panic")
},
expectError: true,
errorMsg: "panic: test panic",
},
{
name: "function_panics_with_error",
getTempsFn: func(ctx context.Context) ([]sensors.TemperatureStat, error) {
panic(fmt.Errorf("panic error"))
},
expectError: true,
errorMsg: "panic:",
},
{
name: "function_panics_with_index_out_of_bounds",
getTempsFn: func(ctx context.Context) ([]sensors.TemperatureStat, error) {
slice := []int{1, 2, 3}
_ = slice[10] // out of bounds panic
return nil, nil
},
expectError: true,
errorMsg: "panic:",
},
{
name: "function_panics_with_any_conversion",
getTempsFn: func(ctx context.Context) ([]sensors.TemperatureStat, error) {
var i any = "string"
_ = i.(int) // type assertion panic
return nil, nil
},
expectError: true,
errorMsg: "panic:",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
var temps []sensors.TemperatureStat
var err error
// The function should not panic, regardless of what the injected function does
assert.NotPanics(t, func() {
temps, err = agent.getTempsWithPanicRecovery(tt.getTempsFn)
}, "getTempsWithPanicRecovery should not panic")
if tt.expectError {
assert.Error(t, err, "Expected an error to be returned")
if tt.errorMsg != "" {
assert.Contains(t, err.Error(), tt.errorMsg,
"Error message should contain expected text")
}
assert.Nil(t, temps, "Temps should be nil when panic occurs")
} else {
assert.NoError(t, err, "Should not return error for successful calls")
}
})
}
}

286
agent/sensors_windows.go Normal file
View File

@@ -0,0 +1,286 @@
//go:build windows
//go:generate dotnet build -c Release lhm/beszel_lhm.csproj
package agent
import (
"bufio"
"context"
"embed"
"errors"
"fmt"
"io"
"log/slog"
"os"
"os/exec"
"path"
"path/filepath"
"strconv"
"strings"
"sync"
"time"
"github.com/shirou/gopsutil/v4/sensors"
)
// Note: This is always called from Agent.gatherStats() which holds Agent.Lock(),
// so no internal concurrency protection is needed.
// lhmProcess is a wrapper around the LHM .NET process.
type lhmProcess struct {
cmd *exec.Cmd
stdin io.WriteCloser
stdout io.ReadCloser
scanner *bufio.Scanner
isRunning bool
stoppedNoSensors bool
consecutiveNoSensors uint8
execPath string
tempDir string
}
//go:embed all:lhm/bin/Release/net48
var lhmFs embed.FS
var (
beszelLhm *lhmProcess
beszelLhmOnce sync.Once
useLHM = os.Getenv("LHM") == "true"
)
var errNoSensors = errors.New("no sensors found (try running as admin with LHM=true)")
// newlhmProcess copies the embedded LHM executable to a temporary directory and starts it.
func newlhmProcess() (*lhmProcess, error) {
destDir := filepath.Join(os.TempDir(), "beszel")
execPath := filepath.Join(destDir, "beszel_lhm.exe")
if err := os.MkdirAll(destDir, 0755); err != nil {
return nil, fmt.Errorf("failed to create temp directory: %w", err)
}
// Only copy if executable doesn't exist
if _, err := os.Stat(execPath); os.IsNotExist(err) {
if err := copyEmbeddedDir(lhmFs, "lhm/bin/Release/net48", destDir); err != nil {
return nil, fmt.Errorf("failed to copy embedded directory: %w", err)
}
}
lhm := &lhmProcess{
execPath: execPath,
tempDir: destDir,
}
if err := lhm.startProcess(); err != nil {
return nil, fmt.Errorf("failed to start process: %w", err)
}
return lhm, nil
}
// startProcess starts the external LHM process
func (lhm *lhmProcess) startProcess() error {
// Clean up any existing process
lhm.cleanupProcess()
cmd := exec.Command(lhm.execPath)
stdin, err := cmd.StdinPipe()
if err != nil {
return err
}
stdout, err := cmd.StdoutPipe()
if err != nil {
stdin.Close()
return err
}
if err := cmd.Start(); err != nil {
stdin.Close()
stdout.Close()
return err
}
// Update process state
lhm.cmd = cmd
lhm.stdin = stdin
lhm.stdout = stdout
lhm.scanner = bufio.NewScanner(stdout)
lhm.isRunning = true
// Give process a moment to initialize
time.Sleep(100 * time.Millisecond)
return nil
}
// cleanupProcess terminates the process and closes resources but preserves files
func (lhm *lhmProcess) cleanupProcess() {
lhm.isRunning = false
if lhm.cmd != nil && lhm.cmd.Process != nil {
lhm.cmd.Process.Kill()
lhm.cmd.Wait()
}
if lhm.stdin != nil {
lhm.stdin.Close()
lhm.stdin = nil
}
if lhm.stdout != nil {
lhm.stdout.Close()
lhm.stdout = nil
}
lhm.cmd = nil
lhm.scanner = nil
lhm.stoppedNoSensors = false
lhm.consecutiveNoSensors = 0
}
func (lhm *lhmProcess) getTemps(ctx context.Context) (temps []sensors.TemperatureStat, err error) {
if !useLHM || lhm.stoppedNoSensors {
// Fall back to gopsutil if we can't get sensors from LHM
return sensors.TemperaturesWithContext(ctx)
}
// Start process if it's not running
if !lhm.isRunning || lhm.stdin == nil || lhm.scanner == nil {
err := lhm.startProcess()
if err != nil {
return temps, err
}
}
// Send command to process
_, err = fmt.Fprintln(lhm.stdin, "getTemps")
if err != nil {
lhm.isRunning = false
return temps, fmt.Errorf("failed to send command: %w", err)
}
// Read all sensor lines until we hit an empty line or EOF
for lhm.scanner.Scan() {
line := strings.TrimSpace(lhm.scanner.Text())
if line == "" {
break
}
parts := strings.Split(line, "|")
if len(parts) != 2 {
slog.Debug("Invalid sensor format", "line", line)
continue
}
name := strings.TrimSpace(parts[0])
valueStr := strings.TrimSpace(parts[1])
value, err := strconv.ParseFloat(valueStr, 64)
if err != nil {
slog.Debug("Failed to parse sensor", "err", err, "line", line)
continue
}
if name == "" || value <= 0 || value > 150 {
slog.Debug("Invalid sensor", "name", name, "val", value, "line", line)
continue
}
temps = append(temps, sensors.TemperatureStat{
SensorKey: name,
Temperature: value,
})
}
if err := lhm.scanner.Err(); err != nil {
lhm.isRunning = false
return temps, err
}
// Handle no sensors case
if len(temps) == 0 {
lhm.consecutiveNoSensors++
if lhm.consecutiveNoSensors >= 3 {
lhm.stoppedNoSensors = true
slog.Warn(errNoSensors.Error())
lhm.cleanup()
}
return sensors.TemperaturesWithContext(ctx)
}
lhm.consecutiveNoSensors = 0
return temps, nil
}
// getSensorTemps attempts to pull sensor temperatures from the embedded LHM process.
// NB: LibreHardwareMonitorLib requires admin privileges to access all available sensors.
func getSensorTemps(ctx context.Context) (temps []sensors.TemperatureStat, err error) {
defer func() {
if err != nil {
slog.Debug("Error reading sensors", "err", err)
}
}()
if !useLHM {
return sensors.TemperaturesWithContext(ctx)
}
// Initialize process once
beszelLhmOnce.Do(func() {
beszelLhm, err = newlhmProcess()
})
if err != nil {
return temps, fmt.Errorf("failed to initialize lhm: %w", err)
}
if beszelLhm == nil {
return temps, fmt.Errorf("lhm not available")
}
return beszelLhm.getTemps(ctx)
}
// cleanup terminates the process and closes resources
func (lhm *lhmProcess) cleanup() {
lhm.cleanupProcess()
if lhm.tempDir != "" {
os.RemoveAll(lhm.tempDir)
}
}
// copyEmbeddedDir copies the embedded directory to the destination path
func copyEmbeddedDir(fs embed.FS, srcPath, destPath string) error {
entries, err := fs.ReadDir(srcPath)
if err != nil {
return err
}
if err := os.MkdirAll(destPath, 0755); err != nil {
return err
}
for _, entry := range entries {
srcEntryPath := path.Join(srcPath, entry.Name())
destEntryPath := filepath.Join(destPath, entry.Name())
if entry.IsDir() {
if err := copyEmbeddedDir(fs, srcEntryPath, destEntryPath); err != nil {
return err
}
continue
}
data, err := fs.ReadFile(srcEntryPath)
if err != nil {
return err
}
if err := os.WriteFile(destEntryPath, data, 0755); err != nil {
return err
}
}
return nil
}

224
agent/server.go Normal file
View File

@@ -0,0 +1,224 @@
package agent
import (
"encoding/json"
"errors"
"fmt"
"io"
"log/slog"
"net"
"os"
"strings"
"time"
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/internal/common"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/blang/semver"
"github.com/fxamacker/cbor/v2"
"github.com/gliderlabs/ssh"
gossh "golang.org/x/crypto/ssh"
)
// ServerOptions contains configuration options for starting the SSH server.
type ServerOptions struct {
Addr string // Network address to listen on (e.g., ":45876" or "/path/to/socket")
Network string // Network type ("tcp" or "unix")
Keys []gossh.PublicKey // SSH public keys for authentication
}
// hubVersions caches hub versions by session ID to avoid repeated parsing.
var hubVersions map[string]semver.Version
// StartServer starts the SSH server with the provided options.
// It configures the server with secure defaults, sets up authentication,
// and begins listening for connections. Returns an error if the server
// is already running or if there's an issue starting the server.
func (a *Agent) StartServer(opts ServerOptions) error {
if a.server != nil {
return errors.New("server already started")
}
slog.Info("Starting SSH server", "addr", opts.Addr, "network", opts.Network)
if opts.Network == "unix" {
// remove existing socket file if it exists
if err := os.Remove(opts.Addr); err != nil && !os.IsNotExist(err) {
return err
}
}
// start listening on the address
ln, err := net.Listen(opts.Network, opts.Addr)
if err != nil {
return err
}
defer ln.Close()
// base config (limit to allowed algorithms)
config := &gossh.ServerConfig{
ServerVersion: fmt.Sprintf("SSH-2.0-%s_%s", beszel.AppName, beszel.Version),
}
config.KeyExchanges = common.DefaultKeyExchanges
config.MACs = common.DefaultMACs
config.Ciphers = common.DefaultCiphers
// set default handler
ssh.Handle(a.handleSession)
a.server = &ssh.Server{
ServerConfigCallback: func(ctx ssh.Context) *gossh.ServerConfig {
return config
},
// check public key(s)
PublicKeyHandler: func(ctx ssh.Context, key ssh.PublicKey) bool {
remoteAddr := ctx.RemoteAddr()
for _, pubKey := range opts.Keys {
if ssh.KeysEqual(key, pubKey) {
slog.Info("SSH connected", "addr", remoteAddr)
return true
}
}
slog.Warn("Invalid SSH key", "addr", remoteAddr)
return false
},
// disable pty
PtyCallback: func(ctx ssh.Context, pty ssh.Pty) bool {
return false
},
// close idle connections after 70 seconds
IdleTimeout: 70 * time.Second,
}
// Start SSH server on the listener
return a.server.Serve(ln)
}
// getHubVersion retrieves and caches the hub version for a given session.
// It extracts the version from the SSH client version string and caches
// it to avoid repeated parsing. Returns a zero version if parsing fails.
func (a *Agent) getHubVersion(sessionId string, sessionCtx ssh.Context) semver.Version {
if hubVersions == nil {
hubVersions = make(map[string]semver.Version, 1)
}
hubVersion, ok := hubVersions[sessionId]
if ok {
return hubVersion
}
// Extract hub version from SSH client version
clientVersion := sessionCtx.Value(ssh.ContextKeyClientVersion)
if versionStr, ok := clientVersion.(string); ok {
hubVersion, _ = extractHubVersion(versionStr)
}
hubVersions[sessionId] = hubVersion
return hubVersion
}
// handleSession handles an incoming SSH session by gathering system statistics
// and sending them to the hub. It signals connection events, determines the
// appropriate encoding format based on hub version, and exits with appropriate
// status codes.
func (a *Agent) handleSession(s ssh.Session) {
a.connectionManager.eventChan <- SSHConnect
sessionCtx := s.Context()
sessionID := sessionCtx.SessionID()
hubVersion := a.getHubVersion(sessionID, sessionCtx)
stats := a.gatherStats(sessionID)
err := a.writeToSession(s, stats, hubVersion)
if err != nil {
slog.Error("Error encoding stats", "err", err, "stats", stats)
s.Exit(1)
} else {
s.Exit(0)
}
}
// writeToSession encodes and writes system statistics to the session.
// It chooses between CBOR and JSON encoding based on the hub version,
// using CBOR for newer versions and JSON for legacy compatibility.
func (a *Agent) writeToSession(w io.Writer, stats *system.CombinedData, hubVersion semver.Version) error {
if hubVersion.GTE(beszel.MinVersionCbor) {
return cbor.NewEncoder(w).Encode(stats)
}
return json.NewEncoder(w).Encode(stats)
}
// extractHubVersion extracts the beszel version from SSH client version string.
// Expected format: "SSH-2.0-beszel_X.Y.Z" or "beszel_X.Y.Z"
func extractHubVersion(versionString string) (semver.Version, error) {
_, after, _ := strings.Cut(versionString, "_")
return semver.Parse(after)
}
// ParseKeys parses a string containing SSH public keys in authorized_keys format.
// It returns a slice of ssh.PublicKey and an error if any key fails to parse.
func ParseKeys(input string) ([]gossh.PublicKey, error) {
var parsedKeys []gossh.PublicKey
for line := range strings.Lines(input) {
line = strings.TrimSpace(line)
// Skip empty lines or comments
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
// Parse the key
parsedKey, _, _, _, err := gossh.ParseAuthorizedKey([]byte(line))
if err != nil {
return nil, fmt.Errorf("failed to parse key: %s, error: %w", line, err)
}
parsedKeys = append(parsedKeys, parsedKey)
}
return parsedKeys, nil
}
// GetAddress determines the network address to listen on from various sources.
// It checks the provided address, then environment variables (LISTEN, PORT),
// and finally defaults to ":45876".
func GetAddress(addr string) string {
if addr == "" {
addr, _ = GetEnv("LISTEN")
}
if addr == "" {
// Legacy PORT environment variable support
addr, _ = GetEnv("PORT")
}
if addr == "" {
return ":45876"
}
// prefix with : if only port was provided
if GetNetwork(addr) != "unix" && !strings.Contains(addr, ":") {
addr = ":" + addr
}
return addr
}
// GetNetwork determines the network type based on the address format.
// It checks the NETWORK environment variable first, then infers from
// the address format: addresses starting with "/" are "unix", others are "tcp".
func GetNetwork(addr string) string {
if network, ok := GetEnv("NETWORK"); ok && network != "" {
return network
}
if strings.HasPrefix(addr, "/") {
return "unix"
}
return "tcp"
}
// StopServer stops the SSH server if it's running.
// It returns an error if the server is not running or if there's an error stopping it.
func (a *Agent) StopServer() error {
if a.server == nil {
return errors.New("SSH server not running")
}
slog.Info("Stopping SSH server")
_ = a.server.Close()
a.server = nil
a.connectionManager.eventChan <- SSHDisconnect
return nil
}

606
agent/server_test.go Normal file
View File

@@ -0,0 +1,606 @@
package agent
import (
"context"
"crypto/ed25519"
"encoding/json"
"fmt"
"net"
"os"
"path/filepath"
"strings"
"sync"
"testing"
"time"
"github.com/henrygd/beszel/internal/entities/container"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/blang/semver"
"github.com/fxamacker/cbor/v2"
"github.com/gliderlabs/ssh"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
gossh "golang.org/x/crypto/ssh"
)
func TestStartServer(t *testing.T) {
// Generate a test key pair
pubKey, privKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
signer, err := gossh.NewSignerFromKey(privKey)
require.NoError(t, err)
sshPubKey, err := gossh.NewPublicKey(pubKey)
require.NoError(t, err)
// Generate a different key pair for bad key test
badPubKey, badPrivKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
badSigner, err := gossh.NewSignerFromKey(badPrivKey)
require.NoError(t, err)
sshBadPubKey, err := gossh.NewPublicKey(badPubKey)
require.NoError(t, err)
socketFile := filepath.Join(t.TempDir(), "beszel-test.sock")
tests := []struct {
name string
config ServerOptions
wantErr bool
errContains string
setup func() error
cleanup func() error
}{
{
name: "tcp port only",
config: ServerOptions{
Network: "tcp",
Addr: ":45987",
Keys: []gossh.PublicKey{sshPubKey},
},
},
{
name: "tcp with ipv4",
config: ServerOptions{
Network: "tcp4",
Addr: "127.0.0.1:45988",
Keys: []gossh.PublicKey{sshPubKey},
},
},
{
name: "tcp with ipv6",
config: ServerOptions{
Network: "tcp6",
Addr: "[::1]:45989",
Keys: []gossh.PublicKey{sshPubKey},
},
},
{
name: "unix socket",
config: ServerOptions{
Network: "unix",
Addr: socketFile,
Keys: []gossh.PublicKey{sshPubKey},
},
setup: func() error {
// Create a socket file that should be removed
f, err := os.Create(socketFile)
if err != nil {
return err
}
return f.Close()
},
cleanup: func() error {
return os.Remove(socketFile)
},
},
{
name: "bad key should fail",
config: ServerOptions{
Network: "tcp",
Addr: ":45987",
Keys: []gossh.PublicKey{sshBadPubKey},
},
wantErr: true,
errContains: "ssh: handshake failed",
},
{
name: "good key still good",
config: ServerOptions{
Network: "tcp",
Addr: ":45987",
Keys: []gossh.PublicKey{sshPubKey},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.setup != nil {
err := tt.setup()
require.NoError(t, err)
}
if tt.cleanup != nil {
defer tt.cleanup()
}
agent, err := NewAgent("")
require.NoError(t, err)
// Start server in a goroutine since it blocks
errChan := make(chan error, 1)
go func() {
errChan <- agent.StartServer(tt.config)
}()
// Add a short delay to allow the server to start
time.Sleep(100 * time.Millisecond)
// Try to connect to verify server is running
var client *gossh.Client
// Choose the appropriate signer based on the test case
testSigner := signer
if tt.name == "bad key should fail" {
testSigner = badSigner
}
sshClientConfig := &gossh.ClientConfig{
User: "a",
Auth: []gossh.AuthMethod{
gossh.PublicKeys(testSigner),
},
HostKeyCallback: gossh.InsecureIgnoreHostKey(),
Timeout: 4 * time.Second,
}
switch tt.config.Network {
case "unix":
client, err = gossh.Dial("unix", tt.config.Addr, sshClientConfig)
default:
if !strings.Contains(tt.config.Addr, ":") {
tt.config.Addr = ":" + tt.config.Addr
}
client, err = gossh.Dial("tcp", tt.config.Addr, sshClientConfig)
}
if tt.wantErr {
assert.Error(t, err)
if tt.errContains != "" {
assert.Contains(t, err.Error(), tt.errContains)
}
return
}
require.NoError(t, err)
require.NotNil(t, client)
client.Close()
})
}
}
/////////////////////////////////////////////////////////////////
//////////////////// ParseKeys Tests ////////////////////////////
/////////////////////////////////////////////////////////////////
// Helper function to generate a temporary file with content
func createTempFile(content string) (string, error) {
tmpFile, err := os.CreateTemp("", "ssh_keys_*.txt")
if err != nil {
return "", fmt.Errorf("failed to create temp file: %w", err)
}
defer tmpFile.Close()
if _, err := tmpFile.WriteString(content); err != nil {
return "", fmt.Errorf("failed to write to temp file: %w", err)
}
return tmpFile.Name(), nil
}
// Test case 1: String with a single SSH key
func TestParseSingleKeyFromString(t *testing.T) {
input := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo"
keys, err := ParseKeys(input)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 1 {
t.Fatalf("Expected 1 key, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" {
t.Fatalf("Expected key type 'ssh-ed25519', got '%s'", keys[0].Type())
}
}
// Test case 2: String with multiple SSH keys
func TestParseMultipleKeysFromString(t *testing.T) {
input := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D \n #comment\n ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D"
keys, err := ParseKeys(input)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 3 {
t.Fatalf("Expected 3 keys, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" || keys[1].Type() != "ssh-ed25519" || keys[2].Type() != "ssh-ed25519" {
t.Fatalf("Unexpected key types: %s, %s, %s", keys[0].Type(), keys[1].Type(), keys[2].Type())
}
}
// Test case 3: File with a single SSH key
func TestParseSingleKeyFromFile(t *testing.T) {
content := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo"
filePath, err := createTempFile(content)
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(filePath) // Clean up the file after the test
// Read the file content
fileContent, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("Failed to read temp file: %v", err)
}
// Parse the keys
keys, err := ParseKeys(string(fileContent))
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 1 {
t.Fatalf("Expected 1 key, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" {
t.Fatalf("Expected key type 'ssh-ed25519', got '%s'", keys[0].Type())
}
}
// Test case 4: File with multiple SSH keys
func TestParseMultipleKeysFromFile(t *testing.T) {
content := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D \n #comment\n ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D"
filePath, err := createTempFile(content)
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
// defer os.Remove(filePath) // Clean up the file after the test
// Read the file content
fileContent, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("Failed to read temp file: %v", err)
}
// Parse the keys
keys, err := ParseKeys(string(fileContent))
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 3 {
t.Fatalf("Expected 3 keys, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" || keys[1].Type() != "ssh-ed25519" || keys[2].Type() != "ssh-ed25519" {
t.Fatalf("Unexpected key types: %s, %s, %s", keys[0].Type(), keys[1].Type(), keys[2].Type())
}
}
// Test case 5: Invalid SSH key input
func TestParseInvalidKey(t *testing.T) {
input := "invalid-key-data"
_, err := ParseKeys(input)
if err == nil {
t.Fatalf("Expected an error for invalid key, got nil")
}
expectedErrMsg := "failed to parse key"
if !strings.Contains(err.Error(), expectedErrMsg) {
t.Fatalf("Expected error message to contain '%s', got: %v", expectedErrMsg, err)
}
}
/////////////////////////////////////////////////////////////////
//////////////////// Hub Version Tests //////////////////////////
/////////////////////////////////////////////////////////////////
func TestExtractHubVersion(t *testing.T) {
tests := []struct {
name string
clientVersion string
expectedVersion string
expectError bool
}{
{
name: "valid beszel client version with underscore",
clientVersion: "SSH-2.0-beszel_0.11.1",
expectedVersion: "0.11.1",
expectError: false,
},
{
name: "valid beszel client version with beta",
clientVersion: "SSH-2.0-beszel_1.0.0-beta",
expectedVersion: "1.0.0-beta",
expectError: false,
},
{
name: "valid beszel client version with rc",
clientVersion: "SSH-2.0-beszel_0.12.0-rc1",
expectedVersion: "0.12.0-rc1",
expectError: false,
},
{
name: "different SSH client",
clientVersion: "SSH-2.0-OpenSSH_8.0",
expectedVersion: "8.0",
expectError: true,
},
{
name: "malformed version string without underscore",
clientVersion: "SSH-2.0-beszel",
expectError: true,
},
{
name: "empty version string",
clientVersion: "",
expectError: true,
},
{
name: "version string with underscore but no version",
clientVersion: "beszel_",
expectedVersion: "",
expectError: true,
},
{
name: "version with patch and build metadata",
clientVersion: "SSH-2.0-beszel_1.2.3+build.123",
expectedVersion: "1.2.3+build.123",
expectError: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
result, err := extractHubVersion(tt.clientVersion)
if tt.expectError {
assert.Error(t, err)
return
}
require.NoError(t, err)
assert.Equal(t, tt.expectedVersion, result.String())
})
}
}
/////////////////////////////////////////////////////////////////
/////////////// Hub Version Detection Tests ////////////////////
/////////////////////////////////////////////////////////////////
func TestGetHubVersion(t *testing.T) {
agent, err := NewAgent("")
require.NoError(t, err)
// Mock SSH context that implements the ssh.Context interface
mockCtx := &mockSSHContext{
sessionID: "test-session-123",
clientVersion: "SSH-2.0-beszel_0.12.0",
}
// Test first call - should extract and cache version
version := agent.getHubVersion("test-session-123", mockCtx)
assert.Equal(t, "0.12.0", version.String())
// Test second call - should return cached version
mockCtx.clientVersion = "SSH-2.0-beszel_0.11.0" // Change version but should still return cached
version = agent.getHubVersion("test-session-123", mockCtx)
assert.Equal(t, "0.12.0", version.String()) // Should still be cached version
// Test different session - should extract new version
version = agent.getHubVersion("different-session", mockCtx)
assert.Equal(t, "0.11.0", version.String())
// Test with invalid version string (non-beszel client)
mockCtx.clientVersion = "SSH-2.0-OpenSSH_8.0"
version = agent.getHubVersion("invalid-session", mockCtx)
assert.Equal(t, "0.0.0", version.String()) // Should be empty version for non-beszel clients
// Test with no client version
mockCtx.clientVersion = ""
version = agent.getHubVersion("no-version-session", mockCtx)
assert.True(t, version.EQ(semver.Version{})) // Should be empty version
}
// mockSSHContext implements ssh.Context for testing
type mockSSHContext struct {
context.Context
sync.Mutex
sessionID string
clientVersion string
}
func (m *mockSSHContext) SessionID() string {
return m.sessionID
}
func (m *mockSSHContext) ClientVersion() string {
return m.clientVersion
}
func (m *mockSSHContext) ServerVersion() string {
return "SSH-2.0-beszel_test"
}
func (m *mockSSHContext) Value(key interface{}) interface{} {
if key == ssh.ContextKeyClientVersion {
return m.clientVersion
}
return nil
}
func (m *mockSSHContext) User() string { return "test-user" }
func (m *mockSSHContext) RemoteAddr() net.Addr { return nil }
func (m *mockSSHContext) LocalAddr() net.Addr { return nil }
func (m *mockSSHContext) Permissions() *ssh.Permissions { return nil }
func (m *mockSSHContext) SetValue(key, value interface{}) {}
/////////////////////////////////////////////////////////////////
/////////////// CBOR vs JSON Encoding Tests ////////////////////
/////////////////////////////////////////////////////////////////
// TestWriteToSessionEncoding tests that writeToSession actually encodes data in the correct format
func TestWriteToSessionEncoding(t *testing.T) {
tests := []struct {
name string
hubVersion string
expectedUsesCbor bool
}{
{
name: "old hub version should use JSON",
hubVersion: "0.11.1",
expectedUsesCbor: false,
},
{
name: "non-beta release should use CBOR",
hubVersion: "0.12.0",
expectedUsesCbor: true,
},
{
name: "even newer hub version should use CBOR",
hubVersion: "0.16.4",
expectedUsesCbor: true,
},
{
name: "beta version below release threshold should use JSON",
hubVersion: "0.12.0-beta0",
expectedUsesCbor: false,
},
// {
// name: "matching beta version should use CBOR",
// hubVersion: "0.12.0-beta2",
// expectedUsesCbor: true,
// },
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
// Reset the global hubVersions map to ensure clean state for each test
hubVersions = nil
agent, err := NewAgent("")
require.NoError(t, err)
// Parse the test version
version, err := semver.Parse(tt.hubVersion)
require.NoError(t, err)
// Create test data to encode
testData := createTestCombinedData()
var buf strings.Builder
err = agent.writeToSession(&buf, testData, version)
require.NoError(t, err)
encodedData := buf.String()
require.NotEmpty(t, encodedData)
// Verify the encoding format by attempting to decode
if tt.expectedUsesCbor {
var decodedCbor system.CombinedData
err = cbor.Unmarshal([]byte(encodedData), &decodedCbor)
assert.NoError(t, err, "Should be valid CBOR data")
var decodedJson system.CombinedData
err = json.Unmarshal([]byte(encodedData), &decodedJson)
assert.Error(t, err, "Should not be valid JSON data")
assert.Equal(t, testData.Info.Hostname, decodedCbor.Info.Hostname)
assert.Equal(t, testData.Stats.Cpu, decodedCbor.Stats.Cpu)
} else {
// Should be JSON - try to decode as JSON
var decodedJson system.CombinedData
err = json.Unmarshal([]byte(encodedData), &decodedJson)
assert.NoError(t, err, "Should be valid JSON data")
var decodedCbor system.CombinedData
err = cbor.Unmarshal([]byte(encodedData), &decodedCbor)
assert.Error(t, err, "Should not be valid CBOR data")
// Verify the decoded JSON data matches our test data
assert.Equal(t, testData.Info.Hostname, decodedJson.Info.Hostname)
assert.Equal(t, testData.Stats.Cpu, decodedJson.Stats.Cpu)
// Verify it looks like JSON (starts with '{' and contains readable field names)
assert.True(t, strings.HasPrefix(encodedData, "{"), "JSON should start with '{'")
assert.Contains(t, encodedData, `"info"`, "JSON should contain readable field names")
assert.Contains(t, encodedData, `"stats"`, "JSON should contain readable field names")
}
})
}
}
// Helper function to create test data for encoding tests
func createTestCombinedData() *system.CombinedData {
return &system.CombinedData{
Stats: system.Stats{
Cpu: 25.5,
Mem: 8589934592, // 8GB
MemUsed: 4294967296, // 4GB
MemPct: 50.0,
DiskTotal: 1099511627776, // 1TB
DiskUsed: 549755813888, // 512GB
DiskPct: 50.0,
},
Info: system.Info{
Hostname: "test-host",
Cores: 8,
CpuModel: "Test CPU Model",
Uptime: 3600,
AgentVersion: "0.12.0",
Os: system.Linux,
},
Containers: []*container.Stats{
{
Name: "test-container",
Cpu: 10.5,
Mem: 1073741824, // 1GB
},
},
}
}
func TestHubVersionCaching(t *testing.T) {
// Reset the global hubVersions map to ensure clean state
hubVersions = nil
agent, err := NewAgent("")
require.NoError(t, err)
ctx1 := &mockSSHContext{
sessionID: "session1",
clientVersion: "SSH-2.0-beszel_0.12.0",
}
ctx2 := &mockSSHContext{
sessionID: "session2",
clientVersion: "SSH-2.0-beszel_0.11.0",
}
// First calls should cache the versions
v1 := agent.getHubVersion("session1", ctx1)
v2 := agent.getHubVersion("session2", ctx2)
assert.Equal(t, "0.12.0", v1.String())
assert.Equal(t, "0.11.0", v2.String())
// Verify caching by changing context but keeping same session ID
ctx1.clientVersion = "SSH-2.0-beszel_0.10.0"
v1Cached := agent.getHubVersion("session1", ctx1)
assert.Equal(t, "0.12.0", v1Cached.String()) // Should still be cached version
// New session should get new version
ctx3 := &mockSSHContext{
sessionID: "session3",
clientVersion: "SSH-2.0-beszel_0.13.0",
}
v3 := agent.getHubVersion("session3", ctx3)
assert.Equal(t, "0.13.0", v3.String())
}

View File

@@ -1,8 +1,6 @@
package agent
import (
"beszel"
"beszel/internal/entities/system"
"bufio"
"fmt"
"log/slog"
@@ -11,9 +9,14 @@ import (
"strings"
"time"
"github.com/henrygd/beszel"
"github.com/henrygd/beszel/agent/battery"
"github.com/henrygd/beszel/internal/entities/system"
"github.com/shirou/gopsutil/v4/cpu"
"github.com/shirou/gopsutil/v4/disk"
"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"
)
@@ -31,6 +34,9 @@ func (a *Agent) initializeSystemInfo() {
} else if strings.Contains(platform, "indows") {
a.systemInfo.KernelVersion = strings.Replace(platform, "Microsoft ", "", 1) + " " + version
a.systemInfo.Os = system.Windows
} else if platform == "freebsd" {
a.systemInfo.Os = system.Freebsd
a.systemInfo.KernelVersion = version
} else {
a.systemInfo.Os = system.Linux
}
@@ -55,10 +61,10 @@ func (a *Agent) initializeSystemInfo() {
}
// zfs
if _, err := getARCSize(); err == nil {
a.zfs = true
} else {
if _, err := getARCSize(); err != nil {
slog.Debug("Not monitoring ZFS ARC", "err", err)
} else {
a.zfs = true
}
}
@@ -66,6 +72,11 @@ func (a *Agent) initializeSystemInfo() {
func (a *Agent) getSystemStats() system.Stats {
systemStats := system.Stats{}
// battery
if battery.HasReadableBattery() {
systemStats.Battery[0], systemStats.Battery[1], _ = battery.GetBatteryStats()
}
// cpu percent
cpuPct, err := cpu.Percent(0, false)
if err != nil {
@@ -74,6 +85,16 @@ func (a *Agent) getSystemStats() system.Stats {
systemStats.Cpu = twoDecimals(cpuPct[0])
}
// load average
if avgstat, err := load.Avg(); err == nil {
systemStats.LoadAvg[0] = avgstat.Load1
systemStats.LoadAvg[1] = avgstat.Load5
systemStats.LoadAvg[2] = avgstat.Load15
slog.Debug("Load average", "5m", avgstat.Load5, "15m", avgstat.Load15)
} else {
slog.Error("Error getting load average", "err", err)
}
// memory
if v, err := mem.VirtualMemory(); err == nil {
// swap
@@ -160,24 +181,27 @@ func (a *Agent) getSystemStats() system.Stats {
a.initializeNetIoStats()
}
if netIO, err := psutilNet.IOCounters(true); err == nil {
secondsElapsed := time.Since(a.netIoStats.Time).Seconds()
msElapsed := uint64(time.Since(a.netIoStats.Time).Milliseconds())
a.netIoStats.Time = time.Now()
bytesSent := uint64(0)
bytesRecv := uint64(0)
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
}
bytesSent += v.BytesSent
bytesRecv += v.BytesRecv
totalBytesSent += v.BytesSent
totalBytesRecv += v.BytesRecv
}
// add to systemStats
sentPerSecond := float64(bytesSent-a.netIoStats.BytesSent) / secondsElapsed
recvPerSecond := float64(bytesRecv-a.netIoStats.BytesRecv) / secondsElapsed
networkSentPs := bytesToMegabytes(sentPerSecond)
networkRecvPs := bytesToMegabytes(recvPerSecond)
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)
@@ -192,9 +216,10 @@ func (a *Agent) getSystemStats() system.Stats {
} else {
systemStats.NetworkSent = networkSentPs
systemStats.NetworkRecv = networkRecvPs
systemStats.Bandwidth[0], systemStats.Bandwidth[1] = bytesSentPerSecond, bytesRecvPerSecond
// update netIoStats
a.netIoStats.BytesSent = bytesSent
a.netIoStats.BytesRecv = bytesRecv
a.netIoStats.BytesSent = totalBytesSent
a.netIoStats.BytesRecv = totalBytesRecv
}
}
@@ -237,10 +262,17 @@ func (a *Agent) getSystemStats() system.Stats {
// update base system info
a.systemInfo.Cpu = systemStats.Cpu
a.systemInfo.LoadAvg = systemStats.LoadAvg
// TODO: remove these in future release in favor of load avg array
a.systemInfo.LoadAvg1 = systemStats.LoadAvg[0]
a.systemInfo.LoadAvg5 = systemStats.LoadAvg[1]
a.systemInfo.LoadAvg15 = systemStats.LoadAvg[2]
a.systemInfo.MemPct = systemStats.MemPct
a.systemInfo.DiskPct = systemStats.DiskPct
a.systemInfo.Uptime, _ = host.Uptime()
// TODO: in future release, remove MB bandwidth values in favor of bytes
a.systemInfo.Bandwidth = twoDecimals(systemStats.NetworkSent + systemStats.NetworkRecv)
a.systemInfo.BandwidthBytes = systemStats.Bandwidth[0] + systemStats.Bandwidth[1]
slog.Debug("sysinfo", "data", a.systemInfo)
return systemStats

165
agent/update.go Normal file
View File

@@ -0,0 +1,165 @@
package agent
import (
"fmt"
"log"
"os"
"os/exec"
"runtime"
"strings"
"github.com/henrygd/beszel/internal/ghupdate"
)
// restarter knows how to restart the beszel-agent service.
type restarter interface {
Restart() error
}
type systemdRestarter struct{ cmd string }
func (s *systemdRestarter) Restart() error {
// Only restart if the service is active
if err := exec.Command(s.cmd, "is-active", "beszel-agent.service").Run(); err != nil {
return nil
}
ghupdate.ColorPrint(ghupdate.ColorYellow, "Restarting beszel-agent.service via systemd…")
return exec.Command(s.cmd, "restart", "beszel-agent.service").Run()
}
type openRCRestarter struct{ cmd string }
func (o *openRCRestarter) Restart() error {
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, "restart", "beszel-agent").Run()
}
type openWRTRestarter struct{ cmd string }
func (w *openWRTRestarter) Restart() error {
if err := exec.Command(w.cmd, "running", "beszel-agent").Run(); err != nil {
return nil
}
ghupdate.ColorPrint(ghupdate.ColorYellow, "Restarting beszel-agent via procd…")
return exec.Command(w.cmd, "restart", "beszel-agent").Run()
}
type freeBSDRestarter struct{ cmd string }
func (f *freeBSDRestarter) Restart() error {
if err := exec.Command(f.cmd, "beszel-agent", "status").Run(); err != nil {
return nil
}
ghupdate.ColorPrint(ghupdate.ColorYellow, "Restarting beszel-agent via FreeBSD rc…")
return exec.Command(f.cmd, "beszel-agent", "restart").Run()
}
func detectRestarter() restarter {
if path, err := exec.LookPath("systemctl"); err == nil {
return &systemdRestarter{cmd: path}
}
if path, err := exec.LookPath("rc-service"); err == nil {
return &openRCRestarter{cmd: path}
}
if path, err := exec.LookPath("service"); err == nil {
if runtime.GOOS == "freebsd" {
return &freeBSDRestarter{cmd: path}
}
return &openWRTRestarter{cmd: path}
}
return nil
}
// Update checks GitHub for a newer release of beszel-agent, applies it,
// fixes SELinux context if needed, and restarts the service.
func Update(useMirror bool) error {
exePath, _ := os.Executable()
dataDir, err := getDataDir()
if err != nil {
dataDir = os.TempDir()
}
updated, err := ghupdate.Update(ghupdate.Config{
ArchiveExecutable: "beszel-agent",
DataDir: dataDir,
UseMirror: useMirror,
})
if err != nil {
log.Fatal(err)
}
if !updated {
return nil
}
// make sure the file is executable
if err := os.Chmod(exePath, 0755); err != nil {
ghupdate.ColorPrintf(ghupdate.ColorYellow, "Warning: failed to set executable permissions: %v", err)
}
// set ownership to beszel:beszel if possible
if chownPath, err := exec.LookPath("chown"); err == nil {
if err := exec.Command(chownPath, "beszel:beszel", exePath).Run(); err != nil {
ghupdate.ColorPrintf(ghupdate.ColorYellow, "Warning: failed to set file ownership: %v", err)
}
}
// 6) Fix SELinux context if necessary
if err := handleSELinuxContext(exePath); err != nil {
ghupdate.ColorPrintf(ghupdate.ColorYellow, "Warning: SELinux context handling: %v", err)
}
// 7) Restart service if running under a recognised init system
if r := detectRestarter(); r != nil {
if err := r.Restart(); err != nil {
ghupdate.ColorPrintf(ghupdate.ColorYellow, "Warning: failed to restart service: %v", err)
ghupdate.ColorPrint(ghupdate.ColorYellow, "Please restart the service manually.")
} else {
ghupdate.ColorPrint(ghupdate.ColorGreen, "Service restarted successfully")
}
} else {
ghupdate.ColorPrint(ghupdate.ColorYellow, "No supported init system detected; please restart manually if needed.")
}
return nil
}
// handleSELinuxContext restores or applies the correct SELinux label to the binary.
func handleSELinuxContext(path string) error {
out, err := exec.Command("getenforce").Output()
if err != nil {
// SELinux not enabled or getenforce not available
return nil
}
state := strings.TrimSpace(string(out))
if state == "Disabled" {
return nil
}
ghupdate.ColorPrint(ghupdate.ColorYellow, "SELinux is enabled; applying context…")
var errs []string
// Try persistent context via semanage+restorecon
if semanagePath, err := exec.LookPath("semanage"); err == nil {
if err := exec.Command(semanagePath, "fcontext", "-a", "-t", "bin_t", path).Run(); err != nil {
errs = append(errs, "semanage fcontext failed: "+err.Error())
} else if restoreconPath, err := exec.LookPath("restorecon"); err == nil {
if err := exec.Command(restoreconPath, "-v", path).Run(); err != nil {
errs = append(errs, "restorecon failed: "+err.Error())
}
}
}
// Fallback to temporary context via chcon
if chconPath, err := exec.LookPath("chcon"); err == nil {
if err := exec.Command(chconPath, "-t", "bin_t", path).Run(); err != nil {
errs = append(errs, "chcon failed: "+err.Error())
}
}
if len(errs) > 0 {
return fmt.Errorf("SELinux context errors: %s", strings.Join(errs, "; "))
}
return nil
}

15
beszel.go Normal file
View File

@@ -0,0 +1,15 @@
// Package beszel provides core application constants and version information
// which are used throughout the application.
package beszel
import "github.com/blang/semver"
const (
// Version is the current version of the application.
Version = "0.12.7"
// AppName is the name of the application.
AppName = "beszel"
)
// MinVersionCbor is the minimum supported version for CBOR compatibility.
var MinVersionCbor = semver.MustParse("0.12.0")

View File

@@ -1,72 +0,0 @@
# Default OS/ARCH values
OS ?= $(shell go env GOOS)
ARCH ?= $(shell go env GOARCH)
# Skip building the web UI if true
SKIP_WEB ?= false
.PHONY: tidy build-agent build-hub build clean lint dev-server dev-agent dev-hub dev generate-locales
.DEFAULT_GOAL := build
clean:
go clean
rm -rf ./build
lint:
golangci-lint run
test: export GOEXPERIMENT=synctest
test:
go test -tags=testing ./...
tidy:
go mod tidy
build-web-ui:
@if command -v bun >/dev/null 2>&1; then \
bun install --cwd ./site && \
bun run --cwd ./site build; \
else \
npm install --prefix ./site && \
npm run --prefix ./site build; \
fi
build-agent: tidy
GOOS=$(OS) GOARCH=$(ARCH) go build -o ./build/beszel-agent_$(OS)_$(ARCH) -ldflags "-w -s" beszel/cmd/agent
build-hub: tidy $(if $(filter false,$(SKIP_WEB)),build-web-ui)
GOOS=$(OS) GOARCH=$(ARCH) go build -o ./build/beszel_$(OS)_$(ARCH) -ldflags "-w -s" beszel/cmd/hub
build: build-agent build-hub
generate-locales:
@if [ ! -f ./site/src/locales/en/en.ts ]; then \
echo "Generating locales..."; \
command -v bun >/dev/null 2>&1 && cd ./site && bun install && bun run sync || cd ./site && npm install && npm run sync; \
fi
dev-server: generate-locales
cd ./site
@if command -v bun >/dev/null 2>&1; then \
cd ./site && bun run dev; \
else \
cd ./site && npm run dev; \
fi
dev-hub: export ENV=dev
dev-hub:
mkdir -p ./site/dist && touch ./site/dist/index.html
@if command -v entr >/dev/null 2>&1; then \
find ./cmd/hub/*.go ./internal/{alerts,hub,records,users}/*.go | entr -r -s "cd ./cmd/hub && go run . serve"; \
else \
cd ./cmd/hub && go run . serve; \
fi
dev-agent:
@if command -v entr >/dev/null 2>&1; then \
find ./cmd/agent/*.go ./internal/agent/*.go | entr -r go run beszel/cmd/agent; \
else \
go run beszel/cmd/agent; \
fi
# KEY="..." make -j dev
dev: dev-server dev-hub dev-agent

View File

@@ -1,122 +0,0 @@
package main
import (
"beszel"
"beszel/internal/agent"
"flag"
"fmt"
"log"
"os"
"golang.org/x/crypto/ssh"
)
// cli options
type cmdOptions struct {
key string // key is the public key(s) for SSH authentication.
listen string // listen is the address or port to listen on.
}
// parse parses the command line flags and populates the config struct.
// It returns true if a subcommand was handled and the program should exit.
func (opts *cmdOptions) parse() bool {
flag.StringVar(&opts.key, "key", "", "Public key(s) for SSH authentication")
flag.StringVar(&opts.listen, "listen", "", "Address or port to listen on")
flag.Usage = func() {
fmt.Printf("Usage: %s [command] [flags]\n", os.Args[0])
fmt.Println("\nCommands:")
fmt.Println(" health Check if the agent is running")
fmt.Println(" help Display this help message")
fmt.Println(" update Update to the latest version")
fmt.Println(" version Display the version")
fmt.Println("\nFlags:")
flag.PrintDefaults()
}
subcommand := ""
if len(os.Args) > 1 {
subcommand = os.Args[1]
}
switch subcommand {
case "-v", "version":
fmt.Println(beszel.AppName+"-agent", beszel.Version)
return true
case "help":
flag.Usage()
return true
case "update":
agent.Update()
return true
case "health":
// for health, we need to parse flags first to get the listen address
args := append(os.Args[2:], subcommand)
flag.CommandLine.Parse(args)
addr := opts.getAddress()
network := agent.GetNetwork(addr)
err := agent.Health(addr, network)
if err != nil {
log.Fatal(err)
}
fmt.Print("ok")
return true
}
flag.Parse()
return false
}
// loadPublicKeys loads the public keys from the command line flag, environment variable, or key file.
func (opts *cmdOptions) loadPublicKeys() ([]ssh.PublicKey, error) {
// Try command line flag first
if opts.key != "" {
return agent.ParseKeys(opts.key)
}
// Try environment variable
if key, ok := agent.GetEnv("KEY"); ok && key != "" {
return agent.ParseKeys(key)
}
// Try key file
keyFile, ok := agent.GetEnv("KEY_FILE")
if !ok {
return nil, fmt.Errorf("no key provided: must set -key flag, KEY env var, or KEY_FILE env var. Use 'beszel-agent help' for usage")
}
pubKey, err := os.ReadFile(keyFile)
if err != nil {
return nil, fmt.Errorf("failed to read key file: %w", err)
}
return agent.ParseKeys(string(pubKey))
}
func (opts *cmdOptions) getAddress() string {
return agent.GetAddress(opts.listen)
}
func main() {
var opts cmdOptions
subcommandHandled := opts.parse()
if subcommandHandled {
return
}
var serverConfig agent.ServerOptions
var err error
serverConfig.Keys, err = opts.loadPublicKeys()
if err != nil {
log.Fatal("Failed to load public keys:", err)
}
addr := opts.getAddress()
serverConfig.Addr = addr
serverConfig.Network = agent.GetNetwork(addr)
agent := agent.NewAgent()
if err := agent.StartServer(serverConfig); err != nil {
log.Fatal("Failed to start server:", err)
}
}

View File

@@ -1,115 +0,0 @@
// Package agent handles the agent's SSH server and system stats collection.
package agent
import (
"beszel"
"beszel/internal/entities/system"
"log/slog"
"os"
"strings"
"sync"
"time"
)
type Agent struct {
sync.Mutex // Used to lock agent while collecting data
debug bool // true if LOG_LEVEL is set to debug
zfs bool // true if system has arcstats
memCalc string // Memory calculation formula
fsNames []string // List of filesystem device names being monitored
fsStats map[string]*system.FsStats // Keeps track of disk stats for each filesystem
netInterfaces map[string]struct{} // Stores all valid network interfaces
netIoStats system.NetIoStats // Keeps track of bandwidth usage
dockerManager *dockerManager // Manages Docker API requests
sensorConfig *SensorConfig // Sensors config
systemInfo system.Info // Host system info
gpuManager *GPUManager // Manages GPU data
cache *SessionCache // Cache for system stats based on primary session ID
}
func NewAgent() *Agent {
agent := &Agent{
fsStats: make(map[string]*system.FsStats),
cache: NewSessionCache(69 * time.Second),
}
agent.memCalc, _ = GetEnv("MEM_CALC")
agent.sensorConfig = agent.newSensorConfig()
// Set up slog with a log level determined by the LOG_LEVEL env var
if logLevelStr, exists := GetEnv("LOG_LEVEL"); exists {
switch strings.ToLower(logLevelStr) {
case "debug":
agent.debug = true
slog.SetLogLoggerLevel(slog.LevelDebug)
case "warn":
slog.SetLogLoggerLevel(slog.LevelWarn)
case "error":
slog.SetLogLoggerLevel(slog.LevelError)
}
}
slog.Debug(beszel.Version)
// initialize system info / docker manager
agent.initializeSystemInfo()
agent.initializeDiskInfo()
agent.initializeNetIoStats()
agent.dockerManager = newDockerManager(agent)
// initialize GPU manager
if gm, err := NewGPUManager(); err != nil {
slog.Debug("GPU", "err", err)
} else {
agent.gpuManager = gm
}
// if debugging, print stats
if agent.debug {
slog.Debug("Stats", "data", agent.gatherStats(""))
}
return agent
}
// GetEnv retrieves an environment variable with a "BESZEL_AGENT_" prefix, or falls back to the unprefixed key.
func GetEnv(key string) (value string, exists bool) {
if value, exists = os.LookupEnv("BESZEL_AGENT_" + key); exists {
return value, exists
}
// Fallback to the old unprefixed key
return os.LookupEnv(key)
}
func (a *Agent) gatherStats(sessionID string) *system.CombinedData {
a.Lock()
defer a.Unlock()
cachedData, ok := a.cache.Get(sessionID)
if ok {
slog.Debug("Cached stats", "session", sessionID)
return cachedData
}
*cachedData = system.CombinedData{
Stats: a.getSystemStats(),
Info: a.systemInfo,
}
slog.Debug("System stats", "data", cachedData)
if containerStats, err := a.dockerManager.getDockerStats(); err == nil {
cachedData.Containers = containerStats
slog.Debug("Docker stats", "data", cachedData.Containers)
} else {
slog.Debug("Docker stats", "err", err)
}
cachedData.Stats.ExtraFs = make(map[string]*system.FsStats)
for name, stats := range a.fsStats {
if !stats.Root && stats.DiskTotal > 0 {
cachedData.Stats.ExtraFs[name] = stats
}
}
slog.Debug("Extra filesystems", "data", cachedData.Stats.ExtraFs)
a.cache.Set(sessionID, cachedData)
return cachedData
}

View File

@@ -1,18 +0,0 @@
package agent
import (
"net"
"time"
)
// Health checks if the agent's server is running by attempting to connect to it.
//
// If an error occurs when attempting to connect to the server, it returns the error.
func Health(addr string, network string) error {
conn, err := net.DialTimeout(network, addr, 4*time.Second)
if err != nil {
return err
}
conn.Close()
return nil
}

View File

@@ -1,118 +0,0 @@
//go:build testing
// +build testing
package agent_test
import (
"fmt"
"net"
"os"
"testing"
"github.com/stretchr/testify/require"
"beszel/internal/agent"
)
// setupTestServer creates a temporary server for testing
func setupTestServer(t *testing.T) (string, func()) {
// Create a temporary socket file for Unix socket testing
tempSockFile := os.TempDir() + "/beszel_health_test.sock"
// Clean up any existing socket file
os.Remove(tempSockFile)
// Create a listener
listener, err := net.Listen("unix", tempSockFile)
require.NoError(t, err, "Failed to create test listener")
// Start a simple server in a goroutine
go func() {
conn, err := listener.Accept()
if err != nil {
return // Listener closed
}
defer conn.Close()
// Just accept the connection and do nothing
}()
// Return the socket file path and a cleanup function
return tempSockFile, func() {
listener.Close()
os.Remove(tempSockFile)
}
}
// setupTCPTestServer creates a temporary TCP server for testing
func setupTCPTestServer(t *testing.T) (string, func()) {
// Listen on a random available port
listener, err := net.Listen("tcp", "127.0.0.1:0")
require.NoError(t, err, "Failed to create test listener")
// Get the port that was assigned
addr := listener.Addr().(*net.TCPAddr)
port := addr.Port
// Start a simple server in a goroutine
go func() {
conn, err := listener.Accept()
if err != nil {
return // Listener closed
}
defer conn.Close()
// Just accept the connection and do nothing
}()
// Return the address and a cleanup function
return fmt.Sprintf("127.0.0.1:%d", port), func() {
listener.Close()
}
}
func TestHealth(t *testing.T) {
t.Run("server is running (unix socket)", func(t *testing.T) {
// Setup a test server
sockFile, cleanup := setupTestServer(t)
defer cleanup()
// Run the health check with explicit parameters
err := agent.Health(sockFile, "unix")
require.NoError(t, err, "Failed to check health")
})
t.Run("server is running (tcp address)", func(t *testing.T) {
// Setup a test server
addr, cleanup := setupTCPTestServer(t)
defer cleanup()
// Run the health check with explicit parameters
err := agent.Health(addr, "tcp")
require.NoError(t, err, "Failed to check health")
})
t.Run("server is not running", func(t *testing.T) {
// Use an address that's likely not in use
addr := "127.0.0.1:65535"
// Run the health check with explicit parameters
err := agent.Health(addr, "tcp")
require.Error(t, err, "Health check should return an error when server is not running")
})
t.Run("invalid network", func(t *testing.T) {
// Use an invalid network type
err := agent.Health("127.0.0.1:8080", "invalid_network")
require.Error(t, err, "Health check should return an error with invalid network")
})
t.Run("unix socket not found", func(t *testing.T) {
// Use a non-existent unix socket
nonExistentSocket := os.TempDir() + "/non_existent_socket.sock"
// Make sure it really doesn't exist
os.Remove(nonExistentSocket)
err := agent.Health(nonExistentSocket, "unix")
require.Error(t, err, "Health check should return an error when socket doesn't exist")
})
}

View File

@@ -1,111 +0,0 @@
package agent
import (
"encoding/json"
"fmt"
"log/slog"
"net"
"os"
"strings"
sshServer "github.com/gliderlabs/ssh"
"golang.org/x/crypto/ssh"
)
type ServerOptions struct {
Addr string
Network string
Keys []ssh.PublicKey
}
func (a *Agent) StartServer(opts ServerOptions) error {
sshServer.Handle(a.handleSession)
slog.Info("Starting SSH server", "addr", opts.Addr, "network", opts.Network)
if opts.Network == "unix" {
// remove existing socket file if it exists
if err := os.Remove(opts.Addr); err != nil && !os.IsNotExist(err) {
return err
}
}
// start listening on the address
ln, err := net.Listen(opts.Network, opts.Addr)
if err != nil {
return err
}
defer ln.Close()
// Start SSH server on the listener
return sshServer.Serve(ln, nil, sshServer.NoPty(),
sshServer.PublicKeyAuth(func(ctx sshServer.Context, key sshServer.PublicKey) bool {
for _, pubKey := range opts.Keys {
if sshServer.KeysEqual(key, pubKey) {
return true
}
}
return false
}),
)
}
func (a *Agent) handleSession(s sshServer.Session) {
slog.Debug("New session", "client", s.RemoteAddr())
stats := a.gatherStats(s.Context().SessionID())
if err := json.NewEncoder(s).Encode(stats); err != nil {
slog.Error("Error encoding stats", "err", err, "stats", stats)
s.Exit(1)
}
s.Exit(0)
}
// ParseKeys parses a string containing SSH public keys in authorized_keys format.
// It returns a slice of ssh.PublicKey and an error if any key fails to parse.
func ParseKeys(input string) ([]ssh.PublicKey, error) {
var parsedKeys []ssh.PublicKey
for line := range strings.Lines(input) {
line = strings.TrimSpace(line)
// Skip empty lines or comments
if len(line) == 0 || strings.HasPrefix(line, "#") {
continue
}
// Parse the key
parsedKey, _, _, _, err := ssh.ParseAuthorizedKey([]byte(line))
if err != nil {
return nil, fmt.Errorf("failed to parse key: %s, error: %w", line, err)
}
parsedKeys = append(parsedKeys, parsedKey)
}
return parsedKeys, nil
}
// GetAddress gets the address to listen on or connect to from environment variables or default value.
func GetAddress(addr string) string {
if addr == "" {
addr, _ = GetEnv("LISTEN")
}
if addr == "" {
// Legacy PORT environment variable support
addr, _ = GetEnv("PORT")
}
if addr == "" {
return ":45876"
}
// prefix with : if only port was provided
if GetNetwork(addr) != "unix" && !strings.Contains(addr, ":") {
addr = ":" + addr
}
return addr
}
// GetNetwork returns the network type to use based on the address
func GetNetwork(addr string) string {
if network, ok := GetEnv("NETWORK"); ok && network != "" {
return network
}
if strings.HasPrefix(addr, "/") {
return "unix"
}
return "tcp"
}

View File

@@ -1,289 +0,0 @@
package agent
import (
"crypto/ed25519"
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"golang.org/x/crypto/ssh"
)
func TestStartServer(t *testing.T) {
// Generate a test key pair
pubKey, privKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
signer, err := ssh.NewSignerFromKey(privKey)
require.NoError(t, err)
sshPubKey, err := ssh.NewPublicKey(pubKey)
require.NoError(t, err)
// Generate a different key pair for bad key test
badPubKey, badPrivKey, err := ed25519.GenerateKey(nil)
require.NoError(t, err)
badSigner, err := ssh.NewSignerFromKey(badPrivKey)
require.NoError(t, err)
sshBadPubKey, err := ssh.NewPublicKey(badPubKey)
require.NoError(t, err)
socketFile := filepath.Join(t.TempDir(), "beszel-test.sock")
tests := []struct {
name string
config ServerOptions
wantErr bool
errContains string
setup func() error
cleanup func() error
}{
{
name: "tcp port only",
config: ServerOptions{
Network: "tcp",
Addr: ":45987",
Keys: []ssh.PublicKey{sshPubKey},
},
},
{
name: "tcp with ipv4",
config: ServerOptions{
Network: "tcp4",
Addr: "127.0.0.1:45988",
Keys: []ssh.PublicKey{sshPubKey},
},
},
{
name: "tcp with ipv6",
config: ServerOptions{
Network: "tcp6",
Addr: "[::1]:45989",
Keys: []ssh.PublicKey{sshPubKey},
},
},
{
name: "unix socket",
config: ServerOptions{
Network: "unix",
Addr: socketFile,
Keys: []ssh.PublicKey{sshPubKey},
},
setup: func() error {
// Create a socket file that should be removed
f, err := os.Create(socketFile)
if err != nil {
return err
}
return f.Close()
},
cleanup: func() error {
return os.Remove(socketFile)
},
},
{
name: "bad key should fail",
config: ServerOptions{
Network: "tcp",
Addr: ":45987",
Keys: []ssh.PublicKey{sshBadPubKey},
},
wantErr: true,
errContains: "ssh: handshake failed",
},
{
name: "good key still good",
config: ServerOptions{
Network: "tcp",
Addr: ":45987",
Keys: []ssh.PublicKey{sshPubKey},
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.setup != nil {
err := tt.setup()
require.NoError(t, err)
}
if tt.cleanup != nil {
defer tt.cleanup()
}
agent := NewAgent()
// Start server in a goroutine since it blocks
errChan := make(chan error, 1)
go func() {
errChan <- agent.StartServer(tt.config)
}()
// Add a short delay to allow the server to start
time.Sleep(100 * time.Millisecond)
// Try to connect to verify server is running
var client *ssh.Client
var err error
// Choose the appropriate signer based on the test case
testSigner := signer
if tt.name == "bad key should fail" {
testSigner = badSigner
}
sshClientConfig := &ssh.ClientConfig{
User: "a",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(testSigner),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: 4 * time.Second,
}
switch tt.config.Network {
case "unix":
client, err = ssh.Dial("unix", tt.config.Addr, sshClientConfig)
default:
if !strings.Contains(tt.config.Addr, ":") {
tt.config.Addr = ":" + tt.config.Addr
}
client, err = ssh.Dial("tcp", tt.config.Addr, sshClientConfig)
}
if tt.wantErr {
assert.Error(t, err)
if tt.errContains != "" {
assert.Contains(t, err.Error(), tt.errContains)
}
return
}
require.NoError(t, err)
require.NotNil(t, client)
client.Close()
})
}
}
/////////////////////////////////////////////////////////////////
//////////////////// ParseKeys Tests ////////////////////////////
/////////////////////////////////////////////////////////////////
// Helper function to generate a temporary file with content
func createTempFile(content string) (string, error) {
tmpFile, err := os.CreateTemp("", "ssh_keys_*.txt")
if err != nil {
return "", fmt.Errorf("failed to create temp file: %w", err)
}
defer tmpFile.Close()
if _, err := tmpFile.WriteString(content); err != nil {
return "", fmt.Errorf("failed to write to temp file: %w", err)
}
return tmpFile.Name(), nil
}
// Test case 1: String with a single SSH key
func TestParseSingleKeyFromString(t *testing.T) {
input := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo"
keys, err := ParseKeys(input)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 1 {
t.Fatalf("Expected 1 key, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" {
t.Fatalf("Expected key type 'ssh-ed25519', got '%s'", keys[0].Type())
}
}
// Test case 2: String with multiple SSH keys
func TestParseMultipleKeysFromString(t *testing.T) {
input := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D \n #comment\n ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D"
keys, err := ParseKeys(input)
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 3 {
t.Fatalf("Expected 3 keys, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" || keys[1].Type() != "ssh-ed25519" || keys[2].Type() != "ssh-ed25519" {
t.Fatalf("Unexpected key types: %s, %s, %s", keys[0].Type(), keys[1].Type(), keys[2].Type())
}
}
// Test case 3: File with a single SSH key
func TestParseSingleKeyFromFile(t *testing.T) {
content := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo"
filePath, err := createTempFile(content)
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
defer os.Remove(filePath) // Clean up the file after the test
// Read the file content
fileContent, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("Failed to read temp file: %v", err)
}
// Parse the keys
keys, err := ParseKeys(string(fileContent))
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 1 {
t.Fatalf("Expected 1 key, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" {
t.Fatalf("Expected key type 'ssh-ed25519', got '%s'", keys[0].Type())
}
}
// Test case 4: File with multiple SSH keys
func TestParseMultipleKeysFromFile(t *testing.T) {
content := "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIKCBM91kukN7hbvFKtbpEeo2JXjCcNxXcdBH7V7ADMBo\nssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D \n #comment\n ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJDMtAOQfxDlCxe+A5lVbUY/DHxK1LAF2Z3AV0FYv36D"
filePath, err := createTempFile(content)
if err != nil {
t.Fatalf("Failed to create temp file: %v", err)
}
// defer os.Remove(filePath) // Clean up the file after the test
// Read the file content
fileContent, err := os.ReadFile(filePath)
if err != nil {
t.Fatalf("Failed to read temp file: %v", err)
}
// Parse the keys
keys, err := ParseKeys(string(fileContent))
if err != nil {
t.Fatalf("Expected no error, got: %v", err)
}
if len(keys) != 3 {
t.Fatalf("Expected 3 keys, got %d keys", len(keys))
}
if keys[0].Type() != "ssh-ed25519" || keys[1].Type() != "ssh-ed25519" || keys[2].Type() != "ssh-ed25519" {
t.Fatalf("Unexpected key types: %s, %s, %s", keys[0].Type(), keys[1].Type(), keys[2].Type())
}
}
// Test case 5: Invalid SSH key input
func TestParseInvalidKey(t *testing.T) {
input := "invalid-key-data"
_, err := ParseKeys(input)
if err == nil {
t.Fatalf("Expected an error for invalid key, got nil")
}
expectedErrMsg := "failed to parse key"
if !strings.Contains(err.Error(), expectedErrMsg) {
t.Fatalf("Expected error message to contain '%s', got: %v", expectedErrMsg, err)
}
}

View File

@@ -1,56 +0,0 @@
package agent
import (
"beszel"
"fmt"
"os"
"strings"
"github.com/blang/semver"
"github.com/rhysd/go-github-selfupdate/selfupdate"
)
// Update updates beszel-agent to the latest version
func Update() {
var latest *selfupdate.Release
var found bool
var err error
currentVersion := semver.MustParse(beszel.Version)
fmt.Println("beszel-agent", currentVersion)
fmt.Println("Checking for updates...")
updater, _ := selfupdate.NewUpdater(selfupdate.Config{
Filters: []string{"beszel-agent"},
})
latest, found, err = updater.DetectLatest("henrygd/beszel")
if err != nil {
fmt.Println("Error checking for updates:", err)
os.Exit(1)
}
if !found {
fmt.Println("No updates found")
os.Exit(0)
}
fmt.Println("Latest version:", latest.Version)
if latest.Version.LTE(currentVersion) {
fmt.Println("You are up to date")
return
}
var binaryPath string
fmt.Printf("Updating from %s to %s...\n", currentVersion, latest.Version)
binaryPath, err = os.Executable()
if err != nil {
fmt.Println("Error getting binary path:", err)
os.Exit(1)
}
err = selfupdate.UpdateTo(latest.AssetURL, binaryPath)
if err != nil {
fmt.Println("Please try rerunning with sudo. Error:", err)
os.Exit(1)
}
fmt.Printf("Successfully updated to %s\n\n%s\n", latest.Version, strings.TrimSpace(latest.ReleaseNotes))
}

View File

@@ -1,98 +0,0 @@
package system
// TODO: this is confusing, make common package with common/types common/helpers etc
import (
"beszel/internal/entities/container"
"time"
)
type Stats struct {
Cpu float64 `json:"cpu"`
MaxCpu float64 `json:"cpum,omitempty"`
Mem float64 `json:"m"`
MemUsed float64 `json:"mu"`
MemPct float64 `json:"mp"`
MemBuffCache float64 `json:"mb"`
MemZfsArc float64 `json:"mz,omitempty"` // ZFS ARC memory
Swap float64 `json:"s,omitempty"`
SwapUsed float64 `json:"su,omitempty"`
DiskTotal float64 `json:"d"`
DiskUsed float64 `json:"du"`
DiskPct float64 `json:"dp"`
DiskReadPs float64 `json:"dr"`
DiskWritePs float64 `json:"dw"`
MaxDiskReadPs float64 `json:"drm,omitempty"`
MaxDiskWritePs float64 `json:"dwm,omitempty"`
NetworkSent float64 `json:"ns"`
NetworkRecv float64 `json:"nr"`
MaxNetworkSent float64 `json:"nsm,omitempty"`
MaxNetworkRecv float64 `json:"nrm,omitempty"`
Temperatures map[string]float64 `json:"t,omitempty"`
ExtraFs map[string]*FsStats `json:"efs,omitempty"`
GPUData map[string]GPUData `json:"g,omitempty"`
}
type GPUData struct {
Name string `json:"n"`
Temperature float64 `json:"-"`
MemoryUsed float64 `json:"mu,omitempty"`
MemoryTotal float64 `json:"mt,omitempty"`
Usage float64 `json:"u"`
Power float64 `json:"p,omitempty"`
Count float64 `json:"-"`
}
type FsStats struct {
Time time.Time `json:"-"`
Root bool `json:"-"`
Mountpoint string `json:"-"`
DiskTotal float64 `json:"d"`
DiskUsed float64 `json:"du"`
TotalRead uint64 `json:"-"`
TotalWrite uint64 `json:"-"`
DiskReadPs float64 `json:"r"`
DiskWritePs float64 `json:"w"`
MaxDiskReadPS float64 `json:"rm,omitempty"`
MaxDiskWritePS float64 `json:"wm,omitempty"`
}
type NetIoStats struct {
BytesRecv uint64
BytesSent uint64
Time time.Time
Name string
}
type Os uint8
const (
Linux Os = iota
Darwin
Windows
)
type Info struct {
Hostname string `json:"h"`
KernelVersion string `json:"k,omitempty"`
Cores int `json:"c"`
Threads int `json:"t,omitempty"`
CpuModel string `json:"m"`
Uptime uint64 `json:"u"`
Cpu float64 `json:"cpu"`
MemPct float64 `json:"mp"`
DiskPct float64 `json:"dp"`
Bandwidth float64 `json:"b"`
AgentVersion string `json:"v"`
Podman bool `json:"p,omitempty"`
GpuPct float64 `json:"g,omitempty"`
DashboardTemp float64 `json:"dt,omitempty"`
Os Os `json:"os"`
}
// Final data structure to return to the hub
type CombinedData struct {
Stats Stats `json:"stats"`
Info Info `json:"info"`
Containers []*container.Stats `json:"container"`
}

View File

@@ -1,435 +0,0 @@
package systems
import (
"beszel/internal/entities/system"
"context"
"fmt"
"net"
"strings"
"time"
"github.com/goccy/go-json"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tools/store"
"golang.org/x/crypto/ssh"
)
const (
up string = "up"
down string = "down"
paused string = "paused"
pending string = "pending"
interval int = 60_000
sessionTimeout = 4 * time.Second
)
type SystemManager struct {
hub hubLike
systems *store.Store[string, *System]
sshConfig *ssh.ClientConfig
}
type System struct {
Id string `db:"id"`
Host string `db:"host"`
Port string `db:"port"`
Status string `db:"status"`
manager *SystemManager
client *ssh.Client
data *system.CombinedData
ctx context.Context
cancel context.CancelFunc
}
type hubLike interface {
core.App
GetSSHKey() ([]byte, error)
HandleSystemAlerts(systemRecord *core.Record, data *system.CombinedData) error
HandleStatusAlerts(status string, systemRecord *core.Record) error
}
func NewSystemManager(hub hubLike) *SystemManager {
return &SystemManager{
systems: store.New(map[string]*System{}),
hub: hub,
}
}
// Initialize initializes the system manager.
// It binds the event hooks and starts updating existing systems.
func (sm *SystemManager) Initialize() error {
sm.bindEventHooks()
// ssh setup
key, err := sm.hub.GetSSHKey()
if err != nil {
return err
}
if err := sm.createSSHClientConfig(key); err != nil {
return err
}
// start updating existing systems
var systems []*System
err = sm.hub.DB().NewQuery("SELECT id, host, port, status FROM systems WHERE status != 'paused'").All(&systems)
if err != nil || len(systems) == 0 {
return err
}
go func() {
// time between initial system updates
delta := interval / max(1, len(systems))
delta = min(delta, 2_000)
sleepTime := time.Duration(delta) * time.Millisecond
for _, system := range systems {
time.Sleep(sleepTime)
_ = sm.AddSystem(system)
}
}()
return nil
}
func (sm *SystemManager) bindEventHooks() {
sm.hub.OnRecordCreate("systems").BindFunc(sm.onRecordCreate)
sm.hub.OnRecordAfterCreateSuccess("systems").BindFunc(sm.onRecordAfterCreateSuccess)
sm.hub.OnRecordUpdate("systems").BindFunc(sm.onRecordUpdate)
sm.hub.OnRecordAfterUpdateSuccess("systems").BindFunc(sm.onRecordAfterUpdateSuccess)
sm.hub.OnRecordAfterDeleteSuccess("systems").BindFunc(sm.onRecordAfterDeleteSuccess)
}
// Runs before the record is committed to the database
func (sm *SystemManager) onRecordCreate(e *core.RecordEvent) error {
e.Record.Set("info", system.Info{})
e.Record.Set("status", pending)
return e.Next()
}
// Runs after the record is committed to the database
func (sm *SystemManager) onRecordAfterCreateSuccess(e *core.RecordEvent) error {
if err := sm.AddRecord(e.Record); err != nil {
e.App.Logger().Error("Error adding record", "err", err)
}
return e.Next()
}
// Runs before the record is updated
func (sm *SystemManager) onRecordUpdate(e *core.RecordEvent) error {
if e.Record.GetString("status") == paused {
e.Record.Set("info", system.Info{})
}
return e.Next()
}
// Runs after the record is updated
func (sm *SystemManager) onRecordAfterUpdateSuccess(e *core.RecordEvent) error {
newStatus := e.Record.GetString("status")
switch newStatus {
case paused:
sm.RemoveSystem(e.Record.Id)
return e.Next()
case pending:
if err := sm.AddRecord(e.Record); err != nil {
e.App.Logger().Error("Error adding record", "err", err)
}
return e.Next()
}
system, ok := sm.systems.GetOk(e.Record.Id)
if !ok {
return sm.AddRecord(e.Record)
}
prevStatus := system.Status
system.Status = newStatus
// system alerts if system is up
if system.Status == up {
if err := sm.hub.HandleSystemAlerts(e.Record, system.data); err != nil {
e.App.Logger().Error("Error handling system alerts", "err", err)
}
}
if (system.Status == down && prevStatus == up) || (system.Status == up && prevStatus == down) {
if err := sm.hub.HandleStatusAlerts(system.Status, e.Record); err != nil {
e.App.Logger().Error("Error handling status alerts", "err", err)
}
}
return e.Next()
}
// Runs after the record is deleted
func (sm *SystemManager) onRecordAfterDeleteSuccess(e *core.RecordEvent) error {
sm.RemoveSystem(e.Record.Id)
return e.Next()
}
// AddSystem adds a system to the manager
func (sm *SystemManager) AddSystem(sys *System) error {
if sm.systems.Has(sys.Id) {
return fmt.Errorf("system exists")
}
if sys.Id == "" || sys.Host == "" {
return fmt.Errorf("system is missing required fields")
}
sys.manager = sm
sys.ctx, sys.cancel = context.WithCancel(context.Background())
sys.data = &system.CombinedData{}
sm.systems.Set(sys.Id, sys)
go sys.StartUpdater()
return nil
}
// RemoveSystem removes a system from the manager
func (sm *SystemManager) RemoveSystem(systemID string) error {
system, ok := sm.systems.GetOk(systemID)
if !ok {
return fmt.Errorf("system not found")
}
// cancel the context to signal stop
if system.cancel != nil {
system.cancel()
}
system.resetSSHClient()
sm.systems.Remove(systemID)
return nil
}
// AddRecord adds a record to the system manager.
// It first removes any existing system with the same ID, then creates a new System
// instance from the record data and adds it to the manager.
// This function is typically called when a new system is created or when an existing
// system's status changes to pending.
func (sm *SystemManager) AddRecord(record *core.Record) (err error) {
_ = sm.RemoveSystem(record.Id)
system := &System{
Id: record.Id,
Status: record.GetString("status"),
Host: record.GetString("host"),
Port: record.GetString("port"),
}
return sm.AddSystem(system)
}
// StartUpdater starts the system updater.
// It first fetches the data from the agent then updates the records.
// If the data is not found or the system is down, it sets the system down.
func (sys *System) StartUpdater() {
if sys.data == nil {
sys.data = &system.CombinedData{}
}
if err := sys.update(); err != nil {
_ = sys.setDown(err)
}
c := time.Tick(time.Duration(interval) * time.Millisecond)
for {
select {
case <-sys.ctx.Done():
return
case <-c:
err := sys.update()
if err != nil {
_ = sys.setDown(err)
}
}
}
}
// update updates the system data and records.
// It first fetches the data from the agent then updates the records.
func (sys *System) update() error {
_, err := sys.fetchDataFromAgent()
if err == nil {
_, err = sys.createRecords()
}
return err
}
// createRecords updates the system record and adds system_stats and container_stats records
func (sys *System) createRecords() (*core.Record, error) {
systemRecord, err := sys.getRecord()
if err != nil {
return nil, err
}
hub := sys.manager.hub
// add system_stats and container_stats records
systemStats, err := hub.FindCachedCollectionByNameOrId("system_stats")
if err != nil {
return nil, err
}
systemStatsRecord := core.NewRecord(systemStats)
systemStatsRecord.Set("system", systemRecord.Id)
systemStatsRecord.Set("stats", sys.data.Stats)
systemStatsRecord.Set("type", "1m")
if err := hub.SaveNoValidate(systemStatsRecord); err != nil {
return nil, err
}
// add new container_stats record
if len(sys.data.Containers) > 0 {
containerStats, err := hub.FindCachedCollectionByNameOrId("container_stats")
if err != nil {
return nil, err
}
containerStatsRecord := core.NewRecord(containerStats)
containerStatsRecord.Set("system", systemRecord.Id)
containerStatsRecord.Set("stats", sys.data.Containers)
containerStatsRecord.Set("type", "1m")
if err := hub.SaveNoValidate(containerStatsRecord); 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)
systemRecord.Set("info", sys.data.Info)
if err := hub.SaveNoValidate(systemRecord); err != nil {
return nil, err
}
return systemRecord, nil
}
// getRecord retrieves the system record from the database.
// If the record is not found or the system is paused, it removes the system from the manager.
func (sys *System) getRecord() (*core.Record, error) {
record, err := sys.manager.hub.FindRecordById("systems", sys.Id)
if err != nil || record == nil {
_ = sys.manager.RemoveSystem(sys.Id)
return nil, err
}
return record, nil
}
// setDown marks a system as down in the database.
// It takes the original error that caused the system to go down and returns any error
// encountered during the process of updating the system status.
func (sys *System) setDown(OriginalError error) error {
if sys.Status == down {
return nil
}
record, err := sys.getRecord()
if err != nil {
return err
}
sys.manager.hub.Logger().Error("System down", "system", record.GetString("name"), "err", OriginalError)
record.Set("status", down)
err = sys.manager.hub.SaveNoValidate(record)
if err != nil {
return err
}
return nil
}
// fetchDataFromAgent fetches the data from the agent.
// It first creates a new SSH client if it doesn't exist or the system is down.
// Then it creates a new SSH session and fetches the data from the agent.
// If the data is not found or the system is down, it sets the system down.
func (sys *System) fetchDataFromAgent() (*system.CombinedData, error) {
maxRetries := 1
for attempt := 0; attempt <= maxRetries; attempt++ {
if sys.client == nil || sys.Status == down {
if err := sys.createSSHClient(); err != nil {
return nil, err
}
}
session, err := sys.createSessionWithTimeout(4 * time.Second)
if err != nil {
if attempt >= maxRetries {
return nil, err
}
sys.manager.hub.Logger().Warn("Session closed. Retrying...", "host", sys.Host, "port", sys.Port, "err", err)
sys.resetSSHClient()
continue
}
defer session.Close()
stdout, err := session.StdoutPipe()
if err != nil {
return nil, err
}
if err := session.Shell(); err != nil {
return nil, err
}
// this is initialized in startUpdater, should never be nil
*sys.data = system.CombinedData{}
if err := json.NewDecoder(stdout).Decode(sys.data); err != nil {
return nil, err
}
// wait for the session to complete
if err := session.Wait(); err != nil {
return nil, err
}
return sys.data, nil
}
// this should never be reached due to the return in the loop
return nil, fmt.Errorf("failed to fetch data")
}
func (sm *SystemManager) createSSHClientConfig(key []byte) error {
signer, err := ssh.ParsePrivateKey(key)
if err != nil {
return err
}
sm.sshConfig = &ssh.ClientConfig{
User: "u",
Auth: []ssh.AuthMethod{
ssh.PublicKeys(signer),
},
HostKeyCallback: ssh.InsecureIgnoreHostKey(),
Timeout: sessionTimeout,
}
return nil
}
// createSSHClient creates a new SSH client for the system
func (s *System) createSSHClient() error {
network := "tcp"
host := s.Host
if strings.HasPrefix(host, "/") {
network = "unix"
} else {
host = net.JoinHostPort(host, s.Port)
}
var err error
s.client, err = ssh.Dial(network, host, s.manager.sshConfig)
if err != nil {
return err
}
return nil
}
// createSessionWithTimeout creates a new SSH session with a timeout to avoid hanging
// in case of network issues
func (sys *System) createSessionWithTimeout(timeout time.Duration) (*ssh.Session, error) {
if sys.client == nil {
return nil, fmt.Errorf("client not initialized")
}
ctx, cancel := context.WithTimeout(sys.ctx, timeout)
defer cancel()
sessionChan := make(chan *ssh.Session, 1)
errChan := make(chan error, 1)
go func() {
if session, err := sys.client.NewSession(); err != nil {
errChan <- err
} else {
sessionChan <- session
}
}()
select {
case session := <-sessionChan:
return session, nil
case err := <-errChan:
return nil, err
case <-ctx.Done():
return nil, fmt.Errorf("timeout")
}
}
// resetSSHClient closes the SSH connection and resets the client to nil
func (sys *System) resetSSHClient() {
if sys.client != nil {
sys.client.Close()
}
sys.client = nil
}

View File

@@ -1,57 +0,0 @@
package hub
import (
"beszel"
"fmt"
"os"
"strings"
"github.com/blang/semver"
"github.com/rhysd/go-github-selfupdate/selfupdate"
"github.com/spf13/cobra"
)
// Update updates beszel to the latest version
func Update(_ *cobra.Command, _ []string) {
var latest *selfupdate.Release
var found bool
var err error
currentVersion := semver.MustParse(beszel.Version)
fmt.Println("beszel", currentVersion)
fmt.Println("Checking for updates...")
updater, _ := selfupdate.NewUpdater(selfupdate.Config{
Filters: []string{"beszel_"},
})
latest, found, err = updater.DetectLatest("henrygd/beszel")
if err != nil {
fmt.Println("Error checking for updates:", err)
os.Exit(1)
}
if !found {
fmt.Println("No updates found")
os.Exit(0)
}
fmt.Println("Latest version:", latest.Version)
if latest.Version.LTE(currentVersion) {
fmt.Println("You are up to date")
return
}
var binaryPath string
fmt.Printf("Updating from %s to %s...\n", currentVersion, latest.Version)
binaryPath, err = os.Executable()
if err != nil {
fmt.Println("Error getting binary path:", err)
os.Exit(1)
}
err = selfupdate.UpdateTo(latest.AssetURL, binaryPath)
if err != nil {
fmt.Println("Please try rerunning with sudo. Error:", err)
os.Exit(1)
}
fmt.Printf("Successfully updated to %s\n\n%s\n", latest.Version, strings.TrimSpace(latest.ReleaseNotes))
}

View File

@@ -1,58 +0,0 @@
// Package tests provides helpers for testing the application.
package tests
import (
"beszel/internal/hub"
"github.com/pocketbase/pocketbase/core"
"github.com/pocketbase/pocketbase/tests"
_ "github.com/pocketbase/pocketbase/migrations"
)
// TestHub is a wrapper hub instance used for testing.
type TestHub struct {
core.App
*tests.TestApp
*hub.Hub
}
// NewTestHub creates and initializes a test application instance.
//
// It is the caller's responsibility to call app.Cleanup() when the app is no longer needed.
func NewTestHub(optTestDataDir ...string) (*TestHub, error) {
var testDataDir string
if len(optTestDataDir) > 0 {
testDataDir = optTestDataDir[0]
}
return NewTestHubWithConfig(core.BaseAppConfig{
DataDir: testDataDir,
EncryptionEnv: "pb_test_env",
})
}
// NewTestHubWithConfig creates and initializes a test application instance
// from the provided config.
//
// If config.DataDir is not set it fallbacks to the default internal test data directory.
//
// config.DataDir is cloned for each new test application instance.
//
// It is the caller's responsibility to call app.Cleanup() when the app is no longer needed.
func NewTestHubWithConfig(config core.BaseAppConfig) (*TestHub, error) {
testApp, err := tests.NewTestAppWithConfig(config)
if err != nil {
return nil, err
}
hub := hub.NewHub(testApp)
t := &TestHub{
App: testApp,
TestApp: testApp,
Hub: hub,
}
return t, nil
}

View File

@@ -1,29 +0,0 @@
package migrations
import (
"github.com/pocketbase/pocketbase/core"
m "github.com/pocketbase/pocketbase/migrations"
)
var (
TempAdminEmail = "_@b.b"
)
func init() {
m.Register(func(app core.App) error {
// initial settings
settings := app.Settings()
settings.Meta.AppName = "Beszel"
settings.Meta.HideControls = true
settings.Logs.MinLevel = 4
if err := app.Save(settings); err != nil {
return err
}
// create superuser
collection, _ := app.FindCollectionByNameOrId(core.CollectionNameSuperusers)
user := core.NewRecord(collection)
user.SetEmail(TempAdminEmail)
user.SetRandomPassword()
return app.Save(user)
}, nil)
}

Binary file not shown.

View File

@@ -1,73 +0,0 @@
{
"name": "beszel",
"private": true,
"version": "0.11.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "lingui extract --overwrite && lingui compile && vite build",
"preview": "vite preview",
"sync": "lingui extract --overwrite && lingui compile",
"sync_and_purge": "lingui extract --overwrite --clean && lingui compile"
},
"dependencies": {
"@henrygd/queue": "^1.0.7",
"@henrygd/semaphore": "^0.0.2",
"@lingui/detect-locale": "^5.2.0",
"@lingui/macro": "^5.2.0",
"@lingui/react": "^5.2.0",
"@nanostores/react": "^0.7.3",
"@nanostores/router": "^0.11.0",
"@radix-ui/react-alert-dialog": "^1.1.6",
"@radix-ui/react-checkbox": "^1.1.4",
"@radix-ui/react-dialog": "^1.1.6",
"@radix-ui/react-direction": "^1.1.0",
"@radix-ui/react-dropdown-menu": "^2.1.6",
"@radix-ui/react-label": "^2.1.2",
"@radix-ui/react-select": "^2.1.6",
"@radix-ui/react-separator": "^1.1.2",
"@radix-ui/react-slider": "^1.2.3",
"@radix-ui/react-slot": "^1.1.2",
"@radix-ui/react-switch": "^1.1.3",
"@radix-ui/react-tabs": "^1.1.3",
"@radix-ui/react-toast": "^1.2.6",
"@radix-ui/react-tooltip": "^1.1.8",
"@tanstack/react-table": "^8.21.2",
"class-variance-authority": "^0.7.1",
"clsx": "^2.1.1",
"cmdk": "^1.0.4",
"d3-time": "^3.1.0",
"lucide-react": "^0.452.0",
"nanostores": "^0.11.4",
"pocketbase": "^0.25.2",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"recharts": "^2.15.1",
"tailwind-merge": "^2.6.0",
"tailwindcss-animate": "^1.0.7",
"valibot": "^0.42.0"
},
"devDependencies": {
"@lingui/cli": "^5.2.0",
"@lingui/swc-plugin": "^5.5.0",
"@lingui/vite-plugin": "^5.2.0",
"@types/bun": "^1.2.4",
"@types/react": "^18.3.1",
"@types/react-dom": "^18.3.1",
"@vitejs/plugin-react-swc": "^3.8.0",
"autoprefixer": "^10.4.20",
"postcss": "^8.5.3",
"tailwindcss": "^3.4.17",
"tailwindcss-rtl": "^0.9.0",
"typescript": "^5.8.2",
"vite": "^6.2.0"
},
"overrides": {
"@nanostores/router": {
"nanostores": "^0.11.3"
}
},
"optionalDependencies": {
"@esbuild/linux-arm64": "^0.21.5"
}
}

View File

@@ -1,6 +0,0 @@
export default {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}

View File

@@ -1,132 +0,0 @@
import { t } from "@lingui/core/macro";
import { Trans } from "@lingui/react/macro";
import { memo, useMemo, useState } from "react"
import { useStore } from "@nanostores/react"
import { $alerts } from "@/lib/stores"
import {
Dialog,
DialogTrigger,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog"
import { BellIcon, GlobeIcon, ServerIcon } from "lucide-react"
import { alertInfo, cn } from "@/lib/utils"
import { Button } from "@/components/ui/button"
import { AlertRecord, SystemRecord } from "@/types"
import { Link } from "../router"
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import { Checkbox } from "../ui/checkbox"
import { SystemAlert, SystemAlertGlobal } from "./alerts-system"
export default memo(function AlertsButton({ system }: { system: SystemRecord }) {
const alerts = useStore($alerts)
const [opened, setOpened] = useState(false)
const hasAlert = alerts.some((alert) => alert.system === system.id)
return useMemo(
() => (
<Dialog>
<DialogTrigger asChild>
<Button variant="ghost" size="icon" aria-label={t`Alerts`} data-nolink onClick={() => setOpened(true)}>
<BellIcon
className={cn("h-[1.2em] w-[1.2em] pointer-events-none", {
"fill-primary": hasAlert,
})}
/>
</Button>
</DialogTrigger>
<DialogContent className="max-h-full overflow-auto max-w-[35rem]">
{opened && <AlertDialogContent system={system} />}
</DialogContent>
</Dialog>
),
[opened, hasAlert]
)
})
function AlertDialogContent({ system }: { system: SystemRecord }) {
const alerts = useStore($alerts)
const [overwriteExisting, setOverwriteExisting] = useState<boolean | "indeterminate">(false)
// alertsSignature changes only when alerts for this system change
let alertsSignature = ""
const systemAlerts = alerts.filter((alert) => {
if (alert.system === system.id) {
alertsSignature += alert.name + alert.min + alert.value
return true
}
return false
}) as AlertRecord[]
return useMemo(() => {
// console.log("render modal", system.name, alertsSignature)
const data = Object.keys(alertInfo).map((name) => {
const alert = alertInfo[name as keyof typeof alertInfo]
return {
name: name as keyof typeof alertInfo,
alert,
system,
}
})
return (
<>
<DialogHeader>
<DialogTitle className="text-xl">
<Trans>Alerts</Trans>
</DialogTitle>
<DialogDescription>
<Trans>
See{" "}
<Link href="/settings/notifications" className="link">
notification settings
</Link>{" "}
to configure how you receive alerts.
</Trans>
</DialogDescription>
</DialogHeader>
<Tabs defaultValue="system">
<TabsList className="mb-1 -mt-0.5">
<TabsTrigger value="system">
<ServerIcon className="me-2 h-3.5 w-3.5" />
{system.name}
</TabsTrigger>
<TabsTrigger value="global">
<GlobeIcon className="me-1.5 h-3.5 w-3.5" />
<Trans>All Systems</Trans>
</TabsTrigger>
</TabsList>
<TabsContent value="system">
<div className="grid gap-3">
{data.map((d) => (
<SystemAlert key={d.name} system={system} data={d} systemAlerts={systemAlerts} />
))}
</div>
</TabsContent>
<TabsContent value="global">
<label
htmlFor="ovw"
className="mb-3 flex gap-2 items-center justify-center cursor-pointer border rounded-sm py-3 px-4 border-destructive text-destructive font-semibold text-sm"
>
<Checkbox
id="ovw"
className="text-destructive border-destructive data-[state=checked]:bg-destructive"
checked={overwriteExisting}
onCheckedChange={setOverwriteExisting}
/>
<Trans>Overwrite existing alerts</Trans>
</label>
<div className="grid gap-3">
{data.map((d) => (
<SystemAlertGlobal key={d.name} data={d} overwrite={overwriteExisting} />
))}
</div>
</TabsContent>
</Tabs>
</>
)
}, [alertsSignature, overwriteExisting])
}

View File

@@ -1,310 +0,0 @@
import { t } from "@lingui/core/macro"
import { Trans, Plural } from "@lingui/react/macro"
import { $alerts, $systems, pb } from "@/lib/stores"
import { alertInfo, cn } from "@/lib/utils"
import { Switch } from "@/components/ui/switch"
import { AlertInfo, AlertRecord, SystemRecord } from "@/types"
import { lazy, Suspense, useMemo, useState } from "react"
import { toast } from "../ui/use-toast"
import { BatchService } from "pocketbase"
import { getSemaphore } from "@henrygd/semaphore"
interface AlertData {
checked?: boolean
val?: number
min?: number
updateAlert?: (checked: boolean, value: number, min: number) => void
name: keyof typeof alertInfo
alert: AlertInfo
system: SystemRecord
}
const Slider = lazy(() => import("@/components/ui/slider"))
const failedUpdateToast = () =>
toast({
title: t`Failed to update alert`,
description: t`Please check logs for more details.`,
variant: "destructive",
})
export function SystemAlert({
system,
systemAlerts,
data,
}: {
system: SystemRecord
systemAlerts: AlertRecord[]
data: AlertData
}) {
const alert = systemAlerts.find((alert) => alert.name === data.name)
data.updateAlert = async (checked: boolean, value: number, min: number) => {
try {
if (alert && !checked) {
await pb.collection("alerts").delete(alert.id)
} else if (alert && checked) {
await pb.collection("alerts").update(alert.id, { value, min, triggered: false })
} else if (checked) {
pb.collection("alerts").create({
system: system.id,
user: pb.authStore.record!.id,
name: data.name,
value: value,
min: min,
})
}
} catch (e) {
failedUpdateToast()
}
}
if (alert) {
data.checked = true
data.val = alert.value
data.min = alert.min || 1
}
return <AlertContent data={data} />
}
export const SystemAlertGlobal = ({ data, overwrite }: { data: AlertData; overwrite: boolean | "indeterminate" }) => {
data.checked = false
data.val = data.min = 0
// set of system ids that have an alert for this name when the component is mounted
const existingAlertsSystems = useMemo(() => {
const map = new Set<string>()
const alerts = $alerts.get()
for (const alert of alerts) {
if (alert.name === data.name) {
map.add(alert.system)
}
}
return map
}, [])
data.updateAlert = async (checked: boolean, value: number, min: number) => {
const sem = getSemaphore("alerts")
await sem.acquire()
try {
// if another update is waiting behind, don't start this one
if (sem.size() > 1) {
return
}
const recordData: Partial<AlertRecord> = {
value,
min,
triggered: false,
}
const batch = batchWrapper("alerts", 25)
const systems = $systems.get()
const currentAlerts = $alerts.get()
// map of current alerts with this name right now by system id
const currentAlertsSystems = new Map<string, AlertRecord>()
for (const alert of currentAlerts) {
if (alert.name === data.name) {
currentAlertsSystems.set(alert.system, alert)
}
}
if (overwrite) {
existingAlertsSystems.clear()
}
const processSystem = async (system: SystemRecord): Promise<void> => {
const existingAlert = existingAlertsSystems.has(system.id)
if (!overwrite && existingAlert) {
return
}
const currentAlert = currentAlertsSystems.get(system.id)
// delete existing alert if unchecked
if (!checked && currentAlert) {
return batch.remove(currentAlert.id)
}
if (checked && currentAlert) {
// update existing alert if checked
return batch.update(currentAlert.id, recordData)
}
if (checked) {
// create new alert if checked and not existing
return batch.create({
system: system.id,
user: pb.authStore.record!.id,
name: data.name,
...recordData,
})
}
}
// make sure current system is updated in the first batch
await processSystem(data.system)
for (const system of systems) {
if (system.id === data.system.id) {
continue
}
if (sem.size() > 1) {
return
}
await processSystem(system)
}
await batch.send()
} finally {
sem.release()
}
}
return <AlertContent data={data} />
}
/**
* Creates a wrapper for performing batch operations on a specified collection.
*/
function batchWrapper(collection: string, batchSize: number) {
let batch: BatchService | undefined
let count = 0
const create = async <T extends Record<string, any>>(options: T) => {
batch ||= pb.createBatch()
batch.collection(collection).create(options)
if (++count >= batchSize) {
await send()
}
}
const update = async <T extends Record<string, any>>(id: string, data: T) => {
batch ||= pb.createBatch()
batch.collection(collection).update(id, data)
if (++count >= batchSize) {
await send()
}
}
const remove = async (id: string) => {
batch ||= pb.createBatch()
batch.collection(collection).delete(id)
if (++count >= batchSize) {
await send()
}
}
const send = async () => {
if (count) {
await batch?.send({ requestKey: null })
batch = undefined
count = 0
}
}
return {
update,
remove,
send,
create,
}
}
function AlertContent({ data }: { data: AlertData }) {
const { name } = data
const singleDescription = data.alert.singleDesc?.()
const [checked, setChecked] = useState(data.checked || false)
const [min, setMin] = useState(data.min || 10)
const [value, setValue] = useState(data.val || (singleDescription ? 0 : 80))
const Icon = alertInfo[name].icon
return (
<div className="rounded-lg border border-muted-foreground/15 hover:border-muted-foreground/20 transition-colors duration-100 group">
<label
htmlFor={`s${name}`}
className={cn("flex flex-row items-center justify-between gap-4 cursor-pointer p-4", {
"pb-0": checked,
})}
>
<div className="grid gap-1 select-none">
<p className="font-semibold flex gap-3 items-center">
<Icon className="h-4 w-4 opacity-85" /> {data.alert.name()}
</p>
{!checked && <span className="block text-sm text-muted-foreground">{data.alert.desc()}</span>}
</div>
<Switch
id={`s${name}`}
checked={checked}
onCheckedChange={(newChecked) => {
setChecked(newChecked)
data.updateAlert?.(newChecked, value, min)
}}
/>
</label>
{checked && (
<div className="grid sm:grid-cols-2 mt-1.5 gap-5 px-4 pb-5 tabular-nums text-muted-foreground">
<Suspense fallback={<div className="h-10" />}>
{!singleDescription && (
<div>
<p id={`v${name}`} className="text-sm block h-8">
<Trans>
Average exceeds{" "}
<strong className="text-foreground">
{value}
{data.alert.unit}
</strong>
</Trans>
</p>
<div className="flex gap-3">
<Slider
aria-labelledby={`v${name}`}
defaultValue={[value]}
onValueCommit={(val) => {
data.updateAlert?.(true, val[0], min)
}}
onValueChange={(val) => {
setValue(val[0])
}}
min={1}
max={alertInfo[name].max ?? 99}
/>
</div>
</div>
)}
<div className={cn(singleDescription && "col-span-full lowercase")}>
<p id={`t${name}`} className="text-sm block h-8 first-letter:uppercase">
{singleDescription && (
<>
{singleDescription}
{` `}
</>
)}
<Trans>
For <strong className="text-foreground">{min}</strong>{" "}
<Plural value={min} one="minute" other="minutes" />
</Trans>
</p>
<div className="flex gap-3">
<Slider
aria-labelledby={`v${name}`}
defaultValue={[min]}
onValueCommit={(min) => {
data.updateAlert?.(true, value, min[0])
}}
onValueChange={(val) => {
setMin(val[0])
}}
min={1}
max={60}
/>
</div>
</div>
</Suspense>
</div>
)}
</div>
)
}

View File

@@ -1,150 +0,0 @@
import { t } from "@lingui/core/macro"
import { Area, AreaChart, CartesianGrid, YAxis } from "recharts"
import { ChartContainer, ChartTooltip, ChartTooltipContent, xAxis } from "@/components/ui/chart"
import {
useYAxisWidth,
cn,
formatShortDate,
toFixedWithoutTrailingZeros,
decimalString,
chartMargin,
} from "@/lib/utils"
// import Spinner from '../spinner'
import { ChartData } from "@/types"
import { memo, useMemo } from "react"
import { useLingui } from "@lingui/react/macro"
/** [label, key, color, opacity] */
type DataKeys = [string, string, number, number]
const getNestedValue = (path: string, max = false, data: any): number | null => {
// fallback value (obj?.stats?.cpum ? 0 : null) should only come into play when viewing
// a max value which doesn't exist, or the value was zero and omitted from the stats object.
// so we check if cpum is present. if so, return 0 to make sure the zero value is displayed.
// if not, return null - there is no max data so do not display anything.
return `stats.${path}${max ? "m" : ""}`
.split(".")
.reduce((acc: any, key: string) => acc?.[key] ?? (data.stats?.cpum ? 0 : null), data)
}
export default memo(function AreaChartDefault({
maxToggled = false,
unit = " MB/s",
chartName,
chartData,
max,
tickFormatter,
contentFormatter,
}: {
maxToggled?: boolean
unit?: string
chartName: string
chartData: ChartData
max?: number
tickFormatter?: (value: number) => string
contentFormatter?: (value: number) => string
}) {
const { yAxisWidth, updateYAxisWidth } = useYAxisWidth()
const { i18n } = useLingui()
const { chartTime } = chartData
const showMax = chartTime !== "1h" && maxToggled
const dataKeys: DataKeys[] = useMemo(() => {
// [label, key, color, opacity]
if (chartName === "CPU Usage") {
return [[t`CPU Usage`, "cpu", 1, 0.4]]
} else if (chartName === "dio") {
return [
[t({ message: "Write", comment: "Disk write" }), "dw", 3, 0.3],
[t({ message: "Read", comment: "Disk read" }), "dr", 1, 0.3],
]
} else if (chartName === "bw") {
return [
[t({ message: "Sent", comment: "Network bytes sent (upload)" }), "ns", 5, 0.2],
[t({ message: "Received", comment: "Network bytes received (download)" }), "nr", 2, 0.2],
]
} else if (chartName.startsWith("efs")) {
return [
[t`Write`, `${chartName}.w`, 3, 0.3],
[t`Read`, `${chartName}.r`, 1, 0.3],
]
} else if (chartName.startsWith("g.")) {
return [chartName.includes("mu") ? [t`Used`, chartName, 2, 0.25] : [t`Usage`, chartName, 1, 0.4]]
}
return []
}, [chartName, i18n.locale])
// console.log('Rendered at', new Date())
if (chartData.systemStats.length === 0) {
return null
}
return (
<div>
<ChartContainer
className={cn("h-full w-full absolute aspect-auto bg-card opacity-0 transition-opacity", {
"opacity-100": yAxisWidth,
})}
>
<AreaChart accessibilityLayer data={chartData.systemStats} margin={chartMargin}>
<CartesianGrid vertical={false} />
<YAxis
direction="ltr"
orientation={chartData.orientation}
className="tracking-tighter"
width={yAxisWidth}
domain={[0, max ?? "auto"]}
tickFormatter={(value) => {
let val: string
if (tickFormatter) {
val = tickFormatter(value)
} else {
val = toFixedWithoutTrailingZeros(value, 2) + unit
}
return updateYAxisWidth(val)
}}
tickLine={false}
axisLine={false}
/>
{xAxis(chartData)}
<ChartTooltip
animationEasing="ease-out"
animationDuration={150}
content={
<ChartTooltipContent
labelFormatter={(_, data) => formatShortDate(data[0].payload.created)}
contentFormatter={({ value }) => {
if (contentFormatter) {
return contentFormatter(value)
}
return decimalString(value) + unit
}}
// indicator="line"
/>
}
/>
{dataKeys.map((key, i) => {
const color = `hsl(var(--chart-${key[2]}))`
return (
<Area
key={i}
dataKey={getNestedValue.bind(null, key[1], showMax)}
name={key[0]}
type="monotoneX"
fill={color}
fillOpacity={key[3]}
stroke={color}
isAnimationActive={false}
/>
)
})}
{/* <ChartLegend content={<ChartLegendContent />} /> */}
</AreaChart>
</ChartContainer>
</div>
)
})

View File

@@ -1,56 +0,0 @@
import { Trans } from "@lingui/react/macro";
import { t } from "@lingui/core/macro";
import { LaptopIcon, MoonStarIcon, SunIcon } from "lucide-react"
import { Button } from "@/components/ui/button"
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuTrigger } from "@/components/ui/dropdown-menu"
import { useTheme } from "@/components/theme-provider"
import { cn } from "@/lib/utils"
export function ModeToggle() {
const { theme, setTheme } = useTheme()
const options = [
{
theme: "light",
Icon: SunIcon,
label: <Trans comment="Light theme">Light</Trans>,
},
{
theme: "dark",
Icon: MoonStarIcon,
label: <Trans comment="Dark theme">Dark</Trans>,
},
{
theme: "system",
Icon: LaptopIcon,
label: <Trans comment="System theme">System</Trans>,
},
]
return (
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant={"ghost"} size="icon" aria-label={t`Toggle theme`}>
<SunIcon className="h-[1.2rem] w-[1.2rem] dark:opacity-0" />
<MoonStarIcon className="absolute h-[1.2rem] w-[1.2rem] opacity-0 dark:opacity-100" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent>
{options.map((opt) => {
const selected = opt.theme === theme
return (
<DropdownMenuItem
key={opt.theme}
className={cn("px-2.5", selected ? "font-semibold" : "")}
onClick={() => setTheme(opt.theme as "dark" | "light" | "system")}
>
<opt.Icon className={cn("me-2 h-4 w-4 opacity-80", selected && "opacity-100")} />
{opt.label}
</DropdownMenuItem>
)
})}
</DropdownMenuContent>
</DropdownMenu>
)
}

View File

@@ -1,131 +0,0 @@
import { Suspense, lazy, memo, useEffect, useMemo } from "react"
import { Card, CardContent, CardHeader, CardTitle } from "../ui/card"
import { $alerts, $systems, pb } from "@/lib/stores"
import { useStore } from "@nanostores/react"
import { GithubIcon } from "lucide-react"
import { Separator } from "../ui/separator"
import { alertInfo, updateRecordList, updateSystemList } from "@/lib/utils"
import { AlertRecord, SystemRecord } from "@/types"
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"
import { $router, Link } from "../router"
import { Plural, Trans, useLingui } from "@lingui/react/macro"
import { getPagePath } from "@nanostores/router"
const SystemsTable = lazy(() => import("../systems-table/systems-table"))
export const Home = memo(() => {
const alerts = useStore($alerts)
const systems = useStore($systems)
const { t } = useLingui()
let alertsKey = ""
const activeAlerts = useMemo(() => {
const activeAlerts = alerts.filter((alert) => {
const active = alert.triggered && alert.name in alertInfo
if (!active) {
return false
}
alert.sysname = systems.find((system) => system.id === alert.system)?.name
alertsKey += alert.id
return true
})
return activeAlerts
}, [systems, alerts])
useEffect(() => {
document.title = t`Dashboard` + " / Beszel"
}, [t])
useEffect(() => {
// make sure we have the latest list of systems
updateSystemList()
// subscribe to real time updates for systems / alerts
pb.collection<SystemRecord>("systems").subscribe("*", (e) => {
updateRecordList(e, $systems)
})
pb.collection<AlertRecord>("alerts").subscribe("*", (e) => {
updateRecordList(e, $alerts)
})
return () => {
pb.collection("systems").unsubscribe("*")
// pb.collection('alerts').unsubscribe('*')
}
}, [])
return useMemo(
() => (
<>
{/* show active alerts */}
{activeAlerts.length > 0 && <ActiveAlerts key={activeAlerts.length} activeAlerts={activeAlerts} />}
<Suspense>
<SystemsTable />
</Suspense>
<div className="flex gap-1.5 justify-end items-center pe-3 sm:pe-6 mt-3.5 text-xs opacity-80">
<a
href="https://github.com/henrygd/beszel"
target="_blank"
className="flex items-center gap-0.5 text-muted-foreground hover:text-foreground duration-75"
>
<GithubIcon className="h-3 w-3" /> GitHub
</a>
<Separator orientation="vertical" className="h-2.5 bg-muted-foreground opacity-70" />
<a
href="https://github.com/henrygd/beszel/releases"
target="_blank"
className="text-muted-foreground hover:text-foreground duration-75"
>
Beszel {globalThis.BESZEL.HUB_VERSION}
</a>
</div>
</>
),
[alertsKey]
)
})
const ActiveAlerts = memo(({ activeAlerts }: { activeAlerts: AlertRecord[] }) => {
return (
<Card className="mb-4">
<CardHeader className="pb-4 px-2 sm:px-6 max-sm:pt-5 max-sm:pb-1">
<div className="px-2 sm:px-1">
<CardTitle>
<Trans>Active Alerts</Trans>
</CardTitle>
</div>
</CardHeader>
<CardContent className="max-sm:p-2">
{activeAlerts.length > 0 && (
<div className="grid sm:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-3">
{activeAlerts.map((alert) => {
const info = alertInfo[alert.name as keyof typeof alertInfo]
return (
<Alert
key={alert.id}
className="hover:-translate-y-[1px] duration-200 bg-transparent border-foreground/10 hover:shadow-md shadow-black"
>
<info.icon className="h-4 w-4" />
<AlertTitle>
{alert.sysname} {info.name().toLowerCase().replace("cpu", "CPU")}
</AlertTitle>
<AlertDescription>
<Trans>
Exceeds {alert.value}
{info.unit} in last <Plural value={alert.min} one="# minute" other="# minutes" />
</Trans>
</AlertDescription>
<Link
href={getPagePath($router, "system", { name: alert.sysname! })}
className="absolute inset-0 w-full h-full"
aria-label="View system"
></Link>
</Alert>
)
})}
</div>
)}
</CardContent>
</Card>
)
})

View File

@@ -1,111 +0,0 @@
import { Trans } from "@lingui/react/macro"
import { Button } from "@/components/ui/button"
import { Label } from "@/components/ui/label"
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
import { chartTimeData } from "@/lib/utils"
import { Separator } from "@/components/ui/separator"
import { LanguagesIcon, LoaderCircleIcon, SaveIcon } from "lucide-react"
import { UserSettings } from "@/types"
import { saveSettings } from "./layout"
import { useState } from "react"
import languages from "@/lib/languages"
import { dynamicActivate } from "@/lib/i18n"
import { useLingui } from "@lingui/react/macro"
// import { setLang } from "@/lib/i18n"
export default function SettingsProfilePage({ userSettings }: { userSettings: UserSettings }) {
const [isLoading, setIsLoading] = useState(false)
const { i18n } = useLingui()
async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
e.preventDefault()
setIsLoading(true)
const formData = new FormData(e.target as HTMLFormElement)
const data = Object.fromEntries(formData) as Partial<UserSettings>
await saveSettings(data)
setIsLoading(false)
}
return (
<div>
<div>
<h3 className="text-xl font-medium mb-2">
<Trans>General</Trans>
</h3>
<p className="text-sm text-muted-foreground leading-relaxed">
<Trans>Change general application options.</Trans>
</p>
</div>
<Separator className="my-4" />
<form onSubmit={handleSubmit} className="space-y-5">
<div className="space-y-2">
<div className="mb-4">
<h3 className="mb-1 text-lg font-medium flex items-center gap-2">
<LanguagesIcon className="h-4 w-4" />
<Trans>Language</Trans>
</h3>
<p className="text-sm text-muted-foreground leading-relaxed">
<Trans>
Want to help improve our translations? Check{" "}
<a href="https://crowdin.com/project/beszel" className="link" target="_blank" rel="noopener noreferrer">
Crowdin
</a>{" "}
for details.
</Trans>
</p>
</div>
<Label className="block" htmlFor="lang">
<Trans>Preferred Language</Trans>
</Label>
<Select value={i18n.locale} onValueChange={(lang: string) => dynamicActivate(lang)}>
<SelectTrigger id="lang">
<SelectValue />
</SelectTrigger>
<SelectContent>
{languages.map((lang) => (
<SelectItem key={lang.lang} value={lang.lang}>
<span className="me-2.5">{lang.e}</span>
{lang.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<Separator />
<div className="space-y-2">
<div className="mb-4">
<h3 className="mb-1 text-lg font-medium">
<Trans>Chart options</Trans>
</h3>
<p className="text-sm text-muted-foreground leading-relaxed">
<Trans>Adjust display options for charts.</Trans>
</p>
</div>
<Label className="block" htmlFor="chartTime">
<Trans>Default time period</Trans>
</Label>
<Select name="chartTime" key={userSettings.chartTime} defaultValue={userSettings.chartTime}>
<SelectTrigger id="chartTime">
<SelectValue />
</SelectTrigger>
<SelectContent>
{Object.entries(chartTimeData).map(([value, { label }]) => (
<SelectItem key={value} value={value}>
{label()}
</SelectItem>
))}
</SelectContent>
</Select>
<p className="text-[0.8rem] text-muted-foreground">
<Trans>Sets the default time range for charts when a system is viewed.</Trans>
</p>
</div>
<Separator />
<Button type="submit" className="flex items-center gap-1.5 disabled:opacity-100" disabled={isLoading}>
{isLoading ? <LoaderCircleIcon className="h-4 w-4 animate-spin" /> : <SaveIcon className="h-4 w-4" />}
<Trans>Save Settings</Trans>
</Button>
</form>
</div>
)
}

View File

@@ -1,736 +0,0 @@
import {
CellContext,
ColumnDef,
ColumnFiltersState,
getFilteredRowModel,
SortingState,
getSortedRowModel,
flexRender,
VisibilityState,
getCoreRowModel,
useReactTable,
HeaderContext,
Row,
Table as TableType,
} from "@tanstack/react-table"
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table"
import { Button, buttonVariants } from "@/components/ui/button"
import {
DropdownMenu,
DropdownMenuCheckboxItem,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuLabel,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuSeparator,
DropdownMenuTrigger,
} from "@/components/ui/dropdown-menu"
import {
AlertDialog,
AlertDialogAction,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog"
import { SystemRecord } from "@/types"
import {
MoreHorizontalIcon,
ArrowUpDownIcon,
MemoryStickIcon,
CopyIcon,
PauseCircleIcon,
PlayCircleIcon,
Trash2Icon,
WifiIcon,
HardDriveIcon,
ServerIcon,
CpuIcon,
LayoutGridIcon,
LayoutListIcon,
ArrowDownIcon,
ArrowUpIcon,
Settings2Icon,
EyeIcon,
PenBoxIcon,
} from "lucide-react"
import { memo, useEffect, useMemo, useRef, useState } from "react"
import { $systems, pb } from "@/lib/stores"
import { useStore } from "@nanostores/react"
import { cn, copyToClipboard, decimalString, isReadOnlyUser, useLocalStorage } from "@/lib/utils"
import AlertsButton from "../alerts/alert-button"
import { $router, Link, navigate } from "../router"
import { EthernetIcon, GpuIcon, ThermometerIcon } from "../ui/icons"
import { useLingui, Trans } from "@lingui/react/macro"
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "../ui/card"
import { Input } from "../ui/input"
import { ClassValue } from "clsx"
import { getPagePath } from "@nanostores/router"
import { SystemDialog } from "../add-system"
import { Dialog } from "../ui/dialog"
type ViewMode = "table" | "grid"
function CellFormatter(info: CellContext<SystemRecord, unknown>) {
const val = (info.getValue() as number) || 0
return (
<div className="flex gap-2 items-center tabular-nums tracking-tight">
<span className="min-w-[3.3em]">{decimalString(val, 1)}%</span>
<span className="grow min-w-10 block bg-muted h-[1em] relative rounded-sm overflow-hidden">
<span
className={cn(
"absolute inset-0 w-full h-full origin-left",
(info.row.original.status !== "up" && "bg-primary/30") ||
(val < 65 && "bg-green-500") ||
(val < 90 && "bg-yellow-500") ||
"bg-red-600"
)}
style={{
transform: `scalex(${val / 100})`,
}}
></span>
</span>
</div>
)
}
function sortableHeader(context: HeaderContext<SystemRecord, unknown>) {
const { column } = context
// @ts-ignore
const { Icon, hideSort, name }: { Icon: React.ElementType; name: () => string; hideSort: boolean } = column.columnDef
return (
<Button
variant="ghost"
className="h-9 px-3 flex"
onClick={() => column.toggleSorting(column.getIsSorted() === "asc")}
>
{Icon && <Icon className="me-2 size-4" />}
{name()}
{hideSort || <ArrowUpDownIcon className="ms-2 size-4" />}
</Button>
)
}
export default function SystemsTable() {
const data = useStore($systems)
const { i18n, t } = useLingui()
const [filter, setFilter] = useState<string>()
const [sorting, setSorting] = useState<SortingState>([{ id: "system", desc: false }])
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([])
const [columnVisibility, setColumnVisibility] = useLocalStorage<VisibilityState>("cols", {})
const [viewMode, setViewMode] = useLocalStorage<ViewMode>("viewMode", window.innerWidth > 1024 ? "table" : "grid")
const locale = i18n.locale
useEffect(() => {
if (filter !== undefined) {
table.getColumn("system")?.setFilterValue(filter)
}
}, [filter])
const columnDefs = useMemo(() => {
const statusTranslations = {
up: () => t`Up`.toLowerCase(),
down: () => t`Down`.toLowerCase(),
paused: () => t`Paused`.toLowerCase(),
}
return [
{
// size: 200,
size: 200,
minSize: 0,
accessorKey: "name",
id: "system",
name: () => t`System`,
filterFn: (row, _, filterVal) => {
const filterLower = filterVal.toLowerCase()
const { name, status } = row.original
// Check if the filter matches the name or status for this row
if (
name.toLowerCase().includes(filterLower) ||
statusTranslations[status as keyof typeof statusTranslations]?.().includes(filterLower)
) {
return true
}
return false
},
enableHiding: false,
Icon: ServerIcon,
cell: (info) => (
<span className="flex gap-0.5 items-center text-base md:pe-5">
<IndicatorDot system={info.row.original} />
<Button
data-nolink
variant={"ghost"}
className="text-primary/90 h-7 px-1.5 gap-1.5"
onClick={() => copyToClipboard(info.getValue() as string)}
>
{info.getValue() as string}
<CopyIcon className="h-2.5 w-2.5" />
</Button>
</span>
),
header: sortableHeader,
},
{
accessorKey: "info.cpu",
id: "cpu",
name: () => t`CPU`,
invertSorting: true,
cell: CellFormatter,
Icon: CpuIcon,
header: sortableHeader,
},
{
accessorKey: "info.mp",
id: "memory",
name: () => t`Memory`,
invertSorting: true,
cell: CellFormatter,
Icon: MemoryStickIcon,
header: sortableHeader,
},
{
accessorKey: "info.dp",
id: "disk",
name: () => t`Disk`,
invertSorting: true,
cell: CellFormatter,
Icon: HardDriveIcon,
header: sortableHeader,
},
{
accessorFn: (originalRow) => originalRow.info.g,
id: "gpu",
name: () => "GPU",
invertSorting: true,
sortUndefined: -1,
cell: CellFormatter,
Icon: GpuIcon,
header: sortableHeader,
},
{
accessorFn: (originalRow) => originalRow.info.b || 0,
id: "net",
name: () => t`Net`,
invertSorting: true,
size: 50,
Icon: EthernetIcon,
header: sortableHeader,
cell(info) {
const val = info.getValue() as number
return (
<span
className={cn("tabular-nums whitespace-nowrap", {
"ps-1": viewMode === "table",
})}
>
{decimalString(val, val >= 100 ? 1 : 2)} MB/s
</span>
)
},
},
{
accessorFn: (originalRow) => originalRow.info.dt,
id: "temp",
name: () => t({ message: "Temp", comment: "Temperature label in systems table" }),
invertSorting: true,
sortUndefined: -1,
size: 50,
hideSort: true,
Icon: ThermometerIcon,
header: sortableHeader,
cell(info) {
const val = info.getValue() as number
if (!val) {
return null
}
return (
<span
className={cn("tabular-nums whitespace-nowrap", {
"ps-1.5": viewMode === "table",
})}
>
{decimalString(val)} °C
</span>
)
},
},
{
accessorKey: "info.v",
id: "agent",
name: () => t`Agent`,
invertSorting: true,
size: 50,
Icon: WifiIcon,
hideSort: true,
header: sortableHeader,
cell(info) {
const version = info.getValue() as string
if (!version) {
return null
}
const system = info.row.original
return (
<span
className={cn("flex gap-2 items-center md:pe-5 tabular-nums", {
"ps-1": viewMode === "table",
})}
>
<IndicatorDot
system={system}
className={
(system.status !== "up" && "bg-primary/30") ||
(version === globalThis.BESZEL.HUB_VERSION && "bg-green-500") ||
"bg-yellow-500"
}
/>
<span>{info.getValue() as string}</span>
</span>
)
},
},
{
id: "actions",
// @ts-ignore
name: () => t({ message: "Actions", comment: "Table column" }),
size: 50,
cell: ({ row }) => (
<div className="flex justify-end items-center gap-1">
<AlertsButton system={row.original} />
<ActionsButton system={row.original} />
</div>
),
},
] as ColumnDef<SystemRecord>[]
}, [])
const table = useReactTable({
data,
columns: columnDefs,
getCoreRowModel: getCoreRowModel(),
onSortingChange: setSorting,
getSortedRowModel: getSortedRowModel(),
onColumnFiltersChange: setColumnFilters,
getFilteredRowModel: getFilteredRowModel(),
onColumnVisibilityChange: setColumnVisibility,
state: {
sorting,
columnFilters,
columnVisibility,
},
defaultColumn: {
minSize: 0,
size: 900,
maxSize: 900,
},
})
const rows = table.getRowModel().rows
const columns = table.getAllColumns()
const visibleColumns = table.getVisibleLeafColumns()
// TODO: hiding temp then gpu messes up table headers
const CardHead = useMemo(() => {
return (
<CardHeader className="pb-5 px-2 sm:px-6 max-sm:pt-5 max-sm:pb-1">
<div className="grid md:flex gap-5 w-full items-end">
<div className="px-2 sm:px-1">
<CardTitle className="mb-2.5">
<Trans>All Systems</Trans>
</CardTitle>
<CardDescription>
<Trans>Updated in real time. Click on a system to view information.</Trans>
</CardDescription>
</div>
<div className="flex gap-2 ms-auto w-full md:w-80">
<Input placeholder={t`Filter...`} onChange={(e) => setFilter(e.target.value)} className="px-4" />
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="outline">
<Settings2Icon className="me-1.5 size-4 opacity-80" />
<Trans>View</Trans>
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end" className="h-72 md:h-auto min-w-48 md:min-w-auto overflow-y-auto">
<div className="grid grid-cols-1 md:grid-cols-3 divide-y md:divide-s md:divide-y-0">
<div>
<DropdownMenuLabel className="pt-2 px-3.5 flex items-center gap-2">
<LayoutGridIcon className="size-4" />
<Trans>Layout</Trans>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<DropdownMenuRadioGroup
className="px-1 pb-1"
value={viewMode}
onValueChange={(view) => setViewMode(view as ViewMode)}
>
<DropdownMenuRadioItem value="table" onSelect={(e) => e.preventDefault()} className="gap-2">
<LayoutListIcon className="size-4" />
<Trans>Table</Trans>
</DropdownMenuRadioItem>
<DropdownMenuRadioItem value="grid" onSelect={(e) => e.preventDefault()} className="gap-2">
<LayoutGridIcon className="size-4" />
<Trans>Grid</Trans>
</DropdownMenuRadioItem>
</DropdownMenuRadioGroup>
</div>
<div>
<DropdownMenuLabel className="pt-2 px-3.5 flex items-center gap-2">
<ArrowUpDownIcon className="size-4" />
<Trans>Sort By</Trans>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<div className="px-1 pb-1">
{columns.map((column) => {
if (!column.getCanSort()) return null
let Icon = <span className="w-6"></span>
// if current sort column, show sort direction
if (sorting[0]?.id === column.id) {
if (sorting[0]?.desc) {
Icon = <ArrowUpIcon className="me-2 size-4" />
} else {
Icon = <ArrowDownIcon className="me-2 size-4" />
}
}
return (
<DropdownMenuItem
onSelect={(e) => {
e.preventDefault()
setSorting([{ id: column.id, desc: sorting[0]?.id === column.id && !sorting[0]?.desc }])
}}
key={column.id}
>
{Icon}
{/* @ts-ignore */}
{column.columnDef.name()}
</DropdownMenuItem>
)
})}
</div>
</div>
<div>
<DropdownMenuLabel className="pt-2 px-3.5 flex items-center gap-2">
<EyeIcon className="size-4" />
<Trans>Visible Fields</Trans>
</DropdownMenuLabel>
<DropdownMenuSeparator />
<div className="px-1.5 pb-1">
{columns
.filter((column) => column.getCanHide())
.map((column) => {
return (
<DropdownMenuCheckboxItem
key={column.id}
onSelect={(e) => e.preventDefault()}
checked={column.getIsVisible()}
onCheckedChange={(value) => column.toggleVisibility(!!value)}
>
{/* @ts-ignore */}
{column.columnDef.name()}
</DropdownMenuCheckboxItem>
)
})}
</div>
</div>
</div>
</DropdownMenuContent>
</DropdownMenu>
</div>
</div>
</CardHeader>
)
}, [visibleColumns.length, sorting, viewMode, locale])
return (
<Card>
{CardHead}
<div className="p-6 pt-0 max-sm:py-3 max-sm:px-2">
{viewMode === "table" ? (
// table layout
<div className="rounded-md border overflow-hidden">
<AllSystemsTable table={table} rows={rows} colLength={visibleColumns.length} />
</div>
) : (
// grid layout
<div className="grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3">
{rows?.length ? (
rows.map((row) => {
return <SystemCard key={row.original.id} row={row} table={table} colLength={visibleColumns.length} />
})
) : (
<div className="col-span-full text-center py-8">
<Trans>No systems found.</Trans>
</div>
)}
</div>
)}
</div>
</Card>
)
}
const AllSystemsTable = memo(
({ table, rows, colLength }: { table: TableType<SystemRecord>; rows: Row<SystemRecord>[]; colLength: number }) => {
return (
<Table>
<SystemsTableHead table={table} colLength={colLength} />
<TableBody>
{rows.length ? (
rows.map((row) => (
<SystemTableRow key={row.original.id} row={row} length={rows.length} colLength={colLength} />
))
) : (
<TableRow>
<TableCell colSpan={colLength} className="h-24 text-center">
<Trans>No systems found.</Trans>
</TableCell>
</TableRow>
)}
</TableBody>
</Table>
)
}
)
function SystemsTableHead({ table, colLength }: { table: TableType<SystemRecord>; colLength: number }) {
const { i18n } = useLingui()
return useMemo(() => {
return (
<TableHeader>
{table.getHeaderGroups().map((headerGroup) => (
<TableRow key={headerGroup.id}>
{headerGroup.headers.map((header) => {
return (
<TableHead className="px-2" key={header.id}>
{flexRender(header.column.columnDef.header, header.getContext())}
</TableHead>
)
})}
</TableRow>
))}
</TableHeader>
)
}, [i18n.locale, colLength])
}
const SystemTableRow = memo(
({ row, length, colLength }: { row: Row<SystemRecord>; 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", {
"opacity-50": system.status === "paused",
})}
onClick={(e) => {
const target = e.target as HTMLElement
if (!target.closest("[data-nolink]") && e.currentTarget.contains(target)) {
navigate(getPagePath($router, "system", { name: system.name }))
}
}}
>
{row.getVisibleCells().map((cell) => (
<TableCell
key={cell.id}
style={{
width: cell.column.getSize(),
}}
className={cn("overflow-hidden relative", length > 10 ? "py-2" : "py-2.5")}
>
{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 }) => {
const system = row.original
const { t } = useLingui()
return useMemo(() => {
return (
<Card
key={system.id}
className={cn(
"cursor-pointer hover:shadow-md transition-all bg-transparent w-full dark:border-border duration-200 relative",
{
"opacity-50": system.status === "paused",
}
)}
>
<CardHeader className="py-1 ps-5 pe-3 bg-muted/30 border-b border-border/60">
<div className="flex items-center justify-between gap-2">
<CardTitle className="text-base tracking-normal shrink-1 text-primary/90 flex items-center min-h-10 gap-2.5 min-w-0">
<div className="flex items-center gap-2.5 min-w-0">
<IndicatorDot system={system} />
<CardTitle className="text-[.95em]/normal tracking-normal truncate text-primary/90">
{system.name}
</CardTitle>
</div>
</CardTitle>
{table.getColumn("actions")?.getIsVisible() && (
<div className="flex gap-1 flex-shrink-0 relative z-10">
<AlertsButton system={system} />
<ActionsButton system={system} />
</div>
)}
</div>
</CardHeader>
<CardContent className="space-y-2.5 text-sm px-5 pt-3.5 pb-4">
{table.getAllColumns().map((column) => {
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-ignore
const { Icon, name } = column.columnDef as ColumnDef<SystemRecord, unknown>
return (
<div key={column.id} className="flex items-center gap-3">
{Icon && <Icon className="size-4 text-muted-foreground" />}
<div className="flex items-center gap-3 flex-1">
<span className="text-muted-foreground min-w-16">{name()}:</span>
<div className="flex-1">{flexRender(cell.column.columnDef.cell, cell.getContext())}</div>
</div>
</div>
)
})}
</CardContent>
<Link
href={getPagePath($router, "system", { name: row.original.name })}
className="inset-0 absolute w-full h-full"
>
<span className="sr-only">{row.original.name}</span>
</Link>
</Card>
)
}, [system, colLength, t])
}
)
const ActionsButton = memo(({ system }: { system: SystemRecord }) => {
const [deleteOpen, setDeleteOpen] = useState(false)
const [editOpen, setEditOpen] = useState(false)
let editOpened = useRef(false)
const { t } = useLingui()
const { id, status, host, name } = system
return useMemo(() => {
return (
<>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button variant="ghost" size={"icon"} data-nolink>
<span className="sr-only">
<Trans>Open menu</Trans>
</span>
<MoreHorizontalIcon className="w-5" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
{!isReadOnlyUser() && (
<DropdownMenuItem
onSelect={() => {
editOpened.current = true
setEditOpen(true)
}}
>
<PenBoxIcon className="me-2.5 size-4" />
<Trans>Edit</Trans>
</DropdownMenuItem>
)}
<DropdownMenuItem
className={cn(isReadOnlyUser() && "hidden")}
onClick={() => {
pb.collection("systems").update(id, {
status: status === "paused" ? "pending" : "paused",
})
}}
>
{status === "paused" ? (
<>
<PlayCircleIcon className="me-2.5 size-4" />
<Trans>Resume</Trans>
</>
) : (
<>
<PauseCircleIcon className="me-2.5 size-4" />
<Trans>Pause</Trans>
</>
)}
</DropdownMenuItem>
<DropdownMenuItem onClick={() => copyToClipboard(host)}>
<CopyIcon className="me-2.5 size-4" />
<Trans>Copy host</Trans>
</DropdownMenuItem>
<DropdownMenuSeparator className={cn(isReadOnlyUser() && "hidden")} />
<DropdownMenuItem className={cn(isReadOnlyUser() && "hidden")} onSelect={() => setDeleteOpen(true)}>
<Trash2Icon className="me-2.5 size-4" />
<Trans>Delete</Trans>
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
{/* edit dialog */}
<Dialog open={editOpen} onOpenChange={setEditOpen}>
{editOpened.current && <SystemDialog system={system} setOpen={setEditOpen} />}
</Dialog>
{/* deletion dialog */}
<AlertDialog open={deleteOpen} onOpenChange={(open) => setDeleteOpen(open)}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>
<Trans>Are you sure you want to delete {name}?</Trans>
</AlertDialogTitle>
<AlertDialogDescription>
<Trans>
This action cannot be undone. This will permanently delete all current records for {name} from the
database.
</Trans>
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel>
<Trans>Cancel</Trans>
</AlertDialogCancel>
<AlertDialogAction
className={cn(buttonVariants({ variant: "destructive" }))}
onClick={() => pb.collection("systems").delete(id)}
>
<Trans>Continue</Trans>
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
</>
)
}, [id, status, host, name, t, deleteOpen, editOpen])
})
function IndicatorDot({ system, className }: { system: SystemRecord; className?: ClassValue }) {
className ||= {
"bg-green-500": system.status === "up",
"bg-red-500": system.status === "down",
"bg-primary/40": system.status === "paused",
"bg-yellow-500": system.status === "pending",
}
return (
<span
className={cn("flex-shrink-0 size-2 rounded-full", className)}
// style={{ marginBottom: "-1px" }}
/>
)
}

View File

@@ -1,132 +0,0 @@
import * as React from "react"
import { DialogTitle, type DialogProps } from "@radix-ui/react-dialog"
import { Command as CommandPrimitive } from "cmdk"
import { Search } from "lucide-react"
import { cn } from "@/lib/utils"
import { Dialog, DialogContent } from "@/components/ui/dialog"
const Command = React.forwardRef<
React.ElementRef<typeof CommandPrimitive>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive>
>(({ className, ...props }, ref) => (
<CommandPrimitive
ref={ref}
className={cn("flex h-full w-full flex-col overflow-hidden bg-popover text-popover-foreground", className)}
{...props}
/>
))
Command.displayName = CommandPrimitive.displayName
interface CommandDialogProps extends DialogProps {}
const CommandDialog = ({ children, ...props }: CommandDialogProps) => {
return (
<Dialog {...props}>
<DialogContent className="overflow-hidden p-0 shadow-lg">
<div className="sr-only">
<DialogTitle>Command</DialogTitle>
</div>
<Command className="[&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground [&_[cmdk-group]:not([hidden])_~[cmdk-group]]:pt-0 [&_[cmdk-group]]:px-2 [&_[cmdk-input-wrapper]_svg]:h-5 [&_[cmdk-input-wrapper]_svg]:w-5 [&_[cmdk-input]]:h-12 [&_[cmdk-item]]:px-2 [&_[cmdk-item]]:py-3 [&_[cmdk-item]_svg]:h-5 [&_[cmdk-item]_svg]:w-5">
{children}
</Command>
</DialogContent>
</Dialog>
)
}
const CommandInput = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Input>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Input>
>(({ className, ...props }, ref) => (
<div className="flex items-center border-b px-3" cmdk-input-wrapper="">
<Search className="me-2 h-4 w-4 shrink-0 opacity-50" />
<CommandPrimitive.Input
ref={ref}
className={cn(
"flex h-11 w-full rounded-md bg-transparent py-3 text-sm outline-none placeholder:text-muted-foreground disabled:cursor-not-allowed disabled:opacity-50",
className
)}
{...props}
/>
</div>
))
CommandInput.displayName = CommandPrimitive.Input.displayName
const CommandList = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.List>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.List>
>(({ className, ...props }, ref) => (
<CommandPrimitive.List
ref={ref}
className={cn("max-h-[300px] overflow-y-auto overflow-x-hidden", className)}
{...props}
/>
))
CommandList.displayName = CommandPrimitive.List.displayName
const CommandEmpty = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Empty>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Empty>
>((props, ref) => <CommandPrimitive.Empty ref={ref} className="py-6 text-center text-sm" {...props} />)
CommandEmpty.displayName = CommandPrimitive.Empty.displayName
const CommandGroup = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Group>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Group>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Group
ref={ref}
className={cn(
"overflow-hidden p-1 text-foreground [&_[cmdk-group-heading]]:px-2 [&_[cmdk-group-heading]]:py-1.5 [&_[cmdk-group-heading]]:text-xs [&_[cmdk-group-heading]]:font-medium [&_[cmdk-group-heading]]:text-muted-foreground",
className
)}
{...props}
/>
))
CommandGroup.displayName = CommandPrimitive.Group.displayName
const CommandSeparator = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Separator>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Separator>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Separator ref={ref} className={cn("-mx-1 h-px bg-border", className)} {...props} />
))
CommandSeparator.displayName = CommandPrimitive.Separator.displayName
const CommandItem = React.forwardRef<
React.ElementRef<typeof CommandPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof CommandPrimitive.Item>
>(({ className, ...props }, ref) => (
<CommandPrimitive.Item
ref={ref}
className={cn(
"relative flex cursor-default opacity-70 select-none items-center rounded-sm px-2 py-1.5 text-sm outline-none aria-selected:bg-accent aria-selected:opacity-90 data-[disabled='true']:pointer-events-none data-[disabled='true']:opacity-50",
className
)}
{...props}
/>
))
CommandItem.displayName = CommandPrimitive.Item.displayName
const CommandShortcut = ({ className, ...props }: React.HTMLAttributes<HTMLSpanElement>) => {
return <span className={cn("ms-auto text-xs tracking-wide text-muted-foreground", className)} {...props} />
}
CommandShortcut.displayName = "CommandShortcut"
export {
Command,
CommandDialog,
CommandInput,
CommandList,
CommandEmpty,
CommandGroup,
CommandItem,
CommandShortcut,
CommandSeparator,
}

View File

@@ -1,22 +0,0 @@
import * as React from "react"
import { cn } from "@/lib/utils"
export interface InputProps extends React.InputHTMLAttributes<HTMLInputElement> {}
const Input = React.forwardRef<HTMLInputElement, InputProps>(({ className, type, ...props }, ref) => {
return (
<input
type={type}
className={cn(
"flex h-10 w-full rounded-md border bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
className
)}
ref={ref}
{...props}
/>
)
})
Input.displayName = "Input"
export { Input }

View File

@@ -1,24 +0,0 @@
import { Toast, ToastClose, ToastDescription, ToastProvider, ToastTitle, ToastViewport } from "@/components/ui/toast"
import { useToast } from "@/components/ui/use-toast"
export function Toaster() {
const { toasts } = useToast()
return (
<ToastProvider>
{toasts.map(function ({ id, title, description, action, ...props }) {
return (
<Toast key={id} {...props}>
<div className="grid gap-1">
{title && <ToastTitle>{title}</ToastTitle>}
{description && <ToastDescription>{description}</ToastDescription>}
</div>
{action}
<ToastClose />
</Toast>
)
})}
<ToastViewport />
</ToastProvider>
)
}

View File

@@ -1,28 +0,0 @@
import * as React from "react"
import * as TooltipPrimitive from "@radix-ui/react-tooltip"
import { cn } from "@/lib/utils"
const TooltipProvider = TooltipPrimitive.Provider
const Tooltip = TooltipPrimitive.Root
const TooltipTrigger = TooltipPrimitive.Trigger
const TooltipContent = React.forwardRef<
React.ElementRef<typeof TooltipPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>
>(({ className, sideOffset = 4, ...props }, ref) => (
<TooltipPrimitive.Content
ref={ref}
sideOffset={sideOffset}
className={cn(
"z-50 overflow-hidden rounded-md border bg-popover px-3 py-1.5 text-sm text-popover-foreground shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2",
className
)}
{...props}
/>
))
TooltipContent.displayName = TooltipPrimitive.Content.displayName
export { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider }

View File

@@ -1,103 +0,0 @@
@tailwind base;
@tailwind components;
@tailwind utilities;
@layer base {
:root {
--background: 30 8% 98.5%;
--foreground: 30 0% 0%;
--card: 30 0% 100%;
--card-foreground: 240 6.67% 2.94%;
--popover: 30 0% 100%;
--popover-foreground: 240 10% 6.2%;
--primary: 240 5.88% 10%;
--primary-foreground: 30 0% 100%;
--secondary: 240 4.76% 95.88%;
--secondary-foreground: 240 5.88% 10%;
--muted: 26 6% 94%;
--muted-foreground: 24 2.79% 35.1%;
--accent: 20 23.08% 94%;
--accent-foreground: 240 5.88% 10%;
--destructive: 0 66% 53%;
--destructive-foreground: 0 0% 98.04%;
--border: 30 8.11% 85.49%;
--input: 30 4.29% 72.55%;
--ring: 30 3.97% 49.41%;
--radius: 0.8rem;
/* charts */
--chart-1: 220 70% 50%;
--chart-2: 160 60% 45%;
--chart-3: 30 80% 55%;
--chart-4: 280 65% 60%;
--chart-5: 340 75% 55%;
}
.dark {
color-scheme: dark;
--background: 220 5.5% 9%;
--foreground: 220 2% 97%;
--card: 220 5.5% 10.5%;
--card-foreground: 220 2% 97%;
--popover: 220 5.5% 9%;
--popover-foreground: 220 2% 97%;
--primary: 220 2% 96%;
--primary-foreground: 220 4% 10%;
--secondary: 220 4% 16%;
--secondary-foreground: 220 0% 98%;
--muted: 220 6% 16%;
--muted-foreground: 220 4% 67%;
--accent: 220 5% 15.5%;
--accent-foreground: 220 2% 98%;
--destructive: 0 62% 46%;
--destructive-foreground: 0 0% 97%;
--border: 220 3% 16%;
--input: 220 4% 22%;
--ring: 220 4% 80%;
--radius: 0.8rem;
}
}
/* Fonts */
@supports (font-variation-settings: normal) {
:root {
font-family: Inter, InterVariable, sans-serif;
}
}
@font-face {
font-family: InterVariable;
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url("/static/InterVariable.woff2?v=4.0") format("woff2");
}
@layer base {
* {
@apply border-border;
overflow-anchor: none;
}
body {
@apply bg-background text-foreground;
}
}
@layer utilities {
.link {
@apply text-primary font-medium underline-offset-4 hover:underline;
}
/* New system dialog width */
.ns-dialog {
min-width: 30.3rem;
}
:where(:lang(zh), :lang(zh-CN), :lang(ko)) .ns-dialog {
min-width: 27.9rem;
}
}
.recharts-tooltip-wrapper {
z-index: 1;
}
.recharts-yAxis {
@apply tabular-nums;
}

View File

@@ -1,13 +0,0 @@
export enum Os {
Linux = 0,
Darwin,
Windows,
// FreeBSD,
}
export enum ChartType {
Memory,
Disk,
Network,
CPU,
}

View File

@@ -1,48 +0,0 @@
import PocketBase from "pocketbase"
import { atom, map, PreinitializedWritableAtom } from "nanostores"
import { AlertRecord, ChartTimes, SystemRecord, UserSettings } from "@/types"
import { basePath } from "@/components/router"
/** PocketBase JS Client */
export const pb = new PocketBase(basePath)
/** Store if user is authenticated */
export const $authenticated = atom(pb.authStore.isValid)
/** List of system records */
export const $systems = atom([] as SystemRecord[])
/** List of alert records */
export const $alerts = atom([] as AlertRecord[])
/** SSH public key */
export const $publicKey = atom("")
/** Chart time period */
export const $chartTime = atom("1h") as PreinitializedWritableAtom<ChartTimes>
/** Whether to display average or max chart values */
export const $maxValues = atom(false)
/** User settings */
export const $userSettings = map<UserSettings>({
chartTime: "1h",
emails: [pb.authStore.record?.email || ""],
})
// update local storage on change
$userSettings.subscribe((value) => {
// console.log('user settings changed', value)
$chartTime.set(value.chartTime)
})
/** Container chart filter */
export const $containerFilter = atom("")
/** Temperature chart filter */
export const $temperatureFilter = atom("")
/** Fallback copy to clipboard dialog content */
export const $copyContent = atom("")
/** Direction for localization */
export const $direction = atom<"ltr" | "rtl">("ltr")

View File

@@ -1,357 +0,0 @@
import { t } from "@lingui/core/macro";
import { toast } from "@/components/ui/use-toast"
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
import { $alerts, $copyContent, $systems, $userSettings, pb } from "./stores"
import { AlertInfo, AlertRecord, ChartTimeData, ChartTimes, SystemRecord } from "@/types"
import { RecordModel, RecordSubscription } from "pocketbase"
import { WritableAtom } from "nanostores"
import { timeDay, timeHour } from "d3-time"
import { useEffect, useState } from "react"
import { CpuIcon, HardDriveIcon, MemoryStickIcon, ServerIcon } from "lucide-react"
import { EthernetIcon, ThermometerIcon } from "@/components/ui/icons"
import { prependBasePath } from "@/components/router"
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
/** Adds event listener to node and returns function that removes the listener */
export function listen<T extends Event = Event>(
node: Node,
event: string,
handler: (event: T) => void
) {
node.addEventListener(event, handler as EventListener)
return () => node.removeEventListener(event, handler as EventListener)
}
export async function copyToClipboard(content: string) {
const duration = 1500
try {
await navigator.clipboard.writeText(content)
toast({
duration,
description: t`Copied to clipboard`,
})
} catch (e: any) {
$copyContent.set(content)
}
}
const verifyAuth = () => {
pb.collection("users")
.authRefresh()
.catch(() => {
logOut()
toast({
title: t`Failed to authenticate`,
description: t`Please log in again`,
variant: "destructive",
})
})
}
export const updateSystemList = (() => {
let isFetchingSystems = false
return async () => {
if (isFetchingSystems) {
return
}
isFetchingSystems = true
try {
const records = await pb
.collection<SystemRecord>("systems")
.getFullList({ sort: "+name", fields: "id,name,host,port,info,status" })
if (records.length) {
$systems.set(records)
} else {
verifyAuth()
}
} finally {
isFetchingSystems = false
}
}
})()
/** Logs the user out by clearing the auth store and unsubscribing from realtime updates. */
export async function logOut() {
sessionStorage.setItem("lo", "t")
pb.authStore.clear()
pb.realtime.unsubscribe()
}
export const updateAlerts = () => {
pb.collection("alerts")
.getFullList<AlertRecord>({ fields: "id,name,system,value,min,triggered", sort: "updated" })
.then((records) => {
$alerts.set(records)
})
}
const hourWithMinutesFormatter = new Intl.DateTimeFormat(undefined, {
hour: "numeric",
minute: "numeric",
})
export const hourWithMinutes = (timestamp: string) => {
return hourWithMinutesFormatter.format(new Date(timestamp))
}
const shortDateFormatter = new Intl.DateTimeFormat(undefined, {
day: "numeric",
month: "short",
hour: "numeric",
minute: "numeric",
})
export const formatShortDate = (timestamp: string) => {
return shortDateFormatter.format(new Date(timestamp))
}
const dayFormatter = new Intl.DateTimeFormat(undefined, {
day: "numeric",
month: "short",
})
export const formatDay = (timestamp: string) => {
return dayFormatter.format(new Date(timestamp))
}
export const updateFavicon = (newIcon: string) => {
;(document.querySelector("link[rel='icon']") as HTMLLinkElement).href = prependBasePath(`/static/${newIcon}`)
}
export const isAdmin = () => pb.authStore.record?.role === "admin"
export const isReadOnlyUser = () => pb.authStore.record?.role === "readonly"
/** Update systems / alerts list when records change */
export function updateRecordList<T extends RecordModel>(e: RecordSubscription<T>, $store: WritableAtom<T[]>) {
const curRecords = $store.get()
const newRecords = []
if (e.action === "delete") {
for (const server of curRecords) {
if (server.id !== e.record.id) {
newRecords.push(server)
}
}
} else {
let found = 0
for (const server of curRecords) {
if (server.id === e.record.id) {
found = newRecords.push(e.record)
} else {
newRecords.push(server)
}
}
if (!found) {
newRecords.push(e.record)
}
}
$store.set(newRecords)
}
export function getPbTimestamp(timeString: ChartTimes, d?: Date) {
d ||= chartTimeData[timeString].getOffset(new Date())
const year = d.getUTCFullYear()
const month = String(d.getUTCMonth() + 1).padStart(2, "0")
const day = String(d.getUTCDate()).padStart(2, "0")
const hours = String(d.getUTCHours()).padStart(2, "0")
const minutes = String(d.getUTCMinutes()).padStart(2, "0")
const seconds = String(d.getUTCSeconds()).padStart(2, "0")
return `${year}-${month}-${day} ${hours}:${minutes}:${seconds}`
}
export const chartTimeData: ChartTimeData = {
"1h": {
type: "1m",
expectedInterval: 60_000,
label: () => t`1 hour`,
// ticks: 12,
format: (timestamp: string) => hourWithMinutes(timestamp),
getOffset: (endTime: Date) => timeHour.offset(endTime, -1),
},
"12h": {
type: "10m",
expectedInterval: 60_000 * 10,
label: () => t`12 hours`,
ticks: 12,
format: (timestamp: string) => hourWithMinutes(timestamp),
getOffset: (endTime: Date) => timeHour.offset(endTime, -12),
},
"24h": {
type: "20m",
expectedInterval: 60_000 * 20,
label: () => t`24 hours`,
format: (timestamp: string) => hourWithMinutes(timestamp),
getOffset: (endTime: Date) => timeHour.offset(endTime, -24),
},
"1w": {
type: "120m",
expectedInterval: 60_000 * 120,
label: () => t`1 week`,
ticks: 7,
format: (timestamp: string) => formatDay(timestamp),
getOffset: (endTime: Date) => timeDay.offset(endTime, -7),
},
"30d": {
type: "480m",
expectedInterval: 60_000 * 480,
label: () => t`30 days`,
ticks: 30,
format: (timestamp: string) => formatDay(timestamp),
getOffset: (endTime: Date) => timeDay.offset(endTime, -30),
},
}
/** Sets the correct width of the y axis in recharts based on the longest label */
export function useYAxisWidth() {
const [yAxisWidth, setYAxisWidth] = useState(0)
let maxChars = 0
let timeout: Timer
function updateYAxisWidth(str: string) {
if (str.length > maxChars) {
maxChars = str.length
const div = document.createElement("div")
div.className = "text-xs tabular-nums tracking-tighter table sr-only"
div.innerHTML = str
clearTimeout(timeout)
timeout = setTimeout(() => {
document.body.appendChild(div)
const width = div.offsetWidth + 24
if (width > yAxisWidth) {
setYAxisWidth(div.offsetWidth + 24)
}
document.body.removeChild(div)
})
}
return str
}
return { yAxisWidth, updateYAxisWidth }
}
export function toFixedWithoutTrailingZeros(num: number, digits: number) {
return parseFloat(num.toFixed(digits)).toString()
}
export function toFixedFloat(num: number, digits: number) {
return parseFloat(num.toFixed(digits))
}
let decimalFormatters: Map<number, Intl.NumberFormat> = new Map()
/** Format number to x decimal places */
export function decimalString(num: number, digits = 2) {
let formatter = decimalFormatters.get(digits)
if (!formatter) {
formatter = new Intl.NumberFormat(undefined, {
minimumFractionDigits: digits,
maximumFractionDigits: digits,
})
decimalFormatters.set(digits, formatter)
}
return formatter.format(num)
}
/** Get value from local storage */
function getStorageValue(key: string, defaultValue: any) {
const saved = localStorage?.getItem(key)
return saved ? JSON.parse(saved) : defaultValue
}
/** Hook to sync value in local storage */
export function useLocalStorage<T>(key: string, defaultValue: T) {
key = `besz-${key}`
const [value, setValue] = useState(() => {
return getStorageValue(key, defaultValue)
})
useEffect(() => {
localStorage?.setItem(key, JSON.stringify(value))
}, [key, value])
return [value, setValue]
}
export async function updateUserSettings() {
try {
const req = await pb.collection("user_settings").getFirstListItem("", { fields: "settings" })
$userSettings.set(req.settings)
return
} catch (e) {
console.log("get settings", e)
}
// create user settings if error fetching existing
try {
const createdSettings = await pb.collection("user_settings").create({ user: pb.authStore.record!.id })
$userSettings.set(createdSettings.settings)
} catch (e) {
console.log("create settings", e)
}
}
/**
* Get the value and unit of size (TB, GB, or MB) for a given size
* @param n size in gigabytes or megabytes
* @param isGigabytes boolean indicating if n represents gigabytes (true) or megabytes (false)
* @returns an object containing the value and unit of size
*/
export const getSizeAndUnit = (n: number, isGigabytes = true) => {
const sizeInGB = isGigabytes ? n : n / 1_000
if (sizeInGB >= 1_000) {
return { v: sizeInGB / 1_000, u: " TB" }
} else if (sizeInGB >= 1) {
return { v: sizeInGB, u: " GB" }
}
return { v: isGigabytes ? sizeInGB * 1_000 : n, u: " MB" }
}
export const chartMargin = { top: 12 }
export const alertInfo: Record<string, AlertInfo> = {
Status: {
name: () => t`Status`,
unit: "",
icon: ServerIcon,
desc: () => t`Triggers when status switches between up and down`,
/** "for x minutes" is appended to desc when only one value */
singleDesc: () => t`System` + " " + t`Down`,
},
CPU: {
name: () => t`CPU Usage`,
unit: "%",
icon: CpuIcon,
desc: () => t`Triggers when CPU usage exceeds a threshold`,
},
Memory: {
name: () => t`Memory Usage`,
unit: "%",
icon: MemoryStickIcon,
desc: () => t`Triggers when memory usage exceeds a threshold`,
},
Disk: {
name: () => t`Disk Usage`,
unit: "%",
icon: HardDriveIcon,
desc: () => t`Triggers when usage of any disk exceeds a threshold`,
},
Bandwidth: {
name: () => t`Bandwidth`,
unit: " MB/s",
icon: EthernetIcon,
desc: () => t`Triggers when combined up/down exceeds a threshold`,
max: 125,
},
Temperature: {
name: () => t`Temperature`,
unit: "°C",
icon: ThermometerIcon,
desc: () => t`Triggers when any sensor exceeds a threshold`,
},
}
/**
* Retuns value of system host, truncating full path if socket.
* @example
* // Assuming system.host is "/var/run/beszel.sock"
* const hostname = getHostDisplayValue(system) // hostname will be "beszel.sock"
*/
export const getHostDisplayValue = (system: SystemRecord): string => system.host.slice(system.host.lastIndexOf("/") + 1)

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: ar\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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 {# أيام}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# ساعة} other {# ساعات}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ساعة"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 أسبوع"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 ساعة"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 ساعة"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 يومًا"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "إجراءات"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "التنبيهات النشطة"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "إضافة <0>نظام</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "إضافة نظام جديد"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "إضافة نظام"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "إضافة عنوان URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "تعديل خيارات العرض للرسوم البيانية."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "مسؤول"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "وكيل"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "التنبيهات"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "جميع الأنظمة"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "هل أنت متأكد أنك تريد حذف {name}؟"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "النسخ التلقائي يتطلب سياقًا آمنًا."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "متوسط"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "متوسط استخدام وحدة المعالجة المركزية للحاويات"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "المتوسط يتجاوز <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "متوسط ​​استهلاك طاقة GPUs"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "متوسط استخدام وحدة المعالجة المركزية على مستوى النظام"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "متوسط ​​استخدام {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "النسخ الاحتياطية"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "عرض النطاق الترددي"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "يدعم Beszel OpenID Connect والعديد من مزودي المصادقة OAuth2."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "يستخدم بيزيل <0>Shoutrrr</0> للتكامل مع خدمات الإشعارات الشهيرة."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "ثنائي"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "ذاكرة التخزين المؤقت / المخازن المؤقتة"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "إلغاء"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "تحذير - فقدان محتمل للبيانات"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "تغيير خيارات التطبيق العامة."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "خيارات الرسم البياني"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "تحقق من {email} للحصول على رابط إعادة التعيين."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "تحقق من السجلات لمزيد من التفاصيل."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "تحقق من خدمة الإشعارات الخاصة بك"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "انقر للنسخ"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "تعليمات سطر الأوامر"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "قم بتكوين كيفية تلقي إشعارات التنبيه."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "تأكيد كلمة المرور"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "متابعة"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "تم النسخ إلى الحافظة"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "نسخ docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "نسخ docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "نسخ المضيف"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "نسخ أمر لينكس"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "نسخ النص"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "المعالج"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "استخدام وحدة المعالجة المركزية"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "إنشاء حساب"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "داكن"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "لوحة التحكم"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "الفترة الزمنية الافتراضية"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "حذف"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "القرص"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "إدخال/إخراج القرص"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "استخدام القرص"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "استخدام القرص لـ {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "استخدام المعالج لـ Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "استخدام الذاكرة لـ Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "إدخال/إخراج الشبكة لـ Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "التوثيق"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "معطل"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "تعديل"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "البريد الإشباكي"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "إشعارات البريد الإشباكي"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "أدخل عنوان البريد الإشباكي لإعادة تعيين كلمة المرور"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "أدخل عنوان البريد الإشباكي..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "خطأ"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "يتجاوز {0}{1} في آخر {2, plural, one {# دقيقة} other {# دقائق}}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "تصدير التكوين"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "تصدير تكوين الأنظمة الحالية الخاصة بك."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "فشل في المصادقة"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "فشل في حفظ الإعدادات"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "فشل في إرسال إشعار الاختبار"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "فشل في تحديث التنبيه"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "تصفية..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "لمدة <0>{min}</0> {min, plural, one {دقيقة} other {دقائق}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "هل نسيت كلمة المرور؟"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "عام"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "استهلاك طاقة GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "شبكة"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "أمر Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "مضيف / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "إذا فقدت كلمة المرور لحساب المسؤول الخاص بك، يمكنك إعادة تعيينها باستخدام الأمر التالي."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "عنوان البريد الإشباكي غير صالح."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "النواة"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "اللغة"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "التخطيط"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "فاتح"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "تسجيل الخروج"
#: src/components/login/login.tsx
msgid "Login"
msgstr "تسجيل الدخول"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "فشل محاولة تسجيل الدخول"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "هل تبحث عن مكان لإنشاء التنبيهات؟ انقر على أيقونات الجرس <0/> في جدول الأنظمة."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "إدارة تفضيلات العرض والإشعارات."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "تعليمات الإعداد اليدوي"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "1 دقيقة كحد"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "الذاكرة"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "استخدام الذاكرة"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "استخدام الذاكرة لحاويات Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "الاسم"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "الشبكة"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "حركة مرور الشبكة لحاويات Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "حركة مرور الشبكة للواجهات العامة"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "لم يتم العثور على نتائج."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "لم يتم العثور على أنظمة."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "الإشعارات"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "دعم OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "في كل إعادة تشغيل، سيتم تحديث الأنظمة في قاعدة البيانات لتتطابق مع الأنظمة المعرفة في الملف."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "فتح القائمة"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "أو المتابعة باستخدام"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "الكتابة فوق التنبيهات الحالية"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "صفحة"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "الصفحات / الإعدادات"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "كلمة المرور"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "كلمة المرور يجب أن تتكون من 8 أحرف على الأقل."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "يجب أن تكون كلمة المرور أقل من 72 بايت."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "تم استلام طلب إعادة تعيين كلمة المرور"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "إيقاف مؤقت"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "متوقف مؤقتًا"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "يرجى <0>تكوين خادم SMTP</0> لضمان تسليم التنبيهات."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "يرجى التحقق من السجلات لمزيد من التفاصيل."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "يرجى التحقق من بيانات الاعتماد الخاصة بك والمحاولة مرة أخرى"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "يرجى إنشاء حساب مسؤول"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "يرجى تمكين النوافذ المنبثقة لهذا الموقع"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "يرجى تسجيل الدخول مرة أخرى"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "يرجى الاطلاع على <0>التوثيق</0> للحصول على التعليمات."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "يرجى تسجيل الدخول إلى حسابك"
#: src/components/add-system.tsx
msgid "Port"
msgstr "المنفذ"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "الاستخدام الدقيق في الوقت المسجل"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "اللغة المفضلة"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "المفتاح العام"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "قراءة"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "تم الاستلام"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "إعادة تعيين كلمة المرور"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "استئناف"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "احفظ العنوان باستخدام مفتاح الإدخال أو الفاصلة. اتركه فارغًا لتعطيل إشعارات البريد الإشباكي."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "حفظ الإعدادات"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "احفظ النظام"
#: src/components/navbar.tsx
msgid "Search"
msgstr "بحث"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "البحث عن الأنظمة أو الإعدادات..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "راجع <0>إعدادات الإشعارات</0> لتكوين كيفية تلقي التنبيهات."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "تم الإرسال"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "يحدد النطاق الزمني الافتراضي للرسوم البيانية عند عرض النظام."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "الإعدادات"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "تم حفظ الإعدادات"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "تسجيل الدخول"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "إعدادات SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "الترتيب حسب"
#: src/lib/utils.ts
msgid "Status"
msgstr "الحالة"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "مساحة التبديل المستخدمة من قبل النظام"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "استخدام التبديل"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "النظام"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "الأنظمة"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "يمكن إدارة الأنظمة في ملف <0>config.yml</0> داخل دليل البيانات الخاص بك."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "جدول"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "درجة الحرارة"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "درجة الحرارة"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "درجات حرارة مستشعرات النظام"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "اختبار <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "تم إرسال إشعار الاختبار"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "يجب أن يكون الوكيل قيد التشغيل على النظام للاتصال. انسخ أمر التثبيت للوكيل أدناه."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "يجب أن يكون الوكيل قيد التشغيل على النظام للاتصال. انسخ <0>docker-compose.yml</0> للوكيل أدناه."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "ثم قم بتسجيل الدخول إلى الواجهة الخلفية وأعد تعيين كلمة مرور حساب المستخدم الخاص بك في جدول المستخدمين."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "لا يمكن التراجع عن هذا الإجراء. سيؤدي ذلك إلى حذف جميع السجلات الحالية لـ {name} من قاعدة البيانات بشكل دائم."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "معدل نقل {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "معدل نقل نظام الملفات الجذر"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "إلى البريد الإشباكي"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "تبديل الشبكة"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "تبديل السمة"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز أي مستشعر عتبة معينة"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز الجمع بين الصعود/الهبوط عتبة معينة"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام وحدة المعالجة المركزية عتبة معينة"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام الذاكرة عتبة معينة"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "يتم التفعيل عندما يتغير الحالة بين التشغيل والإيقاف"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "يتم التفعيل عندما يتجاوز استخدام أي قرص عتبة معينة"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "قيد التشغيل"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "محدث في الوقت الحقيقي. انقر على نظام لعرض المعلومات."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "مدة التشغيل"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "الاستخدام"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "استخدام القسم الجذر"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "مستخدم"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "المستخدمون"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "عرض"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "الأعمدة الظاهرة"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "في انتظار وجود سجلات كافية للعرض"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "هل تريد مساعدتنا في تحسين ترجماتنا؟ تحقق من <0>Crowdin</0> لمزيد من التفاصيل."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "إشعارات Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "أمر Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "كتابة"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "تكوين YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "تكوين YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "تم تحديث إعدادات المستخدم الخاصة بك."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: bg\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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 {# дни}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# час} other {# часа}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 час"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 седмица"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 часа"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 часа"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 дни"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Действия"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Активни тревоги"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Добави <0>Система</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Добави нова система"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Добави система"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Добави URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Настрой опциите за показване на диаграмите."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Администратор"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Агент"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Тревоги"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Всички системи"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Сигурен ли си, че искаш да изтриеш {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Автоматичното копиране изисква защитен контескт."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Средно"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Средно използване на процесора на контейнерите"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Средната стойност надхвърля <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Средна консумация на ток от графични карти"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Средно използване на процесора на цялата система"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Средно използване на {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Архиви"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Bandwidth на мрежата"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel поддържа OpenID Connect и много други OAuth2 доставчици за удостоверяване."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel ползва <0>Shoutrrr</0> за да се интегрира с известни услуги за уведомяване."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Двоичен код"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Кеш / Буфери"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Откажи"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Внимание - възможност за загуба на данни"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Смени общите опции на приложението."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Опции на диаграмата"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Провери {email} за линк за нулиране."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Провери log-овете за повече информация."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Провери услугата си за удостоверяване"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Настисни за да копираш"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Инструкции за командната линия"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Настрой как получаваш нотификации за тревоги."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Потвърди парола"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Продължи"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Записано в клипборда"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Копирай docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Копирай docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Копирай хоста"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Копирай linux командата"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Копирай текста"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "Процесор"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Употреба на процесор"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Създай акаунт"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Тъмно"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Табло"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Времеви диапазон по подразбиране"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Изтрий"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Диск"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Диск I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Използване на диск"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Изполване на диск от {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Използване на процесор от docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Изполване на памет от docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Мрежов I/O използван от docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Документация"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Имейл"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Имейл нотификации"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Въведи имейл адрес за да нулираш паролата"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Въведи имейл адрес..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Грешка"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Надвишава {0}{1} в последните {2, plural, one {# минута} other {# минути}}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Експортирай конфигурация"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Експортирай конфигурацията на системите."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Неуспешно удостоверяване"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Неуспешно запазване на настройки"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Неуспешно изпрати тестова нотификация"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Неуспешно обнови тревога"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Филтрирай..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "За <0>{min}</0> {min, plural, one {минута} other {минути}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Забравена парола?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Общо"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Консумация на ток от графична карта"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Мрежово"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Команда Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Хост / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Ако си загубил паролата до администраторския акаунт, можеш да я нулираш със следващата команда."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Невалиден имейл адрес."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Linux Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Език"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Подреждане"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Светъл"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Изход"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Вход"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Неуспешен опит за вход"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "Търсиш къде да създадеш тревоги? Натисни емотиконата за звънец <0/> в таблицата за системи."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Управление на предпочитанията за показване и уведомяване."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Максимум 1 минута"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Памет"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Употреба на паметта"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Използването на памет от docker контейнерите"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Име"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Мрежа"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Мрежов трафик на docker контейнери"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Мрежов трафик на публични интерфейси"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Няма намерени резултати."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Няма намерени системи."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Нотификации"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Поддръжка на OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "На всеки рестарт, системите в датабазата ще бъдат обновени да съвпадат със системите зададени във файла."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Отвори менюто"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Или продължи с"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Презапиши съществуващи тревоги"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Страница"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Страници / Настройки"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Парола"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Паролата трябва да е поне 8 символа."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Получено е искането за нулиране на паролата"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Пауза"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "На пауза"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Моля <0>конфигурурай SMTP сървър</0> за да се подсигуриш, че тревогите са доставени."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Моля провери log-овете за повече информация."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Моля провери дадената информация и опитай отново"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Моля създай администраторски акаунт"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Моля активирай изскачащите прозорци за този сайт"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Моля влез отново"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Моля виж <0>документацията</0> за инструкции."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Моля влез в акаунта ти"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Порт"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Точно използване в записаното време"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Предпочитан език"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Публичен ключ"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Прочети"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Получени"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Нулиране на парола"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Възобнови"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Запази адреса с enter или запетая. Остави празно за да изключиш нотификациите чрез имейл."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Запази настройките"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Търси"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Търси за системи или настройки..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Виж <0>настройките за нотификациите</0> за да конфигурираш как получаваш тревоги."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Изпратени"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Задава диапазона за време за диаграмите, когато се разглежда система."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Настройки"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Настройките са запазени"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Влез"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Настройки за SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Сортиране по"
#: src/lib/utils.ts
msgid "Status"
msgstr "Статус"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Изполван swap от системата"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Използване на swap"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Система"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Системи"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Системите могат да бъдат управлявани в <0>config.yml</0> файл намиращ се в директорията с данни."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Таблица"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Температура"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Температири на системни сензори"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Тествай <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Тестова нотификация изпратена"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Агента трябва да работи на системата за да се свърже. Копирай инсталационната команда за агента долу."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Агемта трябва да работи на системата за да се свърже. Копирай <0>docker-compose.yml</0> файла за агента долу."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "След това влез в backend-а и нулирай паролата за потребителския акаунт в таблицата за потребители."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Това действие не може да бъде отменено. Това ще изтрие всички записи за {name} от датабазата."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Пропускателна способност на {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Пропускателна способност на root файловата система"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "До имейл(ите)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Превключване на мрежа"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Включи тема"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Задейства се, когато някой даден сензор надвиши зададен праг"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Задейства се, когато комбинираното качване/сваляне надвиши зададен праг"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Задейства се, когато употребата на процесора надвиши зададен праг"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Задейства се, когато употребата на паметта надвиши зададен праг"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Задейства се, когато статуса превключва между долу и горе"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Задейства се, когато употребата на някой диск надивши зададен праг"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Актуализира се в реално време. Натисни на система за да видиш информация."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Време на работа"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Употреба"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Употреба на root partition-а"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Използвани"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Потребители"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Изглед"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Видими полета"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Изчаква се за достатъчно записи за показване"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Искаш да помогнеш да направиш преводите още по-добри? Провери нашия <0>Crowdin</0> за повече детайли."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Пуш нотификации"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Команда Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Запиши"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML конфигурация"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML конфигурация"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Настройките за потребителя ти са обновени."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: cs\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-14 00:50\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í}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# Hodina} few {# Hodiny} many {# Hodin} other {# Hodin}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hodina"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 týden"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 hodin"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 hodin"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dní"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Akce"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktivní výstrahy"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Přidat <0>Systém</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Přidat nový systém"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Přidat systém"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Přidat URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Upravit možnosti zobrazení pro grafy."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Výstrahy"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Všechny systémy"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Opravdu chcete odstranit {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatická kopie vyžaduje zabezpečený kontext."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Průměr"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Průměrné využití CPU kontejnerů"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Průměr je vyšší než <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Průměrná spotřeba energie GPU"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Průměrné využití CPU v celém systému"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Průměrné využití {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Zálohy"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Přenos"
#: 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í."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel používá <0>Shoutrrr</0> k integraci s populárními notifikačními službami."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binary"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / vyrovnávací paměť"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Zrušit"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Upozornění - možná ztráta dat"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Změnit obecné nastavení aplikace."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Možnosti grafu"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Zkontrolujte {email} pro odkaz na obnovení."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Pro více informací zkontrolujte logy."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Zkontrolujte službu upozornění"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Klikněte pro zkopírování"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instrukce příkazového řádku"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfigurace způsobu přijímání upozornění."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Potvrdit heslo"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Pokračovat"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Zkopírováno do schránky"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Kopírovat docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopírovat hostitele"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopírovat příkaz Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopírovat text"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "Procesor"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Využití procesoru"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Vytvořit účet"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Tmavý"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Přehled"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Výchozí doba"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Odstranit"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Využití disku"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Využití disku {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Využití CPU Dockeru"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Využití paměti Dockeru"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Síťové I/O Dockeru"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentace"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Nefunkční"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Upravit"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Emailová upozornění"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Zadejte e-mailovou adresu pro obnovu hesla"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Zadejte e-mailovou adresu..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Chyba"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Exportovat konfiguraci"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exportovat aktuální konfiguraci systémů."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Ověření se nezdařilo"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Nepodařilo se uložit nastavení"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Nepodařilo se odeslat testovací oznámení"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Nepodařilo se aktualizovat upozornění"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtr..."
#: src/components/alerts/alerts-system.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}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Zapomněli jste heslo?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Obecné"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Spotřeba energie GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Mřížka"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr ""
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Hostitel / IP"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Neplatná e-mailová adresa."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Jazyk"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Rozvržení"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Světlý"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Odhlásit"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Přihlásit"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Pokus o přihlášení selhal"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logy"
#: src/components/routes/settings/notifications.tsx
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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Správa nastavení zobrazení a oznámení."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Pokyny k manuálnímu nastavení"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Max. 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Paměť"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Využití paměti"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Využití paměti docker kontejnerů"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Název"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Síť"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Síťový provoz kontejnerů docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Síťový provoz veřejných rozhraní"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Nenalezeny žádné výskyty."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Nenalezeny žádné systémy."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Upozornění"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Podpora OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Při každém restartu budou systémy v databázi aktualizovány tak, aby odpovídaly systémům definovaným v souboru."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Otevřít menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Nebo pokračujte s"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Přepsat existující upozornění"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Stránka"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Stránky / Nastavení"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Heslo"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Heslo musí obsahovat alespoň 8 znaků."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Heslo musí být menší než 72 bytů."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Žádost o obnovu hesla byla přijata"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pozastavit"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pozastaveno"
#: 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."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Pro více informací zkontrolujte logy."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Zkontrolujte prosím Vaše přihlašovací údaje a zkuste to znovu"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Vytvořte si prosím účet administrátora"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Prosím povolte vyskakovací okna pro tento web"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Přihlaste se prosím znovu"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Instrukce naleznete v <0>dokumentaci</0>."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Přihlaste se prosím k vašemu účtu"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Přesné využití v zaznamenaném čase"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Upřednostňovaný jazyk"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Veřejný klíč"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Číst"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Přijato"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Obnovit heslo"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Pokračovat"
#: 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."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Uložit nastavení"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Uložit systém"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Hledat"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Hledat systémy nebo nastavení..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Podívejte se na <0>nastavení upozornění</0> pro nastavení toho, jak přijímáte upozornění."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Odeslat"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Nastaví výchozí časový rozsah grafů, když je systém zobrazen."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Nastavení"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Nastavení uloženo"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Přihlásit se"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Nastavení SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Seřadit podle"
#: src/lib/utils.ts
msgid "Status"
msgstr "Stav"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap prostor využívaný systémem"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap využití"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Systém"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systémy"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Systémy lze spravovat v souboru <0>config.yml</0> uvnitř datového adresáře."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabulka"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Teplota"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Teplota"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Teploty systémových senzorů"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testovací oznámení odesláno"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Agent musí být v systému spuštěn, aby se mohl připojit. Zkopírujte níže uvedený instalační příkaz pro agenta."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Agent musí být v systému spuštěn, aby se mohl připojit. Zkopírujte níže uvedený soubor<0>docker-compose.yml</0> pro agenta."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Poté se přihlaste do backendu a obnovte heslo k uživatelskému účtu v tabulce uživatelů."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Tuto akci nelze vzít zpět. Tím se z databáze trvale odstraní všechny aktuální záznamy pro {name}."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Propustnost {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Propustnost kořenového souborového systému"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Na email(y)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Přepnout mřížku"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Přepnout motiv"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Spustí se, když některý senzor překročí prahovou hodnotu"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Spustí se, když kombinace up/down překročí prahovou hodnotu"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Spustí se, když využití procesoru překročí prahovou hodnotu"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Spustí se, když využití paměti překročí prahovou hodnotu"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Spouští se, když se změní dostupnost"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Spustí se, když využití disku překročí prahovou hodnotu"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Funkční"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Aktualizováno v reálném čase. Klepnutím na systém zobrazíte informace."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Doba provozu"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Využití"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Využití kořenového oddílu"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Využito"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Uživatelé"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Zobrazení"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Viditelné sloupce"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Čeká se na dostatek záznamů k zobrazení"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push oznámení"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr ""
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Psát"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML konfigurace"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML konfigurace"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše uživatelská nastavení byla aktualizována."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: da\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Danish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: da\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 {# day} other {# days}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# hour} other {# hours}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 time"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 uge"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 timer"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 timer"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dage"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Handlinger"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktive Alarmer"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Tilføj <0>System</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Tilføj nyt system"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Tilføj system"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Tilføj URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Juster visningsindstillinger for diagrammer."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Alarmer"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Alle systemer"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Er du sikker på, at du vil slette {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatisk kopiering kræver en sikker kontekst."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Gennemsnitlig"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Gennemsnitlig CPU udnyttelse af containere"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Gennemsnit overstiger <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Gennemsnitligt strømforbrug for GPU'er"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Gennemsnitlig systembaseret CPU-udnyttelse"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Gennemsnitlig udnyttelse af {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Sikkerhedskopier"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Båndbredde"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel understøtter OpenID Connect og mange OAuth2 godkendelsesudbydere."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel bruger <0>Shoutrrr</0> til at integrere med populære notifikationstjenester."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binær"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffere"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Fortryd"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Forsigtig - muligt tab af data"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Skift generelle applikationsindstillinger."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Diagrammuligheder"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Tjek {email} for et nulstillingslink."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Tjek logfiler for flere detaljer."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Tjek din notifikationstjeneste"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Klik for at kopiere"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instruktioner for kommandolinje"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfigurer hvordan du modtager advarselsmeddelelser."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Bekræft adgangskode"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Forsæt"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Kopieret til udklipsholder"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Kopiér docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Kopiér docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopier host"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopier Linux kommando"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopier tekst"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU forbrug"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Opret konto"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Mørk"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Oversigtspanel"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Standard tidsperiode"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Slet"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Diskforbrug"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Diskforbrug af {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU forbrug"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker Hukommelsesforbrug"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker Netværk I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentation"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-mail"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Email-notifikationer"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Indtast e-mailadresse for at nulstille adgangskoden"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Indtast e-mailadresse..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Fejl"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Overskrider {0}{1} i sidste {2, plural, one {# minut} other {# minutter}}"
#: 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 "Eksisterende systemer ikke defineret i <0>config.yml</0> vil blive slettet. Opret venligst regelmæssige sikkerhedskopier."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Eksporter konfiguration"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Eksporter din nuværende systemkonfiguration."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Kunne ikke godkende"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Kunne ikke gemme indstillinger"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Afsendelse af testnotifikation mislykkedes"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Kunne ikke opdatere alarm"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filter..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "For <0>{min}</0> {min, plural, one {minut} other {minutter}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Glemt adgangskode?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Generelt"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Gpu Strøm Træk"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Gitter"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew-kommando"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Vært / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Hvis du har mistet adgangskoden til din administratorkonto, kan du nulstille den ved hjælp af følgende kommando."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ugyldig email adresse."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Sprog"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Layout"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Lys"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Log ud"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Log ind"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Loginforsøg mislykkedes"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logs"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Leder du i stedet for efter hvor du kan oprette alarmer? Klik på klokken <0/> ikoner i system tabellen."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Administrer display og notifikationsindstillinger."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Maks. 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Hukommelse"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Hukommelsesforbrug"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Hukommelsesforbrug af dockercontainere"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Navn"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Net"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Netværkstrafik af dockercontainere"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Netværkstrafik af offentlige grænseflader"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Ingen resultater fundet."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Ingen systemer fundet."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Notifikationer"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC understøttelse"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Ved hver genstart vil systemer i databasen blive opdateret til at matche de systemer, der er defineret i filen."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Åbn menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Eller fortsæt med"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Overskriv eksisterende alarmer"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Side"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Sider / Indstillinger"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Adgangskode"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Adgangskoden skal være på mindst 8 tegn."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Anmodning om nulstilling af adgangskode modtaget"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pause"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Sat på pause"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Konfigurer <0>en SMTP server</0> for at sikre at alarmer bliver leveret."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Tjek logfiler for flere detaljer."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Tjek dine legitimationsoplysninger og prøv igen"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Opret venligst en administratorkonto"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Aktiver pop-ups for dette websted"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Log venligst ind igen"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Se <0>dokumentationen</0> for instruktioner."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Log venligst ind på din konto"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Præcis udnyttelse på det registrerede tidspunkt"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Foretrukket sprog"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Offentlig nøgle"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Læs"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Modtaget"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Nulstil adgangskode"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Genoptag"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Gem adresse ved hjælp af enter eller komma. Lad feltet stå tomt for at deaktivere e-mail-meddelelser."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Gem indstillinger"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Søg"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Søg efter systemer eller indstillinger..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Se <0>meddelelsesindstillinger</0> for at konfigurere, hvordan du modtager alarmer."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Sendt"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Sætter standardtidsintervallet for diagrammer når et system vises."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Indstillinger"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Indstillinger gemt"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Log ind"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP-indstillinger"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sorter efter"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap plads brugt af systemet"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap forbrug"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "System"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systemer"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Systemer kan være administreres i filen <0>config.yml</0> i din datamappe."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabel"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatur"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperaturer i systemsensorer"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Test notifikation sendt"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Agenten skal køre på systemet for at forbinde. Kopier installationskommandoen for agenten nedenfor."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Agenten skal køre på systemet for at forbinde. Kopier <0>docker-compose.yml</0> for agenten nedenfor."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Log derefter ind på backend og nulstil adgangskoden til din brugerkonto i tabellen brugere."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Denne handling kan ikke fortrydes. Dette vil permanent slette alle aktuelle elementer for {name} fra databasen."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Gennemløb af {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Gennemløb af rodfilsystemet"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Til email(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Slå gitter til/fra"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Skift tema"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Udløser når en sensor overstiger en tærskel"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Udløses når de kombinerede op/ned overstiger en tærskel"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Udløser når CPU-forbrug overstiger en tærskel"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Udløser når hukommelsesforbruget overstiger en tærskel"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Udløser når status skifter mellem op og ned"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Udløser når brugen af en disk overstiger en tærskel"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Opdateret i realtid. Klik på et system for at se information."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Oppetid"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Forbrug"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Brug af rodpartition"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Brugt"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Brugere"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Vis"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Synlige felter"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Venter på nok posteringer til at vise"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Vil du hjælpe os med at gøre vores oversættelser endnu bedre? Tjek <0>Crowdin</0> for flere detaljer."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push notifikationer"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows-kommando"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Skriv"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML Konfiguration"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML Konfiguration"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Dine brugerindstillinger er opdateret."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: de\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# Stunde} other {# Stunden}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 Stunde"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 Woche"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 Stunden"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 Stunden"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 Tage"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Aktionen"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktive Warnungen"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>System</0> hinzufügen"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Neues System hinzufügen"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "System hinzufügen"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "URL hinzufügen"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Anzeigeoptionen für Diagramme anpassen."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Warnungen"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Alle Systeme"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Möchtest du {name} wirklich löschen?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatisches Kopieren erfordert einen sicheren Kontext."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Durchschnitt"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Durchschnittliche CPU-Auslastung der Container"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Durchschnitt überschreitet <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Durchschnittlicher Stromverbrauch der GPUs"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Durchschnittliche systemweite CPU-Auslastung"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Durchschnittliche Auslastung von {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Backups"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Bandbreite"
#: 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."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel verwendet <0>Shoutrrr</0>, um sich mit beliebten Benachrichtigungsdiensten zu integrieren."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binär"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Puffer"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Abbrechen"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Vorsicht - potenzieller Datenverlust"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Allgemeine Anwendungsoptionen ändern."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Diagrammoptionen"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Überprüfe {email} auf einen Link zum Zurücksetzen."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Überprüfe die Protokolle für weitere Details."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Überprüfe deinen Benachrichtigungsdienst"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Zum Kopieren klicken"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Befehlszeilenanweisungen"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfiguriere, wie du Warnbenachrichtigungen erhältst."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Passwort bestätigen"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Fortfahren"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "In die Zwischenablage kopiert"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Docker compose kopieren"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Docker run kopieren"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Host kopieren"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Linux-Befehl kopieren"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Text kopieren"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU-Auslastung"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Konto erstellen"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Dunkel"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Dashboard"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Standardzeitraum"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Löschen"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Festplatte"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Festplatten-I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Festplattennutzung"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Festplattennutzung von {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker-CPU-Auslastung"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker-Arbeitsspeichernutzung"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker-Netzwerk-I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentation"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Bearbeiten"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-Mail"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-Mail-Benachrichtigungen"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "E-Mail-Adresse eingeben, um das Passwort zurückzusetzen"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "E-Mail-Adresse eingeben..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Fehler"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Konfiguration exportieren"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exportiere die aktuelle Systemkonfiguration."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Authentifizierung fehlgeschlagen"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Einstellungen konnten nicht gespeichert werden"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Testbenachrichtigung konnte nicht gesendet werden"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Warnung konnte nicht aktualisiert werden"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filter..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Für <0>{min}</0> {min, plural, one {Minute} other {Minuten}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Passwort vergessen?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Allgemein"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU-Leistungsaufnahme"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Raster"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew-Befehl"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ungültige E-Mail-Adresse."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Sprache"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Anordnung"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Hell"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Abmelden"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Anmelden"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Anmeldeversuch fehlgeschlagen"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Protokolle"
#: src/components/routes/settings/notifications.tsx
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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Anzeige- und Benachrichtigungseinstellungen verwalten."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Max 1 Min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Arbeitsspeicher"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Arbeitsspeichernutzung"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Arbeitsspeichernutzung der Docker-Container"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Name"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Netz"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Netzwerkverkehr der Docker-Container"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Netzwerkverkehr der öffentlichen Schnittstellen"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Keine Ergebnisse gefunden."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Keine Systeme gefunden."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Benachrichtigungen"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC-Unterstützung"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Bei jedem Neustart werden die Systeme in der Datenbank aktualisiert, um den in der Datei definierten Systemen zu entsprechen."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Menü öffnen"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Oder fortfahren mit"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Bestehende Warnungen überschreiben"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Seite"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Seiten / Einstellungen"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Passwort"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Das Passwort muss mindestens 8 Zeichen haben."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Das Passwort muss weniger als 72 Bytes lang sein."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Anfrage zum Zurücksetzen des Passworts erhalten"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pause"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pausiert"
#: 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."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Bitte überprüfe die Protokolle für weitere Details."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Bitte überprüfe deine Anmeldedaten und versuche es erneut"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Bitte erstelle ein Administratorkonto"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Bitte aktiviere Pop-ups für diese Seite"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Bitte melde dich erneut an"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "In der <0>Dokumentation</0> findest du weitere Anweisungen."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Bitte melde dich bei beinem Konto an"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Genaue Nutzung zum aufgezeichneten Zeitpunkt"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Bevorzugte Sprache"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Schlüssel"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Lesen"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Empfangen"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Passwort zurücksetzen"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Fortsetzen"
#: 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."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Einstellungen speichern"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Suche"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Nach Systemen oder Einstellungen suchen..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Siehe <0>Benachrichtigungseinstellungen</0>, um zu konfigurieren, wie du Warnungen erhältst."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Gesendet"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Legt den Standardzeitraum für Diagramme fest, wenn ein System angezeigt wird."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Einstellungen"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Einstellungen gespeichert"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Anmelden"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP-Einstellungen"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sortieren nach"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Vom System genutzter Swap-Speicher"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap-Nutzung"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "System"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systeme"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Systeme können in einer <0>config.yml</0>-Datei im Datenverzeichnis verwaltet werden."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabelle"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatur"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperaturen der Systemsensoren"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testbenachrichtigung gesendet"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Der Agent muss auf dem System laufen, um eine Verbindung herzustellen. Kopiere den Installationsbefehl für den Agent unten."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Der Agent muss auf dem System laufen, um eine Verbindung herzustellen. Kopiere die <0>docker-compose.yml</0> für den Agent unten."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Melde dich dann im Backend an und setze dein Benutzerkontopasswort in der Benutzertabelle zurück."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Diese Aktion kann nicht rückgängig gemacht werden. Dadurch werden alle aktuellen Datensätze für {name} dauerhaft aus der Datenbank gelöscht."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Durchsatz von {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Durchsatz des Root-Dateisystems"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "An E-Mail(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Raster umschalten"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Darstellung umschalten"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Löst aus, wenn ein Sensor einen Schwellenwert überschreitet"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Löst aus, wenn die kombinierte Auf-/Abwärtsbewegung einen Schwellenwert überschreitet"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Löst aus, wenn die CPU-Auslastung einen Schwellenwert überschreitet"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Löst aus, wenn die Arbeitsspeichernutzung einen Schwellenwert überschreitet"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Löst aus, wenn der Status zwischen online und offline wechselt"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Löst aus, wenn die Nutzung einer Festplatte einen Schwellenwert überschreitet"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "In Echtzeit aktualisiert. Klicke auf ein System, um Informationen anzuzeigen."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Betriebszeit"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Nutzung"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Nutzung der Root-Partition"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Verwendet"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Benutzer"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Ansicht"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Sichtbare Spalten"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Warten auf genügend Datensätze zur Anzeige"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push-Benachrichtigungen"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows-Befehl"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Schreiben"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML-Konfiguration"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML-Konfiguration"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Deine Benutzereinstellungen wurden aktualisiert."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: es\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Spanish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: es-ES\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 {# día} other {# días}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# hora} other {# horas}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hora"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 semana"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 horas"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 horas"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 días"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Acciones"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Alertas Activas"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Agregar <0>Sistema</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Agregar Nuevo Sistema"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Agregar sistema"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Agregar URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Ajustar las opciones de visualización para los gráficos."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Administrador"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agente"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Alertas"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Todos los Sistemas"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "¿Está seguro de que desea eliminar {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "La copia automática requiere un contexto seguro."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Promedio"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Utilización promedio de CPU de los contenedores"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "El promedio excede <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Consumo de energía promedio de GPUs"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Utilización promedio de CPU del sistema"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Uso promedio de {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Copias de Seguridad"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Ancho de banda"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel admite OpenID Connect y muchos proveedores de autenticación OAuth2."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel utiliza <0>Shoutrrr</0> para integrarse con servicios populares de notificación."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binario"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Caché / Buffers"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Cancelar"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Precaución - posible pérdida de datos"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Cambiar las opciones generales de la aplicación."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Opciones de Gráficos"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Revise {email} para un enlace de restablecimiento."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Revise los registros para más detalles."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Verifique su servicio de notificaciones"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Haga clic para copiar"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instrucciones de línea de comandos"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Configure cómo recibe las notificaciones de alertas."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Confirmar contraseña"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Continuar"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Copiado al portapapeles"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Copiar docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Copiar docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Copiar host"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Copiar comando de Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Copiar texto"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Uso de CPU"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Crear cuenta"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Oscuro"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Tablero"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Período de tiempo predeterminado"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Eliminar"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disco"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "E/S de Disco"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Uso de Disco"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Uso de disco de {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Uso de CPU de Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Uso de Memoria de Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "E/S de Red de Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Documentación"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Abajo"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Editar"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Correo electrónico"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Notificaciones por correo"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Ingrese la dirección de correo electrónico para restablecer la contraseña"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Ingrese dirección de correo..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Error"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Excede {0}{1} en el último {2, plural, one {# minuto} other {# minutos}}"
#: 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 "Los sistemas existentes no definidos en <0>config.yml</0> serán eliminados. Por favor, haga copias de seguridad regularmente."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Exportar configuración"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exporte la configuración actual de sus sistemas."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Error al autenticar"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Error al guardar la configuración"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Error al enviar la notificación de prueba"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Error al actualizar la alerta"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtrar..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Por <0>{min}</0> {min, plural, one {minuto} other {minutos}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "¿Olvidó su contraseña?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "General"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Consumo de energía de la GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Cuadrícula"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Comando Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Si ha perdido la contraseña de su cuenta de administrador, puede restablecerla usando el siguiente comando."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Dirección de correo electrónico no válida."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Idioma"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Diseño"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Claro"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Cerrar Sesión"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Iniciar sesión"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Intento de inicio de sesión fallido"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Registros"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "¿Busca dónde crear alertas? Haga clic en los iconos de campana <0/> en la tabla de sistemas."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Administrar preferencias de visualización y notificaciones."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Instrucciones manuales de configuración"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Máx 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Memoria"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Uso de Memoria"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Uso de memoria de los contenedores de Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Nombre"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Red"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Tráfico de red de los contenedores de Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Tráfico de red de interfaces públicas"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "No se encontraron resultados."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "No se encontraron sistemas."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Notificaciones"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Soporte para OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "En cada reinicio, los sistemas en la base de datos se actualizarán para coincidir con los sistemas definidos en el archivo."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Abrir menú"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "O continuar con"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Sobrescribir alertas existentes"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Página"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Páginas / Configuraciones"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Contraseña"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "La contraseña debe tener al menos 8 caracteres."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "La contraseña debe ser menor de 72 bytes."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Solicitud de restablecimiento de contraseña recibida"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pausar"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pausado"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Por favor, <0>configure un servidor SMTP</0> para asegurar que las alertas sean entregadas."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Por favor, revise los registros para más detalles."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Por favor, verifique sus credenciales e intente de nuevo"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Por favor, cree una cuenta de administrador"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Por favor, habilite las ventanas emergentes para este sitio"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Por favor, inicie sesión de nuevo"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Por favor, consulte <0>la documentación</0> para obtener instrucciones."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Por favor, inicie sesión en su cuenta"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Puerto"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Utilización precisa en el momento registrado"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Idioma Preferido"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Clave Pública"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Lectura"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Recibido"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Restablecer Contraseña"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Reanudar"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Guarde la dirección usando la tecla enter o coma. Deje en blanco para desactivar las notificaciones por correo."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Guardar Configuración"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Guardar Sistema"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Buscar"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Buscar sistemas o configuraciones..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Consulte <0>configuración de notificaciones</0> para configurar cómo recibe alertas."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Enviado"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Establece el rango de tiempo predeterminado para los gráficos cuando se visualiza un sistema."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Configuración"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Configuración guardada"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Iniciar sesión"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Configuración SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Ordenar por"
#: src/lib/utils.ts
msgid "Status"
msgstr "Estado"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Espacio de swap utilizado por el sistema"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Uso de Swap"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Sistema"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemas"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Los sistemas pueden ser gestionados en un archivo <0>config.yml</0> dentro de su directorio de datos."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabla"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Temperatura"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatura"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperaturas de los sensores del sistema"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Probar <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Notificación de prueba enviada"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "El agente debe estar ejecutándose en el sistema para conectarse. Copie el comando de instalación para el agente a continuación."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "El agente debe estar ejecutándose en el sistema para conectarse. Copie el <0>docker-compose.yml</0> para el agente a continuación."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Luego inicie sesión en el backend y restablezca la contraseña de su cuenta de usuario en la tabla de usuarios."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Esta acción no se puede deshacer. Esto eliminará permanentemente todos los registros actuales de {name} de la base de datos."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Rendimiento de {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Rendimiento del sistema de archivos raíz"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "A correo(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Alternar cuadrícula"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Alternar tema"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Se activa cuando cualquier sensor supera un umbral"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Se activa cuando la suma de subida/bajada supera un umbral"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Se activa cuando el uso de CPU supera un umbral"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Se activa cuando el uso de memoria supera un umbral"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Se activa cuando el estado cambia entre activo e inactivo"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Se activa cuando el uso de cualquier disco supera un umbral"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Activo"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Actualizado en tiempo real. Haga clic en un sistema para ver la información."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Tiempo de actividad"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Uso"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Uso de la partición raíz"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Usado"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Usuarios"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Vista"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Columnas visibles"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Esperando suficientes registros para mostrar"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "¿Quieres ayudarnos a mejorar nuestras traducciones? Consulta <0>Crowdin</0> para más detalles."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Notificaciones Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Comando Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Escritura"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Configuración YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Configuración YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Su configuración de usuario ha sido actualizada."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: fa\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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 {# روز}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# ساعت} other {# ساعت}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "۱ ساعت"
#: src/lib/utils.ts
msgid "1 week"
msgstr "۱ هفته"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "۱۲ ساعت"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "۲۴ ساعت"
#: src/lib/utils.ts
msgid "30 days"
msgstr "۳۰ روز"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "عملیات"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr " هشدارهای فعال"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "افزودن <0>سیستم</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "افزودن سیستم جدید"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "افزودن سیستم"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "افزودن آدرس اینترنتی"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "تنظیم گزینه‌های نمایش برای نمودارها."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "مدیر"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "عامل"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "هشدارها"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "همه سیستم‌ها"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "آیا مطمئن هستید که می‌خواهید {name} را حذف کنید؟"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "کپی خودکار نیاز به یک زمینه امن دارد."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "میانگین"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "میانگین استفاده از CPU کانتینرها"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr ""
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "میانگین مصرف برق پردازنده‌های گرافیکی"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "میانگین استفاده از CPU در کل سیستم"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "میانگین استفاده از {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "پشتیبان‌گیری‌ها"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "پهنای باند"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "بِزل از OpenID Connect و بسیاری از ارائه‌دهندگان احراز هویت OAuth2 پشتیبانی می‌کند."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "بِزل از <0>Shoutrrr</0> برای ادغام با سرویس‌های اطلاع‌رسانی محبوب استفاده می‌کند."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "دودویی"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "حافظه پنهان / بافرها"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "لغو"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "احتیاط - احتمال از دست رفتن داده‌ها"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "تغییر گزینه‌های کلی برنامه."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "گزینه‌های نمودار"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "ایمیل {email} خود را برای لینک بازنشانی بررسی کنید."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "برای جزئیات بیشتر، لاگ‌ها را بررسی کنید."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "سرویس اطلاع‌رسانی خود را بررسی کنید"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "برای کپی کردن کلیک کنید"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "دستورالعمل‌های خط فرمان"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "نحوه دریافت هشدارهای اطلاع‌رسانی را پیکربندی کنید."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "تأیید رمز عبور"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "ادامه"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "در کلیپ‌بورد کپی شد"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "کپی docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "کپی docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "کپی میزبان"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "کپی دستور لینوکس"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "کپی متن"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "پردازنده"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "میزان استفاده از پردازنده"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "ایجاد حساب کاربری"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "تیره"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "داشبورد"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "بازه زمانی پیش‌فرض"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "حذف"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "دیسک"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "ورودی/خروجی دیسک"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "میزان استفاده از دیسک"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "میزان استفاده از دیسک {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "میزان استفاده از CPU داکر"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "میزان استفاده از حافظه داکر"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "ورودی/خروجی شبکه داکر"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "مستندات"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "ایمیل"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "اعلان‌های ایمیلی"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "آدرس ایمیل را برای بازنشانی رمز عبور وارد کنید"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "آدرس ایمیل را وارد کنید..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "خطا"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "در {2, plural, one {# دقیقه} other {# دقیقه}} گذشته از {0}{1} بیشتر است"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "خارج کردن پیکربندی"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "پیکربندی سیستم‌های فعلی خود را خارج کنید."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "احراز هویت ناموفق بود"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "ذخیره تنظیمات ناموفق بود"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "ارسال اعلان آزمایشی ناموفق بود"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "به‌روزرسانی هشدار ناموفق بود"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "فیلتر..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "برای <0>{min}</0> {min, plural, one {دقیقه} other {دقیقه}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "رمز عبور را فراموش کرده‌اید؟"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "عمومی"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "مصرف برق پردازنده گرافیکی"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "جدول"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "دستور Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "میزبان / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "اگر رمز عبور حساب مدیر خود را گم کرده‌اید، می‌توانید آن را با استفاده از دستور زیر بازنشانی کنید."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "آدرس ایمیل نامعتبر است."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "هسته"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "زبان"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "طرح‌بندی"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "روشن"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "خروج"
#: src/components/login/login.tsx
msgid "Login"
msgstr "ورود"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "تلاش برای ورود ناموفق بود"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "به دنبال جایی برای ایجاد هشدار هستید؟ روی آیکون‌های زنگ <0/> در جدول سیستم‌ها کلیک کنید."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "مدیریت تنظیمات نمایش و اعلان‌ها."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "حداکثر ۱ دقیقه"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "حافظه"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "میزان استفاده از حافظه"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "میزان استفاده از حافظه کانتینرهای داکر"
#: src/components/add-system.tsx
msgid "Name"
msgstr "نام"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "شبکه"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "ترافیک شبکه کانتینرهای داکر"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "ترافیک شبکه رابط‌های عمومی"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "هیچ نتیجه‌ای یافت نشد."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "هیچ سیستمی یافت نشد."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "اعلان‌ها"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "پشتیبانی از OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "در هر بار راه‌اندازی مجدد، سیستم‌های موجود در پایگاه داده با سیستم‌های تعریف شده در فایل مطابقت داده می‌شوند."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "باز کردن منو"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "یا ادامه با"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "بازنویسی هشدارهای موجود"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "صفحه"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "صفحات / تنظیمات"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "رمز عبور"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "رمز عبور باید حداقل ۸ کاراکتر باشد."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "درخواست بازنشانی رمز عبور دریافت شد"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "توقف"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "مکث شده"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "لطفاً برای اطمینان از تحویل هشدارها، یک <0>سرور SMTP پیکربندی کنید</0>."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "لطفاً برای جزئیات بیشتر، لاگ‌ها را بررسی کنید."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "لطفاً اعتبارنامه‌های خود را بررسی کرده و دوباره تلاش کنید."
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "لطفاً یک حساب مدیر ایجاد کنید"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "لطفاً پنجره‌های بازشو را برای این سایت فعال کنید"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "لطفاً دوباره وارد شوید"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "لطفاً برای دستورالعمل‌ها به <0>مستندات</0> مراجعه کنید."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "لطفاً به حساب کاربری خود وارد شوید"
#: src/components/add-system.tsx
msgid "Port"
msgstr "پورت"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "میزان دقیق استفاده در زمان ثبت شده"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "زبان ترجیحی"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "کلید عمومی"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "خواندن"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "دریافت شد"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "بازنشانی رمز عبور"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "ادامه"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "آدرس را با استفاده از کلید Enter یا کاما ذخیره کنید. برای غیرفعال کردن اعلان‌های ایمیلی، خالی بگذارید."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "ذخیره تنظیمات"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "جستجو"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "جستجو برای سیستم‌ها یا تنظیمات..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "برای پیکربندی نحوه دریافت هشدارها، به <0>تنظیمات اعلان</0> مراجعه کنید."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "ارسال شد"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "بازه زمانی پیش‌فرض برای نمودارها هنگام مشاهده یک سیستم را تعیین می‌کند."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "تنظیمات"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "تنظیمات ذخیره شد"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "ورود"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "تنظیمات SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "مرتب‌سازی بر اساس"
#: src/lib/utils.ts
msgid "Status"
msgstr "وضعیت"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "فضای Swap استفاده شده توسط سیستم"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "میزان استفاده از Swap"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "سیستم"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "سیستم‌ها"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "سیستم‌ها ممکن است در یک فایل <0>config.yml</0> درون دایرکتوری داده شما مدیریت شوند."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "جدول"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "دما"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "دمای حسگرهای سیستم"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "تست <0>آدرس اینترنتی</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "اعلان آزمایشی ارسال شد"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "برای اتصال، عامل باید روی سیستم در حال اجرا باشد. دستور نصب عامل را از زیر کپی کنید."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "برای اتصال، عامل باید روی سیستم در حال اجرا باشد. <0>docker-compose.yml</0> مربوط به عامل را از زیر کپی کنید."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "سپس وارد بخش پشتیبان شوید و رمز عبور حساب کاربری خود را در جدول کاربران بازنشانی کنید."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "این عمل قابل برگشت نیست. این کار تمام رکوردهای فعلی {name} را برای همیشه از پایگاه داده حذف خواهد کرد."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "توان عملیاتی {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "توان عملیاتی سیستم فایل ریشه"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "به ایمیل(ها)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "تغییر نمایش جدول"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "تغییر تم"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "هنگامی که هر حسگری از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "هنگامی که مجموع بالا/پایین از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "هنگامی که میزان استفاده از CPU از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "هنگامی که میزان استفاده از حافظه از یک آستانه فراتر رود، فعال می‌شود"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "هنگامی که وضعیت بین بالا و پایین تغییر می‌کند، فعال می‌شود"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "هنگامی که استفاده از هر دیسکی از یک آستانه فراتر رود، فعال می‌شود"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "به صورت لحظه‌ای به‌روزرسانی می‌شود. برای مشاهده اطلاعات، روی یک سیستم کلیک کنید."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "آپتایم"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "میزان استفاده"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "میزان استفاده از پارتیشن ریشه"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "استفاده شده"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "کاربران"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "مشاهده"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "فیلدهای قابل مشاهده"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "در انتظار رکوردهای کافی برای نمایش"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "می‌خواهید به ما کمک کنید تا ترجمه‌های خود را بهتر کنیم؟ برای جزئیات بیشتر به <0>Crowdin</0> مراجعه کنید."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "اعلان‌های Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "دستور Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "نوشتن"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "پیکربندی YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "پیکربندی YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "تنظیمات کاربری شما به‌روزرسانی شد."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: fr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# heure} other {# heures}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 heure"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 semaine"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 heures"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 heures"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 jours"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Actions"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Alertes actives"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Ajouter <0>Système</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Ajouter un nouveau système"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Ajouter un système"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Ajouter URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Ajuster les options d'affichage pour les graphiques."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Alertes"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Tous les systèmes"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Êtes-vous sûr de vouloir supprimer {name} ?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "La copie automatique nécessite un contexte sécurisé."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Moyenne"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Utilisation moyenne du CPU des conteneurs"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "La moyenne dépasse <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Consommation d'énergie moyenne des GPUs"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Utilisation moyenne du CPU à l'échelle du système"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Utilisation moyenne de {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Sauvegardes"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Bande passante"
#: 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."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel utilise <0>Shoutrrr</0> pour s'intégrer aux services de notification populaires."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binaire"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Tampons"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Annuler"
#: 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 "Change general application options."
msgstr "Modifier les options générales de l'application."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Options de graphique"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Vérifiez {email} pour un lien de réinitialisation."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Vérifiez les journaux pour plus de détails."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Vérifiez votre service de notification"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Cliquez pour copier"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instructions en ligne de commande"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Configurez comment vous recevez les notifications d'alerte."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Confirmer le mot de passe"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Continuer"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Copié dans le presse-papiers"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Copier docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Copier docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Copier l'hôte"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Copier la commande Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Copier le texte"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Utilisation du CPU"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Créer un compte"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Sombre"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Tableau de bord"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Période par défaut"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Supprimer"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disque"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Entrée/Sortie disque"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Utilisation du disque"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Utilisation du disque de {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Utilisation du CPU Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Utilisation de la mémoire Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Entrée/Sortie réseau Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Documentation"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Injoignable"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Éditer"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Notifications par email"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Entrez l'adresse email pour réinitialiser le mot de passe"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Entrez l'adresse email..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Erreur"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Exporter la configuration"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exportez la configuration actuelle de vos systèmes."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Échec de l'authentification"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Échec de l'enregistrement des paramètres"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Échec de l'envoi de la notification de test"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Échec de la mise à jour de l'alerte"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtrer..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Pour <0>{min}</0> {min, plural, one {minute} other {minutes}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Mot de passe oublié ?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Général"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Consommation du GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Grille"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Commande Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Hôte / IP"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Adresse email invalide."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Noyau"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Langue"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Disposition"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Clair"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Déconnexion"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Connexion"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Échec de la tentative de connexion"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Journaux"
#: src/components/routes/settings/notifications.tsx
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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Gérer les préférences d'affichage et de notification."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Guide pour une installation manuelle"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Mémoire"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Utilisation de la mémoire"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Utilisation de la mémoire des conteneurs Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Nom"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Net"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Trafic réseau des conteneurs Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Trafic réseau des interfaces publiques"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Aucun résultat trouvé."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Aucun système trouvé."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Notifications"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Support OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "À chaque redémarrage, les systèmes dans la base de données seront mis à jour pour correspondre aux systèmes définis dans le fichier."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Ouvrir le menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Ou continuer avec"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Écraser les alertes existantes"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Page"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Pages / Paramètres"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Mot de passe"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Le mot de passe doit contenir au moins 8 caractères."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Le mot de passe doit être inférieur à 72 Octets."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Demande de réinitialisation du mot de passe reçue"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "En pause"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "En pause"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Veuillez <0>configurer un serveur SMTP</0> pour garantir la livraison des alertes."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Veuillez vérifier les journaux pour plus de détails."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Veuillez vérifier vos identifiants et réessayer"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Veuillez créer un compte administrateur"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Veuillez activer les pop-ups pour ce site"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Veuillez vous reconnecter"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Veuillez consulter <0>la documentation</0> pour les instructions."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Veuillez vous connecter à votre compte"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Utilisation précise au moment enregistré"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Langue préférée"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Clé publique"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Lecture"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Reçu"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Réinitialiser le mot de passe"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Reprendre"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Enregistrez l'adresse en utilisant la touche Entrée ou la virgule. Laissez vide pour désactiver les notifications par email."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Enregistrer les paramètres"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Sauvegarder le système"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Recherche"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Rechercher des systèmes ou des paramètres..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Voir les <0>paramètres de notification</0> pour configurer comment vous recevez les alertes."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Envoyé"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Définit la plage de temps par défaut pour les graphiques lorsqu'un système est consulté."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Paramètres"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Paramètres enregistrés"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Se connecter"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Paramètres SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Trier par"
#: src/lib/utils.ts
msgid "Status"
msgstr "Statut"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Espace Swap utilisé par le système"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Utilisation du swap"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Système"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systèmes"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Les systèmes peuvent être gérés dans un fichier <0>config.yml</0> à l'intérieur de votre répertoire de données."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tableau"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Temp."
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Température"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Températures des capteurs du système"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Tester <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Notification de test envoyée"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "L'agent doit être en cours d'exécution sur le système pour se connecter. Copiez la commande d'installation pour l'agent ci-dessous."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "L'agent doit être en cours d'exécution sur le système pour se connecter. Copiez le <0>docker-compose.yml</0> pour l'agent ci-dessous."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Ensuite, connectez-vous au backend et réinitialisez le mot de passe de votre compte utilisateur dans la table des utilisateurs."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Cette action ne peut pas être annulée. Cela supprimera définitivement tous les enregistrements actuels pour {name} de la base de données."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Débit de {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Débit du système de fichiers racine"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Aux email(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Basculer la grille"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Changer le thème"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Déclenchement lorsque tout capteur dépasse un seuil"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Déclenchement lorsque le montant/descendant combinée dépasse un seuil"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation du CPU dépasse un seuil"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation de la mémoire dépasse un seuil"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Se déclenche lorsque le statut passe de \"Joignable\" à \"Injoignable\""
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Déclenchement lorsque l'utilisation de tout disque dépasse un seuil"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Joignable"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Mis à jour en temps réel. Cliquez sur un système pour voir les informations."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Temps de fonctionnement"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Utilisation"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Utilisation de la partition racine"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Utilisé"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Utilisateurs"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Vue"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Colonnes visibles"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "En attente de suffisamment d'enregistrements à afficher"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Notifications Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Commande Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Écriture"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Configuration YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Configuration YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vos paramètres utilisateur ont été mis à jour."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: hr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Croatian\n"
"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: hr\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 {# dan} other {# dani}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# sat} other {# sati}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 sat"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 tjedan"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 sati"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 sati"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dana"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Akcije"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktivna upozorenja"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Dodaj <0>Sistem</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Dodaj Novi Sistem"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Dodaj sistem"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Dodaj URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Podesite opcije prikaza za grafikone."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Upozorenja"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Svi Sistemi"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Jeste li sigurni da želite izbrisati {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatsko kopiranje zahtijeva siguran kontekst."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Prosjek"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Prosječna iskorištenost procesora u spremnicima"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Prosjek premašuje <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr ""
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Prosječna iskorištenost procesora na cijelom sustavu"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr ""
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Sigurnosne kopije"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Propusnost"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel podržava OpenID Connect i mnoge druge OAuth2 davatalje autentifikacije."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel koristi <0>Shoutrrr</0> za integraciju sa popularnim servisima za notifikacije."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binarni"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Predmemorija / Međuspremnici"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Otkaži"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Oprez - mogući gubitak podataka"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Promijenite opće opcije aplikacije."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Opcije grafikona"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Provjerite {email} za vezu za resetiranje."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Provjerite logove za više detalja."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Provjerite Vaš servis notifikacija"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Pritisnite za kopiranje"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Upute za naredbeni redak"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfigurirajte način primanja obavijesti upozorenja."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Potvrdite lozinku"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Nastavite"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Kopirano u međuspremnik"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Kopiraj docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Kopiraj docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopiraj hosta"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopiraj Linux komandu"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopiraj tekst"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "Procesor"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Iskorištenost procesora"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Napravite račun"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Tamno"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Nadzorna ploča"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Zadano vremensko razdoblje"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Izbriši"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Iskorištenost Diska"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Iskorištenost diska od {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Iskorištenost Docker Procesora"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Iskorištenost Docker Memorije"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker Mrežni I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentacija"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Email notifikacije"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Unesite email adresu za resetiranje lozinke"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Unesite email adresu..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Greška"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Premašuje {0}{1} u posljednjih {2, plural, one {# minuta} other {# minute}}"
#: 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 "Postojeći sistemi koji nisu definirani u <0>config.yml</0> će biti izbrisani. Molimo Vas napravite redovite sigurnosne kopije."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Izvoz konfiguracije"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Izvoz trenutne sistemske konfiguracije."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Provjera autentičnosti nije uspjela"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Neuspješno snimanje postavki"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Neuspješno slanje testne notifikacije"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Ažuriranje upozorenja nije uspjelo"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filter..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Za <0>{min}</0> {min, plural, one {minutu} other {minute}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Zaboravljena lozinka?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Općenito"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Mreža"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew naredba"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Ako ste izgubili lozinku za svoj administratorski račun, možete ju resetirati pomoću sljedeće naredbe."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Nevažeća adresa e-pošte."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Jezik"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Izgled"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Svijetlo"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Odjava"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Prijava"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Pokušaj prijave nije uspio"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logovi"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Tražite gdje stvoriti upozorenja? Kliknite ikonu zvona <0/> u tablici sustava."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Upravljajte postavkama prikaza i obavijesti."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Maksimalno 1 minuta"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Memorija"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Upotreba memorije"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Upotreba memorije Docker spremnika"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Ime"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Mreža"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Mrežni promet Docker spremnika"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Mrežni promet javnih sučelja"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Nema rezultata."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Nije pronađen nijedan sustav."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Obavijesti"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Podrška za OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Prilikom svakog ponovnog pokretanja, sustavi u bazi podataka biti će ažurirani kako bi odgovarali sustavima definiranim u datoteci."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Otvori menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Ili nastavi sa"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Prebrišite postojeća upozorenja"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Stranica"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Stranice / Postavke"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Lozinka"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Lozinka mora imati najmanje 8 znakova."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Zahtjev za ponovno postavljanje lozinke primljen"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pauza"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pauzirano"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Molimo <0>konfigurirajte SMTP server</0> kako biste osigurali isporuku upozorenja."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Za više detalja provjerite logove."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Provjerite svoje podatke i pokušajte ponovno"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Molimo kreirajte administratorski račun"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Omogućite skočne prozore za ovu stranicu"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Molimo prijavite se ponovno"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Molimo pogledajte <0>dokumentaciju</0> za instrukcije."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Molimo prijavite se u svoj račun"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Precizno iskorištenje u zabilježenom vremenu"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Preferirani jezik"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Javni Ključ"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Pročitaj"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Primljeno"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Resetiraj Lozinku"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Nastavi"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Spremite adresu pomoću tipke enter ili zareza. Ostavite prazno kako biste onemogućili obavijesti e-poštom."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Spremi Postavke"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Pretraži"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Pretraži za sisteme ili postavke..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Pogledajte <0>postavke obavijesti</0> da biste konfigurirali način primanja upozorenja."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Poslano"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Postavlja zadani vremenski raspon za grafikone kada se sustav gleda."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Postavke"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Postavke spremljene"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Prijava"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP postavke"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sortiraj po"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap prostor uzet od strane sistema"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap Iskorištenost"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Sistem"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemi"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Sistemima se može upravljati u <0>config.yml</0> datoteci unutar data direktorija."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tablica"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatura"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperature sistemskih senzora"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Testni <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testna obavijest poslana"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Agent mora biti pokrenut na sistemu da bi se spojio. Kopirajte instalacijske komande za agenta ispod."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Agent mora biti pokrenut na sistemu da bi se spojio. Kopirajte <0>docker-compose.yml</0> za agenta ispod."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Zatim se prijavite u backend i resetirajte lozinku korisničkog računa u tablici korisnika."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Ova radnja se ne može poništiti. Ovo će trajno izbrisati sve trenutne zapise za {name} iz baze podataka."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Protok {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Protok root datotečnog sustava"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Primaoci e-pošte"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Uključi/isključi rešetku"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Uključi/isključi temu"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Pokreće se kada bilo koji senzor prijeđe prag"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Pokreće se kada kombinacija gore/dolje premaši prag"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Pokreće se kada iskorištenost procesora premaši prag"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Pokreće se kada iskorištenost memorije premaši prag"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Pokreće se kada se status sistema promijeni"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Pokreće se kada iskorištenost bilo kojeg diska premaši prag"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Ažurirano odmah. Kliknite na sistem za više informacija."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Vrijeme rada"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Iskorištenost"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Iskorištenost root datotečnog sustava"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Iskorišteno"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Korisnici"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Prikaz"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Vidljiva polja"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Čeka se na više podataka prije prikaza"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Želite li nam pomoći da naše prijevode učinimo još boljim? Posjetite <0>Crowdin</0> za više detalja."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push obavijest"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows naredba"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Piši"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML Config"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML Konfiguracija"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše korisničke postavke su ažurirane."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: hu\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Hungarian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: hu\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 {# nap} other {# nap}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# óra} other {# óra}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 óra"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 hét"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 óra"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 óra"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 nap"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Műveletek"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktív riasztások"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Hozzáadás <0>System</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Új rendszer hozzáadása"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Rendszer hozzáadása"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "URL hozzáadása"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Állítsa be a diagram megjelenítését."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Ügynök"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Riasztások"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Minden rendszer"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Biztosan törölni szeretnéd {name}-t?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Az automatikus másolás biztonságos környezetet igényel."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Átlag"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Konténerek átlagos CPU kihasználtsága"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Az átlag meghaladja a <0>{value}{0}</0> értéket"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPU-k átlagos energiafogyasztása"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Rendszerszintű CPU átlagos kihasználtság"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "{0} átlagos kihasználtsága"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Biztonsági mentések"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Sávszélesség"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "A Beszel támogatja az OpenID Connect-et és számos OAuth2 hitelesítési szolgáltatót."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "A Beszel a <0>Shoutrrr</0>-t használja a népszerű értesítési szolgáltatások integrálására."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Bináris"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Gyorsítótár / Pufferelések"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Mégsem"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Figyelem - potenciális adatvesztés"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Általános alkalmazásbeállítások módosítása."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Diagram beállítások"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Ellenőrizd a {email} címet a visszaállító linkért."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Ellenőrizd a naplót a további részletekért."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Ellenőrizd az értesítési szolgáltatásodat"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Kattints a másoláshoz"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Parancssori utasítások"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfiguráld, hogyan kapod az értesítéseket."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Jelszó megerősítése"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Tovább"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Vágólapra másolva"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Docker compose másolása"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Docker run másolása"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Hoszt másolása"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Linux parancs másolása"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Szöveg másolása"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU használat"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Fiók létrehozása"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Sötét"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Áttekintés"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Alapértelmezett időszak"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Törlés"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Lemez"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Lemez I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Lemezhasználat"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Lemezhasználat a {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU használat"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker memória használat"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker hálózat I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentáció"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-mail értesítések"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "E-mail cím megadása a jelszó visszaállításához"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Adja meg az e-mail címet..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Hiba"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Túllépi a {0}{1} értéket az elmúlt {2, plural, one {# percben} other {# percben}}"
#: 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 "A <0>config.yml</0> fájlban nem definiált meglévő rendszerek törlésre kerülnek. Kérjük, készítsen rendszeres biztonsági mentéseket."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Konfiguráció exportálása"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exportálja a jelenlegi rendszerkonfigurációt."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Hitelesítés sikertelen"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Nem sikerült menteni a beállításokat"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Teszt értesítés elküldése sikertelen"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Nem sikerült frissíteni a riasztást"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Szűrő..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "A <0>{min}</0> {min, plural, one {perc} other {percek}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Elfelejtette a jelszavát?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Általános"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU áramfelvétele"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Rács"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew parancs"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Állomás / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Ha elvesztette az admin fiók jelszavát, a következő paranccsal állíthatja vissza."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Érvénytelen e-mail cím."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Nyelv"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Elrendezés"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Világos"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Kijelentkezés"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Bejelentkezés"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Bejelentkezés sikertelen"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Naplók"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Inkább azt keresi, hogy hol hozhat létre riasztásokat? Kattintson a csengő <0/> ikonokra a rendszerek táblázatában."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "A megjelenítési és értesítési beállítások kezelése."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Maximum 1 perc"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "RAM"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Memóriahasználat"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Docker konténerek memória használata"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Név"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Hálózat"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Docker konténerek hálózati forgalma"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Nyilvános interfészek hálózati forgalma"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Nincs találat."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Nem található rendszer."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Értesítések"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC támogatás"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Minden újraindításkor az adatbázisban lévő rendszerek frissítésre kerülnek, hogy megfeleljenek a fájlban meghatározott rendszereknek."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Menü megnyitása"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Vagy folytasd ezzel"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Felülírja a meglévő riasztásokat"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Oldal"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Oldalak / Beállítások"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Jelszó"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "A jelszónak legalább 8 karakternek kell lennie."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Jelszó-visszaállítási kérelmet kaptunk"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Szüneteltetés"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Szüneteltetve"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Kérjük, <0>konfigurálj egy SMTP szervert</0> az értesítések kézbesítésének biztosítása érdekében."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Kérjük, ellenőrizd a naplókat a további részletekért."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Kérjük, ellenőrizze a hitelesítő adatait, és próbálja újra"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Kérjük, hozzon létre egy admin fiókot"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Kérjük, engedélyezze a felugró ablakokat ezen az oldalon"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Kérjük jelentkezz be újra"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Kérjük, nézze meg <0>a dokumentációt</0> az utasításokért."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Kérjük, jelentkezzen be a fiókjába"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Pontos kihasználás a rögzített időpontban"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Preferált nyelv"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Nyilvános kulcs"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Olvasás"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Fogadott"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Jelszó visszaállítása"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Folytatás"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Mentse el a címet az Enter billentyű vagy a vessző használatával. Hagyja üresen az e-mail értesítések letiltásához."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Beállítások mentése"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Keresés"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Keresés rendszerek vagy beállítások után..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Lásd <0>az értesítési beállításokat</0>, hogy konfigurálja, hogyan kap értesítéseket."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Elküldve"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Beállítja az alapértelmezett időtartamot a diagramokhoz, amikor egy rendszert néznek."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Beállítások"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Beállítások elmentve"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Bejelentkezés"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP beállítások"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Rendezés"
#: src/lib/utils.ts
msgid "Status"
msgstr "Állapot"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Rendszer által használt swap terület"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap használat"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Rendszer"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Rendszer"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "A rendszereket egy <0>config.yml</0> fájlban lehet kezelni az adatkönyvtárban."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tábla"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Hőmérséklet"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "A rendszer érzékelőinek hőmérséklete"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Teszt <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Teszt értesítés elküldve"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "A csatlakozáshoz az ügynöknek futnia kell a rendszerben. Másolja ki az alábbi telepítési parancsot az ügynök telepítéséhez."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "A csatlakozáshoz az ügynöknek futnia kell a rendszerben. Másolja az<0>docker-compose.yml</0> fájlt az ügynök futtatásához."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Ezután jelentkezzen be a backendbe, és állítsa vissza a felhasználói fiók jelszavát a felhasználók táblázatban."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Ezt a műveletet nem lehet visszavonni! Véglegesen törli a {name} összes jelenlegi rekordját az adatbázisból!"
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "A {extraFsName} átviteli teljesítménye"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "A gyökér fájlrendszer átviteli teljesítménye"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "E-mailben"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Rács ki- és bekapcsolása"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Téma váltása"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Bekapcsol, ha bármelyik érzékelő túllép egy küszöbértéket"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Bekapcsol, ha a CPU érzékelő túllép egy küszöbértéket"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Bekapcsol, ha a Ram érzékelő túllép egy küszöbértéket"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Bekapcsol, amikor az állapot fel és le között változik"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Bekapcsol, ha a lemez érzékelő túllép egy küszöbértéket"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Valós időben frissítve. Kattintson egy rendszerre az információk megtekintéséhez."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Üzemidő"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Használat"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Root partíció kihasználtsága"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Felhasznált"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Felhasználók"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Nézet"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Látható mezők"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Elegendő rekordra várva a megjelenítéshez"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Szeretne segíteni nekünk abban, hogy fordításaink még jobbak legyenek? További részletekért nézze meg a <0>Crowdin</0> honlapot."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push értesítések"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows parancs"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Írás"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML konfiguráció"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML konfiguráció"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "A felhasználói beállítások frissítésre kerültek."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: it\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# ora} other {# ore}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ora"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 settimana"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 ore"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 ore"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 giorni"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Azioni"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Avvisi Attivi"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Aggiungi <0>Sistema</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Aggiungi Nuovo Sistema"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Aggiungi sistema"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Aggiungi URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Regola le opzioni di visualizzazione per i grafici."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Amministratore"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agente"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Avvisi"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Tutti i Sistemi"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Sei sicuro di voler eliminare {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "La copia automatica richiede un contesto sicuro."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Media"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Utilizzo medio della CPU dei container"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "La media supera <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Consumo energetico medio delle GPU"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Utilizzo medio della CPU a livello di sistema"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Utilizzo medio di {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Backup"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Larghezza di banda"
#: 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."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel utilizza <0>Shoutrrr</0> per integrarsi con i servizi di notifica popolari."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binario"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffer"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Annulla"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Attenzione - possibile perdita di dati"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Modifica le opzioni generali dell'applicazione."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Opzioni del grafico"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Controlla {email} per un link di reset."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Controlla i log per maggiori dettagli."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Controlla il tuo servizio di notifica"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Clicca per copiare"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Istruzioni da riga di comando"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Configura come ricevere le notifiche di avviso."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Conferma password"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Continua"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Copiato negli appunti"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Copia docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Copia docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Copia host"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Copia comando Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Copia testo"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Utilizzo CPU"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Crea account"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Scuro"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Cruscotto"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Periodo di tempo predefinito"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Elimina"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disco"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "I/O Disco"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Utilizzo Disco"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Utilizzo del disco di {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Utilizzo CPU Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Utilizzo Memoria Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "I/O di Rete Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Documentazione"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Offline"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Modifica"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Notifiche email"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Inserisci l'indirizzo email per reimpostare la password"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Inserisci l'indirizzo email..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Errore"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Esporta configurazione"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Esporta la configurazione attuale dei tuoi sistemi."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Autenticazione fallita"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Salvataggio delle impostazioni fallito"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Invio della notifica di test fallito"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Aggiornamento dell'avviso fallito"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtra..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Per <0>{min}</0> {min, plural, one {minuto} other {minuti}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Password dimenticata?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Generale"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Consumo della GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Griglia"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Comando Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Indirizzo email non valido."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Lingua"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Aspetto"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Chiaro"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Disconnetti"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Accedi"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Tentativo di accesso fallito"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Log"
#: src/components/routes/settings/notifications.tsx
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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Gestisci le preferenze di visualizzazione e notifica."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Istruzioni di configurazione manuale"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Memoria"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Utilizzo Memoria"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Utilizzo della memoria dei container Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Nome"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Rete"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Traffico di rete dei container Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Traffico di rete delle interfacce pubbliche"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Nessun risultato trovato."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Nessun sistema trovato."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Notifiche"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Supporto OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Ad ogni riavvio, i sistemi nel database verranno aggiornati per corrispondere ai sistemi definiti nel file."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Apri menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Oppure continua con"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Sovrascrivi avvisi esistenti"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Pagina"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Pagine / Impostazioni"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Password"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "La password deve contenere almeno 8 caratteri."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "La password deve essere inferiore a 72 byte."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Richiesta di reimpostazione password ricevuta"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pausa"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "In pausa"
#: 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."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Si prega di controllare i log per maggiori dettagli."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Si prega di controllare le credenziali e riprovare"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Si prega di creare un account amministratore"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Si prega di abilitare i pop-up per questo sito"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Si prega di accedere nuovamente"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Si prega di consultare <0>la documentazione</0> per le istruzioni."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Si prega di accedere al proprio account"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Porta"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Utilizzo preciso al momento registrato"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Lingua Preferita"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Chiave Pub"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Lettura"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Ricevuto"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Reimposta Password"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Riprendi"
#: 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."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Salva Impostazioni"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Salva sistema"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Cerca"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Cerca sistemi o impostazioni..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Vedi <0>impostazioni di notifica</0> per configurare come ricevere gli avvisi."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Inviato"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Imposta l'intervallo di tempo predefinito per i grafici quando viene visualizzato un sistema."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Impostazioni"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Impostazioni salvate"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Accedi"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Impostazioni SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Ordina per"
#: src/lib/utils.ts
msgid "Status"
msgstr "Stato"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Spazio di swap utilizzato dal sistema"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Utilizzo Swap"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Sistema"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemi"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "I sistemi possono essere gestiti in un file <0>config.yml</0> all'interno della tua directory dati."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabella"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Temperatura"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatura"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperature dei sensori di sistema"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Notifica di test inviata"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "L'agente deve essere in esecuzione sul sistema per connettersi. Copia il comando di installazione per l'agente qui sotto."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "L'agente deve essere in esecuzione sul sistema per connettersi. Copia il<0>docker-compose.yml</0> per l'agente qui sotto."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Quindi accedi al backend e reimposta la password del tuo account utente nella tabella degli utenti."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Questa azione non può essere annullata. Questo eliminerà permanentemente tutti i record attuali per {name} dal database."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Throughput di {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Throughput del filesystem root"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "A email(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Attiva/disattiva griglia"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Attiva/disattiva tema"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Attiva quando un sensore supera una soglia"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Attiva quando il combinato up/down supera una soglia"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Attiva quando l'utilizzo della CPU supera una soglia"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Attiva quando l'utilizzo della memoria supera una soglia"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Attiva quando lo stato passa tra up e down"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Attiva quando l'utilizzo di un disco supera una soglia"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Attivo"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Aggiornato in tempo reale. Clicca su un sistema per visualizzare le informazioni."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Tempo di attività"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Utilizzo"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Utilizzo della partizione root"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Utilizzato"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Utenti"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Vista"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Colonne visibili"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "In attesa di abbastanza record da visualizzare"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Notifiche Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Comando Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Scrittura"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Configurazione YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Configurazione YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Le impostazioni utente sono state aggiornate."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: ja\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-13 10:13\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 {# 日}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# 時間} other {# 時間}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1時間"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1週間"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12時間"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24時間"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30日間"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "アクション"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "アクティブなアラート"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>システム</0>を追加"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "新しいシステムを追加"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "システムを追加"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "URLを追加"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "チャートの表示オプションを調整します。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "管理者"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "エージェント"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "アラート"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "すべてのシステム"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "{name}を削除してもよろしいですか?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "自動コピーには安全なコンテキストが必要です。"
#: src/components/routes/system.tsx
msgid "Average"
msgstr "平均"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "コンテナの平均CPU使用率"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "平均が<0>{value}{0}</0>を超えています"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPUの平均消費電力"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "システム全体の平均CPU使用率"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "{0}の平均使用率"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "バックアップ"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "帯域幅"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "BeszelはOpenID Connectと多くのOAuth2認証プロバイダーをサポートしています。"
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszelは<0>Shoutrrr</0>を使用して、人気のある通知サービスと統合します。"
#: src/components/add-system.tsx
msgid "Binary"
msgstr "バイナリ"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "キャッシュ / バッファ"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "キャンセル"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "注意 - データ損失の可能性"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "一般的なアプリケーションオプションを変更します。"
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "チャートオプション"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "{email}を確認してリセットリンクを探してください。"
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "詳細についてはログを確認してください。"
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "通知サービスを確認してください"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "クリックしてコピー"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "コマンドラインの指示"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "アラート通知の受信方法を設定します。"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "パスワードを確認"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "続行"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "クリップボードにコピーされました"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "docker compose をコピー"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "docker run をコピー"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "ホストをコピー"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Linuxコマンドをコピー"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "テキストをコピー"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU使用率"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "アカウントを作成"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "ダーク"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "ダッシュボード"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "デフォルトの期間"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "削除"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "ディスク"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "ディスクI/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "ディスク使用率"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "{extraFsName}のディスク使用率"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU使用率"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Dockerメモリ使用率"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "DockerネットワークI/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "ドキュメント"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "停止"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "編集"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "メール"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "メール通知"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "パスワードをリセットするためにメールアドレスを入力してください"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "メールアドレスを入力..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "エラー"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "過去{2, plural, one {# 分} other {# 分}}で{0}{1}を超えています"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "設定をエクスポート"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "現在のシステム設定をエクスポートします。"
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "認証に失敗しました"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "設定の保存に失敗しました"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "テスト通知の送信に失敗しました"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "アラートの更新に失敗しました"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "フィルター..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "<0>{min}</0> {min, plural, one {分} other {分}}の間"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "パスワードをお忘れですか?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "一般"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPUの消費電力"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "グリッド"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew コマンド"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "ホスト / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "管理者アカウントのパスワードを忘れた場合は、次のコマンドを使用してリセットできます。"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "無効なメールアドレスです。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "カーネル"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "言語"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "レイアウト"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "ライト"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "ログアウト"
#: src/components/login/login.tsx
msgid "Login"
msgstr "ログイン"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "ログイン試行に失敗しました"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "アラートを作成する場所を探していますか?システムテーブルのベル<0/>アイコンをクリックしてください。"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "表示と通知の設定を管理します。"
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "手動セットアップの手順"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "最大1分"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "メモリ"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "メモリ使用率"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Dockerコンテナのメモリ使用率"
#: src/components/add-system.tsx
msgid "Name"
msgstr "名前"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "帯域"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Dockerコンテナのネットワークトラフィック"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "パブリックインターフェースのネットワークトラフィック"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "結果が見つかりませんでした。"
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "システムが見つかりませんでした。"
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "通知"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDCサポート"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "再起動のたびに、データベース内のシステムはファイルに定義されたシステムに一致するように更新されます。"
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "メニューを開く"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "または、以下の方法でログイン"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "既存のアラートを上書き"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "ページ"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "ページ / 設定"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "パスワード"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "パスワードは8文字以上である必要があります。"
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "パスワードは72バイト未満でなければなりません。"
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "パスワードリセットのリクエストを受け取りました"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "一時停止"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "一時停止中"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "アラートが配信されるように<0>SMTPサーバーを設定</0>してください。"
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "詳細についてはログを確認してください。"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "資格情報を確認して再試行してください"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "管理者アカウントを作成してください"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "このサイトのポップアップを有効にしてください"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "再度ログインしてください"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "手順については<0>ドキュメント</0>を参照してください。"
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "アカウントにサインインしてください"
#: src/components/add-system.tsx
msgid "Port"
msgstr "ポート"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "記録された時点での正確な利用"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "優先言語"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "公開鍵"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "読み取り"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "受信"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "パスワードをリセット"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "再開"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Enterキーまたはカンマを使用してアドレスを保存します。空白のままにするとメール通知が無効になります。"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "設定を保存"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "システムを保存"
#: src/components/navbar.tsx
msgid "Search"
msgstr "検索"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "システムまたは設定を検索..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "アラートの受信方法を設定するには<0>通知設定</0>を参照してください。"
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "送信"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "システムを表示する際のチャートのデフォルトの時間範囲を設定します。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "設定"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "設定が保存されました"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "サインイン"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP設定"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "並び替え基準"
#: src/lib/utils.ts
msgid "Status"
msgstr "ステータス"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "システムが使用するスワップ領域"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "スワップ使用量"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "システム"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "システム"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "システムはデータディレクトリ内の<0>config.yml</0>ファイルで管理できます。"
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "テーブル"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "温度"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "温度"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "システムセンサーの温度"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "テスト<0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "テスト通知が送信されました"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "接続するにはエージェントがシステム上で実行されている必要があります。以下のエージェントのインストールコマンドをコピーしてください。"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "接続するにはエージェントがシステム上で実行されている必要があります。以下のエージェント用<0>docker-compose.yml</0>をコピーしてください。"
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "その後、バックエンドにログインして、ユーザーテーブルでユーザーアカウントのパスワードをリセットしてください。"
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "この操作は元に戻せません。これにより、データベースから{name}のすべての現在のレコードが永久に削除されます。"
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}のスループット"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "ルートファイルシステムのスループット"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "宛先メールアドレス"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "グリッドを切り替え"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "テーマを切り替え"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "センサーがしきい値を超えたときにトリガーされます"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "上り/下りの合計がしきい値を超えたときにトリガーされます"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "CPU使用率がしきい値を超えたときにトリガーされます"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "メモリ使用率がしきい値を超えたときにトリガーされます"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "ステータスが上から下に切り替わるときにトリガーされます"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "ディスクの使用量がしきい値を超えたときにトリガーされます"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "正常"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "リアルタイムで更新されます。システムをクリックして情報を表示します。"
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "稼働時間"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "使用量"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "ルートパーティションの使用量"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "使用中"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "ユーザー"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "表示"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "表示列"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "表示するのに十分なレコードを待っています"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "翻訳をさらに良くするためにご協力いただけますか?詳細については<0>Crowdin</0>をご覧ください。"
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / プッシュ通知"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows コマンド"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "書き込み"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML設定"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML設定"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "ユーザー設定が更新されました。"

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: ko\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-07 10:06\n"
"Last-Translator: \n"
"Language-Team: Korean\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: ko\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 {# 일}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# 시간} other {# 시간}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1시간"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1주"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12시간"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24시간"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30일"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "작업"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "활성화된 알림들"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>시스템</0> 추가"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "새 시스템 추가"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "시스템 추가"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "URL 추가"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "차트 표시 옵션 변경."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "관리자"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "에이전트"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "알림"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "모든 시스템"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "{name}을(를) 삭제하시겠습니까?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "자동 복사는 안전한 컨텍스트가 필요합니다."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "평균"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "컨테이너의 평균 CPU 사용량"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "평균이 <0>{value}{0}</0>을(를) 초과합니다"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPU들의 평균 전원 사용량"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "시스템 전체의 평균 CPU 사용량"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "평균 {0} 사용량"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "백업"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "대역폭"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel은 OpenID Connect 및 많은 OAuth2 인증 제공자를 지원합니다."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel은 여러 인기 있는 알림 서비스와 연동하기 위해 <0>Shoutrrr</0>을 이용합니다."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "실행 파일"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "캐시 / 버퍼"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "취소"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "주의 - 데이터 손실 가능성"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "일반 애플리케이션 옵션 변경."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "차트 옵션"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "{email}에서 재설정 링크를 확인하세요."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "자세한 내용은 로그를 확인하세요."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "알림 서비스를 확인하세요."
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "클릭하여 복사"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "명령어 사용 지침"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "알림을 수신할 방법을 설정하세요."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "비밀번호 확인"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "계속"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "클립보드에 복사됨"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "docker compose 복사"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "docker run 복사"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "호스트 복사"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "리눅스 명령어 복사"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "텍스트 복사"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU 사용량"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "계정 생성"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "어둡게"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "대시보드"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "기본 기간"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "삭제"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "디스크"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "디스크 I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "디스크 사용량"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "{extraFsName}의 디스크 사용량"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU 사용량"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker 메모리 사용량"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker 네트워크 I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "문서"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "오프라인"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "수정"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "이메일"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "이메일 알림"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "비밀번호를 재설정하려면 이메일 주소를 입력하세요"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "이메일 주소 입력..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "오류"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "마지막 {2, plural, one {# 분} other {# 분}} 동안 {0}{1} 초과"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "구성 내보내기"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "현재 시스템 구성 내보내기"
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "인증 실패"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "설정 저장 실패"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "테스트 알림 전송 실패"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "알림 수정 실패"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "필터..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "<0>{min}</0> {min, plural, one {분} other {분}} 동안"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "비밀번호를 잊으셨나요?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "일반"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU 전원 사용량"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "그리드"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew 명령어"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "호스트 / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "관리자 계정의 비밀번호를 잃어버린 경우, 다음 명령어를 사용하여 재설정할 수 있습니다."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "잘못된 이메일 주소입니다."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "커널"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "언어"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "레이아웃"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "밝게"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "로그아웃"
#: src/components/login/login.tsx
msgid "Login"
msgstr "로그인"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "로그인 실패"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "알림을 생성하려 하시나요? 시스템 테이블의 종 <0/> 아이콘을 클릭하세요."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "디스플레이 및 알림 설정"
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "수동 설정 방법"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "1분간 최댓값"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "메모리"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "메모리 사용량"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Docker 컨테이너의 메모리 사용량"
#: src/components/add-system.tsx
msgid "Name"
msgstr "이름"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "네트워크"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Docker 컨테이너의 네트워크 트래픽"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "공용 인터페이스의 네트워크 트래픽"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "결과가 없습니다."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "시스템을 찾을 수 없습니다."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "알림"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC 지원"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "매 시작 시, 데이터베이스가 파일에 정의된 시스템과 일치하도록 업데이트됩니다."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "메뉴 열기"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "또는 아래 항목으로 진행하기"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "기존 알림 덮어쓰기"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "페이지"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "페이지 / 설정"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "비밀번호"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "비밀번호는 최소 8자 이상이어야 합니다."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "비밀번호는 72 바이트 이하여야 합니다."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "비밀번호 재설정 요청이 접수되었습니다"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "일시 중지"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "일시정지됨"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "알림이 전달되도록 <0>SMTP 서버를 구성</0>하세요."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "자세한 내용은 로그를 확인하세요."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "자격 증명을 확인하고 다시 시도하세요."
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "관리자 계정을 생성하세요."
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "이 사이트에 대해 팝업을 활성화하세요."
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "다시 로그인하세요."
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "사용법은 <0>문서</0>를 참조하세요."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "계정에 로그인하세요."
#: src/components/add-system.tsx
msgid "Port"
msgstr "포트"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "기록된 시간의 정확한 사용량"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "선호 언어"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "공개 키"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "읽기"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "수신됨"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "비밀번호 재설정"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "재개"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Enter 키 또는 쉼표를 사용하여 주소를 저장하세요. 이메일 알림을 비활성화하려면 비워 두세요."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "설정 저장"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "시스템 저장"
#: src/components/navbar.tsx
msgid "Search"
msgstr "검색"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "시스템 또는 설정 검색..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "알림을 받는 방법을 구성하려면 <0>알림 설정</0>을 참조하세요."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "보냄"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "시스템을 볼 때 차트의 기본 시간 범위를 설정합니다."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "설정"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "설정이 저장되었습니다."
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "로그인"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP 설정"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "정렬 기준"
#: src/lib/utils.ts
msgid "Status"
msgstr "상태"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "시스템에서 사용된 스왑 공간"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "스왑 사용량"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "시스템"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "시스템"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "시스템은 데이터 디렉토리 내의 <0>config.yml</0> 파일에서 관리할 수 있습니다."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "표"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "온도"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "온도"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "시스템 센서의 온도"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "테스트 <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "테스트 알림이 전송되었습니다."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "에이전트가 시스템에서 실행 중이어야 연결할 수 있습니다. 아래의 에이전트 설치 명령을 복사하세요."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "에이전트가 시스템에서 실행 중이어야 연결할 수 있습니다. 아래의 <0>docker-compose.yml</0>을 복사하세요."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "그런 다음 백엔드에 로그인하여 사용자 테이블에서 사용자 계정 비밀번호를 재설정하세요."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "이 작업은 되돌릴 수 없습니다. 데이터베이스에서 {name}에 대한 모든 현재 기록이 영구적으로 삭제됩니다."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}의 처리량"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "루트 파일 시스템의 처리량"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "받는사람(들)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "그리드 전환"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "테마 전환"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "센서가 임계값을 초과할 때 트리거됩니다."
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "업로드와 다운로드 대역폭의 합이 임계값을 초과할 때 트리거됩니다."
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "CPU 사용량이 임계값을 초과할 때 트리거됩니다."
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "메모리 사용량이 임계값을 초과할 때 트리거됩니다."
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "시스템의 전원이 켜지거나 꺼질때 트리거됩니다."
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "디스크 사용량이 임계값을 초과할 때 트리거됩니다."
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "온라인"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "실시간으로 업데이트됩니다. 시스템을 클릭하여 정보를 확인하세요."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "가동 시간"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "사용량"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "루트 파티션의 사용량"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "사용됨"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "사용자"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "보기"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "표시할 열"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "표시할 충분한 기록을 기다리는 중"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "번역을 더 좋게 만드는 데 도움을 주시겠습니까? 자세한 내용은 <0>Crowdin</0>을 확인하세요."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / 푸시 알림"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows 명령어"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "쓰기"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML 구성"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML 구성"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "사용자 설정이 업데이트되었습니다."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: nl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# uur} other {# uren}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 uur"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 week"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 uren"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 uren"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dagen"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Acties"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Actieve waarschuwingen"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Voeg <0>Systeem</0> toe"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Nieuw systeem toevoegen"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Voeg systeem toe"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Voeg URL toe"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Weergaveopties voor grafieken aanpassen."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Waarschuwingen"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Alle systemen"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Weet je zeker dat je {name} wilt verwijderen?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatisch kopiëren vereist een veilige context."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Gemiddelde"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Gemiddeld CPU-gebruik van containers"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Gemiddelde overschrijdt <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Gemiddeld stroomverbruik van GPU's"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Gemiddeld systeembrede CPU-gebruik"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Gemiddeld gebruik van {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Back-ups"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Bandbreedte"
#: 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."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel gebruikt <0>Shoutrr</0> om te integreren met populaire meldingsdiensten."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binair"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffers"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Annuleren"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Opgelet - potentieel gegevensverlies"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Wijzig algemene applicatie opties."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Grafiekopties"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Controleer {email} op een reset link."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Controleer de logs voor meer details."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Controleer je meldingsservice"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Klik om te kopiëren"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instructies voor de opdrachtregel"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Configureer hoe je waarschuwingsmeldingen ontvangt."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Bevestig wachtwoord"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Volgende"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Gekopieerd naar het klembord"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Docker compose kopiëren"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Docker run kopiëren"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopieer host"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopieer Linux-opdracht"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopieer tekst"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Processorgebruik"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Account aanmaken"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Donker"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Dashboard"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Standaard tijdsduur"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Verwijderen"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Schijf"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Schijf I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Schijfgebruik"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Schijfgebruik van {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU-gebruik"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker geheugengebruik"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker netwerk I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Documentatie"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Offline"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Bewerken"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-mail"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-mailnotificaties"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Voer een e-mailadres in om het wachtwoord opnieuw in te stellen"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Voer een e-mailadres in..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Fout"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Configuratie exporteren"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exporteer je huidige systeemconfiguratie."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Authenticatie mislukt"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Instellingen opslaan mislukt"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Versturen test notificatie mislukt"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Bijwerken waarschuwing mislukt"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filter..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Voor <0>{min}</0> {min, plural, one {minuut} other {minuten}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Wachtwoord vergeten?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Algemeen"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU stroomverbruik"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Raster"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew-commando"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP-adres"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ongeldig e-mailadres."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Taal"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Indeling"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Licht"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Afmelden"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Aanmelden"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Aanmelding mislukt"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logs"
#: 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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Weergave- en notificatievoorkeuren beheren."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
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"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Geheugen"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Geheugengebruik"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Geheugengebruik van docker containers"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Naam"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Net"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Netwerkverkeer van docker containers"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Netwerkverkeer van publieke interfaces"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Geen resultaten gevonden."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Geen systemen gevonden."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Meldingen"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC ondersteuning"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Bij elke herstart zullen systemen in de database worden bijgewerkt om overeen te komen met de systemen die in het bestand zijn gedefinieerd."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Open menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Of ga verder met"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Overschrijf bestaande waarschuwingen"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Pagina"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Pagina's / Instellingen"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Wachtwoord"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Het wachtwoord moet minimaal 8 tekens bevatten."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Het wachtwoord moet minder zijn dat 72 bytes."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Wachtwoord reset aanvraag ontvangen"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pauze"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Gepauzeerd"
#: 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."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Controleer de logs voor meer details."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Controleer je aanmeldgegevens en probeer het opnieuw"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Maak een beheerdersaccount aan"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Activeer pop-ups voor deze website"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Meld je opnieuw aan"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Bekijk <0>de documentatie</0> voor instructies."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Meld je aan bij je account"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Poort"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Nauwkeurig gebruik op de opgenomen tijd"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Voorkeurstaal"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Publieke sleutel"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Lezen"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Ontvangen"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Wachtwoord resetten"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Hervatten"
#: 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."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Instellingen opslaan"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Systeem bewaren"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Zoeken"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Zoek naar systemen of instellingen..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Zie <0>notificatie-instellingen</0> om te configureren hoe je meldingen ontvangt."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Verzonden"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Stelt het standaard tijdsbereik voor grafieken in wanneer een systeem wordt bekeken."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Instellingen"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Instellingen opgeslagen"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Aanmelden"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP-instellingen"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sorteren op"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap ruimte gebruikt door het systeem"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap gebruik"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Systeem"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systemen"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Systemen kunnen worden beheerd in een <0>config.yml</0> bestand in je data map."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabel"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Temperatuur"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatuur"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperatuur van systeem sensoren"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testmelding verzonden"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "De agent moet op het systeem draaien om te verbinden. Kopieer het installatiecommando voor de agent hieronder."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "De agent moet op het systeem draaien om te verbinden. Kopieer de<0>docker-compose.yml</0> voor de agent hieronder."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Log vervolgens in op de backend en reset het wachtwoord van je gebruikersaccount in het gebruikersoverzicht."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Deze actie kan niet ongedaan worden gemaakt. Dit zal alle huidige records voor {name} permanent verwijderen uit de database."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Doorvoer van {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Doorvoer van het root bestandssysteem"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Naar e-mail(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Schakel raster"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Schakel thema"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Triggert wanneer een sensor een drempelwaarde overschrijdt"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Triggert wanneer de gecombineerde up/down een drempelwaarde overschrijdt"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Triggert wanneer het CPU-gebruik een drempelwaarde overschrijdt"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Triggert wanneer het geheugengebruik een drempelwaarde overschrijdt"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Triggert wanneer de status schakelt tussen up en down"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Triggert wanneer het gebruik van een schijf een drempelwaarde overschrijdt"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Online"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "In realtime bijgewerkt. Klik op een systeem om informatie te bekijken."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Actief"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Gebruik"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Gebruik van root-partitie"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Gebruikt"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Gebruikers"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Weergave"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Zichtbare kolommen"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Wachtend op genoeg records om weer te geven"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Pushmeldingen"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows-commando"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Schrijven"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML Configuratie"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML Configuratie"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Je gebruikersinstellingen zijn bijgewerkt."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: no\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Norwegian\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: no\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 {# dager}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# time} other {# timer}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 time"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 uke"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 timer"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 timer"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dager"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Handlinger"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktive Alarmer"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Legg til <0>System</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Legg Til Nytt System"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Legg til system"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Legg Til URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Juster visningsalternativer for diagrammer."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Alarmer"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Alle Systemer"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Er du sikker på at du vil slette {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatisk kopiering krever en sikker kontekst."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Gjennomsnitt"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Gjennomsnittlig CPU-utnyttelse av konteinere"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Gjennomsnittet overstiger <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Gjennomsnittlig strømforbruk for GPU-er"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Gjennomsnittlig CPU-utnyttelse for hele systemet"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Gjennomsnittlig utnyttelse av {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Sikkerhetskopier"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Båndbredde"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel støtter OpenID Connect og mange OAuth2 autentiserings-tilbydere."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel bruker <0>Shoutrrr</0> for integrering mot populære meldingstjenester."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binær"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffere"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Avbryt"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Advarsel - potensielt tap av data"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Endre generelle program-innstillinger."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Diagraminnstillinger"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Sjekk {email} for en nullstillings-link."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Sjekk loggene for flere detaljer."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Sjekk din meldingstjeneste"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Klikk for å kopiere"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Kommandolinje-instrukser"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfigurer hvordan du vil motta alarmvarsler."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Bekreft passord"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Fortsett"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Kopiert til utklippstavlen"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Kopier docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Kopier docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopier vert"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopier Linux-kommando"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopier tekst"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU-bruk"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Opprett konto"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Mørkt"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Dashbord"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Standard tidsperiode"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Slett"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Diskbruk"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Diskbruk av {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU-bruk"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker Minnebruk"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker Nettverks-I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentasjon"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Nede"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Rediger"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-post"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-postvarslinger"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Skriv inn e-postadresse for å nullstille passordet"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Skriv inn e-postadresse..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Feil"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Overstiger {0}{1} {2, plural, one {det siste minuttet} other {de siste # minuttene}}"
#: 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 "Eksisterende systemer som ikke er er definert i <0>config.yml</0> vil bli slettet. Vennligst ta jevnlige sikkerhetskopier."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Eksporter konfigurasjon"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Eksporter din nåværende systemkonfigurasjon"
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Autentisering mislyktes"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Kunne ikke lagre innstillingene"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Kunne ikke sende test-varsling"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Kunne ikke oppdatere alarm"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filter..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "I <0>{min}</0> {min, plural, one {minutt} other {minutter}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Glemt passord?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Generelt"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU Effektforbruk"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Rutenett"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew-kommando"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Vert / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Dersom du har mistet passordet til admin-kontoen kan du nullstille det med følgende kommando."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ugyldig e-postadresse."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kjerne"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Språk"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Layout"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Lyst"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Logg Ut"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Logg Inn"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Innlogging mislyktes"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logger"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Ser du etter hvor du kan opprette alarmer? Klikk på bjelle-ikonene <0/> i systemtabellen."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Endre visnings- og varslingsinnstillinger."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Instruks for Manuell Installasjon"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Maks 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Minne"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Minnebruk"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Minnebruk av docker-konteinere"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Navn"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Nett"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Nettverkstrafikk av docker-konteinere"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Nettverkstrafikk av eksterne nettverksgrensesnitt"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Ingen resultater funnet."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Ingen systemer funnet."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Varslinger"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC-støtte"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Ved hver omstart vil systemer i databasen bli oppdatert til å matche systemene definert i fila."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Åpne meny"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Eller fortsett med"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Overskriv eksisterende alarmer"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Side"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Sider / Innstillinger"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Passord"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Passord må bestå av minst 8 tegn."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Passord må være mindre enn 72 byte."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Mottatt forespørsel om å nullstille passord"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pause"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pauset"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Vennligst <0>konfigurer en SMTP-server</0> for å forsikre deg om at varsler blir levert."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Vennligst sjekk loggene for mer informasjon."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Vennligst kontroller dine innloggingsopplysninger og prøv igjen"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Vennligst opprett en admin-konto"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Vennligst aktiver pop-ups for nettsiden"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Vennligst logg inn på nytt"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Vennligst se <0>dokumentasjonen</0> for instrukser."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Vennligst logg inn på kontoen din"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Nøyaktig utnyttelse på registrert tidspunkt"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Foretrukket Språk"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Offentlig Nøkkel"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Lesing"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Mottatt"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Nullstill Passord"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Gjenoppta"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Lagre adressen med Enter-tasten eller komma. La feltet være tomt for å deaktivere e-postvarsler."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Lagre Innstillinger"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Lagre system"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Søk"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Søk etter systemer eller innstillinger..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Se <0>varslingsinnstillingene</0> for å konfigurere hvordan du vil motta varsler."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Sendt"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Angir standard tidsperiode for diagrammer når et system vises."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Innstillinger"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Innstillinger lagret"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Logg inn"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP-innstillinger"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sorter Etter"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap-plass i bruk av systemet"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap-bruk"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "System"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systemer"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Systemer kan håndteres i en <0>config.yml</0>-fil i din data-katalog."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabell"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Temp"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatur"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperaturer på system-sensorer"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Test-varsling sendt"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Agenten må kjøre på systemet du vil koble til. Kopier installasjons-kommandoen for agenten under."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Agenten må kjøre på systemet du vil koble til. Kopier <0>docker-compose.yml</0> for agenten under."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Logg deretter inn i backend og nullstill passordet på din konto i users-tabellen."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Denne handlingen kan ikke omgjøres. Dette vil slette alle poster for {name} permanent fra databasen."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Gjennomstrømning av {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Gjennomstrømning av rot-filsystemet"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Til e-postadresse(r)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Rutenett av/på"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Tema av/på"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Slår inn når enhver sensor overstiger en grenseverdi"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Slår inn når kombinert opp/ned overskrider en grenseverdi"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Slår inn når CPU-bruken overstiger en grenseverdi"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Slår inn når minnebruken overstiger en grenseverdi"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Slår inn når statusen veksler mellom oppe og nede"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Slår inn når forbruk av hvilken som helst disk overstiger en grenseverdi"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Oppe"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Oppdatert i sanntid. Klikk på et system for å se mer informasjon."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Oppetid"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Forbruk"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Forbruk av rot-partisjon"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Brukt"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Brukere"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Visning"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Synlige Felter"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Venter på nok registreringer til å vise"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Vil du hjelpe oss med å gjøre oversettelsene enda bedre? Ta en titt på <0>Crowdin</0> for mer informasjon."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push-varslinger"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows-kommando"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Skriving"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML Oppsett"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML Konfigurasjon"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Dine brukerinnstillinger har blitt oppdatert."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: pl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: pl\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 {# dzień} few {# dni} many {# dni} other {# dni}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {godzinę} few {# godziny} many {# godzin} other {# godziny}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 godzina"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 tydzień"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 godzin"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 godziny"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dni"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Akcje"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktywne alerty"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Dodaj <0>system</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Dodaj nowy system"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Dodaj system"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Dodaj URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Dostosuj opcje wyświetlania wykresów."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Alerty"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Wszystkie systemy"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Czy na pewno chcesz usunąć {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatyczne kopiowanie wymaga bezpiecznego kontekstu."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Średnia"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Średnie wykorzystanie procesora przez kontenery"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Średnia przekracza <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Średnie zużycie energii przez GPU"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Średnie wykorzystanie procesora w całym systemie"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Średnie użycie {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Kopie"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Przepustowość"
#: 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."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel używa <0>Shoutrrr</0> do integracji z popularnych serwisami powiadomień."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Plik binarny"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Pamięć podręczna / Bufory"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Anuluj"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Uwaga- potencjalna utrata danych."
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Zmiana ogólnych ustawień aplikacji."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Opcje wykresu"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Sprawdź {email}, aby uzyskać link do resetowania."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Sprawdź logi, aby uzyskać więcej informacji."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Sprawdź swój serwis powiadomień"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Kliknij, aby skopiować"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instrukcje wiersza poleceń"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Skonfiguruj sposób otrzymywania powiadomień."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Potwierdź hasło"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Kontynuuj"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Skopiowano do schowka"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Skopiuj docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Skopiuj docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopiuj host"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopiuj polecenie Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopiuj tekst"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "Procesor"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Użycie procesora"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Utwórz konto"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Ciemny"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Panel kontrolny"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Domyślny przedział czasu"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Usuń"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Dysk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Dysk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Użycie dysku"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Wykorzystanie dysku {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Wykorzystanie procesora przez Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Wykorzystanie pamięci przez Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Sieć Docker I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentacja"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-mail"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Powiadomienia e-mail"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Wprowadź adres e-mail, aby zresetować hasło"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Wprowadź adres e-mail..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Błąd"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Eksportuj konfigurację"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Eksportuj aktualną konfigurację systemów."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Błąd autoryzacji"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Nie udało się zapisać ustawień"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Nie udało się wysłać testowego powiadomienia"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Nie udało się zaktualizować powiadomienia"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtruj..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Na <0>{min}</0> {min, plural, one {minutę} other {minut}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Zapomniałeś hasła?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Ogólne"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Moc GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Siatka"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Polecenie Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / adres IP"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Nieprawidłowy adres e-mail."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Jądro"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Język"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Układ"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Jasny"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Wyloguj"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Logowanie"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Próba logowania nie powiodła się"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logi"
#: src/components/routes/settings/notifications.tsx
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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Zarządzaj preferencjami wyświetlania i powiadomień."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Maks. 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Pamięć"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Wykorzystanie pamięci"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Użycie pamięci przez kontenery Docker."
#: src/components/add-system.tsx
msgid "Name"
msgstr "Nazwa"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Sieć"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Ruch sieciowy kontenerów Docker."
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Ruch sieciowy interfejsów publicznych"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Brak wyników."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Nie znaleziono systemów."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Powiadomienia"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Wsparcie OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Przy każdym ponownym uruchomieniu systemy w bazie danych będą aktualizowane, aby odpowiadały systemom zdefiniowanym w pliku."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Otwórz menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Lub kontynuuj z"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Nadpisz istniejące alerty"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Strona"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Strony / Ustawienia"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Hasło"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Hasło musi mieć co najmniej 8 znaków."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Otrzymane żądanie resetowania hasła"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pauza"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Wstrzymane"
#: 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ń."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Sprawdź logi, aby uzyskać więcej informacji."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Sprawdź swoje poświadczenia i spróbuj ponownie"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Utwórz konto administratora"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Włącz wyskakujące okna dla tej strony"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Zaloguj się ponownie"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Proszę zapoznać się z <0>dokumentacją</0>."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Zaloguj się na swoje konto"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Dokładne wykorzystanie w zarejestrowanym czasie"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Preferowany język"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Klucz publiczny"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Czytaj"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Otrzymane"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Resetuj hasło"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Wznów"
#: 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."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Zapisz ustawienia"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Szukaj"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Szukaj systemów lub ustawień..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Zobacz <0>ustawienia powiadomień</0>, aby skonfigurować sposób, w jaki otrzymujesz powiadomienia."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Wysłane"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Ustawia domyślny zakres czasowy dla wykresów, gdy system jest wyświetlony."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Ustawienia"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Ustawienia zapisane"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Zaloguj się"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Ustawienia SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sortuj według"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Pamięć wymiany używana przez system"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Użycie pamięci wymiany"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "System"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Systemy"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Systemy mogą być zarządzane w pliku <0>config.yml</0> znajdującym się w Twoim katalogu danych."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabela"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatura"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperatury czujników systemowych."
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testowe powiadomienie wysłane."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Agent musi być uruchomiony na systemie, aby nawiązać połączenie. Skopiuj poniżej polecenie instalacji agenta."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Agent musi być uruchomiony na systemie, aby nawiązać połączenie. Skopiuj poniżej plik <0>docker-compose.yml</0> dla agenta."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Następnie zaloguj się do panelu administracyjnego i zresetuj hasło do konta użytkownika w tabeli użytkowników."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Tej akcji nie można cofnąć. Spowoduje to trwałe usunięcie wszystkich bieżących rekordów dla {name} z bazy danych."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Przepustowość {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Przepustowość głównego systemu plików"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Do e-mail(ów)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Przełącz siatkę"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Zmień motyw"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Wyzwalane, gdy jakikolwiek czujnik przekroczy ustalony próg."
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Wyzwalane, gdy łączna wartość w górę/w dół przekroczy próg"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Wyzwalane, gdy użycie procesora przekracza próg"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Wyzwalane, wykorzystanie pamięci przekroczy ustalony próg."
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Wyzwalane, gdy status przełącza się między stanem aktywnym a nieaktywnym"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Wyzwalane, gdy wykorzystanie któregokolwiek dysku przekroczy ustalony próg"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Aktualizowane w czasie rzeczywistym. Kliknij system, aby zobaczyć informacje."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Czas pracy"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Wykorzystanie"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Użycie partycji głównej"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Używane"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Użytkownicy"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Widok"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Widoczne kolumny"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Oczekiwanie na wystarczającą liczbę rekordów do wyświetlenia"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Powiadomienia push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Polecenie Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Napisz"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Konf. YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Konfiguracja YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Twoje ustawienia użytkownika zostały zaktualizowane."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: pt\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\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}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# hora} other {# horas}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 hora"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 semana"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 horas"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 horas"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dias"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Ações"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Alertas Ativos"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Adicionar <0>Sistema</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Adicionar Novo Sistema"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Adicionar sistema"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Adicionar URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Ajustar opções de exibição para gráficos."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agente"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Alertas"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Todos os Sistemas"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Tem certeza de que deseja excluir {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "A cópia automática requer um contexto seguro."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Média"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Utilização média de CPU dos contêineres"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "A média excede <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Consumo médio de energia pelas GPU's"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Utilização média de CPU em todo o sistema"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Utilização média de {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Backups"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Largura de Banda"
#: 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."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel usa <0>Shoutrrr</0> para integrar com serviços de notificação populares."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binário"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffers"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Cancelar"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Cuidado - possível perda de dados"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Alterar opções gerais do aplicativo."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Opções de gráfico"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Verifique {email} para um link de redefinição."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Verifique os logs para mais detalhes."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Verifique seu serviço de notificação"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Clique para copiar"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instruções de linha de comando"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Configure como você recebe notificações de alerta."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Confirmar senha"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Continuar"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Copiado para a área de transferência"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Copiar docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Copiar docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Copiar host"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Copiar comando Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Copiar texto"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Uso de CPU"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Criar conta"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Escuro"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Painel"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Período de tempo padrão"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Excluir"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disco"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "E/S de Disco"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Uso de Disco"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Uso de disco de {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Uso de CPU do Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Uso de Memória do Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "E/S de Rede do Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Documentação"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Editar"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Notificações por email"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Digite o endereço de email para redefinir a senha"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Digite o endereço de email..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Erro"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.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/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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Exportar configuração"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exporte a configuração atual dos seus sistemas."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Falha na autenticação"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Falha ao guardar as definições"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Falha ao enviar notificação de teste"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Falha ao atualizar alerta"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtrar..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Por <0>{min}</0> {min, plural, one {minuto} other {minutos}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Esqueceu a senha?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Geral"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Consumo de Energia da GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Grade"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Comando Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
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/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Endereço de email inválido."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Idioma"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Aspeto"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Claro"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Sair"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Entrar"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Tentativa de login falhou"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Logs"
#: src/components/routes/settings/notifications.tsx
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/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Gerenciar preferências de exibição e notificação."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Máx 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Memória"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Uso de Memória"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Uso de memória dos contêineres Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Nome"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Rede"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Tráfego de rede dos contêineres Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Tráfego de rede das interfaces públicas"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Nenhum resultado encontrado."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Nenhum sistema encontrado."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Notificações"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Suporte a OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "A cada reinício, os sistemas no banco de dados serão atualizados para corresponder aos sistemas definidos no arquivo."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Abrir menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Ou continue com"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Sobrescrever alertas existentes"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Página"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Páginas / Configurações"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Senha"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "A senha deve ter pelo menos 8 caracteres."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "A password tem que ter menos de 72 bytes."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Solicitação de redefinição de senha recebida"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Pausar"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pausado"
#: 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."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Por favor, verifique os logs para mais detalhes."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Por favor, verifique suas credenciais e tente novamente"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Por favor, crie uma conta de administrador"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Por favor, habilite pop-ups para este site"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Por favor, faça login novamente"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Por favor, veja <0>a documentação</0> para instruções."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Por favor, entre na sua conta"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Porta"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Utilização precisa no momento registrado"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Idioma Preferido"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Chave Pública"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Ler"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Recebido"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Redefinir Senha"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Retomar"
#: 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."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Guardar Definições"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Guardar Sistema"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Pesquisar"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Pesquisar por sistemas ou configurações..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Veja <0>configurações de notificação</0> para configurar como você recebe alertas."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Enviado"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Define o intervalo de tempo padrão para gráficos quando um sistema é visualizado."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Configurações"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Definições guardadas"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Entrar"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Configurações SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Ordenar Por"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Espaço de swap usado pelo sistema"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Uso de Swap"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Sistema"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemas"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Os sistemas podem ser gerenciados em um arquivo <0>config.yml</0> dentro do seu diretório de dados."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabela"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Temp"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatura"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperaturas dos sensores do sistema"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Testar <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Notificação de teste enviada"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "O agente deve estar em execução no sistema para conectar. Copie o comando de instalação para o agente abaixo."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "O agente deve estar em execução no sistema para conectar. Copie o <0>docker-compose.yml</0> para o agente abaixo."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Em seguida, faça login no backend e redefina a senha da sua conta de usuário na tabela de usuários."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Esta ação não pode ser desfeita. Isso excluirá permanentemente todos os registros atuais de {name} do banco de dados."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Taxa de transferência de {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Taxa de transferência do sistema de arquivos raiz"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Para email(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Alternar grade"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Alternar tema"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Dispara quando qualquer sensor excede um limite"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Dispara quando a soma de subida/descida excede um limite"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Dispara quando o uso de CPU excede um limite"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Dispara quando o uso de memória excede um limite"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Dispara quando o status alterna entre ativo e inativo"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Dispara quando o uso de qualquer disco excede um limite"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Atualizado em tempo real. Clique em um sistema para ver informações."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Tempo de Atividade"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Uso"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Uso da partição raiz"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Usado"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Usuários"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Visual"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Campos Visíveis"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Aguardando registros suficientes para exibir"
#: src/components/routes/settings/general.tsx
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/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Notificações Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Comando Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Escrever"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Configuração YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Configuração YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "As configurações do seu usuário foram atualizadas."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: ru\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Russian\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: ru\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 {# дней}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# час} other {# часов}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 час"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 неделя"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 часов"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 часа"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 дней"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Действия"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Активные оповещения"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Добавить <0>Систему</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Добавить новую систему"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Добавить систему"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Добавить URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Настроить параметры отображения для графиков."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Администратор"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Агент"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Оповещения"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Все системы"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Вы уверены, что хотите удалить {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Автоматическое копирование требует безопасного контекста."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Среднее"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Среднее использование CPU контейнерами"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Среднее превышает <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Среднее потребление мощности всеми GPU"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Среднее использование CPU по всей системе"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Среднее использование {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Резервные копии"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Пропускная способность"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel поддерживает OpenID Connect и множество поставщиков аутентификации OAuth2."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel использует <0>Shoutrrr</0> для интеграции с популярными сервисами уведомлений."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Двоичный"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Кэш / Буферы"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Отмена"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Внимание - возможная потеря данных"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Изменить общие параметры приложения."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Параметры графиков"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Проверьте {email} для получения ссылки на сброс."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Проверьте журналы для получения более подробной информации."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Проверьте ваш сервис уведомлений"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Нажмите, чтобы скопировать"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Инструкции командной строки"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Настройте, как вы получаете уведомления об оповещениях."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Подтвердите пароль"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Продолжить"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Скопировано в буфер обмена"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Скопировать docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Скопировать docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Копировать хост"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Копировать команду Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Копировать текст"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Использование CPU"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Создать аккаунт"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Темная"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Панель управления"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Период по умолчанию"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Удалить"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Диск"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Дисковый ввод/вывод"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Использование диска"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Использование диска {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Использование CPU Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Использование памяти Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Сетевой ввод/вывод Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Документация"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Не в сети"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Редактировать"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Электронная почта"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Уведомления по электронной почте"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Введите адрес электронной почты для сброса пароля"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Введите адрес электронной почты..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Ошибка"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Превышает {0}{1} за последние {2, plural, one {# минуту} other {# минут}}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Экспорт конфигурации"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Экспортируйте текущую конфигурацию систем."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Не удалось аутентифицировать"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Не удалось сохранить настройки"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Не удалось отправить тестовое уведомление"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Не удалось обновить оповещение"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Фильтр..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "На <0>{min}</0> {min, plural, one {минуту} other {минут}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Забыли пароль?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Общие"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Потребляемая мощность GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Сетка"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Команда Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Хост / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Если вы потеряли пароль от своей учетной записи администратора, вы можете сбросить его, используя следующую команду."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Неверный адрес электронной почты."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Ядро"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Язык"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Макет"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Светлая"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Выйти"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Вход"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Попытка входа не удалась"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "Ищете, где создать оповещения? Нажмите на значки колокольчика <0/> в таблице систем."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Управляйте предпочтениями отображения и уведомлений."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Инструкции по ручной настройке"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Макс 1 мин"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Память"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Использование памяти"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Использование памяти контейнерами Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Имя"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Сеть"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Сетевой трафик контейнеров Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Сетевой трафик публичных интерфейсов"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Результаты не найдены."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Системы не найдены."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Уведомления"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Поддержка OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "При каждом перезапуске системы в базе данных будут обновлены в соответствии с системами, определенными в файле."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Открыть меню"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Или продолжить с"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Перезаписать существующие оповещения"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Страница"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Страницы / Настройки"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Пароль"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Пароль должен содержать не менее 8 символов."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Пароль должен быть меньше 72 символов."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Запрос на сброс пароля получен"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Пауза"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Приостановлено"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Пожалуйста, <0>настройте SMTP-сервер</0>, чтобы гарантировать доставку оповещений."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Пожалуйста, проверьте журналы для получения более подробной информации."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Пожалуйста, проверьте свои учетные данные и попробуйте снова"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Пожалуйста, создайте учетную запись администратора"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Пожалуйста, включите всплывающие окна для этого сайта"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Пожалуйста, войдите снова"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Пожалуйста, смотрите <0>документацию</0> для получения инструкций."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Пожалуйста, войдите в свою учетную запись"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Порт"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Точное использование в записанное время"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Предпочтительный язык"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Ключ"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Чтение"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Получено"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Сбросить пароль"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Возобновить"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Сохраните адрес, используя клавишу ввода или запятую. Оставьте пустым, чтобы отключить уведомления по электронной почте."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Сохранить настройки"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Сохранить систему"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Поиск"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Поиск систем или настроек..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Смотрите <0>настройки уведомлений</0>, чтобы настроить, как вы получаете оповещения."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Отправлено"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Устанавливает диапазон времени по умолчанию для графиков при просмотре системы."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Настройки"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Настройки сохранены"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Войти"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Настройки SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Сортировать по"
#: src/lib/utils.ts
msgid "Status"
msgstr "Статус"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Используемое системой пространство подкачки"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Использование подкачки"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Система"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Системы"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Системы могут управляться в файле <0>config.yml</0> внутри вашего каталога данных."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Таблица"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Темп"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Температура"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Температуры датчиков системы"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Тест <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Тестовое уведомление отправлено"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Агент должен работать на системе для подключения. Скопируйте команду установки агента ниже."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Агент должен работать на системе для подключения. Скопируйте <0>docker-compose.yml</0> для агента ниже."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Затем войдите в бэкенд и сбросьте пароль вашей учетной записи в таблице пользователей."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Это действие не может быть отменено. Это навсегда удалит все текущие записи для {name} из базы данных."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Пропускная способность {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Пропускная способность корневой файловой системы"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "На электронную почту"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Переключить сетку"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Переключить тему"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Срабатывает, когда любой датчик превышает порог"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Срабатывает, когда комбинированный вход/выход превышает порог"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Срабатывает, когда использование CPU превышает порог"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Срабатывает, когда использование памяти превышает порог"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Срабатывает, когда статус переключается между включено и выключено"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Срабатывает, когда использование любого диска превышает порог"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "В сети"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Обновляется в реальном времени. Нажмите на систему, чтобы просмотреть информацию."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Время работы"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Использование"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Использование корневого раздела"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Использовано"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Пользователи"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Вид"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Видимые столбцы"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Ожидание достаточного количества записей для отображения"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Хотите помочь нам улучшить наши переводы? Посетите <0>Crowdin</0> для получения более подробной информации."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push уведомления"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Команда Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Запись"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML конфигурация"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML конфигурация"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Ваши настройки пользователя были обновлены."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: sl\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Slovenian\n"
"Plural-Forms: nplurals=4; plural=n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: sl\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 {# dan} two {# dneva} few {# dni} other {# dni}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# ura} two {# uri} few {# ur} other {# ur}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 ura"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 teden"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 ur"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 ur"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dni"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Dejanja"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktivna opozorila"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Dodaj <0>sistem</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Dodaj nov sistem"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Dodaj sistem"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Dodaj URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Prilagodi možnosti prikaza za grafikone."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Administrator"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Opozorila"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Vsi sistemi"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Ali ste prepričani, da želite izbrisati {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Za samodejno kopiranje je potreben varen kontekst."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Povprečno"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Povprečna izkoriščenost procesorja kontejnerjev"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Povprečje presega <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Povprečna poraba energije GPU"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Povprečna CPU izkoriščenost v celotnem sistemu"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Povprečna poraba {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Varnostne kopije"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Pasovna širina"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel podpira OpenID Connect in številne ponudnike preverjanja pristnosti OAuth2."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel uporablja <0>Shoutrrr</0> za integracijo s priljubljenimi storitvami obveščanja."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binarno"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Predpomnilnik / medpomnilniki"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Prekliči"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Pozor - možna izguba podatkov"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Spremeni splošne možnosti aplikacije."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Možnosti grafikona"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Preverite {email} za povezavo za ponastavitev."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Za več podrobnosti preverite dnevnike."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Preverite storitev obveščanja"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Klikni za kopiranje"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Navodila za ukazno vrstico"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Nastavi način prejemanja opozorilnih obvestil."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Potrdite geslo"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Nadaljuj"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Kopirano v odložišče"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Kopiraj docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Kopiraj docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopiraj gostitelja"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopiraj Linux ukaz"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopiraj besedilo"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU poraba"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Ustvari račun"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Temno"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Nadzorna plošča"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Privzeto časovno obdobje"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Izbriši"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Poraba diska"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Poraba diska za {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU poraba"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker poraba spomina"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker I/O mreže"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentacija"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-pošta"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-poštna obvestila"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Vnesite e-poštni naslov za ponastavitev gesla"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Vnesite e-poštni naslov..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Napaka"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Preseženo {0}{1} v zadnjih {2, plural, one {# minuti} other {# minutah}}"
#: 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 "Obstoječi sistemi, ki niso definirani v <0>config.yml</0>, bodo izbrisani. Prosimo, naredite redne varnostne kopije."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Izvozi nastavitve"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Izvozi trenutne nastavitve sistema."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Preverjanje pristnosti ni uspelo"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Shranjevanje nastavitev ni uspelo"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Pošiljanje testnega obvestila ni uspelo"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Opozorila ni bilo mogoče posodobiti"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filter..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Za <0>{min}</0> {min, plural, one {minuto} other {minut}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Pozabljeno geslo?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Splošno"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU poraba moči"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Mreža"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Ukaz Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Gostitelj / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Če ste izgubili geslo za svoj skrbniški račun, ga lahko ponastavite z naslednjim ukazom."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Napačen e-poštni naslov."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Jedro"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Jezik"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Postavitev"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Svetlo"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Odjava"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Prijava"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Poskus prijave ni uspel"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Dnevniki"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Namesto tega iščete, kje ustvariti opozorila? Kliknite ikone zvonca <0/> v sistemski tabeli."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Upravljajte nastavitve prikaza in obvestil."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Največ 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Pomnilnik"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Poraba pomnilnika"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Poraba pomnilnika docker kontejnerjev"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Naziv"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Mreža"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Omrežni promet docker kontejnerjev"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Omrežni promet javnih vmesnikov"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Ni rezultatov."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Ne najdem sistema."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Obvestila"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Podpora za OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Ob vsakem ponovnem zagonu bodo sistemi v zbirki podatkov posodobljeni, da se bodo ujemali s sistemi, definiranimi v datoteki."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Odpri menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Ali nadaljuj z"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Prepiši obstoječe alarme"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Stran"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Strani / Nastavitve"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Geslo"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Geslo mora imeti vsaj 8 znakov."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Prejeta zahteva za ponastavitev gesla"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Premor"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Zaustavljeno"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "<0>Nastavite strežnik SMTP</0>, da zagotovite dostavo opozoril."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Za več podrobnosti preverite dnevnike."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Preverite svoje poverilnice in poskusite znova"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Ustvarite skrbniški račun"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Omogočite pojavna okna za to spletno mesto"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Prosimo, prijavite se znova"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Za navodila glejte <0>dokumentacijo</0>."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Prijavite se v svoj račun"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Vrata"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Natančna poraba v zabeleženem času"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Prednostni jezik"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Javni ključ"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Preberano"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Prejeto"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Ponastavi geslo"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Nadaljuj"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Shranite naslov s tipko enter ali vejico. Pustite prazno, da onemogočite e-poštna obvestila."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Shrani nastavitve"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Iskanje"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Iskanje sistemov ali nastavitev..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Glejte <0>nastavitve obvestil</0>, da nastavite način prejemanja opozoril."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Poslano"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Nastavi privzeti časovni obseg za grafikone, ko si ogledujete sistem."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Nastavitve"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Nastavitve so shranjene"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Prijavite se"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP nastavitve"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Razvrsti po"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap prostor, ki ga uporablja sistem"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap uporaba"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Sistemsko"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemi"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Sisteme lahko upravljate v datoteki <0>config.yml</0> v vašem podatkovnem imeniku."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabela"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatura"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperature sistemskih senzorjev"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Preveri <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testno obvestilo je poslano"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Za vzpostavitev povezave mora biti agent zagnan v sistemu. Kopirajte spodnji namestitveni ukaz za agenta."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Za vzpostavitev povezave mora biti agent zagnan v sistemu. Kopirajte <0>docker-compose.yml</0> za spodnjega agenta."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Nato se prijavite v zaledni sistem in ponastavite geslo svojega uporabniškega računa v tabeli uporabnikov."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Tega dejanja ni mogoče razveljaviti. To bo trajno izbrisalo vse trenutne zapise za {name} iz zbirke podatkov."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Prepustnost {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Prepustnost korenskega datotečnega sistema"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "E-pošta za"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Preklopi način mreže"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Obrni temo"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Sproži se, ko kateri koli senzor preseže prag"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Sproži, ko kombinacija gor/dol preseže prag"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Sproži se, ko poraba procesorja preseže prag"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Sproži se, ko uporaba pomnilnika preseže prag"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Sproži se, ko se stanje preklaplja med gor in dol"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Sproži se, ko uporaba katerega koli diska preseže prag"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Posodobljeno v realnem času. Za ogled informacij kliknite na sistem."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Čas delovanja"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Uporaba"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Uporaba korenske particije"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Uporabljeno"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Uporabniki"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Pogled"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Vidna polja"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Čakam na dovolj zapisov za prikaz"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Ali nam želite pomagati, da bomo naše prevode še izboljšali? Za več podrobnosti si oglejte <0>Crowdin</0>."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / potisna obvestila"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Ukaz Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Pisanje"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML nastaviitev"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML nastavitev"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Vaše uporabniške nastavitve so posodobljene."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: sv\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Swedish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: sv-SE\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 {# dagar}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# timme} other {# timmar}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 timme"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 vecka"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 timmar"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 timmar"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 dagar"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Åtgärder"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktiva larm"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Lägg till <0>System</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Lägg till nytt system"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Lägg till system"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Lägg till URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Justera visningsalternativ för diagram."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Admin"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Agent"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Larm"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Alla system"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Är du säker på att du vill ta bort {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Automatisk kopiering kräver en säker kontext."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Genomsnitt"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Genomsnittlig CPU-användning för containrar"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Genomsnittet överskrider <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Genomsnittlig strömförbrukning för GPU:er"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Genomsnittlig systemomfattande CPU-användning"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Genomsnittlig användning av {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Säkerhetskopior"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Bandbredd"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel stöder OpenID Connect och många OAuth2-autentiseringsleverantörer."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel använder <0>Shoutrrr</0> för att integrera med populära aviseringstjänster."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Binär"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Cache / Buffertar"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Avbryt"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Varning - potentiell dataförlust"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Ändra allmänna programalternativ."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Diagramalternativ"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Kontrollera {email} för en återställningslänk."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Kontrollera loggarna för mer information."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Kontrollera din aviseringstjänst"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Klicka för att kopiera"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Instruktioner för kommandoraden"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Konfigurera hur du tar emot larmaviseringar."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Bekräfta lösenord"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Fortsätt"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Kopierat till urklipp"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Kopiera docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Kopiera docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Kopiera värd"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Kopiera Linux-kommando"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Kopiera text"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU-användning"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Skapa konto"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Mörkt"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Dashboard"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Standardtidsperiod"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Ta bort"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Diskanvändning"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Diskanvändning av {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU-användning"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker Minnesanvändning"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker Nätverks-I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokumentation"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-post"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-postaviseringar"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Ange e-postadress för att återställa lösenord"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Ange e-postadress..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Fel"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Överskrider {0}{1} under de senaste {2, plural, one {# minuten} other {# minuterna}}"
#: 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 "Befintliga system som inte definieras i <0>config.yml</0> kommer att tas bort. Gör regelbundna säkerhetskopior."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Exportera konfiguration"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Exportera din nuvarande systemkonfiguration."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Autentisering misslyckades"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Kunde inte spara inställningar"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Kunde inte skicka testavisering"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Kunde inte uppdatera larm"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtrera..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Under <0>{min}</0> {min, plural, one {minut} other {minuter}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Glömt lösenordet?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Allmänt"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU-strömförbrukning"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Rutnät"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew-kommando"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Värd / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Om du har glömt lösenordet till ditt administratörskonto kan du återställa det med följande kommando."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Ogiltig e-postadress."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kärna"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Språk"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Layout"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Ljust"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Logga ut"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Logga in"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Inloggningsförsök misslyckades"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Loggar"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Letar du istället efter var du skapar larm? Klicka på klockikonerna <0/> i systemtabellen."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Hantera visnings- och aviseringsinställningar."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Max 1 min"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Minne"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Minnesanvändning"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Minnesanvändning för dockercontainrar"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Namn"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Nät"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Nätverkstrafik för dockercontainrar"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Nätverkstrafik för publika gränssnitt"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Inga resultat hittades."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Inga system hittades."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Aviseringar"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Stöd för OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Vid varje omstart kommer systemen i databasen att uppdateras för att matcha systemen som definieras i filen."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Öppna menyn"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Eller fortsätt med"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Skriv över befintliga larm"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Sida"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Sidor / Inställningar"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Lösenord"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Lösenordet måste vara minst 8 tecken."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Begäran om återställning av lösenord mottagen"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Paus"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Pausad"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Vänligen <0>konfigurera en SMTP-server</0> för att säkerställa att larm levereras."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Vänligen kontrollera loggarna för mer information."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Vänligen kontrollera dina inloggningsuppgifter och försök igen"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Vänligen skapa ett administratörskonto"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Vänligen aktivera popup-fönster för den här webbplatsen"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Vänligen logga in igen"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Vänligen se <0>dokumentationen</0> för instruktioner."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Vänligen logga in på ditt konto"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Exakt användning vid den registrerade tidpunkten"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Föredraget språk"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Offentlig nyckel"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Läs"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Mottaget"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Återställ lösenord"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Återuppta"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Spara adressen med Enter-tangenten eller komma. Lämna tomt för att inaktivera e-postaviseringar."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Spara inställningar"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Sök"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Sök efter system eller inställningar..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Se <0>aviseringsinställningar</0> för att konfigurera hur du tar emot larm."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Skickat"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Anger standardtidsintervallet för diagram när ett system visas."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Inställningar"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Inställningar sparade"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Logga in"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP-inställningar"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sortera efter"
#: src/lib/utils.ts
msgid "Status"
msgstr "Status"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Swap-utrymme som används av systemet"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Swap-användning"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "System"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "System"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "System kan hanteras i en <0>config.yml</0>-fil i din datakatalog."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tabell"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Temperatur"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Temperaturer för systemsensorer"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Testa <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Testavisering skickad"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Agenten måste köras på systemet för att ansluta. Kopiera installationskommandot för agenten nedan."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Agenten måste köras på systemet för att ansluta. Kopiera <0>docker-compose.yml</0> för agenten nedan."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Logga sedan in på backend och återställ ditt användarkontos lösenord i användartabellen."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Den här åtgärden kan inte ångras. Detta kommer permanent att ta bort alla aktuella poster för {name} från databasen."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Genomströmning av {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Genomströmning av rotfilsystemet"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Till e-postadress(er)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Växla rutnät"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Växla tema"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Utlöses när någon sensor överskrider ett tröskelvärde"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Utlöses när kombinerad upp/ner överskrider ett tröskelvärde"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Utlöses när CPU-användningen överskrider ett tröskelvärde"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Utlöses när minnesanvändningen överskrider ett tröskelvärde"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Utlöses när status växlar mellan upp och ner"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Utlöses när användningen av någon disk överskrider ett tröskelvärde"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Uppdateras i realtid. Klicka på ett system för att visa information."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Drifttid"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Användning"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Användning av rotpartitionen"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Använt"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Användare"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Visa"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Synliga fält"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Väntar på tillräckligt med poster att visa"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Vill du hjälpa oss att göra våra översättningar ännu bättre? Kolla in <0>Crowdin</0> för mer information."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push-aviseringar"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows-kommando"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Skriv"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML-konfiguration"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML-konfiguration"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Dina användarinställningar har uppdaterats."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: tr\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Turkish\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: tr\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 {# gün} other {# gün}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# saat} other {# saat}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 saat"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 hafta"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 saat"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 saat"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 gün"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Eylemler"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Aktif Uyarılar"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "<0>Sistem</0> Ekle"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Yeni Sistem Ekle"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Sistem ekle"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "URL Ekle"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Grafikler için görüntüleme seçeneklerini ayarlayın."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Yönetici"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Aracı"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Uyarılar"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Tüm Sistemler"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "{name} silmek istediğinizden emin misiniz?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Otomatik kopyalama güvenli bir bağlam gerektirir."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Ortalama"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Konteynerlerin ortalama CPU kullanımı"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Ortalama <0>{value}{0}</0> aşıyor"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPU ların ortalama güç tüketimi"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Sistem genelinde ortalama CPU kullanımı"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "{0} ortalama kullanımı"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Yedekler"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Bant Genişliği"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel, OpenID Connect ve birçok OAuth2 kimlik doğrulama sağlayıcısını destekler."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel, popüler bildirim hizmetleriyle entegre olmak için <0>Shoutrrr</0> kullanır."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "İkili"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Önbellek / Tamponlar"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "İptal"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Dikkat - potansiyel veri kaybı"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Genel uygulama seçeneklerini değiştirin."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Grafik seçenekleri"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Sıfırlama bağlantısı için {email} kontrol edin."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Daha fazla ayrıntı için günlükleri kontrol edin."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Bildirim hizmetinizi kontrol edin"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Kopyalamak için tıklayın"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Komut satırı talimatları"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Uyarı bildirimlerini nasıl alacağınızı yapılandırın."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Şifreyi onayla"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Devam et"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Panoya kopyalandı"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Docker compose kopyala"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Docker run kopyala"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Ana bilgisayarı kopyala"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Linux komutunu kopyala"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Metni kopyala"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU Kullanımı"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Hesap oluştur"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Koyu"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Gösterge Paneli"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Varsayılan zaman dilimi"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Sil"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Disk"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Disk G/Ç"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Disk Kullanımı"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "{extraFsName} disk kullanımı"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU Kullanımı"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker Bellek Kullanımı"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker Ağ G/Ç"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Dokümantasyon"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "E-posta"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "E-posta bildirimleri"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Şifreyi sıfırlamak için e-posta adresini girin"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "E-posta adresini girin..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Hata"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Son {2, plural, one {# dakika} other {# dakika}} içinde {0}{1} aşıyor"
#: 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> içinde tanımlanmayan mevcut sistemler silinecektir. Lütfen düzenli yedekler alın."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Yapılandırmayı dışa aktar"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Mevcut sistem yapılandırmanızı dışa aktarın."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Kimlik doğrulama başarısız"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Ayarlar kaydedilemedi"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Test bildirimi gönderilemedi"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Uyarı güncellenemedi"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Filtrele..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "<0>{min}</0> {min, plural, one {dakika} other {dakika}} için"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Şifrenizi mi unuttunuz?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Genel"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU Güç Çekimi"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Izgara"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew komutu"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Yönetici hesabınızın şifresini kaybettiyseniz, aşağıdaki komutu kullanarak sıfırlayabilirsiniz."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Geçersiz e-posta adresi."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Çekirdek"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Dil"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Düzen"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Açık"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Çıkış Yap"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Giriş Yap"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Giriş denemesi başarısız"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Günlükler"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Uyarı oluşturma yerini mi arıyorsunuz? Sistemler tablosundaki zil <0/> simgelerine tıklayın."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Görüntüleme ve bildirim tercihlerini yönetin."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Maks 1 dk"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Bellek"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Bellek Kullanımı"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Docker konteynerlerinin bellek kullanımı"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Ad"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Ağ"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Docker konteynerlerinin ağ trafiği"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Genel arayüzlerin ağ trafiği"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Sonuç bulunamadı."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Sistem bulunamadı."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Bildirimler"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "OAuth 2 / OIDC desteği"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Her yeniden başlatmada, veritabanındaki sistemler dosyada tanımlanan sistemlerle eşleşecek şekilde güncellenecektir."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Menüyü aç"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Veya devam et"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Mevcut uyarıların üzerine yaz"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Sayfa"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Sayfalar / Ayarlar"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Şifre"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Şifre en az 8 karakter olmalıdır."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Şifre sıfırlama isteği alındı"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Duraklat"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Duraklatıldı"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Uyarıların teslim edilmesini sağlamak için lütfen bir SMTP sunucusu <0>yapılandırın</0>."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Daha fazla ayrıntı için lütfen günlükleri kontrol edin."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Lütfen kimlik bilgilerinizi kontrol edin ve tekrar deneyin"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Lütfen bir yönetici hesabı oluşturun"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Lütfen bu site için açılır pencereleri etkinleştirin"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Lütfen tekrar giriş yapın"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Talimatlar için lütfen <0>dokümantasyonu</0> inceleyin."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Lütfen hesabınıza giriş yapın"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Kayıtlı zamanda kesin kullanım"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Tercih Edilen Dil"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Genel Anahtar"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Oku"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Alındı"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Şifreyi Sıfırla"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Devam et"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Adresleri enter tuşu veya virgül ile kaydedin. E-posta bildirimlerini devre dışı bırakmak için boş bırakın."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Ayarları Kaydet"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Ara"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Sistemler veya ayarlar için ara..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Uyarıları nasıl alacağınızı yapılandırmak için <0>bildirim ayarlarını</0> inceleyin."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Gönderildi"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Bir sistem görüntülendiğinde grafikler için varsayılan zaman aralığını ayarlar."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Ayarlar"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Ayarlar kaydedildi"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Giriş yap"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP ayarları"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sıralama Ölçütü"
#: src/lib/utils.ts
msgid "Status"
msgstr "Durum"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Sistem tarafından kullanılan takas alanı"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Takas Kullanımı"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Sistem"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Sistemler"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Sistemler, veri dizininizdeki bir <0>config.yml</0> dosyasında yönetilebilir."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Tablo"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Sıcaklık"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Sistem sensörlerinin sıcaklıkları"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Test <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Test bildirimi gönderildi"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Bağlanmak için aracının sistemde çalışıyor olması gerekir. Aşağıdaki aracı kurulum komutunu kopyalayın."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Bağlanmak için aracının sistemde çalışıyor olması gerekir. Aşağıdaki <0>docker-compose.yml</0> dosyasını kopyalayın."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Ardından arka uca giriş yapın ve kullanıcılar tablosunda kullanıcı hesabı şifrenizi sıfırlayın."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Bu işlem geri alınamaz. Bu, veritabanından {name} için tüm mevcut kayıtları kalıcı olarak silecektir."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName} verimliliği"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Kök dosya sisteminin verimliliği"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "E-posta(lar)a"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Izgarayı değiştir"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Temayı değiştir"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Herhangi bir sensör bir eşiği aştığında tetiklenir"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Birleştirilmiş yukarı/aşağı bir eşiği aştığında tetiklenir"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "CPU kullanımı bir eşiği aştığında tetiklenir"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Bellek kullanımı bir eşiği aştığında tetiklenir"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Durum yukarı ve aşağı arasında değiştiğinde tetiklenir"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Herhangi bir diskin kullanımı bir eşiği aştığında tetiklenir"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Gerçek zamanlı olarak güncellenir. Bilgileri görüntülemek için bir sisteme tıklayın."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Çalışma Süresi"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Kullanım"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Kök bölümün kullanımı"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Kullanıldı"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Kullanıcılar"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Görüntüle"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Görünür Alanlar"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Görüntülemek için yeterli kayıt bekleniyor"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Çevirilerimizi daha iyi hale getirmemize yardımcı olmak ister misiniz? Daha fazla bilgi için <0>Crowdin</0> inceleyin."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Anlık bildirimler"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows komutu"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Yaz"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML Yapılandırması"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML Yapılandırması"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Kullanıcı ayarlarınız güncellendi."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: uk\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-15 04:14\n"
"Last-Translator: \n"
"Language-Team: Ukrainian\n"
"Plural-Forms: nplurals=4; plural=((n%10==1 && n%100!=11) ? 0 : ((n%10 >= 2 && n%10 <=4 && (n%100 < 12 || n%100 > 14)) ? 1 : ((n%10 == 0 || (n%10 >= 5 && n%10 <=9)) || (n%100 >= 11 && n%100 <= 14)) ? 2 : 3));\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: uk\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 {# день} few {# дні} many {# днів} other {# дня}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# година} few {# години} many {# годин} other {# години}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 година"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 тиждень"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 годин"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 години"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 днів"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Дії"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Активні сповіщення"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Додати <0>Систему</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Додати нову систему"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Додати систему"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Додати URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Налаштуйте параметри відображення для графіків."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Адміністратор"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Агент"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Сповіщення"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Всі системи"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Ви впевнені, що хочете видалити {name}?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Автоматичне копіювання вимагає безпечного контексту."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Середнє"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Середнє використання CPU контейнерами"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Середнє перевищує <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "Середнє енергоспоживання GPUs"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Середнє використання CPU по всій системі"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "Середнє використання {0}"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Резервні копії"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Пропускна здатність"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel підтримує OpenID Connect та багато постачальників автентифікації OAuth2."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel використовує <0>Shoutrrr</0> для інтеграції з популярними сервісами сповіщень."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Двійковий"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Кеш / Буфери"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Скасувати"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Увага - можливе втрата даних"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Змінити загальні параметри програми."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Параметри графіків"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Перевірте {email} для отримання посилання на скидання."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Перевірте журнали для отримання додаткової інформації."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Перевірте свій сервіс сповіщень"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Натисніть, щоб скопіювати"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Інструкції командного рядка"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Налаштуйте, як ви отримуєте сповіщення про тривоги."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Підтвердьте пароль"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Продовжити"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Скопійовано в буфер обміну"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Копіювати docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Копіювати docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Копіювати хост"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Копіювати команду Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Копіювати текст"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "ЦП"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Використання ЦП"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Створити обліковий запис"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Темний"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Панель управління"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Стандартний період часу"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Видалити"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Диск"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Дисковий ввід/вивід"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Використання диска"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Використання диска {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Використання ЦП Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Використання пам'яті Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Мережевий ввід/вивід Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Документація"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "Не працює"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "Редагувати"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Електронна пошта"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Сповіщення електронною поштою"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Введіть адресу електронної пошти для скидання пароля"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Введіть адресу електронної пошти..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Помилка"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Перевищує {0}{1} протягом {2, plural, one {останньої # хвилини} other {останніх # хвилин}}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Експорт конфігурації"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Експортуйте поточну конфігурацію систем."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Не вдалося автентифікувати"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Не вдалося зберегти налаштування"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Не вдалося надіслати тестове сповіщення"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Не вдалося оновити сповіщення"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Фільтр..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Протягом <0>{min}</0> {min, plural, one {хвилини} other {хвилин}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Забули пароль?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Загальні"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "Енергоспоживання GPU"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Сітка"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Команда Homebrew"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Хост / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Якщо ви втратили пароль до свого адміністративного облікового запису, ви можете скинути його за допомогою наступної команди."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Неправильна адреса електронної пошти."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Ядро"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Мова"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Макет"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Світлий"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Вийти"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Увійти"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Спроба входу не вдалася"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "Шукаєте, де створити сповіщення? Натисніть на іконки дзвінка <0/> в таблиці систем."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Керуйте параметрами відображення та сповіщень."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "Інструкції з ручного налаштування"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Макс 1 хв"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Пам'ять"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Використання пам'яті"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Використання пам'яті контейнерами Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Ім'я"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Мережа"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Мережевий трафік контейнерів Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Мережевий трафік публічних інтерфейсів"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Результатів не знайдено."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Систем не знайдено."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Сповіщення"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Підтримка OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "При кожному перезапуску системи в базі даних будуть оновлені, щоб відповідати системам, визначеним у файлі."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Відкрити меню"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Або продовжити з"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Перезаписати існуючі сповіщення"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Сторінка"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Сторінки / Налаштування"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Пароль"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Пароль має містити щонайменше 8 символів."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "Пароль не повинен перевищувати 72 байти."
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Запит на скидання пароля отримано"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Призупинити"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "Призупинено"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Будь ласка, <0>налаштуйте SMTP сервер</0>, щоб забезпечити доставку сповіщень."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Будь ласка, перевірте журнали для отримання додаткової інформації."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Будь ласка, перевірте свої облікові дані та спробуйте ще раз"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Будь ласка, створіть адміністративний обліковий запис"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Будь ласка, увімкніть спливаючі вікна для цього сайту"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Будь ласка, увійдіть знову"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Будь ласка, перегляньте <0>документацію</0> для отримання інструкцій."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Будь ласка, увійдіть у свій обліковий запис"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Порт"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Точне використання в записаний час"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Бажана мова"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Ключ"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Читання"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Отримано"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Скинути пароль"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Відновити"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Збережіть адресу, використовуючи клавішу Enter або кому. Залиште порожнім, щоб вимкнути сповіщення електронною поштою."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Зберегти налаштування"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "Зберегти систему"
#: src/components/navbar.tsx
msgid "Search"
msgstr "Пошук"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Шукати системи або налаштування..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Перегляньте <0>налаштування сповіщень</0>, щоб налаштувати, як ви отримуєте сповіщення."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Відправлено"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Встановлює стандартний діапазон часу для графіків при перегляді системи."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Налаштування"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Налаштування збережено"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Увійти"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Налаштування SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Сортувати за"
#: src/lib/utils.ts
msgid "Status"
msgstr "Статус"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Область підкачки, використана системою"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Використання підкачки"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Система"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Системи"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Системи можуть керуватися у файлі <0>config.yml</0> у вашій директорії даних."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Таблиця"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "Температура"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Температура"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Температури датчиків системи"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Тест <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Тестове сповіщення надіслано"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Агент повинен працювати на системі для підключення. Скопіюйте команду встановлення для агента нижче."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Агент повинен працювати на системі для підключення. Скопіюйте <0>docker-compose.yml</0> для агента нижче."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Потім увійдіть у бекенд і скиньте пароль вашого облікового запису користувача в таблиці користувачів."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Цю дію не можна скасувати. Це назавжди видалить всі поточні записи для {name} з бази даних."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Пропускна здатність {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Пропускна здатність кореневої файлової системи"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "На електронну пошту"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Перемкнути сітку"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Перемкнути тему"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Спрацьовує, коли будь-який датчик перевищує поріг"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Спрацьовує, коли відправлення/отримання сумарно перевищує поріг"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Спрацьовує, коли використання ЦП перевищує поріг"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Спрацьовує, коли використання пам'яті перевищує поріг"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Спрацьовує, коли статус перемикається між «працює» та «не працює»"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Спрацьовує, коли використання будь-якого диска перевищує поріг"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "Працює"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Оновлюється в реальному часі. Натисніть на систему, щоб переглянути інформацію."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Час роботи"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Використання"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Використання кореневого розділу"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Використано"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Користувачі"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Вигляд"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Видимі стовпці"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Очікування достатньої кількості записів для відображення"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Хочете допомогти нам зробити наші переклади ще кращими? Перегляньте <0>Crowdin</0> для отримання додаткової інформації."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / Push сповіщення"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Команда Windows"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Запис"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Конфігурація YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Конфігурація YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Ваші налаштування користувача були оновлені."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: vi\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Vietnamese\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: vi\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 {# ngày} other {# ngày}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# giờ} other {# giờ}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1 giờ"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1 tuần"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12 giờ"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24 giờ"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30 ngày"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "Hành động"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "Cảnh báo hoạt động"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "Thêm <0>Hệ thống</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "Thêm Hệ thống Mới"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "Thêm hệ thống"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "Thêm URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "Điều chỉnh tùy chọn hiển thị cho biểu đồ."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "Quản trị viên"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "Tác nhân"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "Cảnh báo"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "Tất cả Hệ thống"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "Bạn có chắc chắn muốn xóa {name} không?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "Sao chép tự động yêu cầu một ngữ cảnh an toàn."
#: src/components/routes/system.tsx
msgid "Average"
msgstr "Trung bình"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "Sử dụng CPU trung bình của các container"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "Trung bình vượt quá <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr ""
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "Sử dụng CPU trung bình toàn hệ thống"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr ""
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "Sao lưu"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "Băng thông"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel hỗ trợ OpenID Connect và nhiều nhà cung cấp xác thực OAuth2."
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel sử dụng <0>Shoutrrr</0> để tích hợp với các dịch vụ thông báo phổ biến."
#: src/components/add-system.tsx
msgid "Binary"
msgstr "Nhị phân"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "Bộ nhớ đệm / Bộ đệm"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "Hủy bỏ"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "Cẩn thận - có thể mất dữ liệu"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "Thay đổi các tùy chọn ứng dụng chung."
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "Tùy chọn biểu đồ"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "Kiểm tra {email} để lấy liên kết đặt lại."
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "Kiểm tra nhật ký để biết thêm chi tiết."
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "Kiểm tra dịch vụ thông báo của bạn"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "Nhấp để sao chép"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "Hướng dẫn dòng lệnh"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "Cấu hình cách bạn nhận thông báo cảnh báo."
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "Xác nhận mật khẩu"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "Tiếp tục"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "Đã sao chép vào clipboard"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "Sao chép docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "Sao chép docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "Sao chép máy chủ"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "Sao chép lệnh Linux"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "Sao chép văn bản"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "Sử dụng CPU"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "Tạo tài khoản"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "Tối"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "Bảng điều khiển"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "Thời gian mặc định"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "Xóa"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "Đĩa"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "Đĩa I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "Sử dụng Đĩa"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "Sử dụng đĩa của {extraFsName}"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Sử dụng CPU Docker"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Sử dụng Bộ nhớ Docker"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Mạng I/O Docker"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "Tài liệu"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr ""
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "Email"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "Thông báo email"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "Nhập địa chỉ email để đặt lại mật khẩu"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "Nhập địa chỉ email..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "Lỗi"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "Vượt quá {0}{1} trong {2, plural, one {# phút} other {# phút}} qua"
#: 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 "Các hệ thống hiện có không được định nghĩa trong <0>config.yml</0> sẽ bị xóa. Vui lòng sao lưu thường xuyên."
#: src/components/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "Xuất cấu hình"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "Xuất cấu hình hệ thống hiện tại của bạn."
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "Xác thực thất bại"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "Lưu cài đặt thất bại"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "Gửi thông báo thử nghiệm thất bại"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "Cập nhật cảnh báo thất bại"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "Lọc..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "Trong <0>{min}</0> {min, plural, one {phút} other {phút}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "Quên mật khẩu?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "Chung"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "Lưới"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr ""
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Máy chủ / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "Nếu bạn đã mất mật khẩu cho tài khoản quản trị viên của mình, bạn có thể đặt lại bằng cách sử dụng lệnh sau."
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "Địa chỉ email không hợp lệ."
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Nhân"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "Ngôn ngữ"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "Bố cục"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "Sáng"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "Đăng xuất"
#: src/components/login/login.tsx
msgid "Login"
msgstr "Đăng nhập"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "Nỗ lực đăng nhập thất bại"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Logs"
msgstr "Nhật ký"
#: src/components/routes/settings/notifications.tsx
msgid "Looking instead for where to create alerts? Click the bell <0/> icons in the systems table."
msgstr "Thay vào đó, bạn đang tìm nơi để tạo cảnh báo? Nhấp vào biểu tượng chuông <0/> trong bảng hệ thống."
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "Quản lý tùy chọn hiển thị và thông báo."
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr ""
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "Tối đa 1 phút"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "Bộ nhớ"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "Sử dụng Bộ nhớ"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Sử dụng bộ nhớ của các container Docker"
#: src/components/add-system.tsx
msgid "Name"
msgstr "Tên"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "Mạng"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Lưu lượng mạng của các container Docker"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "Lưu lượng mạng của các giao diện công cộng"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "Không tìm thấy kết quả."
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "Không tìm thấy hệ thống."
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "Thông báo"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "Hỗ trợ OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "Mỗi khi khởi động lại, các hệ thống trong cơ sở dữ liệu sẽ được cập nhật để khớp với các hệ thống được định nghĩa trong tệp."
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "Mở menu"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "Hoặc tiếp tục với"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "Ghi đè các cảnh báo hiện có"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "Trang"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "Trang / Cài đặt"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "Mật khẩu"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "Mật khẩu phải có ít nhất 8 ký tự."
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr ""
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "Yêu cầu đặt lại mật khẩu đã được nhận"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "Tạm dừng"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr ""
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "Vui lòng <0>cấu hình máy chủ SMTP</0> để đảm bảo cảnh báo được gửi đi."
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "Vui lòng kiểm tra nhật ký để biết thêm chi tiết."
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "Vui lòng kiểm tra thông tin đăng nhập của bạn và thử lại"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "Vui lòng tạo một tài khoản quản trị viên"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "Vui lòng bật cửa sổ bật lên cho trang web này"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "Vui lòng đăng nhập lại"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "Vui lòng xem <0>tài liệu</0> để biết hướng dẫn."
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "Vui lòng đăng nhập vào tài khoản của bạn"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Cổng"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "Sử dụng chính xác tại thời điểm ghi nhận"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "Ngôn ngữ Ưa thích"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "Khóa"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "Đọc"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "Đã nhận"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "Đặt lại Mật khẩu"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "Tiếp tục"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "Lưu địa chỉ bằng cách sử dụng phím enter hoặc dấu phẩy. Để trống để vô hiệu hóa thông báo email."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "Lưu Cài đặt"
#: src/components/add-system.tsx
msgid "Save system"
msgstr ""
#: src/components/navbar.tsx
msgid "Search"
msgstr "Tìm kiếm"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "Tìm kiếm hệ thống hoặc cài đặt..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "Xem <0>cài đặt thông báo</0> để cấu hình cách bạn nhận cảnh báo."
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "Đã gửi"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "Đặt phạm vi thời gian mặc định cho biểu đồ khi một hệ thống được xem."
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "Cài đặt"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "Cài đặt đã được lưu"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "Đăng nhập"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "Cài đặt SMTP"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "Sắp xếp theo"
#: src/lib/utils.ts
msgid "Status"
msgstr "Trạng thái"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "Không gian hoán đổi được sử dụng bởi hệ thống"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "Sử dụng Hoán đổi"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "Hệ thống"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "Các hệ thống"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "Các hệ thống có thể được quản lý trong tệp <0>config.yml</0> bên trong thư mục dữ liệu của bạn."
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "Bảng"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr ""
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "Nhiệt độ"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "Nhiệt độ của các cảm biến hệ thống"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "Kiểm tra <0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "Thông báo thử nghiệm đã được gửi"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "Tác nhân phải đang chạy trên hệ thống để kết nối. Sao chép lệnh cài đặt cho tác nhân bên dưới."
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "Tác nhân phải đang chạy trên hệ thống để kết nối. Sao chép <0>docker-compose.yml</0> cho tác nhân bên dưới."
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "Sau đó đăng nhập vào backend và đặt lại mật khẩu tài khoản người dùng của bạn trong bảng người dùng."
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "Hành động này không thể hoàn tác. Điều này sẽ xóa vĩnh viễn tất cả các bản ghi hiện tại cho {name} khỏi cơ sở dữ liệu."
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "Thông lượng của {extraFsName}"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Thông lượng của hệ thống tệp gốc"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "Đến email(s)"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "Chuyển đổi lưới"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "Chuyển đổi chủ đề"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "Kích hoạt khi bất kỳ cảm biến nào vượt quá ngưỡng"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "Kích hoạt khi kết hợp lên/xuống vượt quá ngưỡng"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "Kích hoạt khi sử dụng CPU vượt quá ngưỡng"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "Kích hoạt khi sử dụng bộ nhớ vượt quá ngưỡng"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "Kích hoạt khi trạng thái chuyển đổi giữa lên và xuống"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "Kích hoạt khi sử dụng bất kỳ đĩa nào vượt quá ngưỡng"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "Cập nhật theo thời gian thực. Nhấp vào một hệ thống để xem thông tin."
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "Thời gian hoạt động"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "Sử dụng"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Sử dụng phân vùng gốc"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "Đã sử dụng"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "Người dùng"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "Xem"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "Các cột hiển thị"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "Đang chờ đủ bản ghi để hiển thị"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "Muốn giúp chúng tôi cải thiện bản dịch của mình? Xem <0>Crowdin</0> để biết thêm chi tiết."
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Thông báo Webhook / Push"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr ""
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "Ghi"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "Cấu hình YAML"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "Cấu hình YAML"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "Cài đặt người dùng của bạn đã được cập nhật."

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Chinese Simplified\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: zh-CN\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 {# 天}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# 小时} other {# 小时}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1小时"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1周"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12小时"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24小时"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30天"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "操作"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "启用的警报"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "添加<0>客户端</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "添加新客户端"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "添加客户端"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "添加URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "调整图表的显示选项。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "管理员"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "客户端"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "警报"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "所有客户端"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "您确定要删除{name}吗?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "自动复制所需的安全上下文。"
#: src/components/routes/system.tsx
msgid "Average"
msgstr "平均"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "容器的平均 CPU 使用率"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "平均值超过<0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPU 平均能耗"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "系统范围内的平均 CPU 使用率"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "{0} 平均利用率"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "备份"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "带宽"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel支持OpenID Connect和其他OAuth2认证方式。"
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel使用<0>Shoutrrr</0>以实现与常见的通知服务集成。"
#: src/components/add-system.tsx
msgid "Binary"
msgstr "二进制"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "缓存/缓冲区"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "取消"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "注意 - 数据可能已经丢失"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "更改常规应用程序选项。"
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "图表选项"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "检查 {email} 以获取重置链接。"
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "检查日志以获取更多详细信息。"
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "检查您的通知服务"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "点击复制"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "命令行说明"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "配置您接收警报通知的方式。"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "确认密码"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "继续"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "已复制到剪贴板"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "复制 docker compose 文件"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "复制 docker run 命令"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "复制主机名"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "复制 Linux 安装命令"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "复制文本"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU使用率"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "创建账户"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "深色模式"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "仪表板"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "默认时间段"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "删除"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "磁盘"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "磁盘I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "磁盘使用"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "{extraFsName}的磁盘使用"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU使用"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker内存使用"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker网络I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "文档"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr "停止"
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "编辑"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "电子邮件"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "电子邮件通知"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "输入电子邮件地址以重置密码"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "输入电子邮件地址..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "错误"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "在过去的{2, plural, one {# 分钟} other {# 分钟}}中超过{0}{1}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "导出配置"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "导出您当前的系统配置。"
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "认证失败"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "保存设置失败"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "发送测试通知失败"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "更新警报失败"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "过滤..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "持续<0>{min}</0> {min, plural, one {分钟} other {分钟}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "忘记密码?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "常规"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU 功耗"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "网格"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew 安装命令"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "主机/IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "如果您丢失了管理员账户的密码,可以使用以下命令重置。"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "无效的电子邮件地址。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "内核"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "语言"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "布局"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "浅色模式"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "登出"
#: src/components/login/login.tsx
msgid "Login"
msgstr "登录"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "登录尝试失败"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "在寻找创建警报的位置吗?点击系统表中的铃铛<0/>图标。"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "管理显示和通知偏好。"
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "手动设置说明"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "1分钟内最大值"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "内存"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "内存使用"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Docker 容器的内存使用"
#: src/components/add-system.tsx
msgid "Name"
msgstr "名称"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "网络"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Docker 容器的网络流量"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "公共接口的网络流量"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "未找到结果。"
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "未找到系统。"
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "通知"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "支持 OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "每次重启时,数据库中的系统将更新以匹配文件中定义的系统。"
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "打开菜单"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "或使用以下方式登录"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "覆盖现有警报"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "页面"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "页面/设置"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "密码"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "密码必须至少包含 8 个字符。"
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "密码必须小于 72 字节。"
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "已收到密码重置请求"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "暂停"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "已暂停"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "请<0>配置SMTP服务器</0>以确保警报被传递。"
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "请检查日志以获取更多详细信息。"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "请检查您的凭据并重试"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "请创建一个管理员账户"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "请为此网站启用弹出窗口"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "请重新登录"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "请参阅<0>文档</0>以获取说明。"
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "请登录您的账户"
#: src/components/add-system.tsx
msgid "Port"
msgstr "端口"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "采集时间下的精确内存使用率"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "首选语言"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "公钥"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "读取"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "接收"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "重置密码"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "恢复"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "使用回车键或逗号保存地址。留空以禁用电子邮件通知。"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "保存设置"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "保存系统"
#: src/components/navbar.tsx
msgid "Search"
msgstr "搜索"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "搜索系统或设置..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "查看<0>通知设置</0>以配置您接收警报的方式。"
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "发送"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "设置查看系统时图表的默认时间范围。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "设置"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "设置已保存"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "登录"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP设置"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "排序依据"
#: src/lib/utils.ts
msgid "Status"
msgstr "状态"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "系统使用的 SWAP 空间"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "SWAP 使用"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "系统"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "系统"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "系统可以在数据目录中的<0>config.yml</0>文件中管理。"
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "表格"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "温度"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "温度"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "系统传感器的温度"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "测试<0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "测试通知已发送"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "必须在系统上运行客户端之后才能连接。复制下面的客户端安装命令。"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "必须在系统上运行客户端之后才能连接。复制下面的<0>docker-compose.yml</0>。"
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "然后登录到后台并在用户表中重置您的用户账户密码。"
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "此操作无法撤销。这将永久删除数据库中{name}的所有当前记录。"
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}的吞吐量"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "根文件系统的吞吐量"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "发送到电子邮件"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "切换网格"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "切换主题"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "当任何传感器超过阈值时触发"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "当网络的上/下行速度超过阈值时触发"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "当CPU使用率超过阈值时触发"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "当内存使用率超过阈值时触发"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "当状态在上线与掉线之间切换时触发"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "当任何磁盘的使用率超过阈值时触发"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr "启动"
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "实时更新。点击系统查看信息。"
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "正常运行时间"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "使用"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "根分区的使用"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "已用"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "用户"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "视图"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "可见列"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "正在收集足够的数据来显示"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "想帮助我们改进翻译吗?查看<0>Crowdin</0>以获取更多详细信息。"
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / 推送通知"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows 安装命令"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "写入"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML配置"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML配置"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "您的用户设置已更新。"

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional, Hong Kong\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: zh-HK\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 {# 天}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# 小時} other {# 小時}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1小時"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1週"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12小時"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24小時"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30天"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "操作"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "活動警報"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "新增<0>系統</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "新增新系統"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "新增系統"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "添加 URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "調整圖表的顯示選項。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "管理員"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "客户端"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "警報"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "所有系統"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "您確定要刪除 {name} 嗎?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "自動複製需要安全的上下文。"
#: src/components/routes/system.tsx
msgid "Average"
msgstr "平均"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "容器的平均 CPU 使用率"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "平均值超過 <0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPU 的平均功耗"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "系統的平均 CPU 使用率"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "{0} 的平均使用率"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "備份"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "帶寬"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel支持OpenID Connect和許多OAuth2認證提供者。"
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel 使用 <0>Shoutrrr</0> 與流行的通知服務集成。"
#: src/components/add-system.tsx
msgid "Binary"
msgstr "執行檔"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "快取 / 緩衝區"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "取消"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "注意 - 可能遺失資料"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "更改一般應用選項。"
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "圖表選項"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "檢查 {email} 以獲取重置鏈接。"
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "檢查日誌以取得更多資訊。"
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "檢查您的通知服務"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "點擊以複製"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "命令行指令"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "配置您接收警報通知的方式。"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "確認密碼"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "繼續"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "已複製到剪貼板"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "複製 docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "複製 docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "複製主機"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "複製 Linux 指令"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "複製文本"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU 使用率"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "創建帳戶"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "深色"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "控制面板"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "預設時間段"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "刪除"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "磁碟"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "磁碟 I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "磁碟使用"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "{extraFsName} 的磁碟使用量"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU 使用率"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker 記憶體使用率"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker 網絡 I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "文件"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "編輯"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "電子郵件"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "電子郵件通知"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "輸入電子郵件地址以重置密碼"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "輸入電子郵件地址..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "錯誤"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "在過去的{2, plural, one {# 分鐘} other {# 分鐘}}中超過{0}{1}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "匯出設定"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "匯出您現在的系統設定。"
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "認證失敗"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "儲存設定失敗"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "發送測試通知失敗"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "更新警報失敗"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "篩選..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "持續<0>{min}</0> {min, plural, one {分鐘} other {分鐘}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "忘記密碼?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "一般"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU 功耗"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "網格"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew 指令"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "主機 / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "如果您遺失了管理員帳號密碼,可以使用以下指令重設。"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "無效的電子郵件地址。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "語言"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "版面配置"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "淺色"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "登出"
#: src/components/login/login.tsx
msgid "Login"
msgstr "登入"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "登入嘗試失敗"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "在尋找創建警報的位置嗎?點擊系統表中的鈴鐺<0/>。"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "管理顯示和通知偏好。"
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "手動設定說明"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "一分鐘內最大值"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "記憶體"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "記憶體使用"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Docker 容器的記憶體使用量"
#: src/components/add-system.tsx
msgid "Name"
msgstr "名稱"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "網絡"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Docker 容器的網絡流量"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "公共接口的網絡流量"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "未找到結果。"
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "未找到系統。"
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "通知"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "支援 OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "每次重新啟動時,將會以檔案中的系統定義更新資料庫。"
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "開啟選單"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "或繼續使用"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "覆蓋現有警報"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "頁面"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "頁面 / 設定"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "密碼"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "密碼必須至少包含 8 個字符。"
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "密碼必須少於 72 個字節。"
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "已收到密碼重設請求"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "暫停"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "已暫停"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "請<0>配置SMTP伺服器</0>以確保警報被傳送。"
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "請檢查日誌以獲取更多資訊。"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "請檢查您的憑證並重試"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "請建立一個管理員帳號"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "請為此網站啟用彈出窗口"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "請重新登入"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "請參閱<0>文件</0>以取得說明。"
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "請登入您的帳號"
#: src/components/add-system.tsx
msgid "Port"
msgstr "端口"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "記錄時間的精確使用率"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "首選語言"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "公鑰"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "讀取"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "接收"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "重設密碼"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "恢復"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "使用回車鍵或逗號保存地址。留空以禁用電子郵件通知。"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "儲存設定"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "儲存系統"
#: src/components/navbar.tsx
msgid "Search"
msgstr "搜索"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "搜索系統或設置..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "查看<0>通知設置</0>以配置您接收警報的方式。"
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "發送"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "設置查看系統時圖表的默認時間範圍。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "設置"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "設置已保存"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "登錄"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP設置"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "排序依據"
#: src/lib/utils.ts
msgid "Status"
msgstr "狀態"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "系統使用的交換空間"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "交換使用"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "系統"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "系統"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "系統可以在您的數據目錄中的<0>config.yml</0>文件中管理。"
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "表格"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "溫度"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "溫度"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "系統傳感器的溫度"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "測試<0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "測試通知已發送"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "代理必須在系統上運行才能連接。複製下面的代理安裝命令。"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "代理必須在系統上運行才能連接。複製下面的<0>docker-compose.yml</0>。"
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "然後登錄到後端並在用戶表中重置您的用戶帳戶密碼。"
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "此操作無法撤銷。這將永久刪除數據庫中{name}的所有當前記錄。"
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}的吞吐量"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "根文件系統的吞吐量"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "發送到電子郵件"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "切換網格"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "切換主題"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "當任何傳感器超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "當組合的上/下超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "當CPU使用率超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "當記憶體使用率超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "當狀態在上和下之間切換時觸發"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "當任何磁碟的使用超過閾值時觸發"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "實時更新。點擊系統查看信息。"
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "正常運行時間"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "使用"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "根分區的使用"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "已用"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "用戶"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "檢視"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "可見欄位"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "等待足夠的記錄以顯示"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "想幫助我們改進翻譯嗎?查看<0>Crowdin</0>以獲取更多詳細信息。"
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / 推送通知"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows 指令"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "寫入"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML配置"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML配置"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "您的用戶設置已更新。"

View File

@@ -1,886 +0,0 @@
msgid ""
msgstr ""
"POT-Creation-Date: 2024-11-01 11:30-0400\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Generator: @lingui/cli\n"
"Language: zh\n"
"Project-Id-Version: beszel\n"
"Report-Msgid-Bugs-To: \n"
"PO-Revision-Date: 2025-03-06 07:27\n"
"Last-Translator: \n"
"Language-Team: Chinese Traditional\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Crowdin-Project: beszel\n"
"X-Crowdin-Project-ID: 733311\n"
"X-Crowdin-Language: zh-TW\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 {# 天}}"
#: src/components/routes/system.tsx
msgid "{hours, plural, one {# hour} other {# hours}}"
msgstr "{hours, plural, one {# 小時} other {# 小時}}"
#: src/lib/utils.ts
msgid "1 hour"
msgstr "1小時"
#: src/lib/utils.ts
msgid "1 week"
msgstr "1週"
#: src/lib/utils.ts
msgid "12 hours"
msgstr "12小時"
#: src/lib/utils.ts
msgid "24 hours"
msgstr "24小時"
#: src/lib/utils.ts
msgid "30 days"
msgstr "30天"
#. Table column
#: src/components/systems-table/systems-table.tsx
msgid "Actions"
msgstr "操作"
#: src/components/routes/home.tsx
msgid "Active Alerts"
msgstr "活動警報"
#: src/components/add-system.tsx
msgid "Add <0>System</0>"
msgstr "新增<0>系統</0>"
#: src/components/add-system.tsx
msgid "Add New System"
msgstr "新增新系統"
#: src/components/add-system.tsx
msgid "Add system"
msgstr "新增系統"
#: src/components/routes/settings/notifications.tsx
msgid "Add URL"
msgstr "新增 URL"
#: src/components/routes/settings/general.tsx
msgid "Adjust display options for charts."
msgstr "調整圖表的顯示選項。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
msgid "Admin"
msgstr "管理員"
#: src/components/systems-table/systems-table.tsx
msgid "Agent"
msgstr "代理"
#: src/components/alerts/alert-button.tsx
#: src/components/alerts/alert-button.tsx
msgid "Alerts"
msgstr "警報"
#: src/components/systems-table/systems-table.tsx
#: src/components/alerts/alert-button.tsx
msgid "All Systems"
msgstr "所有系統"
#: src/components/systems-table/systems-table.tsx
msgid "Are you sure you want to delete {name}?"
msgstr "您確定要刪除 {name} 嗎?"
#: src/components/copy-to-clipboard.tsx
msgid "Automatic copy requires a secure context."
msgstr "只有在受保護的環境才能自動複製。"
#: src/components/routes/system.tsx
msgid "Average"
msgstr "平均"
#: src/components/routes/system.tsx
msgid "Average CPU utilization of containers"
msgstr "容器的平均 CPU 使用率"
#. placeholder {0}: data.alert.unit
#: src/components/alerts/alerts-system.tsx
msgid "Average exceeds <0>{value}{0}</0>"
msgstr "平均值超過<0>{value}{0}</0>"
#: src/components/routes/system.tsx
msgid "Average power consumption of GPUs"
msgstr "GPU 的平均功耗"
#: src/components/routes/system.tsx
msgid "Average system-wide CPU utilization"
msgstr "系統的平均 CPU 使用率"
#. placeholder {0}: gpu.n
#: src/components/routes/system.tsx
msgid "Average utilization of {0}"
msgstr "{0} 的平均使用率"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Backups"
msgstr "備份"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Bandwidth"
msgstr "網路流量"
#: src/components/login/auth-form.tsx
msgid "Beszel supports OpenID Connect and many OAuth2 authentication providers."
msgstr "Beszel支援OpenID Connect和許多OAuth2認證提供者。"
#: src/components/routes/settings/notifications.tsx
msgid "Beszel uses <0>Shoutrrr</0> to integrate with popular notification services."
msgstr "Beszel 以 <0>Shoutrrr</0> 整合常用的通知服務。"
#: src/components/add-system.tsx
msgid "Binary"
msgstr "執行檔"
#: src/components/charts/mem-chart.tsx
msgid "Cache / Buffers"
msgstr "快取/緩衝"
#: src/components/systems-table/systems-table.tsx
msgid "Cancel"
msgstr "取消"
#: src/components/routes/settings/config-yaml.tsx
msgid "Caution - potential data loss"
msgstr "注意 - 可能遺失資料"
#: src/components/routes/settings/general.tsx
msgid "Change general application options."
msgstr "修改一般應用程式選項。"
#: src/components/routes/settings/general.tsx
msgid "Chart options"
msgstr "圖表選項"
#: src/components/login/forgot-pass-form.tsx
msgid "Check {email} for a reset link."
msgstr "檢查{email}以取得重設連結。"
#: src/components/routes/settings/layout.tsx
msgid "Check logs for more details."
msgstr "檢查系統記錄以取得更多資訊。"
#: src/components/routes/settings/notifications.tsx
msgid "Check your notification service"
msgstr "檢查您的通知服務"
#: src/components/add-system.tsx
msgid "Click to copy"
msgstr "點擊複製"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/forgot-pass-form.tsx
msgid "Command line instructions"
msgstr "命令列指令"
#: src/components/routes/settings/notifications.tsx
msgid "Configure how you receive alert notifications."
msgstr "設定您要如何接收警報通知"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Confirm password"
msgstr "確認密碼"
#: src/components/systems-table/systems-table.tsx
msgid "Continue"
msgstr "繼續"
#: src/lib/utils.ts
msgid "Copied to clipboard"
msgstr "已複製到剪貼簿"
#: src/components/add-system.tsx
msgctxt "Button to copy docker compose file content"
msgid "Copy docker compose"
msgstr "复制 docker compose"
#: src/components/add-system.tsx
msgctxt "Button to copy docker run command"
msgid "Copy docker run"
msgstr "复制 docker run"
#: src/components/systems-table/systems-table.tsx
msgid "Copy host"
msgstr "複製主機"
#: src/components/add-system.tsx
msgid "Copy Linux command"
msgstr "複製 Linux 指令"
#: src/components/copy-to-clipboard.tsx
msgid "Copy text"
msgstr "複製文字"
#: src/components/systems-table/systems-table.tsx
msgid "CPU"
msgstr "CPU"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "CPU Usage"
msgstr "CPU 使用率"
#: src/components/login/auth-form.tsx
msgid "Create account"
msgstr "建立帳號"
#. Dark theme
#: src/components/mode-toggle.tsx
msgid "Dark"
msgstr "深色"
#: src/components/command-palette.tsx
#: src/components/routes/home.tsx
msgid "Dashboard"
msgstr "控制面板"
#: src/components/routes/settings/general.tsx
msgid "Default time period"
msgstr "預設時間段"
#: src/components/systems-table/systems-table.tsx
msgid "Delete"
msgstr "刪除"
#: src/components/systems-table/systems-table.tsx
msgid "Disk"
msgstr "磁碟"
#: src/components/routes/system.tsx
msgid "Disk I/O"
msgstr "磁碟 I/O"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
#: src/components/charts/disk-chart.tsx
msgid "Disk Usage"
msgstr "磁碟使用量"
#: src/components/routes/system.tsx
msgid "Disk usage of {extraFsName}"
msgstr "{extraFsName}的磁碟使用量"
#: src/components/routes/system.tsx
msgid "Docker CPU Usage"
msgstr "Docker CPU 使用率"
#: src/components/routes/system.tsx
msgid "Docker Memory Usage"
msgstr "Docker 記憶體使用率"
#: src/components/routes/system.tsx
msgid "Docker Network I/O"
msgstr "Docker 網路 I/O"
#: src/components/command-palette.tsx
msgid "Documentation"
msgstr "文件"
#. Context: System is down
#: src/lib/utils.ts
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Down"
msgstr ""
#: src/components/add-system.tsx
#: src/components/systems-table/systems-table.tsx
msgid "Edit"
msgstr "編輯"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Email"
msgstr "電子郵件"
#: src/components/routes/settings/notifications.tsx
msgid "Email notifications"
msgstr "電子郵件通知"
#: src/components/login/login.tsx
msgid "Enter email address to reset password"
msgstr "輸入電子郵件地址以重設密碼"
#: src/components/routes/settings/notifications.tsx
msgid "Enter email address..."
msgstr "輸入電子郵件地址..."
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/config-yaml.tsx
#: src/components/login/auth-form.tsx
msgid "Error"
msgstr "錯誤"
#. placeholder {0}: alert.value
#. placeholder {1}: info.unit
#. placeholder {2}: alert.min
#: src/components/routes/home.tsx
msgid "Exceeds {0}{1} in last {2, plural, one {# minute} other {# minutes}}"
msgstr "在過去的{2, plural, one {# 分鐘} other {# 分鐘}}中超過{0}{1}"
#: 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/routes/settings/config-yaml.tsx
msgid "Export configuration"
msgstr "匯出設定"
#: src/components/routes/settings/config-yaml.tsx
msgid "Export your current systems configuration."
msgstr "匯出您現在的系統設定。"
#: src/lib/utils.ts
msgid "Failed to authenticate"
msgstr "認證失敗"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Failed to save settings"
msgstr "儲存設定失敗"
#: src/components/routes/settings/notifications.tsx
msgid "Failed to send test notification"
msgstr "發送測試通知失敗"
#: src/components/alerts/alerts-system.tsx
msgid "Failed to update alert"
msgstr "更新警報失敗"
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Filter..."
msgstr "篩選..."
#: src/components/alerts/alerts-system.tsx
msgid "For <0>{min}</0> {min, plural, one {minute} other {minutes}}"
msgstr "持續<0>{min}</0> {min, plural, one {分鐘} other {分鐘}}"
#: src/components/login/auth-form.tsx
msgid "Forgot password?"
msgstr "忘記密碼?"
#. Context: General settings
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/general.tsx
msgid "General"
msgstr "一般"
#: src/components/routes/system.tsx
msgid "GPU Power Draw"
msgstr "GPU 功耗"
#: src/components/systems-table/systems-table.tsx
msgid "Grid"
msgstr "網格"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Homebrew command"
msgstr "Homebrew 命令"
#: src/components/add-system.tsx
msgid "Host / IP"
msgstr "Host / IP"
#: src/components/login/forgot-pass-form.tsx
msgid "If you've lost the password to your admin account, you may reset it using the following command."
msgstr "如果您遺失管理員帳號密碼,可以使用以下指令重設。"
#: src/components/login/auth-form.tsx
msgid "Invalid email address."
msgstr "無效的電子郵件地址。"
#. Linux kernel
#: src/components/routes/system.tsx
msgid "Kernel"
msgstr "Kernel"
#: src/components/routes/settings/general.tsx
msgid "Language"
msgstr "語言"
#: src/components/systems-table/systems-table.tsx
msgid "Layout"
msgstr "版面配置"
#. Light theme
#: src/components/mode-toggle.tsx
msgid "Light"
msgstr "淺色"
#: src/components/navbar.tsx
msgid "Log Out"
msgstr "登出"
#: src/components/login/login.tsx
msgid "Login"
msgstr "登入"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Login attempt failed"
msgstr "登入失敗"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "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 "在尋找從哪裡建立警報嗎?點擊系統列表中的小鈴鐺<0/>。"
#: src/components/routes/settings/layout.tsx
msgid "Manage display and notification preferences."
msgstr "管理顯示和通知偏好。"
#: src/components/add-system.tsx
msgid "Manual setup instructions"
msgstr "手動設定說明"
#. Chart select field. Please try to keep this short.
#: src/components/routes/system.tsx
msgid "Max 1 min"
msgstr "最多1分鐘"
#: src/components/systems-table/systems-table.tsx
msgid "Memory"
msgstr "記憶體"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Memory Usage"
msgstr "記憶體使用量"
#: src/components/routes/system.tsx
msgid "Memory usage of docker containers"
msgstr "Docker 容器的記憶體使用量"
#: src/components/add-system.tsx
msgid "Name"
msgstr "名稱"
#: src/components/systems-table/systems-table.tsx
msgid "Net"
msgstr "網路"
#: src/components/routes/system.tsx
msgid "Network traffic of docker containers"
msgstr "Docker 容器的網路流量"
#: src/components/routes/system.tsx
msgid "Network traffic of public interfaces"
msgstr "公開介面的網路流量"
#: src/components/command-palette.tsx
msgid "No results found."
msgstr "找不到結果。"
#: src/components/systems-table/systems-table.tsx
#: src/components/systems-table/systems-table.tsx
msgid "No systems found."
msgstr "找不到任何系統。"
#: src/components/command-palette.tsx
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/layout.tsx
msgid "Notifications"
msgstr "通知"
#: src/components/login/auth-form.tsx
msgid "OAuth 2 / OIDC support"
msgstr "支援 OAuth 2 / OIDC"
#: src/components/routes/settings/config-yaml.tsx
msgid "On each restart, systems in the database will be updated to match the systems defined in the file."
msgstr "每次重新啟動時,將會以檔案中的系統定義更新資料庫。"
#: src/components/systems-table/systems-table.tsx
msgid "Open menu"
msgstr "開啟選單"
#: src/components/login/auth-form.tsx
msgid "Or continue with"
msgstr "或繼續使用"
#: src/components/alerts/alert-button.tsx
msgid "Overwrite existing alerts"
msgstr "覆蓋現有警報"
#: src/components/command-palette.tsx
msgid "Page"
msgstr "頁面"
#: src/components/command-palette.tsx
msgid "Pages / Settings"
msgstr "頁面 / 設定"
#: src/components/login/auth-form.tsx
#: src/components/login/auth-form.tsx
msgid "Password"
msgstr "密碼"
#: src/components/login/auth-form.tsx
msgid "Password must be at least 8 characters."
msgstr "密碼需要至少8個字元"
#: src/components/login/auth-form.tsx
msgid "Password must be less than 72 bytes."
msgstr "密碼必須少於 72 個位元組。"
#: src/components/login/forgot-pass-form.tsx
msgid "Password reset request received"
msgstr "已收到密碼重設請求"
#: src/components/systems-table/systems-table.tsx
msgid "Pause"
msgstr "暫停"
#: src/components/systems-table/systems-table.tsx
msgid "Paused"
msgstr "已暂停"
#: src/components/routes/settings/notifications.tsx
msgid "Please <0>configure an SMTP server</0> to ensure alerts are delivered."
msgstr "請<0>設定一個SMTP 伺服器</0>以確保能傳送警報。"
#: src/components/alerts/alerts-system.tsx
msgid "Please check logs for more details."
msgstr "請檢查系統記錄以取得更多資訊。"
#: src/components/login/forgot-pass-form.tsx
#: src/components/login/auth-form.tsx
msgid "Please check your credentials and try again"
msgstr "請檢查您的憑證後重試"
#: src/components/login/login.tsx
msgid "Please create an admin account"
msgstr "請建立一個管理員帳號"
#: src/components/login/auth-form.tsx
msgid "Please enable pop-ups for this site"
msgstr "請為此網站啟用彈出視窗"
#: src/lib/utils.ts
msgid "Please log in again"
msgstr "請重新登入"
#: src/components/login/auth-form.tsx
msgid "Please see <0>the documentation</0> for instructions."
msgstr "請參閱<0>文件</0>以取得說明。"
#: src/components/login/login.tsx
msgid "Please sign in to your account"
msgstr "請登入您的帳號"
#: src/components/add-system.tsx
msgid "Port"
msgstr "Port"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Precise utilization at the recorded time"
msgstr "紀錄時間內的精確使用量"
#: src/components/routes/settings/general.tsx
msgid "Preferred Language"
msgstr "首選語言"
#. Use 'Key' if your language requires many more characters
#: src/components/add-system.tsx
msgid "Public Key"
msgstr "公鑰"
#. Disk read
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Read"
msgstr "讀取"
#. Network bytes received (download)
#: src/components/charts/area-chart.tsx
msgid "Received"
msgstr "接收"
#: src/components/login/forgot-pass-form.tsx
msgid "Reset Password"
msgstr "重設密碼"
#: src/components/systems-table/systems-table.tsx
msgid "Resume"
msgstr "繼續"
#: src/components/routes/settings/notifications.tsx
msgid "Save address using enter key or comma. Leave blank to disable email notifications."
msgstr "使用 Enter 鍵或逗號儲存地址。留空以停用電子郵件通知。"
#: src/components/routes/settings/notifications.tsx
#: src/components/routes/settings/general.tsx
msgid "Save Settings"
msgstr "儲存設定"
#: src/components/add-system.tsx
msgid "Save system"
msgstr "儲存系統"
#: src/components/navbar.tsx
msgid "Search"
msgstr "搜尋"
#: src/components/command-palette.tsx
msgid "Search for systems or settings..."
msgstr "在設定或系統中搜尋..."
#: src/components/alerts/alert-button.tsx
msgid "See <0>notification settings</0> to configure how you receive alerts."
msgstr "查看<0>通知設定</0>以設定您如何接收警報。"
#. Network bytes sent (upload)
#: src/components/charts/area-chart.tsx
msgid "Sent"
msgstr "傳送"
#: src/components/routes/settings/general.tsx
msgid "Sets the default time range for charts when a system is viewed."
msgstr "設定顯示系統圖表的預設時間範圍。"
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/command-palette.tsx
#: src/components/routes/settings/layout.tsx
#: src/components/routes/settings/layout.tsx
msgid "Settings"
msgstr "設定"
#: src/components/routes/settings/layout.tsx
msgid "Settings saved"
msgstr "已儲存設定"
#: src/components/login/auth-form.tsx
msgid "Sign in"
msgstr "登入"
#: src/components/command-palette.tsx
msgid "SMTP settings"
msgstr "SMTP 設定"
#: src/components/systems-table/systems-table.tsx
msgid "Sort By"
msgstr "排序"
#: src/lib/utils.ts
msgid "Status"
msgstr "狀態"
#: src/components/routes/system.tsx
msgid "Swap space used by the system"
msgstr "系統的虛擬記憶體使用量"
#: src/components/routes/system.tsx
msgid "Swap Usage"
msgstr "虛擬記憶體使用量"
#. System theme
#: src/lib/utils.ts
#: src/components/mode-toggle.tsx
#: src/components/systems-table/systems-table.tsx
msgid "System"
msgstr "系統"
#: src/components/navbar.tsx
msgid "Systems"
msgstr "系統"
#: src/components/routes/settings/config-yaml.tsx
msgid "Systems may be managed in a <0>config.yml</0> file inside your data directory."
msgstr "可以用您Data資料夾中的<0>config.yml</0>來管理系統。"
#: src/components/systems-table/systems-table.tsx
msgid "Table"
msgstr "列表"
#. Temperature label in systems table
#: src/components/systems-table/systems-table.tsx
msgid "Temp"
msgstr "溫度"
#: src/lib/utils.ts
#: src/components/routes/system.tsx
msgid "Temperature"
msgstr "溫度"
#: src/components/routes/system.tsx
msgid "Temperatures of system sensors"
msgstr "系統感應器的溫度"
#: src/components/routes/settings/notifications.tsx
msgid "Test <0>URL</0>"
msgstr "測試<0>URL</0>"
#: src/components/routes/settings/notifications.tsx
msgid "Test notification sent"
msgstr "已發送測試通知"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the installation command for the agent below."
msgstr "必須在系統上執行代理程式才能連線,複製以下代理程式的安裝指令。"
#: src/components/add-system.tsx
msgid "The agent must be running on the system to connect. Copy the<0>docker-compose.yml</0> for the agent below."
msgstr "必須在系統上執行代理程式才能連線,複製以下代理程式的<0>docker-compose.yml</0>。"
#: src/components/login/forgot-pass-form.tsx
msgid "Then log into the backend and reset your user account password in the users table."
msgstr "然後登入後台並在使用者列表中重設您的帳號密碼。"
#: src/components/systems-table/systems-table.tsx
msgid "This action cannot be undone. This will permanently delete all current records for {name} from the database."
msgstr "此操作無法復原。這將永久刪除資料庫中{name}的所有當前記錄。"
#: src/components/routes/system.tsx
msgid "Throughput of {extraFsName}"
msgstr "{extraFsName}的傳輸速率"
#: src/components/routes/system.tsx
msgid "Throughput of root filesystem"
msgstr "Root文件系統的傳輸速率"
#: src/components/routes/settings/notifications.tsx
msgid "To email(s)"
msgstr "發送到電子郵件"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
msgid "Toggle grid"
msgstr "切換網格"
#: src/components/mode-toggle.tsx
msgid "Toggle theme"
msgstr "切換主題"
#: src/lib/utils.ts
msgid "Triggers when any sensor exceeds a threshold"
msgstr "當任何感應器超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when combined up/down exceeds a threshold"
msgstr "當總流量超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when CPU usage exceeds a threshold"
msgstr "當CPU使用率超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when memory usage exceeds a threshold"
msgstr "當記憶體使用率超過閾值時觸發"
#: src/lib/utils.ts
msgid "Triggers when status switches between up and down"
msgstr "當連線和離線時觸發"
#: src/lib/utils.ts
msgid "Triggers when usage of any disk exceeds a threshold"
msgstr "當任何磁碟使用率超過閾值時觸發"
#. Context: System is up
#: src/components/systems-table/systems-table.tsx
#: src/components/routes/system.tsx
msgid "Up"
msgstr ""
#: src/components/systems-table/systems-table.tsx
msgid "Updated in real time. Click on a system to view information."
msgstr "實時更新。點擊系統顯示資訊。"
#: src/components/routes/system.tsx
msgid "Uptime"
msgstr "運行時間"
#: src/components/routes/system.tsx
#: src/components/routes/system.tsx
#: src/components/charts/area-chart.tsx
msgid "Usage"
msgstr "使用量"
#: src/components/routes/system.tsx
msgid "Usage of root partition"
msgstr "Root 分區的使用量"
#: src/components/charts/swap-chart.tsx
#: src/components/charts/mem-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Used"
msgstr "已使用"
#: src/components/navbar.tsx
#: src/components/command-palette.tsx
msgid "Users"
msgstr "使用者"
#: src/components/systems-table/systems-table.tsx
msgid "View"
msgstr "檢視"
#: src/components/systems-table/systems-table.tsx
msgid "Visible Fields"
msgstr "顯示欄位"
#: src/components/routes/system.tsx
msgid "Waiting for enough records to display"
msgstr "等待足夠的記錄以顯示"
#: src/components/routes/settings/general.tsx
msgid "Want to help improve our translations? Check <0>Crowdin</0> for details."
msgstr "想幫助我們改善翻譯嗎?查看<0>Crowdin</0>以取得更多詳細信息。"
#: src/components/routes/settings/notifications.tsx
msgid "Webhook / Push notifications"
msgstr "Webhook / 推送通知"
#: src/components/add-system.tsx
msgctxt "Button to copy install command"
msgid "Windows command"
msgstr "Windows 命令"
#. Disk write
#: src/components/charts/area-chart.tsx
#: src/components/charts/area-chart.tsx
msgid "Write"
msgstr "寫入"
#: src/components/routes/settings/layout.tsx
msgid "YAML Config"
msgstr "YAML 設定檔"
#: src/components/routes/settings/config-yaml.tsx
msgid "YAML Configuration"
msgstr "YAML 設定檔"
#: src/components/routes/settings/layout.tsx
msgid "Your user settings have been updated."
msgstr "已更新您的使用者設定"

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