i18n.rs
⎇
Raw
1//! Lightweight i18n: one central registry (in the spirit of `icons.rs`).
2//!
3//! `EN` is the canonical list of user-visible strings; it doubles as the key
4//! table. `DE` and `FR` translate the same keys; a key missing from a
5//! translation falls back to English.
6//!
7//! - `t(key)` resolves a key for the current locale. Non-reactive — for
8//! toasts, event handlers, and one-shot constructions (dialogs).
9//! - `tr(key)` is the same as a reactive closure, for `view!` children and
10//! attributes, so switching the language re-renders in place.
11//! - `error_text(code, fallback)` maps a server error *code* to a
12//! translation; unknown or absent codes fall back to the server message.
13//!
14//! Parameterized strings carry exactly one `{}` placeholder; callers do
15//! `format!(t(k::X), arg)`.
16//!
17//! Every table is sorted by key so lookups can binary-search.
18//!
19//! Locale precedence: the signed-in user's profile setting (persisted
20//! server-side), else the browser language. `init` + `set_locale` drive a
21//! global signal so every `tr` subscriber updates.
22
23use std::sync::OnceLock;
24
25use leptos::prelude::*;
26use wasm_bindgen::JsCast;
27
28/// A supported UI language.
29#[derive(Clone, Copy, PartialEq, Eq, Debug)]
30pub enum Locale {
31 En,
32 De,
33 Fr,
34}
35
36impl Locale {
37 pub const fn code(self) -> &'static str {
38 match self {
39 Locale::En => "en",
40 Locale::De => "de",
41 Locale::Fr => "fr",
42 }
43 }
44
45 /// Parse a BCP-47-ish tag ("de", "de-AT", "DE") into a supported locale.
46 pub fn from_code(code: &str) -> Option<Self> {
47 let lang = code.split(['-', '_']).next()?.to_ascii_lowercase();
48 match lang.as_str() {
49 "en" => Some(Locale::En),
50 "de" => Some(Locale::De),
51 "fr" => Some(Locale::Fr),
52 _ => None,
53 }
54 }
55
56 /// The browser's language, restricted to the supported locales.
57 pub fn from_browser() -> Option<Self> {
58 let lang = web_sys::window()?.navigator().language()?;
59 Self::from_code(&lang)
60 }
61}
62
63static READ: OnceLock<ReadSignal<Locale>> = OnceLock::new();
64static WRITE: OnceLock<WriteSignal<Locale>> = OnceLock::new();
65
66/// Called once during app setup, before the first UI render.
67pub fn init(locale: Locale) {
68 let (read, write) = signal(locale);
69 let _ = READ.set(read);
70 let _ = WRITE.set(write);
71 apply_doc_lang(locale);
72}
73
74pub fn set_locale(locale: Locale) {
75 if let Some(w) = WRITE.get() {
76 w.set(locale);
77 }
78 apply_doc_lang(locale);
79}
80
81pub fn current() -> Locale {
82 READ.get().map(|r| r.get()).unwrap_or(Locale::En)
83}
84
85/// Like [`current`] but without registering a reactive dependency — for
86/// code that reads the locale only to compare before writing (e.g. the
87/// profile effect in `app.rs`), so the read cannot retrigger itself.
88pub fn current_untracked() -> Locale {
89 READ.get().map(|r| r.get_untracked()).unwrap_or(Locale::En)
90}
91
92/// Keep `<html lang>` in sync for screen readers and the browser UI.
93fn apply_doc_lang(locale: Locale) {
94 if let Some(html) = web_sys::window()
95 .and_then(|w| w.document())
96 .and_then(|d| d.document_element())
97 .and_then(|e| e.dyn_into::<web_sys::HtmlElement>().ok())
98 {
99 let _ = html.set_attribute("lang", locale.code());
100 }
101}
102
103/// Resolve a key for the current locale (non-reactive).
104pub fn t(key: &str) -> &'static str {
105 text(key, current())
106}
107
108/// Resolve a key for the current locale as a reactive closure, for use as a
109/// `view!` child or attribute value.
110pub fn tr(key: &str) -> impl Fn() -> String + Clone {
111 move || t(key).to_string()
112}
113
114/// Like [`t`], but substitutes a single `{}` placeholder in the translation
115/// with `arg`.
116pub fn t_fmt(key: &str, arg: &str) -> String {
117 t(key).replace("{}", arg)
118}
119
120/// Like [`t_fmt`] for translations with two placeholders, filling the first
121/// `{}` with `a` and the second with `b`. Positional, so a locale that needs
122/// the other order has to reword rather than swap.
123pub fn t_fmt2(key: &str, a: &str, b: &str) -> String {
124 let s = t(key);
125 match s.split_once("{}") {
126 Some((head, tail)) => format!("{head}{a}{}", tail.replacen("{}", b, 1)),
127 None => s.to_string(),
128 }
129}
130
131/// Localize a server error: a known code maps to its translation, anything
132/// else (no code, unknown code) falls back to the server's English message.
133pub fn error_text(code: Option<&str>, fallback: &str) -> String {
134 let Some(code) = code.filter(|c| find(EN, c).is_some()) else {
135 return fallback.to_string();
136 };
137 // One-shot lookup for a toast message: no reactive context, so read the
138 // locale untracked.
139 text(code, current_untracked()).to_string()
140}
141
142fn text(key: &str, locale: Locale) -> &'static str {
143 // Keys are compile-time constants from `k`; a miss is a bug (the unit
144 // tests pin the tables against each other).
145 match locale {
146 Locale::En => find(EN, key).expect("unknown i18n key"),
147 Locale::De => find(DE, key)
148 .or_else(|| find(EN, key))
149 .expect("unknown i18n key"),
150 Locale::Fr => find(FR, key)
151 .or_else(|| find(EN, key))
152 .expect("unknown i18n key"),
153 }
154}
155
156/// The tables are sorted by key, so a lookup is a binary search. The
157/// `tables_are_sorted` test keeps that invariant true.
158fn find(table: &'static [(&'static str, &'static str)], key: &str) -> Option<&'static str> {
159 table
160 .binary_search_by(|(k, _)| (*k).cmp(key))
161 .ok()
162 .map(|i| table[i].1)
163}
164
165/// Declares the translation keys and the canonical English text in one
166/// place: one row per key, `CONST = "key" => "English"`.
167///
168/// The `k` constants and the `EN` table are generated from the same row, so
169/// a key cannot exist in one without the other. Rows are sorted by key,
170/// because [`find`] binary-searches (`tables_are_sorted` pins that).
171macro_rules! i18n_keys {
172 ($($name:ident = $key:literal => $en:expr),* $(,)?) => {
173 /// Translation keys. Use these, never the raw strings: a typo in a
174 /// key is a compile error, a typo in a string is a runtime panic.
175 pub mod k {
176 $(pub const $name: &str = $key;)*
177 }
178
179 /// Canonical English strings (key → text). The source of truth for
180 /// which keys exist; DE and FR translate the same list.
181 const EN: &[(&str, &str)] = &[$(($key, $en)),*];
182 };
183}
184
185i18n_keys! {
186 ACTIVE_CAN_SIGNIN = "active_can_signin" => "Active (can sign in)",
187 ADD_APP_PASSWORD = "add_app_password" => "Create app password",
188 ADD_FOLDER = "add_folder" => "Add folder…",
189 ADD_HERE = "add_here" => "Add this folder",
190 ADD_PASSKEY = "add_passkey" => "Add passkey",
191 ADMINISTRATOR = "administrator" => "Administrator",
192 ALL_SHARES = "all_shares" => "All shares",
193 ALL_SHARES_HINT = "all_shares_hint" => "Every link on this server, grouped by the account that created it.",
194 ALLOW_EDITING = "allow_editing" => "Allow editing (read-write)",
195 ALLOW_RW_SHARES = "allow_rw_shares" => "Allow writable shares",
196 ALLOW_RW_SHARES_DESC = "allow_rw_shares_desc" => "Let users create read-write share links. Off by default.",
197 AND_MORE = "and_more" => "…and {} more",
198 APP_PASSWORD_LABEL = "app_password_label" => "Name for this app password",
199 APP_PASSWORD_REMOVED = "app_password_removed" => "App password revoked",
200 APP_PASSWORD_SECRET_ONCE = "app_password_secret_once" => "Copy it now. It is never shown again.",
201 APP_PASSWORDS = "app_passwords" => "App passwords",
202 APP_PASSWORDS_HINT = "app_passwords_hint" => "An app password signs in to WebDAV only, never to this page. Use one per client instead of your account password.",
203 CANCEL = "cancel" => "Cancel",
204 CANT_DELETE_SELF = "cant_delete_self" => "You cannot delete yourself",
205 CLOSE = "close" => "Close",
206 CLOSE_ESC = "close_esc" => "Close (Esc)",
207 COPIED = "copied" => "Copied",
208 COPY = "copy" => "Copy",
209 COPY_DAV_LINK = "copy_dav_link" => "Copy WebDAV link",
210 COPY_HERE = "copy_here" => "Copy here",
211 COPY_LINK = "copy_link" => "Copy link",
212 COPY_MANUAL = "copy_manual" => "Copy the link manually",
213 COPY_N_TO = "copy_n_to" => "Copy {} items to…",
214 COPY_TO = "copy_to" => "Copy “{}” to…",
215 CREATE = "create" => "Create",
216 CREATE_ADMIN = "create_admin" => "Create admin account",
217 CREATE_LINK = "create_link" => "Create link",
218 CREATE_USER = "create_user" => "Create user",
219 CREATING = "creating" => "Creating…",
220 CUSTOM = "custom" => "Custom…",
221 DEFAULT_ROOT_DESC = "default_root_desc" => "Open this folder on page load and on the home link.",
222 DEFAULT_ROOT_LABEL = "default_root_label" => "Default folder",
223 DEFAULT_ROOT_NONE = "default_root_none" => "Folder overview",
224 DELETE = "delete" => "Delete",
225 DELETE_ALL = "delete_all" => "Delete all",
226 DELETE_ALL_MSG = "delete_all_msg" => "Delete all {} share links? Anyone holding them loses access. This cannot be undone.",
227 DELETE_ALL_TITLE = "delete_all_title" => "Delete all shares?",
228 DELETE_ALL_USER_MSG = "delete_all_user_msg" => "Delete every share link of “{}”? Anyone holding them loses access. This cannot be undone.",
229 DELETE_FOLDER_MSG = "delete_folder_msg" => "Delete folder “{}” and everything inside it?\nThis cannot be undone.",
230 DELETE_MSG = "delete_msg" => "Delete “{}”?\nThis cannot be undone.",
231 DELETE_N_MSG = "delete_n_msg" => "Delete {} items?\nThis cannot be undone.",
232 DELETE_PARTIAL = "delete_partial" => "{} of {} shares could not be deleted",
233 DELETE_SHARE = "delete_share" => "Delete share",
234 DELETE_USER = "delete_user" => "Delete user",
235 DELETE_USER_CONFIRM = "delete_user_confirm" => "Delete user “{}”? This cannot be undone.",
236 DELETED = "deleted" => "Deleted",
237 DELETED_N_SHARES = "deleted_n_shares" => "Deleted {} shares",
238 DISCARD = "discard" => "Discard",
239 DISCARD_QUESTION = "discard_question" => "Discard your changes and close the editor?",
240 DISMISS = "dismiss" => "Dismiss",
241 DISMISS_ERROR = "dismiss_error" => "Dismiss error",
242 DONE = "done" => "Done",
243 DOWNLOAD = "download" => "Download",
244 DOWNLOAD_FORMATS_MSG = "download_formats_msg" => "Choose an archive format for the folder.",
245 DOWNLOAD_STARTED = "download_started" => "Download started",
246 DOWNLOAD_TITLE = "download_title" => "Download “{}”",
247 EDIT = "edit" => "Edit",
248 EDIT_USER_TITLE = "edit_user_title" => "Edit “{}”",
249 EMPTY_FOLDER = "empty_folder" => "This folder is empty.",
250 ERR_ADMIN_ONLY = "err_admin_only" => "admin only",
251 ERR_ALREADY_SET_UP = "err_already_set_up" => "server is already set up",
252 ERR_APP_PASSWORD_LIMIT = "err_app_password_limit" => "This account already has as many app passwords as it may.",
253 ERR_APP_PASSWORD_NOT_FOUND = "err_app_password_not_found" => "No such app password.",
254 ERR_BAD_ACTION = "err_bad_action" => "expected action=content",
255 ERR_BAD_BODY = "err_bad_body" => "invalid request body",
256 ERR_BAD_EXPIRES_AT = "err_bad_expires_at" => "the expiry date is invalid",
257 ERR_BAD_FORMAT = "err_bad_format" => "format must be one of: zip, tar, tar.gz, tar.zst",
258 ERR_BAD_MULTIPART = "err_bad_multipart" => "expected multipart/form-data with a boundary",
259 ERR_BAD_PART_NAME = "err_bad_part_name" => "invalid part name",
260 ERR_BAD_POST = "err_bad_post" => "POST expects a multipart upload, a JSON mutation, or ?action=mkdir/create-file",
261 ERR_BAD_UPLOAD = "err_bad_upload" => "invalid upload data",
262 ERR_BAD_UPLOAD_PATH = "err_bad_upload_path" => "invalid file path in upload",
263 ERR_CHALLENGE_EXPIRED = "err_challenge_expired" => "That took too long, please try again.",
264 ERR_DEFAULT_CALENDAR = "err_default_calendar" => "The calendar that receives invitations cannot be deleted.",
265 ERR_DST_REQUIRED = "err_dst_required" => "dst_root_id is required",
266 ERR_FILE_NAME_REQUIRED = "err_file_name_required" => "a file name is required",
267 ERR_FILES_EXIST = "err_files_exist" => "some files already exist",
268 ERR_FOLDER_EXISTS = "err_folder_exists" => "a folder with this name already exists",
269 ERR_FOLDER_NAME_REQUIRED = "err_folder_name_required" => "a folder name is required",
270 ERR_FS_CONFLICT = "err_fs_conflict" => "already exists",
271 ERR_FS_FORBIDDEN = "err_fs_forbidden" => "access denied",
272 ERR_FS_NOT_A_DIR = "err_fs_not_a_dir" => "not a folder",
273 ERR_FS_NOT_FOUND = "err_fs_not_found" => "folder not found",
274 ERR_FS_ROOT_MISSING = "err_fs_root_missing" => "the configured folder no longer exists",
275 ERR_INTERNAL = "err_internal" => "internal error",
276 ERR_INVALID_CREDENTIALS = "err_invalid_credentials" => "invalid name or password",
277 ERR_INVALID_DEFAULT_ROOT = "err_invalid_default_root" => "the default folder is not one of your folders",
278 ERR_INVALID_LANGUAGE = "err_invalid_language" => "invalid language tag",
279 ERR_LAST_ADMIN = "err_last_admin" => "cannot remove the last active admin",
280 ERR_LAST_ADMIN_DELETE = "err_last_admin_delete" => "cannot delete the last active admin",
281 ERR_LOCKED_OUT = "err_locked_out" => "That would leave the account with no way to sign in.",
282 ERR_MODE_NEEDS_PASSKEY = "err_mode_needs_passkey" => "Add a passkey before requiring both.",
283 ERR_MODE_NEEDS_PASSWORD = "err_mode_needs_password" => "Set a password before requiring both.",
284 ERR_NAME_LENGTH = "err_name_length" => "name must be 1–64 characters",
285 ERR_NEW_NAME_REQUIRED = "err_new_name_required" => "new_name is required",
286 ERR_NO_FILES_UPLOADED = "err_no_files_uploaded" => "no files were uploaded",
287 ERR_NO_SUCH_FOLDER = "err_no_such_folder" => "no such folder",
288 ERR_NOT_A_FILE = "err_not_a_file" => "not a file",
289 ERR_NOT_SIGNED_IN = "err_not_signed_in" => "not signed in",
290 ERR_OWN_ACCOUNT = "err_own_account" => "you cannot disable your own account",
291 ERR_OWN_ADMIN = "err_own_admin" => "you cannot remove your own admin rights",
292 ERR_OWN_DELETE = "err_own_delete" => "you cannot delete your own account",
293 ERR_PART_NO_NAME = "err_part_no_name" => "part without a name",
294 ERR_PASSKEY_DUPLICATE = "err_passkey_duplicate" => "That passkey is already registered.",
295 ERR_PASSKEY_FAILED = "err_passkey_failed" => "That passkey could not be used.",
296 ERR_PASSKEY_LAST_CREDENTIAL = "err_passkey_last_credential" => "Set a password before removing your last passkey.",
297 ERR_PASSKEY_LIMIT = "err_passkey_limit" => "This account already has as many passkeys as it may.",
298 ERR_PASSKEY_MALFORMED = "err_passkey_malformed" => "The browser sent unreadable data.",
299 ERR_PASSKEY_NOT_FOUND = "err_passkey_not_found" => "No such passkey.",
300 ERR_PASSKEY_ORIGIN = "err_passkey_origin" => "Passkeys are set up for a different address.",
301 ERR_PASSKEY_UNAVAILABLE = "err_passkey_unavailable" => "Passkeys are not available here.",
302 ERR_PASSWORD_LAST_CREDENTIAL = "err_password_last_credential" => "Add a passkey before removing your password.",
303 ERR_PASSWORD_SHORT = "err_password_short" => "password must be at least 8 characters",
304 ERR_PATH_REQUIRED = "err_path_required" => "a path inside the folder is required",
305 ERR_READ_ONLY_FOLDER = "err_read_only_folder" => "read-only folder",
306 ERR_REQUIRED_BY_MODE = "err_required_by_mode" => "This account requires a password and a passkey.",
307 ERR_ROOT_FORBIDDEN = "err_root_forbidden" => "root not accessible",
308 ERR_RW_RO_FOLDER = "err_rw_ro_folder" => "this folder is read-only for you, so it cannot be shared writably",
309 ERR_RW_SHARES_DISABLED = "err_rw_shares_disabled" => "writable shares are disabled",
310 ERR_SAVE_FAILED = "err_save_failed" => "could not save the file",
311 ERR_SEARCH_BAD_SCOPE = "err_search_bad_scope" => "scope must be name, content or both",
312 ERR_SEARCH_FORBIDDEN = "err_search_forbidden" => "search requires a signed-in session",
313 ERR_SESSION_EXPIRED = "err_session_expired" => "session expired, please sign in again",
314 ERR_SHARE_EXPIRED = "err_share_expired" => "this share has expired",
315 ERR_SHARE_LOCKED = "err_share_locked" => "This share is password protected.",
316 ERR_SHARE_NO_PASSWORD = "err_share_no_password" => "This share has no password.",
317 ERR_SHARE_NOT_FOUND = "err_share_not_found" => "share not found",
318 ERR_SHARE_TOKEN_FORBIDDEN = "err_share_token_forbidden" => "a share token cannot be used here; sign in instead",
319 ERR_SHARE_WRONG_PASSWORD = "err_share_wrong_password" => "Wrong password.",
320 ERR_TOO_LARGE_PREVIEW = "err_too_large_preview" => "file too large to preview",
321 ERR_TOO_LARGE_SAVE = "err_too_large_save" => "file too large to save",
322 ERR_USER_EXISTS = "err_user_exists" => "a user with that name already exists",
323 ERR_USER_NOT_FOUND = "err_user_not_found" => "user not found",
324 EXCLUDE_DUP_ERR = "exclude_dup_err" => "That folder is already excluded.",
325 EXCLUDE_FOLDER = "exclude_folder" => "Exclude folder…",
326 EXCLUDE_HERE = "exclude_here" => "Exclude this folder",
327 EXCLUDE_ROOT_ERR = "exclude_root_err" => "The whole root cannot be excluded; that would turn search off.",
328 EXPIRES = "expires" => "Expires",
329 EXPIRES_AT = "expires_at" => "Expires {}",
330 EXPIRY_1D = "expiry_1d" => "1 day",
331 EXPIRY_1H = "expiry_1h" => "1 hour",
332 EXPIRY_1MO = "expiry_1mo" => "1 month",
333 EXPIRY_1W = "expiry_1w" => "1 week",
334 FILE = "file" => "File",
335 FILE_CHANGED = "file_changed" => "File changed on disk",
336 FILE_CREATED = "file_created" => "File created",
337 FILE_INFO = "file_info" => "File info",
338 FILE_NAME = "file_name" => "File name",
339 FILE_NOT_FOUND = "file_not_found" => "File not found",
340 FILES = "files" => "Files",
341 FMT_TAR = "fmt_tar" => "Tar",
342 FMT_TARGZ = "fmt_targz" => "Tar + gzip",
343 FMT_TARZST = "fmt_tarzst" => "Tar + zstd",
344 FMT_ZIP = "fmt_zip" => "Zip",
345 FOLDER = "folder" => "Folder",
346 FOLDER_CREATED = "folder_created" => "Folder created",
347 FOLDER_GONE_MSG = "folder_gone_msg" => "This folder is no longer accessible. Choose another one from the sidebar.",
348 FOLDER_GONE_TITLE = "folder_gone_title" => "Folder not available",
349 FOLDER_NAME = "folder_name" => "Folder name",
350 FOLDERS = "folders" => "Folders",
351 FOLDERS_PATHS_HINT = "folders_paths_hint" => "Paths are relative to the server root. “.” is the whole root.",
352 GRID_VIEW = "grid_view" => "Grid view",
353 INFO = "info" => "Info",
354 KEEP_EDITING = "keep_editing" => "Keep editing",
355 LANG_AUTO = "lang_auto" => "Automatic",
356 LANG_DE = "lang_de" => "German",
357 LANG_EN = "lang_en" => "English",
358 LANG_FR = "lang_fr" => "French",
359 LANGUAGE = "language" => "Language",
360 LANGUAGE_DESC = "language_desc" => "The interface language. Automatic uses your browser's language.",
361 LINK_COPIED = "link_copied" => "Link copied to clipboard",
362 LIST_VIEW = "list_view" => "List view",
363 LOAD_LATEST = "load_latest" => "Load latest",
364 LOADING = "loading" => "Loading…",
365 LOADING_SHARE = "loading_share" => "Loading share…",
366 LOCATION = "location" => "Location",
367 LOG_OUT = "log_out" => "Log out",
368 LOGIN_SUBTITLE = "login_subtitle" => "Sign in to continue.",
369 MANAGE = "manage" => "Manage",
370 MENU = "menu" => "Menu",
371 META_CREATED = "meta_created" => "created {}",
372 META_EXPIRES = "meta_expires" => "expires {}",
373 MODE_RO = "mode_ro" => "read-only",
374 MODE_RW = "mode_rw" => "read-write",
375 MODIFIED = "modified" => "Modified",
376 MODIFIED_AFTER = "modified_after" => "This file was modified after you opened it. “Load latest” discards your unsaved changes; “Overwrite” keeps your version.",
377 MORE_ACTIONS = "more_actions" => "More actions",
378 MOVE = "move" => "Move",
379 MOVE_HERE = "move_here" => "Move here",
380 MOVE_N_TO = "move_n_to" => "Move {} items to…",
381 MOVE_TO = "move_to" => "Move “{}” to…",
382 MOVED = "moved" => "Moved",
383 NAME = "name" => "Name",
384 NAME_TAKEN = "name_taken" => "Name already in use",
385 NEED_FOLDER = "need_folder" => "Give the user at least one folder.",
386 NEVER = "never" => "Never",
387 NEVER_EXPIRES = "never_expires" => "Never expires",
388 NEW_FILE = "new_file" => "New file",
389 NEW_FOLDER = "new_folder" => "New folder",
390 NEW_NAME = "new_name" => "New name",
391 NEW_PASSWORD = "new_password" => "New password",
392 NEW_PASSWORD_HINT = "new_password_hint" => "Leave empty to keep your current password.",
393 NEW_PASSWORD_KEEP = "new_password_keep" => "New password (leave blank to keep)",
394 NEW_USER = "new_user" => "New user",
395 NO_APP_PASSWORDS = "no_app_passwords" => "No app passwords.",
396 NO_FOLDERS_MSG = "no_folders_msg" => "An administrator hasn't assigned you any folders yet.",
397 NO_FOLDERS_TITLE = "no_folders_title" => "No folders available",
398 NO_PASSKEYS = "no_passkeys" => "No passkeys yet.",
399 NO_PASSWORD_SET = "no_password_set" => "This account signs in with passkeys only.",
400 NO_PREVIEW = "no_preview" => "No preview available",
401 NO_PREVIEW_MSG = "no_preview_msg" => "The app can’t display “{}” here.",
402 NO_SHARES = "no_shares" => "No shares yet",
403 NO_SUBFOLDERS = "no_subfolders" => "No subfolders",
404 NO_USERS = "no_users" => "No users.",
405 OPEN = "open" => "Open",
406 OPEN_IN_NEW_TAB = "open_in_new_tab" => "Open in new tab",
407 OPEN_MENU = "open_menu" => "Open menu",
408 OR_LABEL = "or_label" => "or",
409 OVERWRITE = "overwrite" => "Overwrite",
410 OVERWRITE_QUESTION = "overwrite_question" => "The following files already exist. Overwrite them?",
411 PAGE_FIRST = "page_first" => "First page",
412 PAGE_GOTO = "page_goto" => "Page",
413 PAGE_LAST = "page_last" => "Last page",
414 PAGE_NEXT = "page_next" => "Next page",
415 PAGE_PREV = "page_prev" => "Previous page",
416 PAGE_SIZE = "page_size" => "Entries per page",
417 PAGE_SIZE_N = "page_size_n" => "{} per page",
418 PASSKEY_ADDED = "passkey_added" => "Passkey added",
419 PASSKEY_ADDED_ON = "passkey_added_on" => "Added {}",
420 PASSKEY_LABEL = "passkey_label" => "Name for this passkey",
421 PASSKEY_LAST_USED = "passkey_last_used" => "Last used {}",
422 PASSKEY_NEEDS_NAME = "passkey_needs_name" => "Needs your user name",
423 PASSKEY_NEEDS_NAME_HINT = "passkey_needs_name_hint" => "This passkey is not stored on the authenticator itself, so the server has to look it up. Type your user name on the sign-in page before using it.",
424 PASSKEY_NEVER_USED = "passkey_never_used" => "Never used",
425 PASSKEY_NOT_USED = "passkey_not_used" => "No passkey was used.",
426 PASSKEY_REMOVED = "passkey_removed" => "Passkey removed",
427 PASSKEY_UNSUPPORTED = "passkey_unsupported" => "This browser cannot use passkeys.",
428 PASSKEYS = "passkeys" => "Passkeys",
429 PASSKEYS_HINT = "passkeys_hint" => "A passkey signs you in with your fingerprint, your face or a security key.",
430 PASSWORD = "password" => "Password",
431 PASSWORD_MIN_HINT = "password_min_hint" => "at least 8 characters",
432 PASSWORD_REMOVED = "password_removed" => "Password removed",
433 PASSWORD_RESETS_SIGNIN = "password_resets_signin" => "Setting a password also deletes this account's passkeys and drops any two-factor requirement.",
434 PIM_ACCESS = "pim_access" => "Access",
435 PIM_ADD = "pim_add" => "Add",
436 PIM_ADDRESS = "pim_address" => "Address for apps",
437 PIM_ADDRESS_BOOKS = "pim_address_books" => "Address books",
438 PIM_APP_PASSWORDS = "pim_app_passwords" => "Create an app password",
439 PIM_AUTO = "pim_auto" => "automatic",
440 PIM_BIRTHDAYS = "pim_birthdays" => "Birthdays",
441 PIM_CAL_HINT = "pim_cal_hint" => "Pick a calendar on the left to manage it, or connect a calendar app.",
442 PIM_CALENDAR = "pim_calendar" => "Calendar",
443 PIM_CALENDARS = "pim_calendars" => "Calendars",
444 PIM_CLIENTS = "pim_clients" => "Apps",
445 PIM_COLLECTION_URLS = "pim_collection_urls" => "Addresses of single calendars and address books",
446 PIM_COLOR = "pim_color" => "Color",
447 PIM_CONNECT = "pim_connect" => "Connect an app",
448 PIM_CONNECT_TITLE = "pim_connect_title" => "Connect a calendar or contacts app",
449 PIM_CONTACTS = "pim_contacts" => "Contacts",
450 PIM_CONTACTS_HINT = "pim_contacts_hint" => "Pick an address book on the left to manage it, or connect a contacts app.",
451 PIM_CREATED = "pim_created" => "Created",
452 PIM_CUSTOM_COLOR = "pim_custom_color" => "Custom color",
453 PIM_DEFAULT_HINT = "pim_default_hint" => "This calendar receives invitations. It cannot be deleted.",
454 PIM_DELETE_MSG = "pim_delete_msg" => "Everything in it is deleted. The attendees of your meetings get a cancellation.",
455 PIM_DELETE_TITLE = "pim_delete_title" => "Delete “{}”?",
456 PIM_DESCRIPTION = "pim_description" => "Description",
457 PIM_DETAIL = "pim_detail" => "Details",
458 PIM_DETAIL_BUSY = "pim_detail_busy" => "Busy times only",
459 PIM_DETAIL_FULL = "pim_detail_full" => "All details",
460 PIM_DIRECTORY = "pim_directory" => "Directory",
461 PIM_EXPORT = "pim_export" => "Export",
462 PIM_EXPORTED = "pim_exported" => "Saved as {}",
463 PIM_FEEDS = "pim_feeds" => "Calendar and contact feeds",
464 PIM_FEEDS_HINT = "pim_feeds_hint" => "Every public calendar and address book link on this server.",
465 PIM_FILE_CONTACTS = "pim_file_contacts" => "{} contacts",
466 PIM_FILE_EVENTS = "pim_file_events" => "{} entries",
467 PIM_FILE_INVALID = "pim_file_invalid" => "{} not valid",
468 PIM_GENERAL = "pim_general" => "General",
469 PIM_GENERATED_HINT = "pim_generated_hint" => "The server fills this in. It is read-only.",
470 PIM_HIDE = "pim_hide" => "Hide",
471 PIM_HINT_APPLE = "pim_hint_apple" => "Apple: add a CalDAV and a CardDAV account with the server address. Apple needs HTTPS.",
472 PIM_HINT_DAVX5 = "pim_hint_davx5" => "Android: in DAVx⁵, sign in with URL and user name, and use the server address.",
473 PIM_HINT_GNOME = "pim_hint_gnome" => "GNOME and Evolution: add a CalDAV or WebDAV account with the server address.",
474 PIM_HINT_THUNDERBIRD = "pim_hint_thunderbird" => "Thunderbird: add a network calendar with the server address. Set its email identity to “None”, or it sends no invitations.",
475 PIM_IMPORT_BTN = "pim_import_btn" => "Import",
476 PIM_IMPORT_DONE = "pim_import_done" => "{} new, {} updated.",
477 PIM_IMPORT_INTO = "pim_import_into" => "Import into",
478 PIM_IMPORT_MENU = "pim_import_menu" => "Import into calendar or contacts…",
479 PIM_IMPORT_SKIPPED = "pim_import_skipped" => "{} skipped:",
480 PIM_IMPORT_TITLE = "pim_import_title" => "Import “{}”",
481 PIM_IMPORTING = "pim_importing" => "Importing…",
482 PIM_KIND_RESOURCE = "pim_kind_resource" => "Resource",
483 PIM_KIND_ROOM = "pim_kind_room" => "Room",
484 PIM_LINK_BUSY = "pim_link_busy" => "busy times only",
485 PIM_LINK_FULL = "pim_link_full" => "all details",
486 PIM_LINK_REVOKED = "pim_link_revoked" => "Link revoked",
487 PIM_LINKS = "pim_links" => "Public links",
488 PIM_LINKS_HINT = "pim_links_hint" => "Anyone with the link can subscribe. Google Calendar and Outlook.com need a link without a password.",
489 PIM_LINKS_HINT_CARDS = "pim_links_hint_cards" => "Anyone with the link can download the contacts once. Apps do not follow changes.",
490 PIM_MODE_RO = "pim_mode_ro" => "Read only",
491 PIM_MODE_RW = "pim_mode_rw" => "Read and write",
492 PIM_MODE_SCHEDULE = "pim_mode_schedule" => "Read, write and send invitations",
493 PIM_NAV = "pim_nav" => "Calendar & contacts",
494 PIM_NEW_ADDRESS_BOOK = "pim_new_address_book" => "New address book",
495 PIM_NEW_CALENDAR = "pim_new_calendar" => "New calendar",
496 PIM_NEW_ROOM = "pim_new_room" => "New room",
497 PIM_NO_FEEDS = "pim_no_feeds" => "No public feeds.",
498 PIM_NO_LINKS = "pim_no_links" => "No public links.",
499 PIM_NO_ROOMS = "pim_no_rooms" => "No rooms or resources.",
500 PIM_NO_SHARES = "pim_no_shares" => "Not shared with anyone.",
501 PIM_NO_TARGET = "pim_no_target" => "You have no writable calendar or address book for this file.",
502 PIM_NO_WRITABLE_FOLDER = "pim_no_writable_folder" => "You have no writable folder.",
503 PIM_PASSWORD_HINT = "pim_password_hint" => "Use an app password rather than your account password.",
504 PIM_REMOVE_FROM_LIST = "pim_remove_from_list" => "Remove from my list",
505 PIM_REMOVE_MSG = "pim_remove_msg" => "You no longer see it. The owner can share it again.",
506 PIM_REMOVED = "pim_removed" => "Removed from your list",
507 PIM_ROOM_DELETE_CONFIRM = "pim_room_delete_confirm" => "Delete “{}”? Its bookings are lost.",
508 PIM_ROOM_DISPLAY = "pim_room_display" => "Display name",
509 PIM_ROOM_NAME = "pim_room_name" => "Name (part of its address, cannot change)",
510 PIM_ROOMS = "pim_rooms" => "Rooms and resources",
511 PIM_ROOMS_HINT = "pim_rooms_hint" => "Rooms and resources can be invited to meetings. They accept free times and decline busy ones on their own.",
512 PIM_SAVE_ERR = "pim_save_err" => "Could not save: {}",
513 PIM_SAVE_HERE = "pim_save_here" => "Save here",
514 PIM_SAVE_TO_FOLDER = "pim_save_to_folder" => "Save to folder…",
515 PIM_SERVER_ADDRESS = "pim_server_address" => "Server address",
516 PIM_SERVER_ADDRESS_HINT = "pim_server_address_hint" => "If an app does not find the server, use this address:",
517 PIM_SHARED_BY = "pim_shared_by" => "Shared by {}",
518 PIM_SHARED_OK = "pim_shared_ok" => "Shared with {}",
519 PIM_SHARED_WITH_ME = "pim_shared_with_me" => "Shared with me",
520 PIM_SHARING = "pim_sharing" => "Sharing",
521 PIM_SHARING_HINT = "pim_sharing_hint" => "Share with another account on this server.",
522 PIM_SHOW = "pim_show" => "Show",
523 PIM_SUBSCRIBE = "pim_subscribe" => "Subscribe",
524 PIM_TRANSPARENT = "pim_transparent" => "Show as free: its events do not block time in invitations",
525 PIM_UNSHARE = "pim_unshare" => "Stop sharing",
526 PIM_UNSHARED = "pim_unshared" => "No longer shared",
527 PIM_USER = "pim_user" => "User name",
528 PIM_USER_NAME = "pim_user_name" => "User name",
529 PROFILE = "profile" => "Profile",
530 PROFILE_SAVE_ERR = "profile_save_err" => "Could not save profile: {}",
531 PROFILE_SAVED = "profile_saved" => "Profile saved",
532 PW_SHORT = "pw_short" => "Password must be at least 8 characters.",
533 READ_ONLY_BADGE = "read_only_badge" => "Read-only",
534 READ_ONLY_HINT = "read_only_hint" => "Read-only folder",
535 REFRESH = "refresh" => "Refresh",
536 REFRESH_FOLDERS = "refresh_folders" => "Refresh your folders",
537 REMOVE_FOLDER = "remove_folder" => "Remove folder",
538 REMOVE_PASSWORD = "remove_password" => "Remove password",
539 REMOVE_PASSWORD_DESC = "remove_password_desc" => "Sign in with passkeys only. Needs at least one passkey.",
540 RENAME = "rename" => "Rename",
541 RENAME_TITLE = "rename_title" => "Rename “{}”",
542 RENAMED = "renamed" => "Renamed",
543 REPEAT_PASSWORD = "repeat_password" => "Repeat password",
544 RETRY = "retry" => "Retry",
545 ROOT_DUP_ERR = "root_dup_err" => "That folder is already in the list.",
546 RW_DISABLED = "rw_disabled" => "Writable shares are disabled by the server.",
547 RW_RO_FOLDER = "rw_ro_folder" => "This folder is read-only, so the share is read-only too.",
548 SAVE = "save" => "Save",
549 SAVE_PROFILE = "save_profile" => "Save profile",
550 SAVE_SETTINGS = "save_settings" => "Save settings",
551 SAVED = "saved" => "Saved",
552 SAVING = "saving" => "Saving…",
553 SEARCH = "search" => "Search",
554 SEARCH_BOTH = "search_both" => "Both",
555 SEARCH_COLLAPSE_ALL = "search_collapse_all" => "Collapse all",
556 SEARCH_CONTENT = "search_content" => "Content",
557 SEARCH_EXCLUDES = "search_excludes" => "Excluded from search",
558 SEARCH_EXCLUDES_EMPTY = "search_excludes_empty" => "No folders are excluded.",
559 SEARCH_EXPAND_ALL = "search_expand_all" => "Expand all",
560 SEARCH_FAILED = "search_failed" => "The search failed.",
561 SEARCH_GOTO = "search_goto" => "Show in folder",
562 SEARCH_HERE = "search_here" => "Search here",
563 SEARCH_IN = "search_in" => "Search in…",
564 SEARCH_IN_FOLDER = "search_in_folder" => "Search in this folder",
565 SEARCH_IN_N_FILES = "search_in_n_files" => "in {} files",
566 SEARCH_N_MATCHES = "search_n_matches" => "{} matches",
567 SEARCH_N_RESULTS = "search_n_results" => "{} results",
568 SEARCH_NAME = "search_name" => "Name",
569 SEARCH_NO_RESULTS = "search_no_results" => "no results",
570 SEARCH_PLACEHOLDER = "search_placeholder" => "Search files and their contents",
571 SEARCH_RUN = "search_run" => "Search",
572 SEARCH_SCANNED = "search_scanned" => "scanned {} files",
573 SEARCH_SHOW_MORE = "search_show_more" => "Show {} more",
574 SEARCH_SHOWN_OF = "search_shown_of" => "Showing {} of {}",
575 SEARCH_SKIPPED = "search_skipped" => "{} skipped (over 10 MiB)",
576 SEARCH_STOP = "search_stop" => "Stop",
577 SEARCH_STOPPED = "search_stopped" => "stopped · {} results",
578 SEARCH_TOOK = "search_took" => "{} ms",
579 SEARCHING = "searching" => "searching…",
580 SECOND_FACTOR_PASSKEY = "second_factor_passkey" => "Now confirm with your passkey.",
581 SECOND_FACTOR_PASSWORD = "second_factor_password" => "Enter the password for {}.",
582 SECURITY = "security" => "Security",
583 SELECT_FOLDER_MSG = "select_folder_msg" => "Choose a folder from the sidebar to start browsing.",
584 SELECT_FOLDER_TITLE = "select_folder_title" => "Select a folder",
585 SERVER = "server" => "Server",
586 SERVER_ROOT = "server_root" => "Server root",
587 SERVER_UNREACHABLE = "server_unreachable" => "The server is not reachable.",
588 SETTINGS = "settings" => "Settings",
589 SETTINGS_SAVE_ERR = "settings_save_err" => "Could not save settings: {}",
590 SETTINGS_SAVED = "settings_saved" => "Settings saved",
591 SETUP_INTRO = "setup_intro" => "First boot: create the admin account. This user can manage other users and server settings.",
592 SETUP_PW_MISMATCH = "setup_pw_mismatch" => "Passwords don't match.",
593 SHARE = "share" => "Share",
594 SHARE_CREATE_ERR = "share_create_err" => "Could not create share: {}",
595 SHARE_DELETE_ERR = "share_delete_err" => "Could not delete share",
596 SHARE_DELETED = "share_deleted" => "Share deleted",
597 SHARE_DIALOG_HINT = "share_dialog_hint" => "Create a link for this item. Writable links let viewers upload and edit.",
598 SHARE_EXPIRED = "share_expired" => "Share expired",
599 SHARE_EXPIRED_MSG = "share_expired_msg" => "This share link is no longer active.",
600 SHARE_LINK = "share_link" => "Share link",
601 SHARE_LOCKED_TITLE = "share_locked_title" => "Password required",
602 SHARE_NOT_FOUND = "share_not_found" => "Share not found",
603 SHARE_NOT_FOUND_MSG = "share_not_found_msg" => "This link is invalid or the share was removed.",
604 SHARE_OWNER_DISABLED = "share_owner_disabled" => "deactivated account",
605 SHARE_PASSWORD_HINT = "share_password_hint" => "Optional. Visitors must enter it before the share opens, at least 8 characters.",
606 SHARE_PERM_RO = "share_perm_ro" => "Anyone with this link can read “{}”.",
607 SHARE_PERM_RW = "share_perm_rw" => "Anyone with this link can read and write “{}”.",
608 SHARE_PROTECTED = "share_protected" => "Password protected",
609 SHARE_TITLE = "share_title" => "Share {}",
610 SHARES = "shares" => "Shares",
611 SHARES_DELETE_ERR = "shares_delete_err" => "Could not delete shares",
612 SHARES_EMPTY_HINT = "shares_empty_hint" => "Right-click a file or folder and choose “Share” to create a link.",
613 SHARES_VIEW_HINT = "shares_view_hint" => "Links you created. Right-click a file or folder and choose “Share” to add one.",
614 SIGN_IN = "sign_in" => "Sign in",
615 SIGNIN_BOTH = "signin_both" => "Password and passkey",
616 SIGNIN_BOTH_DESC = "signin_both_desc" => "Both are required. WebDAV then needs an app password, because a mount can only send a password.",
617 SIGNIN_EITHER = "signin_either" => "Password or passkey",
618 SIGNIN_EITHER_DESC = "signin_either_desc" => "Either one on its own signs you in.",
619 SIGNIN_REQUIREMENT = "signin_requirement" => "Sign-in requirement",
620 SINGLE_CLICK_DESC = "single_click_desc" => "When on, a single click opens an entry and Ctrl+click selects it. When off, a single click selects and a double click opens.",
621 SINGLE_CLICK_LABEL = "single_click_label" => "Use single click to open",
622 SIZE = "size" => "Size",
623 SOME_FILES_EXIST = "some_files_exist" => "Some files already exist",
624 SORT_ASC = "sort_asc" => "Ascending",
625 SORT_BY = "sort_by" => "Sort by",
626 SORT_DESC = "sort_desc" => "Descending",
627 THEME_AUTO = "theme_auto" => "Auto",
628 THEME_DARK = "theme_dark" => "Dark",
629 THEME_LIGHT = "theme_light" => "Light",
630 THEME_TITLE = "theme_title" => "Theme: {} (click to switch)",
631 THUMBNAILS_DESC = "thumbnails_desc" => "Show a small preview instead of an icon for images and videos in grid view.",
632 THUMBNAILS_LABEL = "thumbnails_label" => "Show thumbnails",
633 TYPE = "type" => "Type",
634 UNLOCK = "unlock" => "Open share",
635 UNSAVED_CHANGES = "unsaved_changes" => "Unsaved changes",
636 UNTIL = "until" => "Until",
637 UPLOAD_ABORT = "upload_abort" => "Abort",
638 UPLOAD_ABORTED = "upload_aborted" => "Aborted",
639 UPLOAD_ACTIVE_N = "upload_active_n" => "{} active",
640 UPLOAD_APPLY_ALL = "upload_apply_all" => "Apply to files that appear during the upload",
641 UPLOAD_CHECK_FAILED = "upload_check_failed" => "Could not check for existing files: {}",
642 UPLOAD_CLEAR = "upload_clear" => "Remove from list",
643 UPLOAD_CLEAR_FINISHED = "upload_clear_finished" => "Clear finished",
644 UPLOAD_COLLAPSE = "upload_collapse" => "Collapse",
645 UPLOAD_COMPLETE = "upload_complete" => "Upload complete",
646 UPLOAD_CONFLICT_QUESTION = "upload_conflict_question" => "The following files already exist. Overwrite or skip them?",
647 UPLOAD_DROP_HINT = "upload_drop_hint" => "Drop to upload here",
648 UPLOAD_ERRORS_N = "upload_errors_n" => "{} failed",
649 UPLOAD_EXISTS_ASK = "upload_exists_ask" => "“{}” appeared on the server during the upload.",
650 UPLOAD_EXPAND = "upload_expand" => "Expand",
651 UPLOAD_FAILED = "upload_failed" => "Failed",
652 UPLOAD_FILES = "upload_files" => "Upload files",
653 UPLOAD_FOLDER = "upload_folder" => "Upload folder",
654 UPLOAD_N_FILES = "upload_n_files" => "{} files",
655 UPLOAD_PAUSE = "upload_pause" => "Pause",
656 UPLOAD_PAUSED = "upload_paused" => "Paused",
657 UPLOAD_PREPARING = "upload_preparing" => "Preparing…",
658 UPLOAD_RESUME = "upload_resume" => "Resume",
659 UPLOAD_SHOW_GRAPH = "upload_show_graph" => "Details and speed graph",
660 UPLOAD_SKIP = "upload_skip" => "Skip",
661 UPLOAD_SKIPPED_N = "upload_skipped_n" => "{} skipped",
662 UPLOAD_SPEED = "upload_speed" => "{}/s",
663 UPLOAD_WAITING = "upload_waiting" => "Waiting for your answer",
664 UPLOADS = "uploads" => "Uploads",
665 UPLOADS_EMPTY = "uploads_empty" => "No uploads yet",
666 USE_PASSKEY = "use_passkey" => "Use a passkey",
667 USE_PASSKEY_HINT = "use_passkey_hint" => "Leave the name empty unless your passkey needs it.",
668 USER_CREATED = "user_created" => "User created",
669 USER_DELETE_ERR = "user_delete_err" => "Could not delete user",
670 USER_DISABLED = "user_disabled" => "disabled",
671 USER_NAME_EXAMPLE = "user_name_example" => "e.g. alice",
672 USER_SAVE_ERR = "user_save_err" => "Could not save user: {}",
673 USER_UPDATED = "user_updated" => "User updated",
674 USER_YOU = "user_you" => "(you)",
675 USERS = "users" => "Users",
676 YOUR_SHARES = "your_shares" => "Your shares",
677}
678
679/// German translations.
680const DE: &[(&str, &str)] = &[
681 ("active_can_signin", "Aktiv (kann sich anmelden)"),
682 ("add_app_password", "App-Passwort erstellen"),
683 ("add_folder", "Ordner hinzufügen…"),
684 ("add_here", "Diesen Ordner hinzufügen"),
685 ("add_passkey", "Passkey hinzufügen"),
686 ("administrator", "Administrator"),
687 ("all_shares", "Alle Freigaben"),
688 (
689 "all_shares_hint",
690 "Jeder Link auf diesem Server, gruppiert nach dem Konto, das ihn erstellt hat.",
691 ),
692 ("allow_editing", "Bearbeitung erlauben (lesen/schreiben)"),
693 ("allow_rw_shares", "Schreibbare Freigaben erlauben"),
694 (
695 "allow_rw_shares_desc",
696 "Benutzern erlauben, schreibbare Freigabelinks zu erstellen. Standardmäßig aus.",
697 ),
698 ("and_more", "…und {} weitere"),
699 ("app_password_label", "Name für dieses App-Passwort"),
700 ("app_password_removed", "App-Passwort widerrufen"),
701 (
702 "app_password_secret_once",
703 "Jetzt kopieren. Es wird nie wieder angezeigt.",
704 ),
705 ("app_passwords", "App-Passwörter"),
706 (
707 "app_passwords_hint",
708 "Ein App-Passwort gilt nur für WebDAV, nicht für diese Seite. Nutze pro Client eines statt deines Kontopassworts.",
709 ),
710 ("cancel", "Abbrechen"),
711 ("cant_delete_self", "Sie können sich nicht selbst löschen"),
712 ("close", "Schließen"),
713 ("close_esc", "Schließen (Esc)"),
714 ("copied", "Kopiert"),
715 ("copy", "Kopieren"),
716 ("copy_dav_link", "WebDAV-Link kopieren"),
717 ("copy_here", "Hierher kopieren"),
718 ("copy_link", "Link kopieren"),
719 ("copy_manual", "Link manuell kopieren"),
720 ("copy_n_to", "{} Elemente kopieren nach…"),
721 ("copy_to", "„{}“ kopieren nach…"),
722 ("create", "Erstellen"),
723 ("create_admin", "Administrator-Konto erstellen"),
724 ("create_link", "Link erstellen"),
725 ("create_user", "Benutzer erstellen"),
726 ("creating", "Wird erstellt…"),
727 ("custom", "Benutzerdefiniert…"),
728 (
729 "default_root_desc",
730 "Diesen Ordner beim Laden der Seite und über den Home-Link öffnen.",
731 ),
732 ("default_root_label", "Standardordner"),
733 ("default_root_none", "Ordnerübersicht"),
734 ("delete", "Löschen"),
735 ("delete_all", "Alle löschen"),
736 (
737 "delete_all_msg",
738 "Alle {} Freigabelinks löschen? Jeder, der sie besitzt, verliert den Zugriff. Das kann nicht rückgängig gemacht werden.",
739 ),
740 ("delete_all_title", "Alle Freigaben löschen?"),
741 (
742 "delete_all_user_msg",
743 "Alle Freigabelinks von „{}“ löschen? Jeder, der sie besitzt, verliert den Zugriff. Das kann nicht rückgängig gemacht werden.",
744 ),
745 (
746 "delete_folder_msg",
747 "Ordner „{}“ mit allem Inhalt löschen?\nDas kann nicht rückgängig gemacht werden.",
748 ),
749 (
750 "delete_msg",
751 "„{}“ löschen?\nDas kann nicht rückgängig gemacht werden.",
752 ),
753 (
754 "delete_n_msg",
755 "{} Elemente löschen?\nDas kann nicht rückgängig gemacht werden.",
756 ),
757 (
758 "delete_partial",
759 "{} von {} Freigaben konnten nicht gelöscht werden",
760 ),
761 ("delete_share", "Freigabe löschen"),
762 ("delete_user", "Benutzer löschen"),
763 (
764 "delete_user_confirm",
765 "Benutzer „{}“ löschen? Das kann nicht rückgängig gemacht werden.",
766 ),
767 ("deleted", "Gelöscht"),
768 ("deleted_n_shares", "{} Freigabe(n) gelöscht"),
769 ("discard", "Verwerfen"),
770 (
771 "discard_question",
772 "Änderungen verwerfen und den Editor schließen?",
773 ),
774 ("dismiss", "Ausblenden"),
775 ("dismiss_error", "Fehler ausblenden"),
776 ("done", "Fertig"),
777 ("download", "Herunterladen"),
778 (
779 "download_formats_msg",
780 "Archivformat für den Ordner wählen.",
781 ),
782 ("download_started", "Download gestartet"),
783 ("download_title", "„{}“ herunterladen"),
784 ("edit", "Bearbeiten"),
785 ("edit_user_title", "„{}“ bearbeiten"),
786 ("empty_folder", "Dieser Ordner ist leer."),
787 (k::ERR_ADMIN_ONLY, "nur für Administratoren"),
788 (k::ERR_ALREADY_SET_UP, "Server ist bereits eingerichtet"),
789 (
790 k::ERR_APP_PASSWORD_LIMIT,
791 "Dieses Konto hat bereits so viele App-Passwörter, wie es haben darf.",
792 ),
793 (k::ERR_APP_PASSWORD_NOT_FOUND, "Kein solches App-Passwort."),
794 (k::ERR_BAD_ACTION, "action=content erwartet"),
795 (k::ERR_BAD_BODY, "ungültiger Anfrageinhalt"),
796 (k::ERR_BAD_EXPIRES_AT, "das Ablaufdatum ist ungültig"),
797 (
798 k::ERR_BAD_FORMAT,
799 "das Format muss eines der folgenden sein: zip, tar, tar.gz, tar.zst",
800 ),
801 (
802 k::ERR_BAD_MULTIPART,
803 "multipart/form-data mit Boundary erwartet",
804 ),
805 (k::ERR_BAD_PART_NAME, "ungültiger Part-Name"),
806 (
807 k::ERR_BAD_POST,
808 "POST erwartet einen Multipart-Upload, eine JSON-Mutation oder ?action=mkdir/create-file",
809 ),
810 (k::ERR_BAD_UPLOAD, "ungültige Upload-Daten"),
811 (k::ERR_BAD_UPLOAD_PATH, "ungültiger Dateipfad im Upload"),
812 (
813 k::ERR_CHALLENGE_EXPIRED,
814 "Das hat zu lange gedauert. Bitte erneut versuchen.",
815 ),
816 (
817 k::ERR_DEFAULT_CALENDAR,
818 "Der Kalender, der Einladungen empfängt, kann nicht gelöscht werden.",
819 ),
820 (k::ERR_DST_REQUIRED, "dst_root_id ist erforderlich"),
821 (k::ERR_FILE_NAME_REQUIRED, "ein Dateiname ist erforderlich"),
822 (k::ERR_FILES_EXIST, "einige Dateien existieren bereits"),
823 (
824 k::ERR_FOLDER_EXISTS,
825 "ein Ordner mit diesem Namen existiert bereits",
826 ),
827 (
828 k::ERR_FOLDER_NAME_REQUIRED,
829 "ein Ordnername ist erforderlich",
830 ),
831 (k::ERR_FS_CONFLICT, "existiert bereits"),
832 (k::ERR_FS_FORBIDDEN, "Zugriff verweigert"),
833 (k::ERR_FS_NOT_A_DIR, "kein Ordner"),
834 (k::ERR_FS_NOT_FOUND, "Ordner nicht gefunden"),
835 (
836 k::ERR_FS_ROOT_MISSING,
837 "der konfigurierte Ordner existiert nicht mehr",
838 ),
839 (k::ERR_INTERNAL, "interner Fehler"),
840 (k::ERR_INVALID_CREDENTIALS, "Name oder Passwort ungültig"),
841 (
842 k::ERR_INVALID_DEFAULT_ROOT,
843 "Der Standardordner gehört nicht zu Ihren Ordnern",
844 ),
845 (k::ERR_INVALID_LANGUAGE, "ungültiges Sprachkürzel"),
846 (
847 k::ERR_LAST_ADMIN,
848 "der letzte aktive Administrator kann nicht entfernt werden",
849 ),
850 (
851 k::ERR_LAST_ADMIN_DELETE,
852 "der letzte aktive Administrator kann nicht gelöscht werden",
853 ),
854 (
855 k::ERR_LOCKED_OUT,
856 "Dann hätte das Konto keine Anmeldemöglichkeit mehr.",
857 ),
858 (
859 k::ERR_MODE_NEEDS_PASSKEY,
860 "Fügen Sie einen Passkey hinzu, bevor Sie beides verlangen.",
861 ),
862 (
863 k::ERR_MODE_NEEDS_PASSWORD,
864 "Setzen Sie ein Passwort, bevor Sie beides verlangen.",
865 ),
866 (k::ERR_NAME_LENGTH, "der Name muss 1–64 Zeichen haben"),
867 (k::ERR_NEW_NAME_REQUIRED, "new_name ist erforderlich"),
868 (k::ERR_NO_FILES_UPLOADED, "keine Dateien hochgeladen"),
869 (k::ERR_NO_SUCH_FOLDER, "dieser Ordner existiert nicht"),
870 (k::ERR_NOT_A_FILE, "keine Datei"),
871 (k::ERR_NOT_SIGNED_IN, "nicht angemeldet"),
872 (
873 k::ERR_OWN_ACCOUNT,
874 "Sie können Ihr eigenes Konto nicht deaktivieren",
875 ),
876 (
877 k::ERR_OWN_ADMIN,
878 "Sie können Ihre eigenen Administratorrechte nicht entfernen",
879 ),
880 (
881 k::ERR_OWN_DELETE,
882 "Sie können Ihr eigenes Konto nicht löschen",
883 ),
884 (k::ERR_PART_NO_NAME, "Part ohne Namen"),
885 (
886 k::ERR_PASSKEY_DUPLICATE,
887 "Dieser Passkey ist bereits registriert.",
888 ),
889 (
890 k::ERR_PASSKEY_FAILED,
891 "Dieser Passkey konnte nicht verwendet werden.",
892 ),
893 (
894 k::ERR_PASSKEY_LAST_CREDENTIAL,
895 "Setzen Sie ein Passwort, bevor Sie den letzten Passkey entfernen.",
896 ),
897 (
898 k::ERR_PASSKEY_LIMIT,
899 "Dieses Konto hat bereits so viele Passkeys wie erlaubt.",
900 ),
901 (
902 k::ERR_PASSKEY_MALFORMED,
903 "Der Browser hat unlesbare Daten gesendet.",
904 ),
905 (k::ERR_PASSKEY_NOT_FOUND, "Passkey nicht gefunden."),
906 (
907 k::ERR_PASSKEY_ORIGIN,
908 "Passkeys sind für eine andere Adresse eingerichtet.",
909 ),
910 (
911 k::ERR_PASSKEY_UNAVAILABLE,
912 "Passkeys sind hier nicht verfügbar.",
913 ),
914 (
915 k::ERR_PASSWORD_LAST_CREDENTIAL,
916 "Fügen Sie einen Passkey hinzu, bevor Sie das Passwort entfernen.",
917 ),
918 (
919 k::ERR_PASSWORD_SHORT,
920 "das Passwort muss mindestens 8 Zeichen lang sein",
921 ),
922 (
923 k::ERR_PATH_REQUIRED,
924 "ein Pfad innerhalb des Ordners ist erforderlich",
925 ),
926 (k::ERR_READ_ONLY_FOLDER, "schreibgeschützter Ordner"),
927 (
928 k::ERR_REQUIRED_BY_MODE,
929 "Dieses Konto verlangt Passwort und Passkey.",
930 ),
931 (k::ERR_ROOT_FORBIDDEN, "kein Zugriff auf diesen Ordner"),
932 (
933 k::ERR_RW_RO_FOLDER,
934 "dieser Ordner ist für Sie schreibgeschützt und kann nicht schreibbar freigegeben werden",
935 ),
936 (
937 k::ERR_RW_SHARES_DISABLED,
938 "schreibbare Freigaben sind deaktiviert",
939 ),
940 (
941 k::ERR_SAVE_FAILED,
942 "die Datei konnte nicht gespeichert werden",
943 ),
944 (
945 k::ERR_SEARCH_BAD_SCOPE,
946 "Bereich muss name, content oder both sein",
947 ),
948 (
949 k::ERR_SEARCH_FORBIDDEN,
950 "Suche erfordert eine angemeldete Sitzung",
951 ),
952 (
953 k::ERR_SESSION_EXPIRED,
954 "Sitzung abgelaufen, bitte erneut anmelden",
955 ),
956 (k::ERR_SHARE_EXPIRED, "diese Freigabe ist abgelaufen"),
957 (k::ERR_SHARE_LOCKED, "Diese Freigabe ist passwortgeschützt."),
958 (
959 k::ERR_SHARE_NO_PASSWORD,
960 "Diese Freigabe hat kein Passwort.",
961 ),
962 (k::ERR_SHARE_NOT_FOUND, "Freigabe nicht gefunden"),
963 (
964 k::ERR_SHARE_TOKEN_FORBIDDEN,
965 "ein Freigabetoken kann hier nicht verwendet werden; bitte anmelden",
966 ),
967 (k::ERR_SHARE_WRONG_PASSWORD, "Falsches Passwort."),
968 (k::ERR_TOO_LARGE_PREVIEW, "Datei zu groß für eine Vorschau"),
969 (k::ERR_TOO_LARGE_SAVE, "Datei zu groß zum Speichern"),
970 (
971 k::ERR_USER_EXISTS,
972 "ein Benutzer mit diesem Namen existiert bereits",
973 ),
974 (k::ERR_USER_NOT_FOUND, "Benutzer nicht gefunden"),
975 (
976 "exclude_dup_err",
977 "Dieser Ordner ist bereits ausgeschlossen.",
978 ),
979 ("exclude_folder", "Ordner ausschließen…"),
980 ("exclude_here", "Diesen Ordner ausschließen"),
981 (
982 "exclude_root_err",
983 "Das gesamte Stammverzeichnis kann nicht ausgeschlossen werden; das würde die Suche abschalten.",
984 ),
985 ("expires", "Läuft ab"),
986 ("expires_at", "Läuft ab: {}"),
987 ("expiry_1d", "1 Tag"),
988 ("expiry_1h", "1 Stunde"),
989 ("expiry_1mo", "1 Monat"),
990 ("expiry_1w", "1 Woche"),
991 ("file", "Datei"),
992 ("file_changed", "Datei auf der Festplatte geändert"),
993 ("file_created", "Datei erstellt"),
994 ("file_info", "Datei-Info"),
995 ("file_name", "Dateiname"),
996 ("file_not_found", "Datei nicht gefunden"),
997 ("files", "Dateien"),
998 ("fmt_tar", "Tar"),
999 ("fmt_targz", "Tar + gzip"),
1000 ("fmt_tarzst", "Tar + zstd"),
1001 ("fmt_zip", "Zip"),
1002 ("folder", "Ordner"),
1003 ("folder_created", "Ordner erstellt"),
1004 (
1005 "folder_gone_msg",
1006 "Dieser Ordner ist nicht mehr verfügbar. Wählen Sie links einen anderen aus.",
1007 ),
1008 ("folder_gone_title", "Ordner nicht verfügbar"),
1009 ("folder_name", "Ordnername"),
1010 ("folders", "Ordner"),
1011 (
1012 "folders_paths_hint",
1013 "Pfade sind relativ zur Serverwurzel. „.“ ist der gesamte Wurzelordner.",
1014 ),
1015 ("grid_view", "Kachelansicht"),
1016 ("info", "Info"),
1017 ("keep_editing", "Weiter bearbeiten"),
1018 ("lang_auto", "Automatisch"),
1019 ("lang_de", "Deutsch"),
1020 ("lang_en", "Englisch"),
1021 ("lang_fr", "Französisch"),
1022 ("language", "Sprache"),
1023 (
1024 "language_desc",
1025 "Die Sprache der Benutzeroberfläche. „Automatisch“ verwendet die Sprache Ihres Browsers.",
1026 ),
1027 ("link_copied", "Link in die Zwischenablage kopiert"),
1028 ("list_view", "Listenansicht"),
1029 ("load_latest", "Neueste Version laden"),
1030 ("loading", "Wird geladen…"),
1031 ("loading_share", "Freigabe wird geladen…"),
1032 ("location", "Ort"),
1033 ("log_out", "Abmelden"),
1034 ("login_subtitle", "Anmelden, um fortzufahren."),
1035 ("manage", "Verwalten"),
1036 ("menu", "Menü"),
1037 ("meta_created", "erstellt: {}"),
1038 ("meta_expires", "läuft ab: {}"),
1039 ("mode_ro", "nur lesen"),
1040 ("mode_rw", "lesen/schreiben"),
1041 ("modified", "Geändert"),
1042 (
1043 "modified_after",
1044 "Diese Datei wurde nach dem Öffnen geändert. „Neueste Version laden“ verwirft Ihre ungespeicherten Änderungen; „Überschreiben“ behält Ihre Version bei.",
1045 ),
1046 ("more_actions", "Weitere Aktionen"),
1047 ("move", "Verschieben"),
1048 ("move_here", "Hierher verschieben"),
1049 ("move_n_to", "{} Elemente verschieben nach…"),
1050 ("move_to", "„{}“ verschieben nach…"),
1051 ("moved", "Verschoben"),
1052 ("name", "Name"),
1053 ("name_taken", "Name wird bereits verwendet"),
1054 (
1055 "need_folder",
1056 "Dem Benutzer muss mindestens ein Ordner zugewiesen werden.",
1057 ),
1058 ("never", "Nie"),
1059 ("never_expires", "Läuft nie ab"),
1060 ("new_file", "Neue Datei"),
1061 ("new_folder", "Neuer Ordner"),
1062 ("new_name", "Neuer Name"),
1063 ("new_password", "Neues Passwort"),
1064 (
1065 "new_password_hint",
1066 "Leer lassen, um das aktuelle Passwort zu behalten.",
1067 ),
1068 (
1069 "new_password_keep",
1070 "Neues Passwort (leer lassen, um beizubehalten)",
1071 ),
1072 ("new_user", "Neuer Benutzer"),
1073 ("no_app_passwords", "Keine App-Passwörter."),
1074 (
1075 "no_folders_msg",
1076 "Ein Administrator hat Ihnen noch keine Ordner zugewiesen.",
1077 ),
1078 ("no_folders_title", "Keine Ordner verfügbar"),
1079 ("no_passkeys", "Noch keine Passkeys."),
1080 (
1081 "no_password_set",
1082 "Dieses Konto meldet sich nur mit Passkeys an.",
1083 ),
1084 ("no_preview", "Keine Vorschau verfügbar"),
1085 ("no_preview_msg", "Die App kann „{}“ hier nicht anzeigen."),
1086 ("no_shares", "Noch keine Freigaben"),
1087 ("no_subfolders", "Keine Unterordner"),
1088 ("no_users", "Keine Benutzer."),
1089 ("open", "Öffnen"),
1090 ("open_in_new_tab", "In neuem Tab öffnen"),
1091 ("open_menu", "Menü öffnen"),
1092 ("or_label", "oder"),
1093 ("overwrite", "Überschreiben"),
1094 (
1095 "overwrite_question",
1096 "Die folgenden Dateien existieren bereits. Überschreiben?",
1097 ),
1098 ("page_first", "Erste Seite"),
1099 ("page_goto", "Seite"),
1100 ("page_last", "Letzte Seite"),
1101 ("page_next", "Nächste Seite"),
1102 ("page_prev", "Vorherige Seite"),
1103 ("page_size", "Einträge pro Seite"),
1104 ("page_size_n", "{} pro Seite"),
1105 ("passkey_added", "Passkey hinzugefügt"),
1106 ("passkey_added_on", "Hinzugefügt {}"),
1107 ("passkey_label", "Name für diesen Passkey"),
1108 ("passkey_last_used", "Zuletzt benutzt {}"),
1109 ("passkey_needs_name", "Braucht Ihren Benutzernamen"),
1110 (
1111 "passkey_needs_name_hint",
1112 "Dieser Passkey liegt nicht im Authenticator selbst, der Server muss ihn nachschlagen. Geben Sie Ihren Benutzernamen auf der Anmeldeseite ein, bevor Sie ihn verwenden.",
1113 ),
1114 ("passkey_never_used", "Nie benutzt"),
1115 ("passkey_not_used", "Es wurde kein Passkey verwendet."),
1116 ("passkey_removed", "Passkey entfernt"),
1117 (
1118 "passkey_unsupported",
1119 "Dieser Browser kann keine Passkeys verwenden.",
1120 ),
1121 ("passkeys", "Passkeys"),
1122 (
1123 "passkeys_hint",
1124 "Ein Passkey meldet Sie mit Fingerabdruck, Gesicht oder Sicherheitsschlüssel an.",
1125 ),
1126 ("password", "Passwort"),
1127 ("password_min_hint", "mindestens 8 Zeichen"),
1128 ("password_removed", "Passwort entfernt"),
1129 (
1130 "password_resets_signin",
1131 "Ein neues Passwort löscht auch die Passkeys dieses Kontos und hebt eine Zwei-Faktor-Pflicht auf.",
1132 ),
1133 ("pim_access", "Zugriff"),
1134 ("pim_add", "Hinzufügen"),
1135 ("pim_address", "Adresse für Apps"),
1136 ("pim_address_books", "Adressbücher"),
1137 ("pim_app_passwords", "App-Passwort erstellen"),
1138 ("pim_auto", "automatisch"),
1139 ("pim_birthdays", "Geburtstage"),
1140 (
1141 "pim_cal_hint",
1142 "Wählen Sie links einen Kalender, um ihn zu verwalten, oder verbinden Sie eine Kalender-App.",
1143 ),
1144 ("pim_calendar", "Kalender"),
1145 ("pim_calendars", "Kalender"),
1146 ("pim_clients", "Apps"),
1147 (
1148 "pim_collection_urls",
1149 "Adressen einzelner Kalender und Adressbücher",
1150 ),
1151 ("pim_color", "Farbe"),
1152 ("pim_connect", "App verbinden"),
1153 ("pim_connect_title", "Kalender- oder Kontakte-App verbinden"),
1154 ("pim_contacts", "Kontakte"),
1155 (
1156 "pim_contacts_hint",
1157 "Wählen Sie links ein Adressbuch, um es zu verwalten, oder verbinden Sie eine Kontakte-App.",
1158 ),
1159 ("pim_created", "Erstellt"),
1160 ("pim_custom_color", "Eigene Farbe"),
1161 (
1162 "pim_default_hint",
1163 "Dieser Kalender empfängt Einladungen. Er kann nicht gelöscht werden.",
1164 ),
1165 (
1166 "pim_delete_msg",
1167 "Alles darin wird gelöscht. Die Teilnehmer Ihrer Termine erhalten eine Absage.",
1168 ),
1169 ("pim_delete_title", "„{}“ löschen?"),
1170 ("pim_description", "Beschreibung"),
1171 ("pim_detail", "Details"),
1172 ("pim_detail_busy", "Nur belegte Zeiten"),
1173 ("pim_detail_full", "Alle Details"),
1174 ("pim_directory", "Verzeichnis"),
1175 ("pim_export", "Exportieren"),
1176 ("pim_exported", "Gespeichert als {}"),
1177 ("pim_feeds", "Kalender- und Kontakt-Feeds"),
1178 (
1179 "pim_feeds_hint",
1180 "Jeder öffentliche Kalender- und Adressbuch-Link auf diesem Server.",
1181 ),
1182 ("pim_file_contacts", "{} Kontakte"),
1183 ("pim_file_events", "{} Einträge"),
1184 ("pim_file_invalid", "{} ungültig"),
1185 ("pim_general", "Allgemein"),
1186 (
1187 "pim_generated_hint",
1188 "Der Server füllt dies aus. Es ist schreibgeschützt.",
1189 ),
1190 ("pim_hide", "Ausblenden"),
1191 (
1192 "pim_hint_apple",
1193 "Apple: Fügen Sie ein CalDAV- und ein CardDAV-Konto mit der Serveradresse hinzu. Apple braucht HTTPS.",
1194 ),
1195 (
1196 "pim_hint_davx5",
1197 "Android: Melden Sie sich in DAVx⁵ mit URL und Benutzername an und nutzen Sie die Serveradresse.",
1198 ),
1199 (
1200 "pim_hint_gnome",
1201 "GNOME und Evolution: Fügen Sie ein CalDAV- oder WebDAV-Konto mit der Serveradresse hinzu.",
1202 ),
1203 (
1204 "pim_hint_thunderbird",
1205 "Thunderbird: Fügen Sie einen Netzwerkkalender mit der Serveradresse hinzu. Setzen Sie seine E-Mail-Identität auf „Keine“, sonst verschickt er keine Einladungen.",
1206 ),
1207 ("pim_import_btn", "Importieren"),
1208 ("pim_import_done", "{} neu, {} aktualisiert."),
1209 ("pim_import_into", "Importieren in"),
1210 ("pim_import_menu", "In Kalender oder Kontakte importieren…"),
1211 ("pim_import_skipped", "{} übersprungen:"),
1212 ("pim_import_title", "„{}“ importieren"),
1213 ("pim_importing", "Importiere…"),
1214 ("pim_kind_resource", "Ressource"),
1215 ("pim_kind_room", "Raum"),
1216 ("pim_link_busy", "nur belegte Zeiten"),
1217 ("pim_link_full", "alle Details"),
1218 ("pim_link_revoked", "Link widerrufen"),
1219 ("pim_links", "Öffentliche Links"),
1220 (
1221 "pim_links_hint",
1222 "Jeder mit dem Link kann ihn abonnieren. Google Kalender und Outlook.com brauchen einen Link ohne Passwort.",
1223 ),
1224 (
1225 "pim_links_hint_cards",
1226 "Jeder mit dem Link kann die Kontakte einmal herunterladen. Apps folgen keinen Änderungen.",
1227 ),
1228 ("pim_mode_ro", "Nur lesen"),
1229 ("pim_mode_rw", "Lesen und schreiben"),
1230 (
1231 "pim_mode_schedule",
1232 "Lesen, schreiben und Einladungen senden",
1233 ),
1234 ("pim_nav", "Kalender & Kontakte"),
1235 ("pim_new_address_book", "Neues Adressbuch"),
1236 ("pim_new_calendar", "Neuer Kalender"),
1237 ("pim_new_room", "Neuer Raum"),
1238 ("pim_no_feeds", "Keine öffentlichen Feeds."),
1239 ("pim_no_links", "Keine öffentlichen Links."),
1240 ("pim_no_rooms", "Keine Räume oder Ressourcen."),
1241 ("pim_no_shares", "Mit niemandem geteilt."),
1242 (
1243 "pim_no_target",
1244 "Sie haben keinen beschreibbaren Kalender und kein beschreibbares Adressbuch für diese Datei.",
1245 ),
1246 (
1247 "pim_no_writable_folder",
1248 "Sie haben keinen beschreibbaren Ordner.",
1249 ),
1250 (
1251 "pim_password_hint",
1252 "Nutzen Sie ein App-Passwort statt Ihres Kontopassworts.",
1253 ),
1254 ("pim_remove_from_list", "Aus meiner Liste entfernen"),
1255 (
1256 "pim_remove_msg",
1257 "Sie sehen ihn nicht mehr. Der Eigentümer kann ihn erneut teilen.",
1258 ),
1259 ("pim_removed", "Aus Ihrer Liste entfernt"),
1260 (
1261 "pim_room_delete_confirm",
1262 "„{}“ löschen? Seine Buchungen gehen verloren.",
1263 ),
1264 ("pim_room_display", "Anzeigename"),
1265 ("pim_room_name", "Name (Teil der Adresse, nicht änderbar)"),
1266 ("pim_rooms", "Räume und Ressourcen"),
1267 (
1268 "pim_rooms_hint",
1269 "Räume und Ressourcen können zu Terminen eingeladen werden. Sie nehmen freie Zeiten an und lehnen belegte selbst ab.",
1270 ),
1271 ("pim_save_err", "Speichern fehlgeschlagen: {}"),
1272 ("pim_save_here", "Hier speichern"),
1273 ("pim_save_to_folder", "In Ordner speichern…"),
1274 ("pim_server_address", "Serveradresse"),
1275 (
1276 "pim_server_address_hint",
1277 "Wenn eine App den Server nicht findet, nutzen Sie diese Adresse:",
1278 ),
1279 ("pim_shared_by", "Geteilt von {}"),
1280 ("pim_shared_ok", "Geteilt mit {}"),
1281 ("pim_shared_with_me", "Mit mir geteilt"),
1282 ("pim_sharing", "Teilen"),
1283 (
1284 "pim_sharing_hint",
1285 "Mit einem anderen Konto auf diesem Server teilen.",
1286 ),
1287 ("pim_show", "Einblenden"),
1288 ("pim_subscribe", "Abonnieren"),
1289 (
1290 "pim_transparent",
1291 "Als frei anzeigen: Seine Termine blockieren bei Einladungen keine Zeit",
1292 ),
1293 ("pim_unshare", "Nicht mehr teilen"),
1294 ("pim_unshared", "Nicht mehr geteilt"),
1295 ("pim_user", "Benutzername"),
1296 ("pim_user_name", "Benutzername"),
1297 ("profile", "Profil"),
1298 (
1299 "profile_save_err",
1300 "Profil konnte nicht gespeichert werden: {}",
1301 ),
1302 ("profile_saved", "Profil gespeichert"),
1303 (
1304 "pw_short",
1305 "Das Passwort muss mindestens 8 Zeichen lang sein.",
1306 ),
1307 ("read_only_badge", "Schreibgeschützt"),
1308 ("read_only_hint", "Schreibgeschützter Ordner"),
1309 ("refresh", "Aktualisieren"),
1310 ("refresh_folders", "Ordner aktualisieren"),
1311 ("remove_folder", "Ordner entfernen"),
1312 ("remove_password", "Passwort entfernen"),
1313 (
1314 "remove_password_desc",
1315 "Nur noch mit Passkeys anmelden. Braucht mindestens einen Passkey.",
1316 ),
1317 ("rename", "Umbenennen"),
1318 ("rename_title", "„{}“ umbenennen"),
1319 ("renamed", "Umbenannt"),
1320 ("repeat_password", "Passwort wiederholen"),
1321 ("retry", "Erneut versuchen"),
1322 ("root_dup_err", "Dieser Ordner ist bereits in der Liste."),
1323 (
1324 "rw_disabled",
1325 "Schreibbare Freigaben sind vom Server deaktiviert.",
1326 ),
1327 (
1328 "rw_ro_folder",
1329 "Dieser Ordner ist schreibgeschützt, daher ist die Freigabe auch schreibgeschützt.",
1330 ),
1331 ("save", "Speichern"),
1332 ("save_profile", "Profil speichern"),
1333 ("save_settings", "Einstellungen speichern"),
1334 ("saved", "Gespeichert"),
1335 ("saving", "Wird gespeichert…"),
1336 ("search", "Suche"),
1337 ("search_both", "Beides"),
1338 ("search_collapse_all", "Alle einklappen"),
1339 ("search_content", "Inhalt"),
1340 ("search_excludes", "Von der Suche ausgeschlossen"),
1341 ("search_excludes_empty", "Keine Ordner ausgeschlossen."),
1342 ("search_expand_all", "Alle ausklappen"),
1343 ("search_failed", "Die Suche ist fehlgeschlagen."),
1344 ("search_goto", "Im Ordner anzeigen"),
1345 ("search_here", "Hier suchen"),
1346 ("search_in", "Suchen in…"),
1347 ("search_in_folder", "In diesem Ordner suchen"),
1348 ("search_in_n_files", "in {} Dateien"),
1349 ("search_n_matches", "{} Treffer"),
1350 ("search_n_results", "{} Treffer"),
1351 ("search_name", "Name"),
1352 ("search_no_results", "keine Treffer"),
1353 (
1354 "search_placeholder",
1355 "Dateien und deren Inhalte durchsuchen",
1356 ),
1357 ("search_run", "Suchen"),
1358 ("search_scanned", "{} Dateien durchsucht"),
1359 ("search_show_more", "{} weitere anzeigen"),
1360 ("search_shown_of", "{} von {} angezeigt"),
1361 ("search_skipped", "{} übersprungen (über 10 MiB)"),
1362 ("search_stop", "Stopp"),
1363 ("search_stopped", "gestoppt · {} Treffer"),
1364 ("search_took", "{} ms"),
1365 ("searching", "Suche läuft…"),
1366 (
1367 "second_factor_passkey",
1368 "Bestätigen Sie jetzt mit Ihrem Passkey.",
1369 ),
1370 ("second_factor_password", "Passwort für {} eingeben."),
1371 ("security", "Sicherheit"),
1372 (
1373 "select_folder_msg",
1374 "Wählen Sie links einen Ordner aus, um mit dem Durchsuchen zu beginnen.",
1375 ),
1376 ("select_folder_title", "Ordner auswählen"),
1377 ("server", "Server"),
1378 ("server_root", "Serverwurzel"),
1379 ("server_unreachable", "Der Server ist nicht erreichbar."),
1380 ("settings", "Einstellungen"),
1381 (
1382 "settings_save_err",
1383 "Einstellungen konnten nicht gespeichert werden: {}",
1384 ),
1385 ("settings_saved", "Einstellungen gespeichert"),
1386 (
1387 "setup_intro",
1388 "Erster Start: Erstellen Sie das Administrator-Konto. Dieser Benutzer kann andere Benutzer und die Servereinstellungen verwalten.",
1389 ),
1390 ("setup_pw_mismatch", "Die Passwörter stimmen nicht überein."),
1391 ("share", "Teilen"),
1392 (
1393 "share_create_err",
1394 "Freigabe konnte nicht erstellt werden: {}",
1395 ),
1396 ("share_delete_err", "Freigabe konnte nicht gelöscht werden"),
1397 ("share_deleted", "Freigabe gelöscht"),
1398 (
1399 "share_dialog_hint",
1400 "Erstellt einen Link für diesen Eintrag. Mit schreibbaren Links können Empfänger Dateien hochladen und bearbeiten.",
1401 ),
1402 ("share_expired", "Freigabe abgelaufen"),
1403 (
1404 "share_expired_msg",
1405 "Dieser Freigabelink ist nicht mehr aktiv.",
1406 ),
1407 ("share_link", "Freigabelink"),
1408 ("share_locked_title", "Passwort erforderlich"),
1409 ("share_not_found", "Freigabe nicht gefunden"),
1410 (
1411 "share_not_found_msg",
1412 "Dieser Link ist ungültig oder die Freigabe wurde entfernt.",
1413 ),
1414 ("share_owner_disabled", "deaktiviertes Konto"),
1415 (
1416 "share_password_hint",
1417 "Optional. Besucher müssen es eingeben, bevor die Freigabe geöffnet wird, mindestens 8 Zeichen.",
1418 ),
1419 ("share_perm_ro", "Jeder mit diesem Link kann „{}“ lesen."),
1420 (
1421 "share_perm_rw",
1422 "Jeder mit diesem Link kann „{}“ lesen und schreiben.",
1423 ),
1424 ("share_protected", "Passwortgeschützt"),
1425 ("share_title", "{} teilen"),
1426 ("shares", "Freigaben"),
1427 (
1428 "shares_delete_err",
1429 "Freigaben konnten nicht gelöscht werden",
1430 ),
1431 (
1432 "shares_empty_hint",
1433 "Klicken Sie mit der rechten Maustaste auf eine Datei oder einen Ordner und wählen Sie „Teilen“, um einen Link zu erstellen.",
1434 ),
1435 (
1436 "shares_view_hint",
1437 "Von Ihnen erstellte Links. Klicken Sie mit der rechten Maustaste auf eine Datei oder einen Ordner und wählen Sie „Teilen“, um einen hinzuzufügen.",
1438 ),
1439 ("sign_in", "Anmelden"),
1440 ("signin_both", "Passwort und Passkey"),
1441 (
1442 "signin_both_desc",
1443 "Beides ist nötig. WebDAV braucht dann ein App-Passwort, weil eine Einbindung nur ein Passwort senden kann.",
1444 ),
1445 ("signin_either", "Passwort oder Passkey"),
1446 (
1447 "signin_either_desc",
1448 "Eines davon allein genügt zur Anmeldung.",
1449 ),
1450 ("signin_requirement", "Anmeldung verlangt"),
1451 (
1452 "single_click_desc",
1453 "Wenn aktiv, öffnet ein einfacher Klick einen Eintrag und Strg+Klick wählt ihn aus. Wenn inaktiv, wählt ein einfacher Klick aus und ein Doppelklick öffnet.",
1454 ),
1455 ("single_click_label", "Einzelklick öffnet Einträge"),
1456 ("size", "Größe"),
1457 ("some_files_exist", "Einige Dateien existieren bereits"),
1458 ("sort_asc", "Aufsteigend"),
1459 ("sort_by", "Sortieren nach"),
1460 ("sort_desc", "Absteigend"),
1461 ("theme_auto", "Auto"),
1462 ("theme_dark", "Dunkel"),
1463 ("theme_light", "Hell"),
1464 ("theme_title", "Design: {} (klicken zum Wechseln)"),
1465 (
1466 "thumbnails_desc",
1467 "Für Bilder und Videos in der Kachelansicht eine kleine Vorschau statt eines Symbols zeigen.",
1468 ),
1469 ("thumbnails_label", "Vorschaubilder zeigen"),
1470 ("type", "Typ"),
1471 ("unlock", "Freigabe öffnen"),
1472 ("unsaved_changes", "Ungespeicherte Änderungen"),
1473 ("until", "Bis"),
1474 ("upload_abort", "Abbrechen"),
1475 ("upload_aborted", "Abgebrochen"),
1476 ("upload_active_n", "{} aktiv"),
1477 (
1478 "upload_apply_all",
1479 "Auch auf Dateien anwenden, die während des Uploads entstehen",
1480 ),
1481 (
1482 "upload_check_failed",
1483 "Prüfung auf vorhandene Dateien fehlgeschlagen: {}",
1484 ),
1485 ("upload_clear", "Aus der Liste entfernen"),
1486 ("upload_clear_finished", "Abgeschlossene entfernen"),
1487 ("upload_collapse", "Einklappen"),
1488 ("upload_complete", "Hochladen abgeschlossen"),
1489 (
1490 "upload_conflict_question",
1491 "Die folgenden Dateien existieren bereits. Überschreiben oder überspringen?",
1492 ),
1493 ("upload_drop_hint", "Zum Hochladen hier ablegen"),
1494 ("upload_errors_n", "{} fehlgeschlagen"),
1495 (
1496 "upload_exists_ask",
1497 "„{}“ ist während des Uploads auf dem Server entstanden.",
1498 ),
1499 ("upload_expand", "Ausklappen"),
1500 ("upload_failed", "Fehlgeschlagen"),
1501 ("upload_files", "Dateien hochladen"),
1502 ("upload_folder", "Ordner hochladen"),
1503 ("upload_n_files", "{} Dateien"),
1504 ("upload_pause", "Pausieren"),
1505 ("upload_paused", "Pausiert"),
1506 ("upload_preparing", "Wird vorbereitet…"),
1507 ("upload_resume", "Fortsetzen"),
1508 ("upload_show_graph", "Details und Geschwindigkeitsverlauf"),
1509 ("upload_skip", "Überspringen"),
1510 ("upload_skipped_n", "{} übersprungen"),
1511 ("upload_speed", "{}/s"),
1512 ("upload_waiting", "Wartet auf Ihre Antwort"),
1513 ("uploads", "Uploads"),
1514 ("uploads_empty", "Noch keine Uploads"),
1515 ("use_passkey", "Passkey verwenden"),
1516 (
1517 "use_passkey_hint",
1518 "Lassen Sie den Namen leer, außer Ihr Passkey braucht ihn.",
1519 ),
1520 ("user_created", "Benutzer erstellt"),
1521 ("user_delete_err", "Benutzer konnte nicht gelöscht werden"),
1522 ("user_disabled", "deaktiviert"),
1523 ("user_name_example", "z. B. alice"),
1524 (
1525 "user_save_err",
1526 "Benutzer konnte nicht gespeichert werden: {}",
1527 ),
1528 ("user_updated", "Benutzer aktualisiert"),
1529 ("user_you", "(Sie)"),
1530 ("users", "Benutzer"),
1531 ("your_shares", "Ihre Freigaben"),
1532];
1533
1534/// French translations.
1535const FR: &[(&str, &str)] = &[
1536 ("active_can_signin", "Actif (peut se connecter)"),
1537 ("add_app_password", "Créer un mot de passe d'application"),
1538 ("add_folder", "Ajouter un dossier…"),
1539 ("add_here", "Ajouter ce dossier"),
1540 ("add_passkey", "Ajouter une clé d'accès"),
1541 ("administrator", "Administrateur"),
1542 ("all_shares", "Tous les partages"),
1543 (
1544 "all_shares_hint",
1545 "Tous les liens de ce serveur, groupés par le compte qui les a créés.",
1546 ),
1547 (
1548 "allow_editing",
1549 "Autoriser la modification (lecture-écriture)",
1550 ),
1551 ("allow_rw_shares", "Autoriser les partages modifiables"),
1552 (
1553 "allow_rw_shares_desc",
1554 "Autoriser les utilisateurs à créer des liens de partage en lecture-écriture. Désactivé par défaut.",
1555 ),
1556 ("and_more", "…et {} autres"),
1557 ("app_password_label", "Nom de ce mot de passe d'application"),
1558 ("app_password_removed", "Mot de passe d'application révoqué"),
1559 (
1560 "app_password_secret_once",
1561 "Copiez-le maintenant. Il ne sera plus jamais affiché.",
1562 ),
1563 ("app_passwords", "Mots de passe d'application"),
1564 (
1565 "app_passwords_hint",
1566 "Un mot de passe d'application ne sert qu'au WebDAV, jamais à cette page. Utilisez-en un par client au lieu de votre mot de passe de compte.",
1567 ),
1568 ("cancel", "Annuler"),
1569 (
1570 "cant_delete_self",
1571 "Vous ne pouvez pas supprimer votre propre compte",
1572 ),
1573 ("close", "Fermer"),
1574 ("close_esc", "Fermer (Échap)"),
1575 ("copied", "Copié"),
1576 ("copy", "Copier"),
1577 ("copy_dav_link", "Copier le lien WebDAV"),
1578 ("copy_here", "Copier ici"),
1579 ("copy_link", "Copier le lien"),
1580 ("copy_manual", "Copiez le lien manuellement"),
1581 ("copy_n_to", "Copier {} éléments vers…"),
1582 ("copy_to", "Copier « {} » vers…"),
1583 ("create", "Créer"),
1584 ("create_admin", "Créer le compte administrateur"),
1585 ("create_link", "Créer le lien"),
1586 ("create_user", "Créer l'utilisateur"),
1587 ("creating", "Création…"),
1588 ("custom", "Personnalisé…"),
1589 (
1590 "default_root_desc",
1591 "Ouvrir ce dossier au chargement de la page et via le lien d'accueil.",
1592 ),
1593 ("default_root_label", "Dossier par défaut"),
1594 ("default_root_none", "Aperçu des dossiers"),
1595 ("delete", "Supprimer"),
1596 ("delete_all", "Tout supprimer"),
1597 (
1598 "delete_all_msg",
1599 "Supprimer les {} liens de partage ? Toute personne les possédant perdra l'accès. Cette action est irréversible.",
1600 ),
1601 ("delete_all_title", "Supprimer tous les partages ?"),
1602 (
1603 "delete_all_user_msg",
1604 "Supprimer tous les liens de partage de « {} » ? Toute personne les possédant perdra l'accès. Cette action est irréversible.",
1605 ),
1606 (
1607 "delete_folder_msg",
1608 "Supprimer le dossier « {} » et tout son contenu ?\nCette action est irréversible.",
1609 ),
1610 (
1611 "delete_msg",
1612 "Supprimer « {} » ?\nCette action est irréversible.",
1613 ),
1614 (
1615 "delete_n_msg",
1616 "Supprimer {} éléments ?\nCette action est irréversible.",
1617 ),
1618 (
1619 "delete_partial",
1620 "{} des {} liens n'ont pas pu être supprimés",
1621 ),
1622 ("delete_share", "Supprimer le partage"),
1623 ("delete_user", "Supprimer l'utilisateur"),
1624 (
1625 "delete_user_confirm",
1626 "Supprimer l'utilisateur « {} » ? Cette action est irréversible.",
1627 ),
1628 ("deleted", "Supprimé"),
1629 ("deleted_n_shares", "{} partage(s) supprimé(s)"),
1630 ("discard", "Abandonner"),
1631 (
1632 "discard_question",
1633 "Abandonner vos modifications et fermer l'éditeur ?",
1634 ),
1635 ("dismiss", "Ignorer"),
1636 ("dismiss_error", "Ignorer l'erreur"),
1637 ("done", "Terminé"),
1638 ("download", "Télécharger"),
1639 (
1640 "download_formats_msg",
1641 "Choisissez un format d'archivage pour le dossier.",
1642 ),
1643 ("download_started", "Téléchargement démarré"),
1644 ("download_title", "Télécharger « {} »"),
1645 ("edit", "Modifier"),
1646 ("edit_user_title", "Modifier « {} »"),
1647 ("empty_folder", "Ce dossier est vide."),
1648 (k::ERR_ADMIN_ONLY, "réservé aux administrateurs"),
1649 (k::ERR_ALREADY_SET_UP, "le serveur est déjà configuré"),
1650 (
1651 k::ERR_APP_PASSWORD_LIMIT,
1652 "Ce compte possède déjà le nombre maximal de mots de passe d'application.",
1653 ),
1654 (
1655 k::ERR_APP_PASSWORD_NOT_FOUND,
1656 "Aucun mot de passe d'application correspondant.",
1657 ),
1658 (k::ERR_BAD_ACTION, "action=content attendu"),
1659 (k::ERR_BAD_BODY, "corps de requête invalide"),
1660 (k::ERR_BAD_EXPIRES_AT, "la date d'expiration est invalide"),
1661 (
1662 k::ERR_BAD_FORMAT,
1663 "le format doit être zip, tar, tar.gz ou tar.zst",
1664 ),
1665 (
1666 k::ERR_BAD_MULTIPART,
1667 "multipart/form-data avec boundary attendu",
1668 ),
1669 (k::ERR_BAD_PART_NAME, "nom de partie invalide"),
1670 (
1671 k::ERR_BAD_POST,
1672 "POST attend un téléversement multipart, une mutation JSON ou ?action=mkdir/create-file",
1673 ),
1674 (k::ERR_BAD_UPLOAD, "données de téléversement invalides"),
1675 (
1676 k::ERR_BAD_UPLOAD_PATH,
1677 "chemin de fichier invalide dans le téléversement",
1678 ),
1679 (
1680 k::ERR_CHALLENGE_EXPIRED,
1681 "Cela a pris trop de temps. Veuillez réessayer.",
1682 ),
1683 (
1684 k::ERR_DEFAULT_CALENDAR,
1685 "Le calendrier qui reçoit les invitations ne peut pas être supprimé.",
1686 ),
1687 (k::ERR_DST_REQUIRED, "dst_root_id est requis"),
1688 (k::ERR_FILE_NAME_REQUIRED, "un nom de fichier est requis"),
1689 (k::ERR_FILES_EXIST, "certains fichiers existent déjà"),
1690 (k::ERR_FOLDER_EXISTS, "un dossier avec ce nom existe déjà"),
1691 (k::ERR_FOLDER_NAME_REQUIRED, "un nom de dossier est requis"),
1692 (k::ERR_FS_CONFLICT, "existe déjà"),
1693 (k::ERR_FS_FORBIDDEN, "accès refusé"),
1694 (k::ERR_FS_NOT_A_DIR, "ce n'est pas un dossier"),
1695 (k::ERR_FS_NOT_FOUND, "dossier introuvable"),
1696 (k::ERR_FS_ROOT_MISSING, "le dossier configuré n'existe plus"),
1697 (k::ERR_INTERNAL, "erreur interne"),
1698 (k::ERR_INVALID_CREDENTIALS, "nom ou mot de passe incorrect"),
1699 (
1700 k::ERR_INVALID_DEFAULT_ROOT,
1701 "le dossier par défaut ne fait pas partie de vos dossiers",
1702 ),
1703 (k::ERR_INVALID_LANGUAGE, "balise de langue invalide"),
1704 (
1705 k::ERR_LAST_ADMIN,
1706 "impossible de supprimer le dernier administrateur actif",
1707 ),
1708 (
1709 k::ERR_LAST_ADMIN_DELETE,
1710 "impossible de supprimer le dernier administrateur actif",
1711 ),
1712 (
1713 k::ERR_LOCKED_OUT,
1714 "Le compte n'aurait alors plus aucun moyen de connexion.",
1715 ),
1716 (
1717 k::ERR_MODE_NEEDS_PASSKEY,
1718 "Ajoutez une clé d'accès avant d'exiger les deux.",
1719 ),
1720 (
1721 k::ERR_MODE_NEEDS_PASSWORD,
1722 "Définissez un mot de passe avant d'exiger les deux.",
1723 ),
1724 (k::ERR_NAME_LENGTH, "le nom doit contenir 1 à 64 caractères"),
1725 (k::ERR_NEW_NAME_REQUIRED, "new_name est requis"),
1726 (k::ERR_NO_FILES_UPLOADED, "aucun fichier n'a été téléversé"),
1727 (k::ERR_NO_SUCH_FOLDER, "ce dossier n'existe pas"),
1728 (k::ERR_NOT_A_FILE, "ce n'est pas un fichier"),
1729 (k::ERR_NOT_SIGNED_IN, "non connecté"),
1730 (
1731 k::ERR_OWN_ACCOUNT,
1732 "vous ne pouvez pas désactiver votre propre compte",
1733 ),
1734 (
1735 k::ERR_OWN_ADMIN,
1736 "vous ne pouvez pas retirer vos propres droits d'administrateur",
1737 ),
1738 (
1739 k::ERR_OWN_DELETE,
1740 "vous ne pouvez pas supprimer votre propre compte",
1741 ),
1742 (k::ERR_PART_NO_NAME, "partie sans nom"),
1743 (
1744 k::ERR_PASSKEY_DUPLICATE,
1745 "Cette clé d'accès est déjà enregistrée.",
1746 ),
1747 (
1748 k::ERR_PASSKEY_FAILED,
1749 "Cette clé d'accès n'a pas pu être utilisée.",
1750 ),
1751 (
1752 k::ERR_PASSKEY_LAST_CREDENTIAL,
1753 "Définissez un mot de passe avant de retirer votre dernière clé d'accès.",
1754 ),
1755 (
1756 k::ERR_PASSKEY_LIMIT,
1757 "Ce compte a déjà autant de clés d'accès que permis.",
1758 ),
1759 (
1760 k::ERR_PASSKEY_MALFORMED,
1761 "Le navigateur a envoyé des données illisibles.",
1762 ),
1763 (k::ERR_PASSKEY_NOT_FOUND, "Clé d'accès introuvable."),
1764 (
1765 k::ERR_PASSKEY_ORIGIN,
1766 "Les clés d'accès sont configurées pour une autre adresse.",
1767 ),
1768 (
1769 k::ERR_PASSKEY_UNAVAILABLE,
1770 "Les clés d'accès ne sont pas disponibles ici.",
1771 ),
1772 (
1773 k::ERR_PASSWORD_LAST_CREDENTIAL,
1774 "Ajoutez une clé d'accès avant de retirer votre mot de passe.",
1775 ),
1776 (
1777 k::ERR_PASSWORD_SHORT,
1778 "le mot de passe doit contenir au moins 8 caractères",
1779 ),
1780 (k::ERR_PATH_REQUIRED, "un chemin dans le dossier est requis"),
1781 (k::ERR_READ_ONLY_FOLDER, "dossier en lecture seule"),
1782 (
1783 k::ERR_REQUIRED_BY_MODE,
1784 "Ce compte exige un mot de passe et une clé d'accès.",
1785 ),
1786 (k::ERR_ROOT_FORBIDDEN, "dossier inaccessible"),
1787 (
1788 k::ERR_RW_RO_FOLDER,
1789 "ce dossier est en lecture seule pour vous, il ne peut donc pas être partagé en écriture",
1790 ),
1791 (
1792 k::ERR_RW_SHARES_DISABLED,
1793 "les partages modifiables sont désactivés",
1794 ),
1795 (k::ERR_SAVE_FAILED, "impossible d'enregistrer le fichier"),
1796 (
1797 k::ERR_SEARCH_BAD_SCOPE,
1798 "la portée doit être name, content ou both",
1799 ),
1800 (
1801 k::ERR_SEARCH_FORBIDDEN,
1802 "la recherche nécessite une session connectée",
1803 ),
1804 (
1805 k::ERR_SESSION_EXPIRED,
1806 "session expirée, veuillez vous connecter à nouveau",
1807 ),
1808 (k::ERR_SHARE_EXPIRED, "ce partage a expiré"),
1809 (
1810 k::ERR_SHARE_LOCKED,
1811 "Ce partage est protégé par un mot de passe.",
1812 ),
1813 (
1814 k::ERR_SHARE_NO_PASSWORD,
1815 "Ce partage n'a pas de mot de passe.",
1816 ),
1817 (k::ERR_SHARE_NOT_FOUND, "partage introuvable"),
1818 (
1819 k::ERR_SHARE_TOKEN_FORBIDDEN,
1820 "un jeton de partage ne peut pas être utilisé ici ; connectez-vous à la place",
1821 ),
1822 (k::ERR_SHARE_WRONG_PASSWORD, "Mot de passe incorrect."),
1823 (
1824 k::ERR_TOO_LARGE_PREVIEW,
1825 "fichier trop volumineux pour l'aperçu",
1826 ),
1827 (
1828 k::ERR_TOO_LARGE_SAVE,
1829 "fichier trop volumineux pour être enregistré",
1830 ),
1831 (k::ERR_USER_EXISTS, "un utilisateur avec ce nom existe déjà"),
1832 (k::ERR_USER_NOT_FOUND, "utilisateur introuvable"),
1833 ("exclude_dup_err", "Ce dossier est déjà exclu."),
1834 ("exclude_folder", "Exclure un dossier…"),
1835 ("exclude_here", "Exclure ce dossier"),
1836 (
1837 "exclude_root_err",
1838 "La racine entière ne peut pas être exclue ; cela désactiverait la recherche.",
1839 ),
1840 ("expires", "Expire"),
1841 ("expires_at", "Expire le {}"),
1842 ("expiry_1d", "1 jour"),
1843 ("expiry_1h", "1 heure"),
1844 ("expiry_1mo", "1 mois"),
1845 ("expiry_1w", "1 semaine"),
1846 ("file", "Fichier"),
1847 ("file_changed", "Fichier modifié sur disque"),
1848 ("file_created", "Fichier créé"),
1849 ("file_info", "Informations"),
1850 ("file_name", "Nom du fichier"),
1851 ("file_not_found", "Fichier introuvable"),
1852 ("files", "Fichiers"),
1853 ("fmt_tar", "Tar"),
1854 ("fmt_targz", "Tar + gzip"),
1855 ("fmt_tarzst", "Tar + zstd"),
1856 ("fmt_zip", "Zip"),
1857 ("folder", "Dossier"),
1858 ("folder_created", "Dossier créé"),
1859 (
1860 "folder_gone_msg",
1861 "Ce dossier n'est plus accessible. Choisissez-en un autre dans le panneau latéral.",
1862 ),
1863 ("folder_gone_title", "Dossier indisponible"),
1864 ("folder_name", "Nom du dossier"),
1865 ("folders", "Dossiers"),
1866 (
1867 "folders_paths_hint",
1868 "Les chemins sont relatifs à la racine du serveur. « . » désigne toute la racine.",
1869 ),
1870 ("grid_view", "Vue en grille"),
1871 ("info", "Infos"),
1872 ("keep_editing", "Continuer à modifier"),
1873 ("lang_auto", "Automatique"),
1874 ("lang_de", "Allemand"),
1875 ("lang_en", "Anglais"),
1876 ("lang_fr", "Français"),
1877 ("language", "Langue"),
1878 (
1879 "language_desc",
1880 "La langue de l'interface. « Automatique » utilise la langue de votre navigateur.",
1881 ),
1882 ("link_copied", "Lien copié dans le presse-papiers"),
1883 ("list_view", "Vue en liste"),
1884 ("load_latest", "Charger la version la plus récente"),
1885 ("loading", "Chargement…"),
1886 ("loading_share", "Chargement du partage…"),
1887 ("location", "Emplacement"),
1888 ("log_out", "Se déconnecter"),
1889 ("login_subtitle", "Connectez-vous pour continuer."),
1890 ("manage", "Gérer"),
1891 ("menu", "Menu"),
1892 ("meta_created", "créé le {}"),
1893 ("meta_expires", "expire le {}"),
1894 ("mode_ro", "lecture seule"),
1895 ("mode_rw", "lecture-écriture"),
1896 ("modified", "Modifié"),
1897 (
1898 "modified_after",
1899 "Ce fichier a été modifié après son ouverture. « Charger la version la plus récente » abandonne vos modifications non enregistrées ; « Écraser » conserve votre version.",
1900 ),
1901 ("more_actions", "Plus d'actions"),
1902 ("move", "Déplacer"),
1903 ("move_here", "Déplacer ici"),
1904 ("move_n_to", "Déplacer {} éléments vers…"),
1905 ("move_to", "Déplacer « {} » vers…"),
1906 ("moved", "Déplacé"),
1907 ("name", "Nom"),
1908 ("name_taken", "Ce nom est déjà utilisé"),
1909 ("need_folder", "Donnez au moins un dossier à l'utilisateur."),
1910 ("never", "Jamais"),
1911 ("never_expires", "N'expire jamais"),
1912 ("new_file", "Nouveau fichier"),
1913 ("new_folder", "Nouveau dossier"),
1914 ("new_name", "Nouveau nom"),
1915 ("new_password", "Nouveau mot de passe"),
1916 (
1917 "new_password_hint",
1918 "Laissez vide pour conserver votre mot de passe actuel.",
1919 ),
1920 (
1921 "new_password_keep",
1922 "Nouveau mot de passe (laisser vide pour conserver)",
1923 ),
1924 ("new_user", "Nouvel utilisateur"),
1925 ("no_app_passwords", "Aucun mot de passe d'application."),
1926 (
1927 "no_folders_msg",
1928 "Aucun administrateur ne vous a encore attribué de dossier.",
1929 ),
1930 ("no_folders_title", "Aucun dossier disponible"),
1931 ("no_passkeys", "Aucune clé d'accès pour l'instant."),
1932 (
1933 "no_password_set",
1934 "Ce compte se connecte uniquement avec des clés d'accès.",
1935 ),
1936 ("no_preview", "Aperçu non disponible"),
1937 (
1938 "no_preview_msg",
1939 "L'application ne peut pas afficher « {} » ici.",
1940 ),
1941 ("no_shares", "Aucun partage pour l'instant"),
1942 ("no_subfolders", "Aucun sous-dossier"),
1943 ("no_users", "Aucun utilisateur."),
1944 ("open", "Ouvrir"),
1945 ("open_in_new_tab", "Ouvrir dans un nouvel onglet"),
1946 ("open_menu", "Ouvrir le menu"),
1947 ("or_label", "ou"),
1948 ("overwrite", "Écraser"),
1949 (
1950 "overwrite_question",
1951 "Les fichiers suivants existent déjà. Les écraser ?",
1952 ),
1953 ("page_first", "Première page"),
1954 ("page_goto", "Page"),
1955 ("page_last", "Dernière page"),
1956 ("page_next", "Page suivante"),
1957 ("page_prev", "Page précédente"),
1958 ("page_size", "Entrées par page"),
1959 ("page_size_n", "{} par page"),
1960 ("passkey_added", "Clé d'accès ajoutée"),
1961 ("passkey_added_on", "Ajoutée {}"),
1962 ("passkey_label", "Nom de cette clé d'accès"),
1963 ("passkey_last_used", "Dernière utilisation {}"),
1964 ("passkey_needs_name", "Exige votre nom d'utilisateur"),
1965 (
1966 "passkey_needs_name_hint",
1967 "Cette clé d'accès n'est pas stockée dans l'authentificateur, le serveur doit la retrouver. Saisissez votre nom d'utilisateur sur la page de connexion avant de l'utiliser.",
1968 ),
1969 ("passkey_never_used", "Jamais utilisée"),
1970 ("passkey_not_used", "Aucune clé d'accès n'a été utilisée."),
1971 ("passkey_removed", "Clé d'accès retirée"),
1972 (
1973 "passkey_unsupported",
1974 "Ce navigateur ne peut pas utiliser de clés d'accès.",
1975 ),
1976 ("passkeys", "Clés d'accès"),
1977 (
1978 "passkeys_hint",
1979 "Une clé d'accès vous connecte avec votre empreinte, votre visage ou une clé de sécurité.",
1980 ),
1981 ("password", "Mot de passe"),
1982 ("password_min_hint", "au moins 8 caractères"),
1983 ("password_removed", "Mot de passe retiré"),
1984 (
1985 "password_resets_signin",
1986 "Définir un mot de passe supprime aussi les clés d'accès de ce compte et lève toute exigence à deux facteurs.",
1987 ),
1988 ("pim_access", "Accès"),
1989 ("pim_add", "Ajouter"),
1990 ("pim_address", "Adresse pour les applications"),
1991 ("pim_address_books", "Carnets d'adresses"),
1992 ("pim_app_passwords", "Créer un mot de passe d'application"),
1993 ("pim_auto", "automatique"),
1994 ("pim_birthdays", "Anniversaires"),
1995 (
1996 "pim_cal_hint",
1997 "Choisissez un calendrier à gauche pour le gérer, ou connectez une application de calendrier.",
1998 ),
1999 ("pim_calendar", "Calendrier"),
2000 ("pim_calendars", "Calendriers"),
2001 ("pim_clients", "Applications"),
2002 (
2003 "pim_collection_urls",
2004 "Adresses des calendriers et carnets d'adresses",
2005 ),
2006 ("pim_color", "Couleur"),
2007 ("pim_connect", "Connecter une application"),
2008 (
2009 "pim_connect_title",
2010 "Connecter une application de calendrier ou de contacts",
2011 ),
2012 ("pim_contacts", "Contacts"),
2013 (
2014 "pim_contacts_hint",
2015 "Choisissez un carnet d'adresses à gauche pour le gérer, ou connectez une application de contacts.",
2016 ),
2017 ("pim_created", "Créé"),
2018 ("pim_custom_color", "Couleur personnalisée"),
2019 (
2020 "pim_default_hint",
2021 "Ce calendrier reçoit les invitations. Il ne peut pas être supprimé.",
2022 ),
2023 (
2024 "pim_delete_msg",
2025 "Tout son contenu est supprimé. Les participants à vos réunions reçoivent une annulation.",
2026 ),
2027 ("pim_delete_title", "Supprimer « {} » ?"),
2028 ("pim_description", "Description"),
2029 ("pim_detail", "Détails"),
2030 ("pim_detail_busy", "Heures occupées seulement"),
2031 ("pim_detail_full", "Tous les détails"),
2032 ("pim_directory", "Annuaire"),
2033 ("pim_export", "Exporter"),
2034 ("pim_exported", "Enregistré sous {}"),
2035 ("pim_feeds", "Flux de calendriers et de contacts"),
2036 (
2037 "pim_feeds_hint",
2038 "Chaque lien public de calendrier et de carnet d'adresses sur ce serveur.",
2039 ),
2040 ("pim_file_contacts", "{} contacts"),
2041 ("pim_file_events", "{} entrées"),
2042 ("pim_file_invalid", "{} non valides"),
2043 ("pim_general", "Général"),
2044 (
2045 "pim_generated_hint",
2046 "Le serveur le remplit. Il est en lecture seule.",
2047 ),
2048 ("pim_hide", "Masquer"),
2049 (
2050 "pim_hint_apple",
2051 "Apple : ajoutez un compte CalDAV et un compte CardDAV avec l'adresse du serveur. Apple exige HTTPS.",
2052 ),
2053 (
2054 "pim_hint_davx5",
2055 "Android : dans DAVx⁵, connectez-vous avec URL et nom d'utilisateur, et utilisez l'adresse du serveur.",
2056 ),
2057 (
2058 "pim_hint_gnome",
2059 "GNOME et Evolution : ajoutez un compte CalDAV ou WebDAV avec l'adresse du serveur.",
2060 ),
2061 (
2062 "pim_hint_thunderbird",
2063 "Thunderbird : ajoutez un calendrier réseau avec l'adresse du serveur. Réglez son identité e-mail sur « Aucune », sinon il n'envoie pas d'invitations.",
2064 ),
2065 ("pim_import_btn", "Importer"),
2066 ("pim_import_done", "{} nouveaux, {} mis à jour."),
2067 ("pim_import_into", "Importer dans"),
2068 (
2069 "pim_import_menu",
2070 "Importer dans le calendrier ou les contacts…",
2071 ),
2072 ("pim_import_skipped", "{} ignorés :"),
2073 ("pim_import_title", "Importer « {} »"),
2074 ("pim_importing", "Importation…"),
2075 ("pim_kind_resource", "Ressource"),
2076 ("pim_kind_room", "Salle"),
2077 ("pim_link_busy", "heures occupées seulement"),
2078 ("pim_link_full", "tous les détails"),
2079 ("pim_link_revoked", "Lien révoqué"),
2080 ("pim_links", "Liens publics"),
2081 (
2082 "pim_links_hint",
2083 "Toute personne ayant le lien peut s'abonner. Google Agenda et Outlook.com exigent un lien sans mot de passe.",
2084 ),
2085 (
2086 "pim_links_hint_cards",
2087 "Toute personne ayant le lien peut télécharger les contacts une fois. Les applications ne suivent pas les modifications.",
2088 ),
2089 ("pim_mode_ro", "Lecture seule"),
2090 ("pim_mode_rw", "Lecture et écriture"),
2091 (
2092 "pim_mode_schedule",
2093 "Lecture, écriture et envoi d'invitations",
2094 ),
2095 ("pim_nav", "Calendrier et contacts"),
2096 ("pim_new_address_book", "Nouveau carnet d'adresses"),
2097 ("pim_new_calendar", "Nouveau calendrier"),
2098 ("pim_new_room", "Nouvelle salle"),
2099 ("pim_no_feeds", "Aucun flux public."),
2100 ("pim_no_links", "Aucun lien public."),
2101 ("pim_no_rooms", "Aucune salle ni ressource."),
2102 ("pim_no_shares", "Partagé avec personne."),
2103 (
2104 "pim_no_target",
2105 "Vous n'avez aucun calendrier ni carnet d'adresses modifiable pour ce fichier.",
2106 ),
2107 (
2108 "pim_no_writable_folder",
2109 "Vous n'avez aucun dossier modifiable.",
2110 ),
2111 (
2112 "pim_password_hint",
2113 "Utilisez un mot de passe d'application plutôt que celui de votre compte.",
2114 ),
2115 ("pim_remove_from_list", "Retirer de ma liste"),
2116 (
2117 "pim_remove_msg",
2118 "Vous ne le voyez plus. Le propriétaire peut le partager à nouveau.",
2119 ),
2120 ("pim_removed", "Retiré de votre liste"),
2121 (
2122 "pim_room_delete_confirm",
2123 "Supprimer « {} » ? Ses réservations sont perdues.",
2124 ),
2125 ("pim_room_display", "Nom affiché"),
2126 (
2127 "pim_room_name",
2128 "Nom (fait partie de l'adresse, non modifiable)",
2129 ),
2130 ("pim_rooms", "Salles et ressources"),
2131 (
2132 "pim_rooms_hint",
2133 "Les salles et ressources peuvent être invitées aux réunions. Elles acceptent les créneaux libres et refusent les occupés d'elles-mêmes.",
2134 ),
2135 ("pim_save_err", "Impossible d'enregistrer : {}"),
2136 ("pim_save_here", "Enregistrer ici"),
2137 ("pim_save_to_folder", "Enregistrer dans un dossier…"),
2138 ("pim_server_address", "Adresse du serveur"),
2139 (
2140 "pim_server_address_hint",
2141 "Si une application ne trouve pas le serveur, utilisez cette adresse :",
2142 ),
2143 ("pim_shared_by", "Partagé par {}"),
2144 ("pim_shared_ok", "Partagé avec {}"),
2145 ("pim_shared_with_me", "Partagés avec moi"),
2146 ("pim_sharing", "Partage"),
2147 (
2148 "pim_sharing_hint",
2149 "Partager avec un autre compte de ce serveur.",
2150 ),
2151 ("pim_show", "Afficher"),
2152 ("pim_subscribe", "S'abonner"),
2153 (
2154 "pim_transparent",
2155 "Afficher comme libre : ses événements ne bloquent pas de temps dans les invitations",
2156 ),
2157 ("pim_unshare", "Ne plus partager"),
2158 ("pim_unshared", "N'est plus partagé"),
2159 ("pim_user", "Nom d'utilisateur"),
2160 ("pim_user_name", "Nom d'utilisateur"),
2161 ("profile", "Profil"),
2162 (
2163 "profile_save_err",
2164 "Impossible d'enregistrer le profil : {}",
2165 ),
2166 ("profile_saved", "Profil enregistré"),
2167 (
2168 "pw_short",
2169 "Le mot de passe doit contenir au moins 8 caractères.",
2170 ),
2171 ("read_only_badge", "Lecture seule"),
2172 ("read_only_hint", "Dossier en lecture seule"),
2173 ("refresh", "Actualiser"),
2174 ("refresh_folders", "Actualiser vos dossiers"),
2175 ("remove_folder", "Retirer le dossier"),
2176 ("remove_password", "Retirer le mot de passe"),
2177 (
2178 "remove_password_desc",
2179 "Se connecter uniquement avec des clés d'accès. Exige au moins une clé d'accès.",
2180 ),
2181 ("rename", "Renommer"),
2182 ("rename_title", "Renommer « {} »"),
2183 ("renamed", "Renommé"),
2184 ("repeat_password", "Répéter le mot de passe"),
2185 ("retry", "Réessayer"),
2186 ("root_dup_err", "Ce dossier est déjà dans la liste."),
2187 (
2188 "rw_disabled",
2189 "Les partages modifiables sont désactivés par le serveur.",
2190 ),
2191 (
2192 "rw_ro_folder",
2193 "Ce dossier est en lecture seule, le partage l'est donc aussi.",
2194 ),
2195 ("save", "Enregistrer"),
2196 ("save_profile", "Enregistrer le profil"),
2197 ("save_settings", "Enregistrer les paramètres"),
2198 ("saved", "Enregistré"),
2199 ("saving", "Enregistrement…"),
2200 ("search", "Rechercher"),
2201 ("search_both", "Les deux"),
2202 ("search_collapse_all", "Tout replier"),
2203 ("search_content", "Contenu"),
2204 ("search_excludes", "Exclu de la recherche"),
2205 ("search_excludes_empty", "Aucun dossier exclu."),
2206 ("search_expand_all", "Tout déplier"),
2207 ("search_failed", "La recherche a échoué."),
2208 ("search_goto", "Afficher dans le dossier"),
2209 ("search_here", "Rechercher ici"),
2210 ("search_in", "Rechercher dans…"),
2211 ("search_in_folder", "Rechercher dans ce dossier"),
2212 ("search_in_n_files", "dans {} fichiers"),
2213 ("search_n_matches", "{} correspondances"),
2214 ("search_n_results", "{} résultats"),
2215 ("search_name", "Nom"),
2216 ("search_no_results", "aucun résultat"),
2217 (
2218 "search_placeholder",
2219 "Rechercher dans les fichiers et leur contenu",
2220 ),
2221 ("search_run", "Rechercher"),
2222 ("search_scanned", "{} fichiers parcourus"),
2223 ("search_show_more", "Afficher {} de plus"),
2224 ("search_shown_of", "{} sur {} affichés"),
2225 ("search_skipped", "{} ignorés (plus de 10 Mio)"),
2226 ("search_stop", "Arrêter"),
2227 ("search_stopped", "arrêté · {} résultats"),
2228 ("search_took", "{} ms"),
2229 ("searching", "recherche…"),
2230 (
2231 "second_factor_passkey",
2232 "Confirmez maintenant avec votre clé d'accès.",
2233 ),
2234 ("second_factor_password", "Saisissez le mot de passe de {}."),
2235 ("security", "Sécurité"),
2236 (
2237 "select_folder_msg",
2238 "Choisissez un dossier dans le panneau latéral pour commencer à naviguer.",
2239 ),
2240 ("select_folder_title", "Choisir un dossier"),
2241 ("server", "Serveur"),
2242 ("server_root", "Racine du serveur"),
2243 ("server_unreachable", "Le serveur est injoignable."),
2244 ("settings", "Paramètres"),
2245 (
2246 "settings_save_err",
2247 "Impossible d'enregistrer les paramètres : {}",
2248 ),
2249 ("settings_saved", "Paramètres enregistrés"),
2250 (
2251 "setup_intro",
2252 "Premier démarrage : créez le compte administrateur. Cet utilisateur peut gérer les autres utilisateurs et les paramètres du serveur.",
2253 ),
2254 (
2255 "setup_pw_mismatch",
2256 "Les mots de passe ne correspondent pas.",
2257 ),
2258 ("share", "Partager"),
2259 ("share_create_err", "Impossible de créer le partage : {}"),
2260 ("share_delete_err", "Impossible de supprimer le partage"),
2261 ("share_deleted", "Partage supprimé"),
2262 (
2263 "share_dialog_hint",
2264 "Crée un lien pour cet élément. Les liens modifiables permettent aux destinataires de téléverser et de modifier.",
2265 ),
2266 ("share_expired", "Partage expiré"),
2267 ("share_expired_msg", "Ce lien de partage n'est plus actif."),
2268 ("share_link", "Lien de partage"),
2269 ("share_locked_title", "Mot de passe requis"),
2270 ("share_not_found", "Partage introuvable"),
2271 (
2272 "share_not_found_msg",
2273 "Ce lien est invalide ou le partage a été supprimé.",
2274 ),
2275 ("share_owner_disabled", "compte désactivé"),
2276 (
2277 "share_password_hint",
2278 "Facultatif. Les visiteurs doivent le saisir avant d'ouvrir le partage, au moins 8 caractères.",
2279 ),
2280 (
2281 "share_perm_ro",
2282 "Toute personne possédant ce lien peut lire « {} ».",
2283 ),
2284 (
2285 "share_perm_rw",
2286 "Toute personne possédant ce lien peut lire et modifier « {} ».",
2287 ),
2288 ("share_protected", "Protégé par mot de passe"),
2289 ("share_title", "Partager {}"),
2290 ("shares", "Partages"),
2291 ("shares_delete_err", "Impossible de supprimer les partages"),
2292 (
2293 "shares_empty_hint",
2294 "Faites un clic droit sur un fichier ou un dossier, puis choisissez « Partager » pour créer un lien.",
2295 ),
2296 (
2297 "shares_view_hint",
2298 "Liens que vous avez créés. Faites un clic droit sur un fichier ou un dossier, puis choisissez « Partager » pour en ajouter un.",
2299 ),
2300 ("sign_in", "Se connecter"),
2301 ("signin_both", "Mot de passe et clé d'accès"),
2302 (
2303 "signin_both_desc",
2304 "Les deux sont exigés. Le WebDAV exige alors un mot de passe d'application, car un montage ne peut envoyer qu'un mot de passe.",
2305 ),
2306 ("signin_either", "Mot de passe ou clé d'accès"),
2307 (
2308 "signin_either_desc",
2309 "L'un ou l'autre suffit pour se connecter.",
2310 ),
2311 ("signin_requirement", "Exigence de connexion"),
2312 (
2313 "single_click_desc",
2314 "Quand activé, un simple clic ouvre une entrée et Ctrl+clic la sélectionne. Quand désactivé, un simple clic sélectionne et un double-clic ouvre.",
2315 ),
2316 ("single_click_label", "Ouvrir au clic simple"),
2317 ("size", "Taille"),
2318 ("some_files_exist", "Certains fichiers existent déjà"),
2319 ("sort_asc", "Croissant"),
2320 ("sort_by", "Trier par"),
2321 ("sort_desc", "Décroissant"),
2322 ("theme_auto", "Auto"),
2323 ("theme_dark", "Sombre"),
2324 ("theme_light", "Clair"),
2325 ("theme_title", "Thème : {} (cliquer pour changer)"),
2326 (
2327 "thumbnails_desc",
2328 "Afficher un aperçu à la place d'une icône pour les images et les vidéos en vue grille.",
2329 ),
2330 ("thumbnails_label", "Afficher les miniatures"),
2331 ("type", "Type"),
2332 ("unlock", "Ouvrir le partage"),
2333 ("unsaved_changes", "Modifications non enregistrées"),
2334 ("until", "Jusqu'au"),
2335 ("upload_abort", "Interrompre"),
2336 ("upload_aborted", "Interrompu"),
2337 ("upload_active_n", "{} en cours"),
2338 (
2339 "upload_apply_all",
2340 "Appliquer aussi aux fichiers qui apparaissent pendant le téléversement",
2341 ),
2342 (
2343 "upload_check_failed",
2344 "Impossible de vérifier les fichiers existants : {}",
2345 ),
2346 ("upload_clear", "Retirer de la liste"),
2347 ("upload_clear_finished", "Effacer les terminés"),
2348 ("upload_collapse", "Réduire"),
2349 ("upload_complete", "Téléversement terminé"),
2350 (
2351 "upload_conflict_question",
2352 "Les fichiers suivants existent déjà. Les remplacer ou les ignorer ?",
2353 ),
2354 ("upload_drop_hint", "Déposer ici pour téléverser"),
2355 ("upload_errors_n", "{} en échec"),
2356 (
2357 "upload_exists_ask",
2358 "« {} » est apparu sur le serveur pendant le téléversement.",
2359 ),
2360 ("upload_expand", "Développer"),
2361 ("upload_failed", "Échec"),
2362 ("upload_files", "Téléverser des fichiers"),
2363 ("upload_folder", "Téléverser un dossier"),
2364 ("upload_n_files", "{} fichiers"),
2365 ("upload_pause", "Mettre en pause"),
2366 ("upload_paused", "En pause"),
2367 ("upload_preparing", "Préparation…"),
2368 ("upload_resume", "Reprendre"),
2369 ("upload_show_graph", "Détails et graphique de vitesse"),
2370 ("upload_skip", "Ignorer"),
2371 ("upload_skipped_n", "{} ignorés"),
2372 ("upload_speed", "{}/s"),
2373 ("upload_waiting", "En attente de votre réponse"),
2374 ("uploads", "Téléversements"),
2375 ("uploads_empty", "Aucun téléversement pour l'instant"),
2376 ("use_passkey", "Utiliser une clé d'accès"),
2377 (
2378 "use_passkey_hint",
2379 "Laissez le nom vide, sauf si votre clé d'accès en a besoin.",
2380 ),
2381 ("user_created", "Utilisateur créé"),
2382 ("user_delete_err", "Impossible de supprimer l'utilisateur"),
2383 ("user_disabled", "désactivé"),
2384 ("user_name_example", "p. ex. alice"),
2385 (
2386 "user_save_err",
2387 "Impossible d'enregistrer l'utilisateur : {}",
2388 ),
2389 ("user_updated", "Utilisateur mis à jour"),
2390 ("user_you", "(vous)"),
2391 ("users", "Utilisateurs"),
2392 ("your_shares", "Vos partages"),
2393];
2394
2395#[cfg(test)]
2396mod tests {
2397 use super::*;
2398
2399 fn keys<'a>(table: &'a [(&'a str, &'a str)]) -> Vec<&'a str> {
2400 table.iter().map(|(k, _)| *k).collect()
2401 }
2402
2403 #[test]
2404 fn tables_are_sorted() {
2405 // `find` binary-searches, so an out-of-order entry is unreachable.
2406 for (name, table) in [("EN", EN), ("DE", DE), ("FR", FR)] {
2407 let ks = keys(table);
2408 let mut sorted = ks.clone();
2409 sorted.sort_unstable();
2410 assert_eq!(ks, sorted, "{name} table is not sorted by key");
2411 }
2412 }
2413
2414 #[test]
2415 fn no_duplicate_keys() {
2416 for (name, table) in [("EN", EN), ("DE", DE), ("FR", FR)] {
2417 let mut ks = keys(table);
2418 ks.sort_unstable();
2419 let dups = ks
2420 .windows(2)
2421 .filter(|w| w[0] == w[1])
2422 .map(|w| w[0])
2423 .collect::<Vec<_>>();
2424 assert!(dups.is_empty(), "{name} duplicates: {dups:?}");
2425 }
2426 }
2427
2428 #[test]
2429 fn translations_cover_all_keys() {
2430 // Full parity: DE and FR must translate every EN key (both
2431 // directions), so no string can silently fall back to English.
2432 let en = keys(EN);
2433 for (name, table) in [("DE", DE), ("FR", FR)] {
2434 let other = keys(table);
2435 assert_eq!(
2436 en.len(),
2437 other.len(),
2438 "{name} has {} keys, EN has {}",
2439 other.len(),
2440 en.len()
2441 );
2442 for k in &other {
2443 assert!(en.contains(k), "{name} key not in EN: {k}");
2444 }
2445 }
2446 }
2447}
2448