/** English UI strings. */ export const en: Record = { 'toolbar.new_folder': 'New folder', 'toolbar.upload': 'Upload', 'toolbar.search': 'Search', 'toolbar.search.placeholder': 'Search by name or tag:…', 'toolbar.view.list': 'List', 'toolbar.view.grid': 'Grid', 'toolbar.refresh': 'Refresh', 'toolbar.go_up': 'Up one level', 'ctx.open': 'Open', 'ctx.preview': 'Preview', 'ctx.download': 'Download', 'ctx.archive_create': 'Create archive…', 'ctx.archive_extract': 'Extract archive…', 'ctx.rename': 'Rename', 'ctx.delete': 'Delete', 'ctx.delete_perm': 'Delete permanently', 'ctx.restore': 'Restore', 'ctx.share': 'Share', 'ctx.move': 'Move', 'ctx.copy': 'Copy', 'ctx.cut': 'Cut', 'ctx.show_hidden': 'Show hidden files', 'ctx.hide_hidden': 'Hide hidden files', 'ctx.keep_local': 'Keep on this computer', 'ctx.keep_online': 'Keep online only', 'ctx.keep_reveal': 'Open local folder', 'ctx.keep_inherited': 'Kept on this computer with its parent', 'keep.started': 'Will be kept on this computer - sync started', 'keep.failed': 'Could not keep on this computer', 'keep.badge_kept': 'On this computer', 'keep.badge_syncing': 'Syncing…', 'keep.badge_cloud': 'Online only', 'keep.badge_partial': 'Contains items kept on this computer', 'keep.strip_transfer': 'Syncing {name} - {done}/{total} ({pct}%)', 'keep.strip_inventory': 'Syncing {name} - scanning the server…', 'keep.strip_settling': 'Syncing {name} - settling…', 'ctx.paste': 'Paste', 'ctx.info': 'Info', 'ctx.duplicate': 'Duplicate', 'ctx.new_file': 'New file', 'modal.delete.title': 'Delete?', 'modal.delete.message': '{count} items will be moved to trash.', 'modal.delete.message_one': '{count} item will be moved to trash.', 'modal.delete.confirm': 'Move to Trash', 'modal.delete.working': 'Moving to Trash…', 'modal.delete.cancel': 'Cancel', 'modal.delete.permanent_title': 'Delete permanently?', 'modal.delete.permanent_message': '{count} items will be deleted for good. This cannot be undone.', 'modal.delete.permanent_message_one': '{count} item will be deleted for good. This cannot be undone.', 'modal.delete.permanent_confirm': 'Delete permanently', 'modal.delete.permanent_working': 'Deleting…', 'modal.rename.title': 'Rename', 'modal.rename.save': 'Save', 'modal.rename.saving': 'Renaming…', 'modal.rename.cancel': 'Cancel', 'modal.newfolder.title': 'New folder', 'modal.newfolder.placeholder': 'Folder name', 'modal.newfolder.create': 'Create', 'modal.newfolder.creating': 'Creating…', 'modal.newfolder.cancel': 'Cancel', 'modal.share.title': 'Share link', 'archive.create_title': 'Create archive', 'archive.extract_title': 'Extract archive', 'archive.create_count': '{count} selected items', 'archive.create_count_one': '{count} selected item', 'archive.filename': 'Archive name', 'archive.format': 'Format', 'archive.password_optional': 'Password (optional)', 'archive.password_confirm': 'Confirm password', 'archive.password_mismatch': 'Passwords do not match.', 'archive.encrypt_names': 'Encrypt file names', 'archive.compression': 'Compression', 'archive.solid': 'Create solid archive', 'archive.dictionary_size': 'Dictionary size', 'archive.dictionary_size_value': '{n} MiB', 'archive.dictionary_hint': 'Larger dictionaries can improve compression but use more memory while creating and extracting.', 'archive.destination_folder': 'Extract to folder', 'archive.create': 'Create', 'archive.creating': 'Creating…', 'archive.extract': 'Extract', 'archive.extract_here': 'Extract here', 'archive.extract_to_folder': 'Extract to folder', 'archive.extracting': 'Extracting…', 'archive.cancel': 'Cancel', 'archive.invalid_name': 'Enter a file name without slashes.', 'archive.invalid_extension': 'Archive name must use one of the available format extensions.', 'archive.invalid_folder': 'Enter a folder name without slashes.', 'archive.password_required': 'This archive requires a password.', 'archive.password_title': 'Archive password', 'archive.continue': 'Continue', 'archive.opening': 'Opening…', 'archive.bad_password': 'The archive password is incorrect.', 'archive.target_exists': 'An item with that name already exists. Choose another name or remove it first.', 'archive.password_charset': 'A ZIP password can use only ASCII characters: unaccented letters, digits and ordinary punctuation. Choose 7z to use any characters.', 'archive.error_unsupported': 'This archive cannot be extracted: this server cannot read its format, or it holds something filex does not extract (a link, a special file, or a file whose size it does not state).', 'archive.error_limit': 'This archive is larger than the server allows to extract.', 'archive.error_unavailable': 'This server cannot open this kind of archive right now.', 'archive.created': 'Archive created', 'archive.queued': 'Archive creation is running in the background', 'archive.extracted': 'Extracted {count} files', 'archive.extracted_one': 'Extracted {count} file', 'archive.extraction_queued': 'Archive extraction is running in the background', 'archive.preparing_extract': 'Reading {name}… the whole archive is read before it can be extracted.', 'archive.already_preparing': 'Still reading {name} - it is extracted once that is done', 'archive.extraction_completed': 'Extraction completed', 'archive.extraction_cancelled': 'Extraction cancelled after {count} files', 'archive.extraction_cancelled_one': 'Extraction cancelled after {count} file', 'modal.share.pin': 'PIN protected', 'modal.share.expires': 'Expires at', 'modal.share.max_downloads': 'Download limit', 'modal.share.create': 'Share', 'modal.share.cancel': 'Cancel', 'modal.share.close': 'Close', 'modal.share.limit_applied': '(server limit applied)', 'modal.share.copy': 'Copy', 'modal.share.url_copied': 'Link copied', 'modal.share.pin_copied': 'PIN copied', 'modal.share.cli_copied': 'CLI command copied', 'upload.progress': 'Uploading', 'upload.done': 'Done', 'upload.error': 'Error', 'upload.failed': 'Could not upload “{name}”', 'upload.aborted': 'Aborted', 'upload.cancel': 'Cancel', 'upload.resuming': 'Resuming “{name}” from {percent}%', 'upload.saving': 'Saving to the storage…', 'empty.folder': 'This folder is empty', 'empty.search': 'No results', 'loading': 'Loading…', 'notFound.title': 'Folder not found', 'notFound.desc': 'This folder does not exist, was moved, or you do not have access to it.', 'notFound.goRoot': 'Go to root folder', 'col.name': 'Name', 'col.size': 'Size', 'col.modified': 'Modified', 'col.type': 'Type', 'unit.bytes': 'B', 'unit.kb': 'KB', 'unit.mb': 'MB', 'unit.gb': 'GB', 'unit.tb': 'TB', 'unit.pb': 'PB', 'breadcrumb.root': 'Root', 'breadcrumb.copy_path': 'Copy path', 'breadcrumb.go_to_path': 'Go to path', 'breadcrumb.path_placeholder': 'fileman/foo/bar', 'ops.copy': 'Copying', 'ops.move': 'Moving', 'ops.delete': 'Deleting', 'ops.queued': 'queued', 'ops.done': 'done', 'ops.error': 'error', 'node.trash': 'Trash', /* gorunum:v1 - the singular kind, printed under a folder's name on a card * and beside it in the list. The plural section heading is a different * string on purpose. */ 'node.folder': 'Folder', // --- Rich viewer chrome --- 'viewer.open_in_new_tab': 'Open in new tab', 'viewer.loading': 'Loading…', 'viewer.failed_to_load': 'Failed to load file', /* ⚠ Said to a PERSON: it used to tell them to "install the peer dependency". */ 'viewer.peer_not_installed': 'This kind of file cannot be shown here. Download it to open it on your device.', 'viewer.format_unsupported_3d': 'The preview shows 3D models in .glb, .gltf and .usdz only. Download the file to open it in a 3D program.', 'viewer.zoom_in': 'Zoom in', 'viewer.zoom_out': 'Zoom out', 'viewer.fit_width': 'Fit width', 'viewer.next_page': 'Next page', 'viewer.prev_page': 'Previous page', 'viewer.page_n_of_m': 'Page {n} of {m}', 'viewer.tags': 'Tags', 'viewer.layers': 'Layers', 'viewer.toc': 'Contents', 'viewer.font_smaller': 'Smaller text', 'viewer.font_larger': 'Larger text', 'viewer.search': 'Search', 'viewer.download': 'Download', 'viewer.saving': 'Saving…', 'viewer.save': 'Save (Ctrl+S)', 'viewer.saved': 'Saved', 'viewer.save_error': 'Error', 'viewer.editor_loading': 'Loading editor…', 'viewer.no_preview': 'No preview for this file type yet.', 'viewer.edit': 'Edit', 'viewer.close': 'Close', 'presence.expand': 'Show names', 'presence.collapse': 'Collapse', 'viewer.save_annotations': 'Save annotations', 'viewer.annotations_on': 'Annotations: on', 'viewer.annotations_off': 'Annotations: off', 'viewer.read_only': 'Read only', 'viewer.csv_first_row_header': 'First row as header', 'viewer.csv_filter': 'Filter rows…', 'viewer.epub_prev': 'Previous', 'viewer.epub_next': 'Next', /* ⚠ The old sentence named an ENVIRONMENT VARIABLE to every reader ("operator must wire FILEX_DRAWIO_URL"). A person who only wanted to look at a diagram is told what they can do; `_admin` - someone who can fix it - is told where. */ 'viewer.drawio.disabled': 'Diagrams cannot be opened here: this server has no draw.io. Download the file to open it elsewhere.', 'viewer.drawio.disabled_admin': 'draw.io is not set up on this server. Set it up in the admin panel under External services.', 'viewer.drawio.load_failed': 'This diagram could not be read. Download it to open it elsewhere.', 'viewer.drawio.save_failed': 'The diagram could not be saved. Your changes are still in the editor - try again.', 'viewer.archive.entries': '{n} files', 'viewer.archive.entries_one': '{n} file', 'viewer.archive.empty': 'Archive is empty.', 'viewer.archive.error': 'Could not read archive contents.', 'viewer.archive.unsupported': 'This kind of archive cannot be listed here. Download it to see what is inside.', 'viewer.archive.too_large': 'This archive is too large to list here. Download it to see what is inside.', 'viewer.archive.open': 'Open archive', 'viewer.archive.root': 'Archive', 'viewer.archive.location': 'Archive location', 'viewer.archive.reading': 'Still reading… the whole archive is read before its contents can be listed, which takes a while for a large one.', 'viewer.name': 'Name', 'viewer.size': 'Size', // --- cila:a - sorting / date groups / density --- 'col.sort': 'Sort', 'group.today': 'Today', 'group.yesterday': 'Yesterday', 'group.this_week': 'This week', 'group.this_month': 'This month', 'group.no_date': 'No date', 'toolbar.density.compact': 'Compact view', 'toolbar.density.comfortable': 'Comfortable view', // --- cila:c - command palette + shortcuts help + breadcrumb --- 'palette.placeholder': 'Search files, folders or commands…', 'palette.files': 'Files', 'palette.commands': 'Commands', 'palette.goto': 'Go to path', 'palette.empty': 'No results', 'palette.hint': '↑↓ navigate · Enter select · Esc close', 'cmd.view_toggle': 'Toggle view (list ⇄ grid)', 'cmd.trash': 'Open trash', 'shortcuts.title': 'Keyboard shortcuts', 'shortcuts.group.nav': 'Navigation', 'shortcuts.group.selection': 'Selection', 'shortcuts.group.file': 'File operations', 'shortcuts.palette': 'Command palette', 'shortcuts.search': 'Focus search', 'shortcuts.go_up': 'Go up one level', 'shortcuts.open': 'Open selected item', 'shortcuts.close': 'Close / cancel', 'shortcuts.toggle_hidden': 'Show/hide hidden files', 'shortcuts.help': 'This help dialog', 'shortcuts.select_all': 'Select all', 'shortcuts.star': 'Star / unstar', 'shortcuts.rename': 'Rename', 'shortcuts.delete': 'Delete', 'shortcuts.cut': 'Cut', 'shortcuts.copy': 'Copy', 'shortcuts.paste': 'Paste', 'breadcrumb.more': 'Folders in between', // --- State screens + undo snackbar + connection badge (cila:b) --- 'empty.hint': 'Drag and drop files here', 'empty.upload': 'Upload files', 'empty.search.title': 'No files match your search', 'empty.search.hint': 'Try a different search term', 'empty.trash.title': 'Trash is empty', 'error.title': 'Could not load this folder', 'error.retry': 'Try again', 'toast.undo': 'Undo', 'toast.undone': 'Undone', 'toast.undoing': 'Undoing…', 'toast.undo_queued': 'The undo is queued - the operations panel shows when it is done', 'toast.undo_failed': 'Could not undo', 'toast.renamed': 'Renamed', 'toast.rename_queued': 'Renaming to “{name}”…', 'toast.moved': 'Moved', 'toast.trashed': 'Moved to trash', /* i18n:hardcoded - toast copy that used to be Turkish string literals in FileExplorer.vue, unreachable by any locale. */ 'toast.failed': 'Operation failed', /* ── errorWords (lib/errorWords): how a failure is SAID. ⚠ No status code, no JSON, no environment variable ever reaches these; an administrator sees the raw words on a second line, nobody else does. ── */ 'err.status.400': 'Bad request', 'err.status.401': 'Sign-in required', 'err.status.403': 'You are not allowed to do this', 'err.status.404': 'Not found', 'err.status.409': 'Already exists / conflict', 'err.status.413': 'File too large', 'err.status.415': 'Unsupported file type', 'err.status.422': 'Invalid data', 'err.status.429': 'Too many requests', 'err.status.500': 'Server error', 'err.status.501': 'Not supported', 'err.status.502': 'A connected service reported an error', 'err.status.503': 'Service unavailable', 'err.status.504': 'A connected service took too long to answer', 'err.status.other': 'The server refused this request.', 'err.upload_stalled': 'The upload stopped making progress. Try again - it continues where it stopped.', 'err.network': 'The server could not be reached. Check your connection and try again.', /* 0.54 (audit A1/A2): a refusal the server names is said in the SERVER's words (`message`, backend internal/apierr `server.error.*`); the copies that stood here (err.read_only, err.quota, err.e2e_*, err.name_taken, opc.err.*…) are gone with the tables of lib/errorWords that used them. */ 'err.save_failed': 'Your changes could not be saved.', 'err.load_failed': 'This file could not be loaded.', 'err.viewer_failed': 'The viewer for this file could not be started. Download the file to open it.', 'err.detail': 'Details', 'toast.copied': 'Copied', 'toast.deleted': 'Deleted', 'toast.cut': 'Cut', 'toast.cut_ready': 'Cut - ready to paste', 'toast.copy_ready': 'Copied - ready to paste', 'toast.same_folder_cut': 'Cannot cut into the same folder', 'toast.restored': '{n} items restored', 'toast.restored_one': '{n} item restored', 'toast.delete_queued': 'Delete queued', 'toast.trash_retention': 'Items in the trash are removed automatically once the retention window ends. Permanent deletion is done from the admin panel.', /* The Trash row a permanent delete is on its way for (the admin Trash page's words: one sentence, both catalogues - lesson #447). */ 'trash.purging': 'Deleting permanently…', 'trash.row_busy': 'Something is already being done to this item', 'dropzone.hint': 'Drop files here', 'modal.newfolder.invalid': 'Invalid character', 'names.reserved': '“{name}” is reserved for filex’s own use. Choose another name.', /* ⚠ A missing or broken document server is said in words, never as the HTTP layer (it used to read `Config fetch 503: {"error":"onlyoffice not configured"}`). `_admin` is what someone who can fix it reads - where to fix it; everybody else reads how to get the file anyway. */ 'viewer.office_unconfigured': 'Office documents cannot be opened here: this server has no ONLYOFFICE document server. Download the file to open it on your computer.', 'viewer.office_unconfigured_admin': 'ONLYOFFICE is not set up on this server, so office documents cannot be opened here. Set it up in the admin panel under External services.', 'viewer.office_unreachable': 'The document server is not answering right now. Try again later, or download the file.', 'viewer.office_unreachable_admin': 'The ONLYOFFICE document server is not answering. Check it in the admin panel under External services.', /* Task #92: the editor runs in a frame on another origin (the document server's own, or the interface origin), and that page never answered - the address does not reach this filex. */ 'viewer.office_frame_unreachable_admin': 'The ONLYOFFICE editor frame did not load from {origin}. Check that the reverse proxy there sends the frame to filex ({env}).', 'viewer.office_failed': 'This document could not be opened in ONLYOFFICE. Download it to open it on your computer.', 'viewer.csv_office_note': 'Saved as CSV: only the values of the active sheet are kept. Formatting, formulas and other sheets are not saved.', 'viewer.office_forbidden': 'You do not have permission to open this document in ONLYOFFICE.', /* After ONLYOFFICE's "Download failed": which of its two failures it was, as filex saw it (lib/officeDiagnosis, issue #80). */ 'viewer.office_download_served': 'The document server downloaded this file from filex, but your browser could not load the converted copy from the document server. Check the X-Forwarded-Proto and X-Forwarded-Host headers on the reverse proxy in front of the document server.', 'viewer.office_download_not_requested': 'The document server never asked filex for this file. If the file was opened before, the document server may be using its own copy of it.', 'viewer.office_download_refused': 'filex refused the document server’s request for this file: {reason}.', 'viewer.office_fetch_reason.bad_link': 'the address was malformed', 'viewer.office_fetch_reason.signature_expired': 'the address had expired', 'viewer.office_fetch_reason.signature_bad': 'its signature did not match (the JWT secret changed, or the address was altered)', 'viewer.office_fetch_reason.not_found': 'the file no longer exists', 'viewer.office_fetch_reason.storage_unavailable': 'the storage could not be opened', 'viewer.office_fetch_reason.body_unavailable': 'the file’s contents could not be found', 'viewer.office_fetch_reason.object_missing': 'the file is missing from the storage', 'viewer.office_fetch_reason.read_failed': 'reading the file from the storage failed', /* The explorer's Open on a document the document server would open, when there is none - shown to an administrator only (everyone else is not offered the entry at all; lib/serviceGate). */ 'ctx.needs_onlyoffice': 'ONLYOFFICE is not set up - set it up in the admin panel under External services.', 'ctx.needs_drawio': 'draw.io is not set up - set it up in the admin panel under External services.', 'viewer.pdf_inline_failed': 'Your browser could not display this PDF inline.', 'viewer.too_large': 'File is too large (>1 MB).', 'viewer.csv_rows': '{n} rows', 'viewer.csv_rows_one': '{n} row', 'presence.others': '{n} people', 'presence.others_one': '{n} person', 'conn.offline': 'No live connection - changes may be delayed', 'conn.tooltip': 'Live connection to the server is unavailable; the list refreshes periodically. This notice disappears once the connection is back.', /* === bul:s3 === */ 'palette.everywhere': 'Everywhere', 'palette.searching': 'Searching…', 'palette.everywhere_failed': 'The search could not be done. Try again.', 'palette.saved': 'Saved searches', 'palette.save': 'Save search', 'palette.saved.delete': 'Delete saved search', /* #168 - the admin panel's search (components/PanelSearch.vue). */ 'panelsearch.label': 'Search the admin panel', 'panelsearch.trigger': 'Search', 'panelsearch.placeholder': 'Search pages, settings, people, apps…', 'panelsearch.close': 'Close search', 'panelsearch.clear': 'Clear the search', 'panelsearch.results': 'Search results', 'panelsearch.group.page': 'Pages', 'panelsearch.group.setting': 'Settings', 'panelsearch.group.app': 'Apps', 'panelsearch.group.user': 'Users', 'panelsearch.group.group': 'Groups', 'panelsearch.group.key': 'API keys', 'panelsearch.group.storage': 'Storages', 'panelsearch.group.share': 'Shares', 'panelsearch.group.file': 'Files', 'panelsearch.group.recent': 'Recent searches', 'panelsearch.files_all': 'Search files: {q}', 'panelsearch.recent_remove': 'Remove from recent searches', 'panelsearch.recent_clear': 'Clear recent searches', 'panelsearch.empty': 'Nothing matches “{q}”.', 'panelsearch.searching': 'Searching…', 'panelsearch.failed': 'Some results could not be loaded. The rest are shown.', 'panelsearch.prefixes': 'Narrow to one kind:', 'panelsearch.count_one': '{n} result', 'panelsearch.count': '{n} results', 'search.in_content': 'In content', 'search.truncated': 'More results than shown - narrow your search', 'nav.more_shown': 'Showing {shown} of {total}', 'nav.load_more': 'Load more', /* Catalog coverage (docs/LAZY-CATALOGUE.md, lib/catalogCoverage). One sentence per reason; the banner sits over a listing and over search results, and says what is left out and why. */ 'coverage.first_scan': 'This storage’s first sync has not finished. Until it does, search, folder sizes and usage leave part of it out.', 'coverage.lazy_filling': 'filex is still cataloging this storage ({pct}% of the folders found so far). Until it finishes, search, folder sizes and usage leave part of it out.', 'coverage.lazy_on_open': 'Only the folders people open on this storage are cataloged. Search, folder sizes and usage cover those folders only.', 'coverage.search_some': 'Not everything on these storages is cataloged yet: {names}. This search may miss files there.', 'coverage.catalog_all': 'Catalog everything', 'coverage.catalog_started': 'Sync started - the whole storage is being cataloged.', 'coverage.catalog_running': 'Cataloging…', 'coverage.cataloging': 'Cataloging {storage}… this runs in the background, and this page says when it is done.', 'coverage.catalog_done': '{storage} is cataloged in full', 'coverage.catalog_failed': 'Cataloging {storage} failed. The admin panel shows why, under the storage’s sync runs.', 'coverage.catalog_stopped': 'Cataloging {storage} was stopped before it finished', 'coverage.catalog_joined': 'A scan of {storage} was already running - this page says when it is done.', 'coverage.catalog_gone': '{storage} was removed while it was being cataloged', 'coverage.catalog_unfollowed': 'Cataloging {storage} goes on in the background; the admin panel shows how it ends, under the storage’s sync runs', 'size.at_least': '≥ {size}', 'size.partial_hint': 'Part of this folder is not cataloged yet, so its size is at least this.', 'size.unknown_hint': 'This folder is not cataloged yet, so its size is not known.', /* === bag:b4 === */ 'toolbar.more': 'More actions', 'toolbar.search.close': 'Close search', 'sheet.menu': 'Actions', 'sheet.close': 'Close', /* === koru:k1 === */ 'toolbar.inspector': 'Details', 'ctx.details': 'Details', /* yildiz:s1 - starring is an action, so it has a verb in the menu. */ 'ctx.star': 'Star', 'ctx.unstar': 'Unstar', 'star.failed': 'Could not change the star', 'shortcuts.inspector': 'Toggle details panel', 'inspector.title': 'Details', 'inspector.copy_name': 'Copy name', 'inspector.items': '{n} items', 'inspector.items_one': '{n} item', 'inspector.type': 'Type', 'inspector.select_hint': 'Select an item to see its details.', /* pane:p1 - the panel HOLDS the last selected thing (owner's ruling, 2026-09-13), so it can be describing an item in the half of a split window nobody is looking at. This line says which one and where. */ 'inspector.held': 'Last selected - in {where}', 'inspector.close': 'Close', 'inspector.section.general': 'General', 'inspector.section.tags': 'Tags', /* etiket:t1 - TagPicker's own chrome. It printed these three in English regardless of the catalogue until 2026-09-13; `tags.open` is the chip's new "show me everything with this tag". */ 'tags.open': 'Open tag: {tag}', 'tags.add': '+ Add tag', 'tags.name': 'Tag name', 'tags.remove': 'Remove tag', /* etiket:k2 (v0.43.0) - the two KINDS of tag. Every place a tag is drawn says which kind it is, in words as well as the icon, because until this release a tag was silently shared with every account on the server. */ 'tags.kind.label': 'Who sees this tag', 'tags.kind.personal': 'Personal', 'tags.kind.team': 'Team', 'tags.kind.personal_help': 'Only you see it', 'tags.kind.team_help': 'Everyone on your team who can see this file', 'tags.kind.team_locked': 'Adding or removing a team tag needs edit permission on this file.', 'tags.chip.personal': 'Personal tag “{tag}” - only you see it', 'tags.chip.team': 'Team tag “{tag}” - everyone on your team who can see this file sees it', 'tags.add_submit': 'Add', 'inspector.section.versions': 'Versions', 'inspector.section.permissions': 'Permissions', 'inspector.section.shares': 'Shares', 'inspector.path': 'Path', 'inspector.size': 'Size', 'inspector.modified': 'Modified', 'inspector.mime': 'MIME type', 'inspector.etag': 'ETag', 'inspector.nodeId': 'Node ID', 'inspector.copy': 'Copy', 'inspector.copied': 'Copied', 'inspector.error': 'Could not load', 'inspector.items_summary': '{n} items, {size} total', 'inspector.items_summary_one': '{n} item, {size} total', 'inspector.folder_items': '{n} items', 'inspector.folder_items_one': '{n} item', 'inspector.versions.empty': 'No version history', 'inspector.versions.v': 'Version {n}', 'inspector.versions.restore': 'Restore', 'inspector.versions.restore_confirm': 'Restore this version?', 'inspector.versions.snapshot_current': 'Snapshot the current state first', 'inspector.versions.confirm': 'Confirm', 'inspector.versions.restoring': 'Restoring…', 'inspector.versions.cancel': 'Cancel', 'inspector.versions.take_snapshot': 'Snapshot current state', 'inspector.versions.snapshotting': 'Taking a snapshot…', 'inspector.versions.restored': 'Version restored', 'inspector.versions.snapshotted': 'Snapshot taken', 'inspector.versions.unsupported': 'The server does not support this operation', 'inspector.perm.none': 'No access', 'inspector.perm.viewer': 'Viewer', 'inspector.perm.editor': 'Editor', 'inspector.perm.owner': 'Owner', 'inspector.perm.manage': 'Manage permissions', 'inspector.shares.empty': 'No share links', 'inspector.shares.copy': 'Copy link', /* wiring:c1 - theme gallery */ 'theme.menu': 'Theme', 'theme.title': 'Theme gallery', 'theme.hint': 'A theme only changes the color palette - day or night is the choice above.', 'theme.mode.label': 'Appearance', 'theme.mode.light': 'Day', 'theme.mode.dark': 'Night', 'theme.mode.auto': 'Automatic', 'theme.reset': 'Reset to default', 'theme.close': 'Close', 'theme.selected': 'Selected', 'theme.name.default': 'Default', 'theme.name.night': 'Night blue', 'theme.name.forest': 'Forest', 'theme.name.amber': 'Amber', 'theme.name.lilac': 'Lilac', 'theme.name.contrast': 'High contrast', 'theme.name.gray': 'Soft gray', 'theme.name.terminal': 'Terminal green', /* === zaman:z3 - the time-zone picker (embed dialog + web settings) === */ 'tz.menu': 'Time zone', 'tz.title': 'Time zone', 'tz.label': 'Show dates in', 'tz.search': 'Search a city, country or offset - try "Istanbul" or "GMT+3"', 'tz.default.device': "Use this device's zone ({zone})", 'tz.default.account': "Use the account's zone ({zone})", 'tz.default.host': "Use this site's default ({zone})", 'tz.no_match': 'No zone matches “{query}”. Try a city, a country, or an offset like GMT+3.', 'tz.more': '{n} more - keep typing to narrow the list.', 'tz.hint': 'Saved in this browser only. Every date is stored as one moment in time and shown on the clock you pick here.', 'tz.now': 'Right now in {zone}: {time}', /* === wiring:c2 - customizable shortcuts + quick look === */ 'shortcuts.quicklook': 'Quick look', 'shortcuts.customize': 'Customize', 'shortcuts.settings.menu': 'Shortcuts', 'shortcuts.settings.title': 'Shortcut settings', 'shortcuts.settings.hint': 'To remap a shortcut, press "Change" and then the new key combination. Changes are stored in this browser only.', 'shortcuts.settings.change': 'Change', 'shortcuts.settings.capture': 'Press keys… (Esc cancels)', 'shortcuts.settings.reset': 'Reset to default', 'shortcuts.settings.reset_all': 'Reset all', 'shortcuts.settings.unbound': 'Not set', 'shortcuts.settings.fixed': 'Fixed', 'shortcuts.settings.customized': 'Customized', 'shortcuts.settings.conflict': 'is already used by "{name}".', 'shortcuts.settings.conflict_fixed': 'is reserved by the fixed shortcut "{name}" - it cannot be used.', 'shortcuts.settings.conflict_take': 'Unassign old and use here', 'shortcuts.settings.conflict_cancel': 'Cancel', 'quicklook.hint_close': 'close', 'quicklook.hint_nav': 'previous/next', 'quicklook.hint_open': 'open', /* === /wiring:c2 === */ /* === wiring:c3 - operations center === */ 'opc.title': 'Operations', 'opc.aria_badge': '{n} operations - toggle operations center', 'opc.aria_badge_one': '{n} operation - toggle operations center', 'opc.close': 'Close', 'opc.active': 'In progress', 'opc.history': 'History', 'opc.clear': 'Clear', 'opc.empty': 'No operations', 'opc.cancel': 'Cancel', 'opc.retry': 'Retry', 'opc.dismiss': 'Dismiss', 'opc.queued': 'Queued', 'opc.cancelling': 'Cancel requested…', 'opc.percent': '{n}%', 'opc.items': '{done} of {total} items', 'opc.trash_items': '{n} items from the trash', 'opc.trash_items_one': '{n} item from the trash', 'opc.status.running': 'In progress', 'opc.status.done': 'Done', 'opc.status.error': 'Failed', 'opc.status.aborted': 'Cancelled', 'opc.kind.upload': 'Upload', 'opc.kind.copy': 'Copy', 'opc.kind.move': 'Move', 'opc.kind.delete': 'Delete', 'opc.kind.rename': 'Rename', 'opc.kind.restore': 'Restore', 'opc.kind.purge': 'Delete permanently', 'opc.kind.convert': 'Convert', 'opc.kind.archive': 'Archive', 'opc.kind.plugin': 'App', 'opc.kind.trash': 'Empty trash', 'opc.kind.thumbs': 'Thumbnail repair', /* A folder's contents on hover (FolderPeek, useFolderPeek). */ 'peek.items': '{n} items', 'peek.items_one': '{n} item', 'peek.more': '+{n} more', 'peek.empty': 'Empty', 'peek.loading': 'Looking inside…', 'opc.open': 'Open', /* App plugins - rows a WebAssembly plugin adds to the file menu, and the jobs they queue (docs/APP-PLUGINS-API.md). "App" is what the feature is called on every surface; "plugin" is the wire word. */ 'plugin.queued': '{label} queued', 'plugin.done': '{label} finished', 'plugin.failed': '{label} failed', 'plugin.cancel_failed': 'Could not cancel the job', 'plugin.not_applicable': 'This action does not apply to the selection', 'plugin.read_only': 'This storage is read-only', 'plugin.needs_engine': '{name} is not installed on this server - install it and restart filex.', 'plugin.needs_other': '{name} is not available on this server.', 'plugin.needs_office': 'Office documents need {name}, which is not connected to this server - connect it under External services.', 'plugin.confirm.title': 'Confirm', 'plugin.confirm.cancel': 'Cancel', 'plugin.confirm.run': 'Run', 'plugin.view.close': 'Close', 'appframe.confirm_title': 'Confirm', 'appframe.consent_clipboard': '{app} wants to copy text to your clipboard.', 'appframe.consent_download': '{app} wants to save “{name}” to your computer.', 'appframe.consent_job': '{app} wants to start “{action}”.', 'appframe.consent_allow': 'Allow', 'appframe.consent_deny': 'Don’t allow', 'appframe.unsaved_title': 'Unsaved changes', 'appframe.unsaved_text': '{app} has changes that are not saved. Close it anyway?', 'appframe.discard': 'Close without saving', 'appframe.keep_open': 'Keep editing', 'appframe.save_close': 'Save and close', 'appframe.updated': '{app} was updated to {version}.', 'appframe.updated_reload': 'An administrator approved a new version of {app}. Reload it to use the new version - save your work first.', 'appframe.reload': 'Reload', 'appframe.dismiss': 'Dismiss', 'appframe.not_connected': '{app} did not start. Close it and open it again; if it keeps happening, tell your administrator.', 'appframe.save_as_title': '{app}: save “{name}” to', 'plugin.view.busy': 'Working…', 'plugin.view.unsupported': 'This screen uses a component this version cannot draw ({type})', 'plugin.view.error': 'The app answered with an error', 'plugin.output_missing': 'The output is no longer where it was', /* M2 - surface components (components/plugin/nodes/*) */ 'plugin.view.loading': 'Loading…', 'plugin.view.preview_failed': 'The preview could not be loaded', 'plugin.steps.label': 'Steps', 'plugin.list.empty': 'Nothing here yet', 'plugin.list.actions': 'Actions', /* The label on a table row's ONE action control (core RowActions.vue). The explorer's handle is the ⋮ glyph; a panel row's says what it is. Owner, 2026-09-20: "adminde 'Aksiyon' diye yazmalı". */ 'row.actions': 'Actions', 'plugin.people.placeholder': 'Name or email', 'plugin.people.placeholder_email': 'Email address', 'plugin.people.add': 'Add', 'plugin.people.remove': 'Remove {name}', 'plugin.people.invalid_email': 'Enter a valid email address', 'plugin.people.external_off': 'Only people with an account can be added', 'plugin.pin.label': 'PIN', 'plugin.file.choose': 'Choose…', 'plugin.file.clear': 'Clear', 'plugin.file.none': 'Nothing chosen', /* M3 - the sign track: signature-pad + pdf-fields nodes, and the outside participant's public page (views/PublicSurface.vue via usePublicPage). */ 'plugin.sig.mode_draw': 'Draw', 'plugin.sig.mode_type': 'Type', 'plugin.sig.mode_upload': 'Upload', 'plugin.sig.draw_hint': 'Sign here with your finger or mouse', 'plugin.sig.type_placeholder': 'Type your name', 'plugin.sig.upload_pick': 'Choose a picture…', 'plugin.sig.upload_hint': 'PNG or JPEG, at most {kb} KB', 'plugin.sig.upload_too_big': 'The picture is larger than {kb} KB', 'plugin.sig.upload_bad_type': 'Only PNG or JPEG pictures can be used', 'plugin.sig.upload_unreadable': 'The picture could not be read', 'plugin.sig.clear': 'Clear signature', 'plugin.sig.signed': 'Signature captured', 'plugin.pdf.load_failed': 'The document could not be loaded', 'plugin.pdf.palette': 'Field types', 'plugin.pdf.pending': 'Boxes waiting for a place', 'plugin.pdf.place_box_hint': 'Tap the page where “{name}” goes, or drag to size it', 'plugin.pdf.all_placed': 'Every box has a place', 'plugin.pdf.place_idle': 'Choose one of the boxes above, then tap the page where it goes.', 'plugin.pdf.place_idle_done': 'Tap a box on the page to take it off or copy it; drag it to move it.', 'plugin.pdf.no_boxes': 'No boxes yet. Add one below: give it a name, say whose it is, and place it on the document in the next step.', 'plugin.pdf.add_box': 'Add a box', 'plugin.pdf.unplace': 'Take off the page', 'plugin.pdf.place_hint': 'Tap the page where the {type} field goes, or drag to size it', 'plugin.pdf.type_signature': 'Signature', 'plugin.pdf.type_initials': 'Initials', 'plugin.pdf.type_date': 'Date', 'plugin.pdf.type_text': 'Text', 'plugin.pdf.type_checkbox': 'Checkbox', 'plugin.pdf.tap_signature': 'Tap to sign', 'plugin.pdf.tap_initials': 'Tap to initial', 'plugin.pdf.tap_date': 'Tap for today', 'plugin.pdf.tap_text': 'Text', 'plugin.pdf.tap_checkbox': 'Tap to tick', 'plugin.pdf.label': 'Name', 'plugin.pdf.assignee': 'Signer', 'plugin.pdf.unassigned': 'Anyone', 'plugin.pdf.filled_by': 'Filled by', 'plugin.pdf.style': 'How it is signed', 'plugin.pdf.style_drawn': 'Drawn', 'plugin.pdf.style_typed': 'Typed', 'plugin.pdf.lines': 'Printed under it', 'plugin.pdf.lines_preview': 'Under the signature:', 'plugin.pdf.lines_none': 'Nothing is printed under this signature.', 'plugin.pdf.required': 'Required', 'plugin.pdf.copy_to_page': 'Copy to page', 'plugin.pdf.copy': 'Copy', 'plugin.pdf.delete': 'Delete field', 'plugin.pdf.zoom_in': 'Zoom in', 'plugin.pdf.zoom_out': 'Zoom out', 'plugin.pdf.zoom_fit': 'Fit to width', 'plugin.pdf.zoom_fit_page': 'Fit the page to the screen', 'plugin.pdf.pad_for': 'Your {type}', 'plugin.pdf.pad_done': 'Done', 'plugin.page.loading': 'Loading…', 'plugin.page.pin_title': 'This page is protected', 'plugin.page.pin_hint': 'Enter the PIN you were given to continue', 'plugin.page.pin_submit': 'Continue', 'plugin.page.pin_wrong': 'That PIN is not right', 'plugin.page.pin_locked': 'Too many wrong PINs - wait a few minutes and try again', 'plugin.page.unavailable_title': 'This link is not available', 'plugin.page.unavailable_text': 'It may have expired, been used up or been withdrawn. Ask the person who sent it for a new one.', 'plugin.page.accepted_title': 'Received, thank you', 'plugin.page.accepted_text': 'Your answer has been recorded. You can close this page.', 'plugin.page.done_title': 'All done', 'plugin.page.done_text': 'There is nothing more to do here. You can close this page.', 'plugin.page.error_title': 'Something went wrong', 'plugin.page.retry': 'Try again', 'plugin.page.files': 'Documents', 'plugin.page.open_file': 'Open {name} in a new tab', 'plugin.page.footer': 'Served by filex', /* The public pages' own sentences (share, file request) are the SERVER's `server.public.*` (composables/usePublicText) - not keys of this file. */ /* === App plugins v2 - a `page` view, an app's lock on a file, the output mode a job wrote in, and the faces + rules a signature field carries. === */ 'plugin.page_view.back': 'Back to the files', 'plugin.page_view.queued_title': 'The job is queued', 'plugin.page_view.queued_text': 'filex is working on it. This page says when it is done, and its progress is in the operations tray too.', 'plugin.page_view.finished_title': 'The job is done', 'plugin.page_view.finished_text': 'There is nothing more to do here. You can go back to the files or close this tab.', 'plugin.page_view.failed_title': 'The job did not finish', 'plugin.page_view.opening_title': 'Opening the result', 'plugin.page_view.open_ops': 'Open the operations tray', 'plugin.page_view.done_title': 'All done', 'plugin.page_view.done_text': 'There is nothing more to do here. You can close this tab.', 'plugin.page_view.error_title': 'This screen could not be opened', 'plugin.page_view.retry': 'Try again', 'plugin.page_view.blocked': 'The new tab was blocked - allow pop-ups for this site, or the screen will open in a dialog', 'plugin.output.sibling': 'new file', 'plugin.output.version': 'new version', 'plugin.output.sibling_title': 'The result lands as a new file beside the original', 'plugin.output.version_title': 'The result replaces the file as a new version of it', 'plugin.sign.font_label': 'Handwriting', 'plugin.pdf.font': 'Font', 'plugin.pdf.rule_number': 'Numbers only', 'plugin.pdf.rule_email': 'Email address', 'plugin.pdf.rule_length': 'Between {min} and {max} characters', 'plugin.pdf.rule_min': 'At least {min} characters', 'plugin.pdf.rule_max': 'At most {max} characters', 'plugin.pdf.err_number': 'Enter a number', 'plugin.pdf.err_email': 'Enter a valid email address', 'plugin.pdf.err_min': 'Too short - at least {min} characters', 'plugin.pdf.err_max': 'Too long - at most {max} characters', 'applock.badge': 'Locked', 'applock.some_app': 'an app', 'applock.held': '{app} locked this file', 'applock.held_reason': '{app} locked this file: {reason}', 'applock.until': '- until {date}', 'applock.inspector': 'Held by an app', /* issue #34 - a symlink the server will NOT follow (lib/symlink). The badge is the short word on the row; `why` is the sentence behind it, shown on hover, in the details panel and in the toast when somebody tries to open one. ⚠ Broken and outside-of-root are DIFFERENT states and must read differently: only one has an administrator remedy, and offering that remedy for a target that has been deleted sends the person to a settings screen that cannot help them. */ 'symlink.badge.outside_root': 'Outside storage', 'symlink.badge.broken': 'Broken link', 'symlink.badge.unresolved': 'Remote link', 'symlink.badge.unknown': 'Link', 'symlink.why.outside_root': 'A link whose target lies outside this storage, which is why it cannot be opened. An administrator can allow it with "Follow symlinks that leave this folder" in the storage\'s settings.', 'symlink.why.broken': 'A link whose target no longer exists, so there is nothing to open. It has to be repaired or removed on the server - no setting can bring the target back.', 'symlink.why.unresolved': 'A link on a remote server. filex cannot tell whether its target is inside this storage, so it does not follow it and cannot open it.', 'symlink.why.unknown': 'A link filex will not follow, so it cannot be opened. Its target is either outside this storage, missing, or on a remote server filex cannot resolve.', 'symlink.inspector': 'A link that cannot be opened', /* Issue #104 - an entry the storage could not answer for (lib/unavailable). The sentence says what it means and what happens next; the storage's own answer follows it ({reason}), usually in English. */ 'unavailable.why.file': 'The storage could not say whether this file still exists. It cannot be opened or changed until the storage answers for it again; the next scan checks.', 'unavailable.why.dir': 'The storage could not say whether this folder still exists. Neither the folder nor anything inside it can be opened or changed until the storage answers for it again; the next scan checks.', 'unavailable.withReason': '{why} The storage answered: {reason}', 'unavailable.inspector': 'Unavailable', /* 0.50 - why a file has no thumbnail, on the file itself (lib/thumbNote): the marker's name and the sentence a resting pointer or a tap shows. */ 'thumbNote.corrupt': 'Damaged', 'thumbNote.corrupt_why': 'No thumbnail: the file could not be read. It may be damaged or incomplete.', 'thumbNote.encrypted': 'Encrypted', 'thumbNote.encrypted_why': 'No thumbnail: the file is encrypted or protected by a password.', 'thumbNote.too_large': 'Too large', 'thumbNote.too_large_why': 'No thumbnail: the file is larger than the thumbnail size limit.', 'thumbNote.full': '{label}. {why}', 'plugin.pdf.rule': 'Accepts', 'plugin.pdf.rule_kind_any': 'Any text', 'plugin.pdf.rule_kind_number': 'Numbers only', 'plugin.pdf.rule_kind_email': 'Email address', 'plugin.pdf.rule_min_label': 'Min length', 'plugin.pdf.rule_max_label': 'Max length', 'plugin.pdf.format': 'Date layout', 'plugin.pdf.date_order': 'Date order', 'plugin.pdf.date_separator': 'Separator', 'plugin.pdf.date_example': 'Example', 'opc.kind.archive-create': 'Creating archive', 'opc.kind.archive-extract': 'Extracting archive', /* === wiring:c4 - onboarding tour + accessibility + error card === */ 'tour.aria': 'Onboarding tour', 'tour.restart': 'Restart the tour', 'tour.skip': 'Skip tour', 'tour.back': 'Back', 'tour.next': 'Next', 'tour.done': 'Done', 'tour.progress': '{n} / {m}', 'tour.step.nav.title': 'Storages & views', 'tour.step.nav.desc': 'Home, Shared with me, Recent, Starred and Trash are always in this panel, with your storages and connections underneath. The button in the top-left corner collapses it to a rail and brings it back.', 'tour.step.nav.desc_closed': 'This button opens the navigation panel: Home, Shared with me, Recent, Starred and Trash, with your storages and connections underneath.', 'tour.step.new.title': 'Add something', 'tour.step.new.desc': 'Everything new starts here - upload from this device, create a folder, or ask somebody else for a file. Dropping files onto the window uploads them as well.', 'tour.step.new.desc_fab': 'This button uploads files from this device. Dropping files onto the window works as well.', 'tour.step.search.title': 'Search', 'tour.step.search.desc': 'This field searches the whole storage by name - separators and one typo are forgiven, so "invoice 2026" finds invoice_2026.pdf. Add tag:invoice to filter by tag. The sliders button opens advanced search, and {palette} opens the command palette, which runs commands too.', 'tour.step.crumb.title': 'Where you are', 'tour.step.crumb.desc': 'This trail is the address of the folder on screen. Click any step to go back up, and the chevron beside the last one lists the folders inside it.', 'tour.step.filters.title': 'Narrow the list', 'tour.step.filters.desc': 'Type, Owner, Modified and Size filter the folder you are in, the box beside them matches names as you type, and the control at the end of the row sorts.', 'tour.step.view.title': 'Switch views', 'tour.step.view.desc': 'Change how this folder is drawn; your choice is remembered.', 'tour.step.details.title': 'Details & sharing', 'tour.step.details.desc': 'Select a file and open this panel for its details, its activity and its share links. For the full menu, right-click the file or use the button at the end of its row - "Share" there creates a link with an optional PIN and expiry.', 'tour.step.help.title': 'Shortcuts', 'tour.step.help.desc': 'Press {help} for the shortcut cheat-sheet and {palette} for the command palette. Theme and "Restart the tour" are in the "More actions" menu at the top right; your account and sign-out are behind the avatar beside it.', 'error.hint': 'This may be a temporary network or server problem. Please try again.', 'error.details': 'Technical details', 'col.star': 'Star', 'toolbar.view_label': 'View', 'list.aria': 'File list', 'grid.aria': 'File grid', /* === wiring:d1 - tabs + split pane === */ 'tabs.strip': 'Tabs', 'tabs.new': 'New tab', 'tabs.close': 'Close tab', 'tabs.split': 'Split view', 'tabs.split_off': 'Close split', 'ctx.open_new_tab': 'Open in new tab', 'ctx.open_with': 'Open with {app}', 'ctx.open_with_builtin': "Open with the built-in viewer", 'ctx.open_with_choose': "Choose an app…", 'openWith.title': "Open with", 'openWith.lead': "Which app should open {name}?", 'openWith.builtin': "filex viewer (built-in)", 'openWith.onlyoffice': 'ONLYOFFICE (spreadsheet editor)', 'openWith.now': "Opens it now", 'openWith.always': "Always use this app for {ext} files", 'openWith.hint': "Kept on your account. You can change it in Settings, Default apps.", 'openWith.open': "Open", 'shortcuts.group.tabs': 'Tabs', 'shortcuts.tab_new': 'New tab', 'shortcuts.tab_close': 'Close tab', 'shortcuts.tab_next': 'Next tab', 'shortcuts.tab_prev': 'Previous tab', /* tus:t1 - the menu verbs */ 'shortcuts.new_folder': 'New folder', 'shortcuts.upload': 'Upload files', 'shortcuts.refresh': 'Refresh the listing', 'shortcuts.download': 'Download', 'shortcuts.preview': 'Preview', 'shortcuts.share': 'Share', 'shortcuts.tags': 'Tags', 'shortcuts.open_tab': 'Open in a new tab', 'shortcuts.copy_path': 'Copy path', 'shortcuts.copy_id': 'Copy id', 'shortcuts.restore': 'Restore from trash', 'shortcuts.settings.reserved': 'is taken by the browser before the page sees it, so it would do nothing here. Pick another key.', 'shortcuts.settings.reserved_badge': 'Desktop app only', 'shortcuts.settings.reserved_title': 'The browser handles this combination itself. It fires in the desktop app and in an installed PWA, not in a browser tab.', 'cmd.tab_new': 'Open a new tab', 'cmd.split_toggle': 'Toggle split view', 'split.pane': 'Secondary pane', 'split.close': 'Close the side pane', 'split.error': 'Could not load the listing', 'split.retry': 'Retry', 'split.copy_queued': 'Copy queued', 'split.move_queued': 'Move queued', 'toast.move_kept_both': 'Move queued. A name was already taken there, so that item will be kept beside the existing one with “-copy” added. This move cannot be undone.', 'split.cross_copy': 'Different storages - copy queued instead', 'dragout.downloading': 'Downloading into the folder you dropped on…', 'dragout.downloading_n': 'Downloading into the folder you dropped on - {n} files so far…', 'dragout.downloading_n_one': 'Downloading into the folder you dropped on - {n} file so far…', 'dragout.stop': 'Stop', 'dragout.stopping': 'Stopping…', 'dragout.stopped': 'Stopped - what had arrived stays in the folder', 'dragout.not_found': 'Could not find where it was dropped - a drop onto an application (rather than a folder) cannot be filled in', 'dragout.done': 'Download finished', 'dragout.ready': 'Files are ready - drag them to your desktop', 'dragout.preparing': 'Getting them ready to drag…', 'split.cross_move': 'Different storages - move queued (bytes travel, then the original is removed)', /* === /wiring:d1 === */ /* wiring:d2 - gallery view */ 'toolbar.view.gallery': 'Gallery', 'gallery.aria': 'File gallery', /* /wiring:d2 */ /* wiring:d3 - inspector node comments */ 'inspector.section.comments': 'Comments', 'inspector.comments.empty': 'No comments yet.', 'inspector.comments.placeholder': 'Write a comment…', 'inspector.comments.send': 'Send', 'inspector.comments.delete': 'Delete comment', /* wiring:e2 - end-to-end encrypted folders */ 'e2e.create.title': 'Create encrypted folder', 'e2e.create.option': 'Create encrypted folder…', 'e2e.create.pw_label': 'Folder password', 'e2e.create.pw_placeholder': 'At least 8 characters', 'e2e.create.pw2_label': 'Repeat the password', 'e2e.create.warn_title': 'NO WAY BACK', 'e2e.create.warn_body': 'Files in this folder can only be opened with this password or the recovery key shown once when the folder is created. The password is NEVER stored on the server, and filex keeps no copy of the recovery key either. Lose both and the contents are gone for good.', 'e2e.create.ack': 'I understand: if I lose both the password and the recovery key, my data cannot be recovered.', 'e2e.create.ack_required': 'Please confirm the warning to continue.', 'e2e.create.pw_short': 'Password must be at least 8 characters.', 'e2e.create.pw_mismatch': 'Passwords do not match.', 'e2e.create.bad_name': 'Invalid folder name.', 'e2e.create.create': 'Create encrypted folder', 'e2e.create.busy': 'Creating…', 'e2e.create.done': 'Encrypted folder created', 'e2e.create.failed': 'Could not create the encrypted folder', 'e2e.create.nested': 'You cannot create an encrypted folder inside another one.', /* wiring:e2 policy - asking an administrator to allow one encryption (E2eRequestModal), where the tenant's policy wants an approval first. */ 'e2e.request.ctx': 'Request encryption…', 'e2e.request.option': 'Request an encrypted folder…', 'e2e.request.title': 'Request encryption for “{name}”', 'e2e.request.lead': 'Making an encrypted folder here needs an administrator’s approval. Say why you need it; you will be told the answer. An approval is for you and this folder: it can be used once, to make one new encrypted folder directly inside it.', 'e2e.request.lead_folder': 'Encrypting this folder needs an administrator’s approval. Say why you need it; you will be told the answer. An approval is for you and this folder: it can be used once, to encrypt this folder where it is, and not a folder inside it.', 'e2e.request.lead_file': 'Encrypting this file needs an administrator’s approval. Say why you need it; you will be told the answer. An approval is for you and the folder this file is in: it can be used once, for one new encrypted file there.', 'e2e.request.reason': 'Reason', 'e2e.request.reason_placeholder': 'What it holds, and why it must be encrypted', 'e2e.request.reason_required': 'Write a reason for the administrator.', 'e2e.request.send': 'Send request', 'e2e.request.sending': 'Sending…', 'e2e.request.sent': 'Request sent. You will be notified when an administrator answers.', 'e2e.request.already': 'You already asked for this; it is waiting for an administrator.', 'e2e.request.failed': 'The request could not be sent.', 'e2e.locked.title': 'This folder is end-to-end encrypted', 'e2e.locked.hint': 'Enter the folder password to see its contents. The password stays in this tab’s memory only.', 'e2e.locked.pw_placeholder': 'Folder password', 'e2e.locked.unlock': 'Unlock', 'e2e.locked.busy': 'Verifying…', 'e2e.unlock.wrong': 'Wrong password.', 'e2e.unlock.damaged': 'The password is right, but the folder key in the key file (.filex-e2e.json) does not open: the file is damaged. Try the recovery key.', 'e2e.unlock.marker_missing': 'Could not read the key file (.filex-e2e.json).', /* ikon:emoji - the listing marker's accessible name. The row used to print a 🔒 and nothing else; the padlock that replaced it is aria-hidden inside the tile, so the span that carries it says this instead. */ 'e2e.badge': 'Encrypted folder', 'e2e.strip.label': 'Encrypted folder - unlocked', 'e2e.strip.lock': 'Lock', /* wiring:e2 password - changing a folder's password */ 'e2e.password.strip_action': 'Change password…', 'e2e.password.title': 'Change the folder password', 'e2e.password.reset_title': 'Set a new password for this folder', 'e2e.password.reset_lead': 'You opened this folder with its recovery key, so its password was lost or may be known to someone. Set a new one now. Closing this dialog locks the folder again.', 'e2e.password.current': 'Current password', 'e2e.password.recovery': 'Recovery key', 'e2e.password.use_recovery': 'I do not remember it - use the recovery key', 'e2e.password.use_current': 'Use the current password instead', 'e2e.password.new': 'New password', 'e2e.password.current_required': 'Enter the current password, or use the recovery key.', 'e2e.password.bad_recovery': 'That is not a recovery key (32 characters, in groups of four).', 'e2e.password.same': 'The new password is the same as the current one.', 'e2e.password.cheap_note': 'Only the folder’s key file changes. No file is re-encrypted, and the recovery key and any escrow key keep working.', 'e2e.password.old_copies': 'Someone who knows the old password and has an old copy of the key file (a version, a backup) can still open the folder with it. If that is a risk, tick “Also replace the folder key”.', 'e2e.password.rotate_label': 'Also replace the folder key (re-wraps every file’s key; use this if the old password may be known)', 'e2e.password.rekey_title': 'This folder is from before v0.31: its key comes from its password', 'e2e.password.rekey_body': 'A new password therefore needs a new folder key, and the key of every file in the folder is re-wrapped under it. The contents are not re-encrypted. It can take a while, and if it is interrupted it continues where it stopped; the files open throughout.', 'e2e.password.rotate_title': 'The folder key is replaced too', 'e2e.password.rotate_body': 'Every file’s key is re-wrapped under a new folder key. The contents are not re-encrypted. If it is interrupted it continues where it stopped; the files open throughout.', 'e2e.password.rekey_rk_new': 'You get a new recovery key, shown once; the old one stops working.', 'e2e.password.rekey_rk_kept': 'The recovery key you used keeps working.', 'e2e.password.rekey_escrow': 'The operator’s escrow key keeps working: its slot is sealed to the new folder key.', 'e2e.password.rekey_ack': 'I understand: this re-wraps the key of every file in the folder.', 'e2e.password.submit': 'Change password', 'e2e.password.busy': 'Changing…', 'e2e.password.lock_instead': 'Lock the folder instead', 'e2e.password.wrong_current': 'Wrong password.', 'e2e.password.wrong_recovery': 'Wrong recovery key.', 'e2e.password.escrow_blocked': 'This folder has an escrow slot for a key this installation does not have, and replacing the folder key would lose it. Nothing was changed.', 'e2e.password.failed': 'Could not change the password. Nothing was changed.', 'e2e.password.done': 'Password changed. The old password no longer opens this folder.', 'e2e.password.resume_title': 'File keys are still being re-wrapped', 'e2e.password.resume_body': 'The password was changed and a new folder key issued. Some files still have their key under the previous one; they open either way. Continue to finish.', 'e2e.password.progress': '{n} files re-wrapped so far · {failed} failed', 'e2e.password.progress_one': '{n} file re-wrapped so far · {failed} failed', 'e2e.password.rekey_partial': '{n} files could not be re-wrapped. They still open with the previous key; continue to try again.', 'e2e.password.rekey_partial_one': '{n} file could not be re-wrapped. It still opens with the previous key; continue to try again.', 'e2e.password.rekey_done': 'New folder key in place ({n} files re-wrapped). The old password opens nothing here any more.', 'e2e.password.rekey_done_one': 'New folder key in place ({n} file re-wrapped). The old password opens nothing here any more.', 'e2e.recovery.lead_replaced': 'The folder has a new key, so it has a new recovery key too - the old one no longer opens it. Shown once; filex keeps no copy.', /* wiring:e2 names - encrypted file and folder names */ 'e2e.unlock.unsupported': 'This folder needs a newer filex: it uses {features}, which this version does not understand. Nothing was changed.', 'e2e.settings.open': 'Encryption settings…', 'e2e.settings.title': 'Encryption settings', 'e2e.settings.level': 'Encryption level', 'e2e.settings.password': 'Password', 'e2e.settings.escrow': 'Escrow key', 'e2e.settings.close': 'Close', 'e2e.level.content': 'Contents only', 'e2e.level.names': 'Contents and names', 'e2e.level.content_hint': 'File contents are encrypted. File and folder names stay readable to the server, so WebDAV, the command line and desktop sync keep working with them, and every filex since 0.31 opens the folder.', 'e2e.level.names_hint': 'Contents and file and folder names are encrypted: the server sees only scrambled names. WebDAV, the command line and desktop sync see them scrambled too, and filex 0.47 and older will not open the folder.', 'e2e.level.pending': 'the change of level has not finished', 'e2e.level.change': 'Change level…', 'e2e.level.raise_title': 'Move this folder to “Contents and names”?', 'e2e.level.raise_body': 'filex gives every file and folder in here an encrypted name, in this browser. The contents are not touched, and if it is interrupted it continues where it stopped. filex does not offer the way back to readable names.', 'e2e.level.raise_ack': 'I understand what changes', 'e2e.level.raise_go': 'Encrypt the names', /* wiring:e2 vault - level 3, the vault (docs/E2E-VAULT-FORMAT.md) */ 'e2e.level.vault': 'Vault', 'e2e.level.vault_hint': 'Contents, names and the whole tree are encrypted: the server keeps only packs of one size, and does not see how many files there are, their names, their sizes or their dates.', 'e2e.level.vault_cost': 'What it costs: one person writes at a time, and only filex opens it (the web app, the desktop app, filex decrypt and filex vault mount). WebDAV, folder sync, share links and previews on the server do not reach inside.', 'e2e.vault.pack_label': 'Pack size', 'e2e.vault.pack_4': '4 MiB', 'e2e.vault.pack_4_help': 'The default. The smallest change uploads 4 MiB.', 'e2e.vault.pack_16': '16 MiB', 'e2e.vault.pack_16_help': 'Fewer, larger files on the server. Every change uploads at least 16 MiB.', 'e2e.vault.pack_hint': 'Chosen now and never again. Every pack on the server is this size, and what it does not use is filled with random bytes.', 'e2e.vault.read_only': 'Read-only. An upload, a new folder or any other change takes the write lock, when nobody else holds it.', 'e2e.vault.writing': 'You are writing to this vault. If you do nothing for {left}, it goes back to read-only.', 'e2e.vault.lock_countdown': 'If nothing is done in it for {left}, the vault locks and asks for the password again.', 'e2e.vault.held_by': '{name} has been writing since {since}. The vault is read-only for you.', 'e2e.vault.someone': 'Someone', 'e2e.vault.take_over': 'Take over', 'e2e.vault.lost_idle': 'You did nothing for {n} minutes, so this vault went back to read-only. Nothing was lost.', 'e2e.vault.lost_idle_one': 'You did nothing for {n} minute, so this vault went back to read-only. Nothing was lost.', 'e2e.vault.lost_taken': 'Someone else took over writing. What you saved stays; the vault is read-only for you.', 'e2e.vault.lost_taken_by': '{name} took over writing. What you saved stays; the vault is read-only for you.', 'e2e.vault.lost_broken_by': '{name} ended your write lock. What you saved stays; the vault is read-only for you.', 'e2e.vault.lost_connection': 'The connection was lost, so this vault went back to read-only.', 'e2e.vault.lost_expired': 'The write lock ran out, so this vault went back to read-only.', 'e2e.vault.unsaved': 'Not saved: {names}. Do it again when the vault is free.', 'e2e.vault.saving': 'Saving…', 'e2e.vault.saving_progress': 'Saving: {done} of {total}', 'e2e.vault.dismiss': 'OK', 'e2e.vault.continue': 'Continue from this state', 'e2e.vault.ro_damaged': 'The newest state of this vault is damaged. You are looking at the one from {when}, read-only.', 'e2e.vault.ro_damaged_short': 'The newest state of this vault is damaged. You are looking at an older one, read-only.', 'e2e.vault.ro_rollback': 'The server offers an older state of this vault than this tab has already seen. It stays read-only here.', 'e2e.vault.ro_newer': 'A newer filex wrote this vault. This version reads it and does not change it.', 'e2e.vault.unreadable': 'No state of this vault can be read: nothing can be shown, and nothing is written.', 'e2e.vault.limit_warn': 'This vault holds {held} of at most {max} files and folders.', 'e2e.vault.cross': 'Nothing moves between a vault and the folders outside it on the server: download it from one, then upload it into the other.', 'e2e.vault.dl_too_big': 'This browser cannot save a file this large from memory. Use a browser that saves straight to disk (Chrome, Edge), or filex decrypt.', 'e2e.vault.damaged_file': 'This file is damaged in the vault and could not be read.', 'e2e.vault.level_fixed': 'A vault stays a vault: its level does not change and its key is not replaced. To start again with a new key, make a new vault and move the files into it.', 'e2e.vault.locked_idle_toast': 'Nothing was done in “{name}” for 15 minutes, so the vault locked itself. Enter the password to open it again.', 'e2e.vault.open_failed': 'The vault could not be opened.', 'e2e.vault.err.parent_missing': 'The folder it was going into is not there any more.', 'e2e.vault.err.parent_not_folder': '“{name}” is a file, not a folder.', 'e2e.vault.err.name_taken': '“{name}” is already taken there.', 'e2e.vault.err.bad_name': '“{name}” cannot be a name in a vault: 1 to 255 bytes, without slashes or control characters, and not . or ..', 'e2e.vault.err.too_deep': 'Folders in a vault go at most 256 deep.', 'e2e.vault.err.not_found': '“{name}” is not in the vault any more.', 'e2e.vault.err.is_folder': '“{name}” is a folder.', 'e2e.vault.err.into_itself': 'A folder cannot go into itself.', 'e2e.vault.err.too_many_entries': 'This vault is full: it holds at most 250 000 files and folders. Nothing was changed.', 'e2e.vault.err.index_too_large': 'This vault\'s index has reached its limit. Nothing was changed.', 'e2e.vault.err.newer_format': 'A newer filex wrote this vault. This version reads it and does not change it.', 'e2e.vault.err.size_mismatch': 'A file changed while it was being uploaded. Upload it again.', 'e2e.vault.err.failed': 'The change could not be saved.', 'userSettings.vault.idle': 'Vault: back to read-only after', 'userSettings.vault.idle_help': 'How long a vault you write to stays yours while you do nothing in it. Then others may write; your vault goes back to read-only, and 15 minutes later it locks.', 'userSettings.vault.minutes': '{n} minutes', 'userSettings.vault.minutes_one': '{n} minute', 'userSettings.vault.saved': 'Saved', 'userSettings.vault.failed': 'Could not save the vault setting.', 'e2e.names.move_unreadable': 'Not moved: the name of one of the items cannot be read.', 'e2e.names.move_taken': 'Not moved: “{name}” is already taken in that folder. Rename one of the two first.', 'e2e.convert.ctx': 'Encrypt with E2EE…', 'e2e.convert.title': 'Encrypt “{name}”', 'e2e.convert.lead': 'Every file in this folder is encrypted where it is, in this browser, with the password below. Nothing moves; at level 1 the names stay as they are. If it is interrupted, opening the folder again continues it.', 'e2e.convert.past_title': 'What the server already has', 'e2e.convert.past_body': 'Encrypting protects these files from now on. Until now the server has had them in the clear, and some copies remain: filex drops its thumbnails and the text it extracted for search, and can delete older versions and trash entries from this folder.', 'e2e.convert.drop_versions': 'Delete the older versions of these files (they are plaintext)', 'e2e.convert.drop_trash': 'Delete the trash entries that came from this folder', 'e2e.convert.past_outside': 'Backups, replicas and copies anyone already made are outside filex and stay as they are.', 'e2e.convert.submit': 'Encrypt folder', 'e2e.convert.nested': 'This folder holds an encrypted folder. Encrypted folders cannot be nested, so nothing was changed.', 'e2e.convert.failed': 'The folder could not be encrypted. Files already encrypted stay so; open the folder to continue.', 'e2e.convert.stopped': 'Stopped after {n} files. Continue from the strip above the folder.', 'e2e.convert.stopped_one': 'Stopped after {n} file. Continue from the strip above the folder.', 'e2e.convert.partial': '{n} files could not be encrypted (changed meanwhile, too large, or not writable). They are still plaintext; try again to continue.', 'e2e.convert.partial_one': '{n} file could not be encrypted (changed meanwhile, too large, or not writable). It is still plaintext; try again to continue.', 'e2e.convert.too_large_here': '{n} files are too large for this browser to send in one piece, and this server takes no upload in pieces, so they could not be encrypted where they are. They are still plaintext, and the folder stays unfinished until they are encrypted.', 'e2e.convert.too_large_here_one': '{n} file is too large for this browser to send in one piece, and this server takes no upload in pieces, so it could not be encrypted where it is. It is still plaintext, and the folder stays unfinished until it is encrypted.', 'e2e.convert.large_progress': 'Encrypting “{name}”: {percent}%', 'e2e.convert.busy': 'Encrypting the folder…', 'e2e.convert.resume_title': 'Finish encrypting this folder', 'e2e.convert.resume_body': 'Encrypting this folder started and did not finish. Files it has not reached yet are still plaintext on the server. Continuing picks up where it stopped.', 'e2e.convert.progress': '{n} of {total} files encrypted · {failed} not done', 'e2e.convert.progress_one': '{n} of {total} files encrypted · {failed} not done', 'e2e.convert.done': 'Folder encrypted ({n} files). Old versions deleted: {versions}; trash entries deleted: {trash}.', 'e2e.convert.done_one': 'Folder encrypted ({n} file). Old versions deleted: {versions}; trash entries deleted: {trash}.', 'e2e.convert.cleanup_failed': 'The folder is encrypted, but its old versions and trash entries could not be deleted - only the folder’s owner or an administrator can.', 'e2e.names.locked_item': '🔒 Encrypted item', 'e2e.names.unreadable_item': '🔒 Unreadable name', 'e2e.names.key_failed': 'The key file says the names in this folder are encrypted, but their key does not open with this one. Nothing was changed.', 'e2e.names.write_failed': 'Could not write the name file of a long name, so nothing was uploaded.', 'e2e.names.bad_name': '“{name}” cannot be used in an encrypted folder: a name must be 1-255 bytes, with no slash, backslash or control character.', 'e2e.names.offer_cost': 'What changes: WebDAV, the command line and desktop sync will see scrambled names, and filex 0.47 and older will refuse to open this folder. The server still sees how many items there are and how big they are.', 'e2e.names.resume_title': 'Finish encrypting the names', 'e2e.names.resume_body': 'Encrypting the names in this folder started and did not finish. Items it has not reached yet still have readable names. Continuing picks up where it stopped.', 'e2e.names.resume': 'Continue', 'e2e.names.stop': 'Stop', 'e2e.names.busy': 'Encrypting names…', 'e2e.names.progress': '{n} names encrypted so far · {failed} could not be renamed', 'e2e.names.progress_one': '{n} name encrypted so far · {failed} could not be renamed', 'e2e.names.done': 'Names encrypted ({n} items renamed). The server no longer sees them.', 'e2e.names.done_one': 'Names encrypted ({n} item renamed). The server no longer sees them.', 'e2e.names.stopped': 'Stopped after {n} names. The rest keep their readable names until you continue.', 'e2e.names.stopped_one': 'Stopped after {n} name. The rest keep their readable names until you continue.', 'e2e.names.partial': '{n} items could not be renamed (no permission, or a name a disk cannot hold). Their names stay readable; try again to continue.', 'e2e.names.partial_one': '{n} item could not be renamed (no permission, or a name a disk cannot hold). Its name stays readable; try again to continue.', 'e2e.names.failed': 'Could not encrypt the names. Nothing already renamed is lost; try again to continue.', 'e2e.names.strip_fix': 'Fix {n} names (readable, or moved in from outside filex)', 'e2e.names.strip_fix_one': 'Fix {n} name (readable, or moved in from outside filex)', 'e2e.create.names_root_hint': 'The folder’s own name stays readable either way - it sits in a folder that is not encrypted. Pick a name that gives nothing away.', 'e2e.locked_toast': 'Folder locked', 'e2e.upload.locked': 'Unlock the folder first', 'e2e.decrypting': 'Decrypting…', 'e2e.decrypt_failed': 'Could not decrypt the file (password changed or file corrupted).', /* wiring:e2 recovery - recovery keys + operator escrow */ 'e2e.create.escrow_title': 'This server holds a second key', 'e2e.create.escrow_body': 'Key escrow is enabled on this installation, so its operator can open this folder without your password. Using that key notifies you. Escrow is fixed when the server is installed and cannot be turned off for a folder.', 'e2e.locked.use_recovery': 'Lost the password? Use a recovery key', 'e2e.recovery.title': 'Save your recovery key', 'e2e.recovery.title_upgraded': 'Your recovery key', 'e2e.recovery.lead': 'This key opens the folder without its password. It is shown once - filex does not store it and cannot show it again.', 'e2e.recovery.lead_upgraded': 'This folder now has a recovery key. It opens the folder without its password, is shown once, and is not stored by filex.', 'e2e.recovery.copy': 'Copy', 'e2e.recovery.copied': 'Copied', 'e2e.recovery.download': 'Download as a file', 'e2e.recovery.warn_title': 'TREAT THIS LIKE A PASSWORD', 'e2e.recovery.warn_body': 'Anyone holding this key can read the folder. Keep it somewhere separate from the password - a key stored next to the password protects you from forgetting, not from anyone else.', 'e2e.recovery.escrow_title': 'This server also holds a key', 'e2e.recovery.escrow_body': 'Key escrow is enabled here, so the operator of this installation can open this folder without your password. You are notified when that key is used.', 'e2e.recovery.escrow_kid': 'Escrow key', 'e2e.recovery.ack': 'I have saved this key somewhere safe.', 'e2e.recovery.done': 'Done', 'e2e.recover.title': 'Unlock without the password', 'e2e.recover.none': 'This folder was created before recovery keys existed, so it has none. Its password is the only way in. Unlock it with the password once and filex will offer to add a recovery key.', 'e2e.recover.tab_recovery': 'Recovery key', 'e2e.recover.tab_escrow': 'Escrow key', 'e2e.recover.recovery_hint': 'The key shown once when this folder was created.', 'e2e.recover.recovery_placeholder': 'XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX', 'e2e.recover.escrow_warn_title': 'The owner will be told', 'e2e.recover.escrow_warn_body': 'Opening a folder with the escrow key notifies its owner. Use it only when you are entitled to.', 'e2e.recover.escrow_kid': 'Escrow key', 'e2e.recover.escrow_predates': 'This installation has an escrow key, but this folder does not. It was created before escrow was turned on here, so its master key was never wrapped to the escrow identity. The escrow key will not open it. Nothing the operator can do changes that - adding a slot needs this folder\u2019s password, which the server has never had. The folder\u2019s owner can grant it: unlock with the password, then choose to give the operator a key. Until they do, use the password or the recovery key.', 'e2e.recover.escrow_other_key': 'This folder carries an escrow key from a DIFFERENT installation. It was created elsewhere and restored here, so this installation\u2019s escrow key does not open it. Only the private key belonging to the escrow key it was sealed to can.', 'e2e.recover.escrow_placeholder': 'Paste the escrow private key (PKCS#8, base64 or PEM)', 'e2e.recover.bad_format': 'That does not look like a recovery key. It is 32 characters in eight groups of four.', 'e2e.recover.escrow_required': 'Paste the escrow private key.', 'e2e.recover.wrong_recovery': 'That recovery key does not open this folder.', 'e2e.recover.wrong_escrow': 'That escrow key does not open this folder. A folder created before escrow was turned on has no escrow slot until its owner grants one - until then, use the password or the recovery key.', 'e2e.recover.bad_escrow_key': 'That is not a readable private key (expected PKCS#8, base64 or PEM).', 'e2e.recover.notify_failed': 'Could not notify the folder owner, so the folder was not unlocked. Escrow use is always announced.', 'e2e.recover.recovery_done': 'Unlocked with the recovery key', 'e2e.recover.escrow_done': 'Unlocked with the escrow key - the owner has been notified', 'e2e.recover.unlock': 'Unlock', 'e2e.recover.busy': 'Unlocking…', 'e2e.escrowoffer.title': 'Give the operator a key to this folder?', 'e2e.escrowoffer.body': 'This folder was created before key escrow was turned on here, so the operator of this installation cannot open it. Right now - while your password is in memory - filex can seal this folder to the escrow key. Your files are not re-encrypted or moved; only the key file changes.', 'e2e.escrowoffer.consequence': 'What this means: the operator gains a second, permanent way into this folder, without your password. You are notified when that key is used, but that notification is an announcement rather than a control.', 'e2e.escrowoffer.learn_more': 'What escrow can and cannot do', 'e2e.escrowoffer.password_label': 'Folder password', 'e2e.escrowoffer.password_required': 'Enter the folder password.', 'e2e.escrowoffer.wrong_password': 'That is not this folder\u2019s password.', 'e2e.escrowoffer.accept': 'Give the operator a key', 'e2e.escrowoffer.decline': 'No, keep it to myself', 'e2e.escrowoffer.cancel': 'Cancel', 'e2e.escrowoffer.busy': 'Sealing…', 'e2e.escrowoffer.done': 'The operator can now open this folder with the escrow key', 'e2e.escrowoffer.declined_toast': 'Kept to yourself. filex will not ask again for this folder.', 'e2e.escrowoffer.decline_failed': 'Could not record your answer, so filex will ask again next time. Nothing about the folder changed.', 'e2e.escrowoffer.failed': 'Could not give the operator a key to this folder', 'e2e.escrowoffer.strip_action': 'Escrow key…', 'e2e.upgrade.title': 'This folder has no recovery key', 'e2e.upgrade.body': 'It was created before recovery keys existed, so its password is the only way in. Right now - and only right now, while the password is in memory - filex can add one. Your files are not re-encrypted or moved.', 'e2e.upgrade.escrow_note': 'Note: this installation has key escrow enabled, so adding a recovery key also lets its operator open this folder without your password.', 'e2e.upgrade.accept': 'Create a recovery key', 'e2e.upgrade.decline': 'Not now', 'e2e.upgrade.busy': 'Creating…', 'e2e.upgrade.failed': 'Could not add a recovery key to this folder', 'e2e.download.failed': 'Could not download the encrypted file.', /* /wiring:e2 */ /* ── connections: storage config + "how to connect" ────────────── `storages.*` keys are the ones the BACKEND's driver descriptors name (each driver package declares one next to its Init). They are kept identical to web/src/locales/*.json on purpose: the same descriptor is rendered on both surfaces, so a field that reads "Base path" in the admin panel and something else in the desktop app would be the same drift this whole mechanism exists to stop. */ 'conn.title': 'Storage connections', 'conn.subtitle': 'How to reach {host} from your own computer: mount it, or point a client at it.', 'conn.close': 'Close', 'conn.list.disabled': 'Disabled', 'conn.form.required': 'Required', 'conn.form.advanced': 'Advanced settings', /* A two-button decision's own words, when the declaration did not name them. */ 'conn.form.yes': 'Yes', 'conn.form.no': 'No', 'conn.form.noFields': 'This server did not describe any settings for this driver.', 'conn.form.reveal': 'Show', 'conn.form.hide': 'Hide', 'conn.guide.protocol': 'Protocol', 'conn.guide.storage': 'Storage', 'conn.guide.allStorages': 'All storages', 'conn.guide.copy': 'Copy', 'conn.guide.copied': 'Copied', 'conn.guide.goodToKnow': 'Good to know', 'conn.guide.userPlaceholder': 'your-email@example.com', 'conn.guide.secretPlaceholder': 'your-password-or-api-key', 'conn.guide.fact.url': 'Address', 'conn.guide.fact.urlRootHint': 'Every storage you can see appears as a folder under this address.', 'conn.guide.fact.urlStorageHint': 'Mounts “{storage}” directly. Drop the last segment to see every storage.', 'conn.guide.fact.user': 'Username', 'conn.guide.fact.password': 'Password', 'conn.guide.webdav.summary': 'WebDAV mounts filex as a drive: Windows Explorer, macOS Finder, Linux, rclone and Cyberduck all speak it, and every change is mirrored back into filex.', 'conn.guide.webdav.userHint': 'Your username or your email - not your display name.', 'conn.guide.webdav.passwordHint': 'Your account password, or an API key (API keys, in the navigation panel). An account with two-factor authentication MUST use an API key: Basic auth has no second-factor slot.', 'conn.guide.webdav.win.s1': 'Open File Explorer, right-click This PC and choose “Map network drive…”.', 'conn.guide.webdav.win.s2': 'Pick a drive letter and enter {url} as the folder.', 'conn.guide.webdav.win.s3': 'Tick “Connect using different credentials” and sign in with the username and password above.', 'conn.guide.webdav.win.cmdCaption': 'Command Prompt (same thing, without the wizard)', 'conn.guide.webdav.win.limits': 'Windows has three built-in limits that look exactly like filex bugs: transfers stop at ~47.7 MB, folders with about a thousand files refuse to open (“Disk is not formatted”), and the WebClient service must be restarted after changing either.', 'conn.guide.webdav.win.regCaption': 'Run as administrator, then reconnect the drive', 'conn.guide.webdav.win.https': 'HTTPS is mandatory. Windows sends Basic credentials over TLS only, and over plain http:// it silently refuses with no useful message. Do not set BasicAuthLevel to 2 - use TLS.', 'conn.guide.webdav.win.persist': 'The mapped drive does not survive a sign-out: since Windows 7 Basic credentials cannot be stored in Credential Manager, and /persistent:yes does not change that. Re-run the command from a logon script if you need it back automatically.', 'conn.guide.webdav.win.service': 'If nothing mounts at all, make sure the WebClient service is running: sc config WebClient start= auto && net start WebClient.', 'conn.guide.webdav.mac.s1': 'In Finder choose Go → Connect to Server… (⌘K).', 'conn.guide.webdav.mac.s2': 'Enter {url} and connect.', 'conn.guide.webdav.mac.s3': 'Authenticate with the username and password above.', 'conn.guide.webdav.mac.note': 'The drive appears under Locations; each storage is a top-level folder.', 'conn.guide.webdav.linux.mountCaption': 'davfs2, or the desktop file manager (GNOME Files, Dolphin)', 'conn.guide.webdav.linux.gvfsComment': 'or paste this address into GNOME Files / Dolphin', 'conn.guide.webdav.linux.locks': 'davfs2 needs locking turned off. filex keeps WebDAV locks in process memory, so they do not survive a restart and are not shared between replicas - davfs2 assumes otherwise and hangs.', 'conn.guide.webdav.rclone.obscureCaption': 'rclone stores an obscured password - run this first and paste the output below', 'conn.guide.webdav.rclone.passPlaceholder': '', 'conn.guide.webdav.rclone.useCaption': 'Using it', 'conn.guide.webdav.duck.s1': 'New Bookmark → WebDAV (HTTPS).', 'conn.guide.webdav.duck.s2': 'Server {host}, port 443.', 'conn.guide.webdav.duck.s3': 'Path {path}.', 'conn.guide.webdav.duck.s4': 'Username {user}, password as above.', 'conn.guide.webdav.note.delete': 'A WebDAV delete is permanent. The web UI moves files to the filex trash; a client delete removes the object from the backing storage directly.', 'conn.guide.webdav.note.locks': 'Locks live in server memory: they do not survive a restart and are not shared between replicas. They exist to satisfy Windows and Office, not to arbitrate concurrent edits.', 'conn.guide.webdav.note.permissions': 'You see exactly what you see in the web UI. The root lists only the storages you may open, and a path outside your grants answers 404 rather than 403, so the tree never leaks what exists.', 'conn.guide.webdav.note.http': 'This server is reachable over plain http://. Windows will refuse to send your credentials at all, and every other client sends your password in the clear. Put filex behind TLS before mounting it.', // ── S3 endpoint: keys and the guide ────────────────────────────── 'conn.s3keys.title': 'S3 access keys', 'conn.s3keys.lead': 'An access key lets any S3 client - rclone, restic, the AWS CLI, mc, s3fs, Cyberduck - connect to filex. It carries your own permissions and nothing more.', 'conn.s3keys.disabled': 'The S3 endpoint is switched off on this server (FILEX_S3). A key minted here will not connect until an operator turns it back on.', 'conn.s3keys.cannotMint': 'You are not signed in with an account that can mint access keys. The instructions below still apply - ask for a key and paste it in.', 'conn.s3keys.label': 'What is it for? (laptop backup, CI, …)', 'conn.s3keys.defaultLabel': 'access key', 'conn.s3keys.everyBucket': 'Every bucket I can see', 'conn.s3keys.prefix': 'Folder inside the bucket (optional)', 'conn.s3keys.mint': 'Create key', 'conn.s3keys.inheritNote': 'A key can only ever narrow what you already have: your grants and your role. Confining it to one bucket or folder is the difference between a laptop backup and a credential that can read everything.', 'conn.s3keys.once': 'Copy the secret now - this is the only time it is shown.', 'conn.s3keys.accessKeyID': 'Access key ID', 'conn.s3keys.secret': 'Secret key', 'conn.s3keys.dismiss': 'I have copied it', 'conn.s3keys.col.label': 'Label', 'conn.s3keys.col.key': 'Access key ID', 'conn.s3keys.col.scope': 'Limited to', 'conn.s3keys.col.lastUsed': 'Last used', 'conn.s3keys.scopeAll': 'everything you can see', 'conn.s3keys.noLabel': '(no label)', 'conn.s3keys.neverUsed': 'never', 'conn.s3keys.enable': 'Enable', 'conn.s3keys.disable': 'Disable', 'conn.s3keys.revoke': 'Revoke', 'conn.s3keys.confirm': 'Sure?', 'conn.s3keys.empty': 'No access keys yet.', 'conn.guide.s3.summary': 'The S3 endpoint makes filex the destination for anything that speaks S3 - backups, sync tools, SDKs - using the storages you already have.', 'conn.guide.s3.keyPlaceholder': 'create a key above', 'conn.guide.s3.secretPlaceholder': 'shown once, when you create the key', 'conn.guide.s3.fact.endpoint': 'Endpoint', 'conn.guide.s3.fact.endpointHint': 'Point the client here, not at the web address of filex.', 'conn.guide.s3.fact.bucket': 'Bucket', 'conn.guide.s3.fact.bucketHint': 'A bucket is a filex storage. Buckets are created by an administrator, not by the client.', 'conn.guide.s3.fact.key': 'Access key ID', 'conn.guide.s3.fact.keyHint': 'The public half. It travels in every request.', 'conn.guide.s3.fact.secret': 'Secret key', 'conn.guide.s3.fact.secretHint': 'Shown once, when the key is created. filex cannot show it again - create a new key if it is lost.', 'conn.guide.s3.fact.region': 'Region', 'conn.guide.s3.fact.regionHint': 'filex has no regions; any value works and is echoed back. Clients still insist on one.', 'conn.guide.s3.fact.addressing': 'Addressing', 'conn.guide.s3.fact.pathStyle': 'path-style (required)', 'conn.guide.s3.fact.pathStyleHint': 'There is no dedicated S3 host on this install, so bucket.host does not resolve.', 'conn.guide.s3.fact.virtualHosted': 'virtual-hosted or path-style', 'conn.guide.s3.fact.virtualHostedHint': 'This install has its own S3 host, so both styles work.', 'conn.guide.s3.rclone.useCaption': 'Use it', 'conn.guide.s3.rclone.mtime': 'filex carries the file modification time (x-amz-meta-mtime), so rclone sync settles after the first run instead of re-uploading everything.', 'conn.guide.s3.aws.configureCaption': 'Configure once', 'conn.guide.s3.aws.useCaption': 'Use it', 'conn.guide.s3.aws.pathStyle': 'Add path addressing to your AWS config, or every command fails at DNS.', 'conn.guide.s3.restic.envCaption': 'Environment', 'conn.guide.s3.restic.useCaption': 'Back up, verify, prune', 'conn.guide.s3.restic.verified': 'Verified against this endpoint: restic check --read-data reads every pack byte for byte and reports no errors.', 'conn.guide.s3.mc.aliasCaption': 'Add the alias', 'conn.guide.s3.mc.useCaption': 'Use it', 'conn.guide.s3.s3fs.credsCaption': 'Credentials file', 'conn.guide.s3.s3fs.mountCaption': 'Mount it', 'conn.guide.s3.s3fs.note': 'Editing a file over s3fs rewrites the whole object, and a delete goes to the filex trash. Good for a shared folder, not for a database.', 'conn.guide.s3.duck.s1': 'New bookmark → Amazon S3.', 'conn.guide.s3.duck.s2': 'Server: {host}.', 'conn.guide.s3.duck.s3': 'Access key ID: {key}, secret as above.', 'conn.guide.s3.duck.s4': 'Open the bookmark; the buckets are your filex storages.', 'conn.guide.s3.duck.pathStyle': 'In Preferences → S3, turn OFF "Use virtual host style" - this install has no wildcard S3 host.', 'conn.guide.s3.sdk.note': 'Any SigV4 client works the same way: endpoint, key, secret, and path addressing when this install has no S3 host of its own.', 'conn.guide.s3.note.buckets': 'A bucket is a filex storage. A client can create folders and objects inside one, but not the bucket itself - that needs a driver and a path, which an S3 request cannot express.', 'conn.guide.s3.note.permissions': 'The key sees exactly what you see. A bucket you may not open answers "no such bucket" rather than "forbidden", so the endpoint never reveals what exists.', 'conn.guide.s3.note.trash': 'A delete goes to the filex trash, the same as everywhere else, and is recoverable until the retention policy sweeps it.', 'conn.guide.s3.note.mtime': 'Uploads carry their modification time, and the checksums clients send (Content-MD5, x-amz-checksum-*) are verified - a corrupted upload is refused rather than stored.', 'conn.guide.s3.note.pathStyle': 'This install has no dedicated S3 host, so clients must be told to use path-style addressing. Without it a current SDK fails at DNS with an error that names neither filex nor the cause.', 'conn.guide.s3.note.http': 'This endpoint is plain http://. Signatures still protect the request, but the objects travel in the clear. Put filex behind TLS before pointing a backup at it.', // ── SFTP endpoint: keys and the guide ──────────────────────────── 'conn.sshkeys.title': 'SSH keys', 'conn.sshkeys.lead': 'Register a public key and every SSH client - sftp, scp, WinSCP, FileZilla, rclone, sshfs - can connect without sending your password.', 'conn.sshkeys.disabled': 'The SFTP endpoint is switched off on this server (FILEX_SFTP). A key registered here will not connect until an operator turns it back on.', 'conn.sshkeys.cannotAdd': 'You are not signed in with an account that can register keys.', 'conn.sshkeys.paste': 'Paste the contents of ~/.ssh/id_ed25519.pub', 'conn.sshkeys.name': 'Name (optional - the key comment is used otherwise)', 'conn.sshkeys.add': 'Add key', 'conn.sshkeys.noCopyId': 'ssh-copy-id cannot work here: it appends to ~/.ssh/authorized_keys over a shell, and filex has none. This box is the way in.', 'conn.sshkeys.col.name': 'Name', 'conn.sshkeys.col.fingerprint': 'Fingerprint', 'conn.sshkeys.col.added': 'Added', 'conn.sshkeys.col.lastUsed': 'Last used', 'conn.sshkeys.noName': '(no name)', 'conn.sshkeys.neverUsed': 'never', 'conn.sshkeys.enable': 'Enable', 'conn.sshkeys.disable': 'Disable', 'conn.sshkeys.remove': 'Remove', 'conn.sshkeys.confirm': 'Sure?', 'conn.sshkeys.empty': 'No keys yet. Without one, clients sign in with your account password.', 'conn.guide.sftp.summary': 'SFTP makes filex reachable by anything that already speaks SSH - a backup job, a scanner, WinSCP, rclone, or a mounted folder.', 'conn.guide.sftp.fact.host': 'Host', 'conn.guide.sftp.fact.hostHint': 'The same machine as the web app, on a port of its own.', 'conn.guide.sftp.fact.port': 'Port', 'conn.guide.sftp.fact.portHint': 'Not 22 and not 443: SFTP is raw TCP and cannot go through the web proxy.', 'conn.guide.sftp.fact.userHint': 'Your username. An @ in it would have to be quoted in most client config files, which is what the username avoids.', 'conn.guide.sftp.fact.auth': 'Sign in with', 'conn.guide.sftp.fact.authKey': 'your registered SSH key (or your password)', 'conn.guide.sftp.fact.authPassword': 'your account password - or register a key above', 'conn.guide.sftp.fact.authHint': 'An API key works as a password too, and is revocable on its own. An account with two-factor sign-in must use an SSH key or an API key.', 'conn.guide.sftp.fact.path': 'Path', 'conn.guide.sftp.fact.pathHint': 'The first folder is a storage; the root lists the ones you may open.', 'conn.guide.sftp.openssh.connectCaption': 'Connect, put, get', 'conn.guide.sftp.openssh.noShell': 'There is no shell here - only the SFTP subsystem. `ssh host command` is refused on purpose, and scp works because OpenSSH 9 speaks SFTP for it.', 'conn.guide.sftp.key.tab': 'Set up a key', 'conn.guide.sftp.key.s1': 'Generate a key pair on the machine that will connect (skip if you already have one).', 'conn.guide.sftp.key.s2': 'Copy the PUBLIC half - the .pub file, never the other one.', 'conn.guide.sftp.key.s3': 'Paste it into the box above and connect; no password is sent from then on.', 'conn.guide.sftp.key.genCaption': 'On your own machine', 'conn.guide.sftp.key.noCopyId': 'ssh-copy-id will NOT work against filex: it needs a shell to append to ~/.ssh/authorized_keys, and there is none. Paste the key above instead.', 'conn.guide.sftp.winscp.s1': 'New site → File protocol: SFTP.', 'conn.guide.sftp.winscp.s2': 'Host name: {host}, port: {port}.', 'conn.guide.sftp.winscp.s3': 'User name: {user}. For a key: Advanced → SSH → Authentication → private key file.', 'conn.guide.sftp.winscp.s4': 'WinSCP needs a .ppk private key - use its own tool (Tools → PuTTYgen) to convert an OpenSSH key once.', 'conn.guide.sftp.filezilla.s1': 'File → Site Manager → New site, Protocol: SFTP.', 'conn.guide.sftp.filezilla.s2': 'Host: {host}, port: {port}.', 'conn.guide.sftp.filezilla.s3': 'User: {user}. Logon type: Normal for a password, or Key file for a key.', 'conn.guide.sftp.rclone.useCaption': 'Use it', 'conn.guide.sftp.sshfs.mountCaption': 'Mount and unmount', 'conn.guide.sftp.sshfs.note': 'A mounted folder rewrites the whole file on every save. Good for documents, not for a database or a video you are editing in place.', 'conn.guide.sftp.note.storages': 'The root is not a home directory: it lists the storages you may open, and the first path segment names one.', 'conn.guide.sftp.note.permissions': 'The permission bits your client draws come from your access level here, so a file shown as read-only really is one for you.', 'conn.guide.sftp.note.trash': 'A delete goes to the filex trash, the same as everywhere else, and is recoverable until the retention policy sweeps it.', 'conn.guide.sftp.note.totp': 'If your account has two-factor sign-in, the password will not work here - SSH has no way to ask for the code. Register an SSH key, or use an API key as the password.', 'conn.guide.sftp.note.disabled': 'The SFTP endpoint is switched off on this server. These instructions will work once an operator enables it.', // ── FTPS ───────────────────────────────────────────────────────── 'conn.guide.ftps.summary': 'FTPS is here for the equipment that only ever learned FTP - scan-to-folder printers, EDI counterparties, older lab and industrial software. Always over TLS.', 'conn.guide.ftps.fact.host': 'Host', 'conn.guide.ftps.fact.hostHint': 'The same machine as the web app, on a port of its own.', 'conn.guide.ftps.fact.port': 'Port', 'conn.guide.ftps.fact.portHint': 'The control channel. Data moves on a separate port from the passive range below.', 'conn.guide.ftps.fact.mode': 'Encryption', 'conn.guide.ftps.fact.modeValue': 'FTPS - explicit TLS (AUTH TLS), required', 'conn.guide.ftps.fact.modeHint': 'Plain FTP is refused before the password is read. Choose "Require explicit FTP over TLS", never "plain FTP" and never "implicit".', 'conn.guide.ftps.fact.userHint': 'Your username, or your email. An API key works as the password too and can be revoked on its own.', 'conn.guide.ftps.fact.passwordHint': 'Your account password, or an API key. An account with two-factor sign-in must use an API key - FTP has no way to ask for the code.', 'conn.guide.ftps.fact.pasv': 'Passive ports', 'conn.guide.ftps.fact.pasvHint': 'Data connections land here. If your firewall blocks this range the transfer HANGS with no error on either side - that is the classic FTP failure.', 'conn.guide.ftps.filezilla.s1': 'File → Site Manager → New site, Protocol: FTP.', 'conn.guide.ftps.filezilla.s2': 'Host: {host}, port: {port}.', 'conn.guide.ftps.filezilla.s3': 'Encryption: "Require explicit FTP over TLS". Logon type: Normal, user: {user}.', 'conn.guide.ftps.filezilla.s4': 'Transfer settings → Passive. Active mode is refused by this server.', 'conn.guide.ftps.winscp.s1': 'New site → File protocol: FTP, Encryption: TLS/SSL Explicit encryption.', 'conn.guide.ftps.winscp.s2': 'Host name: {host}, port: {port}.', 'conn.guide.ftps.winscp.s3': 'User name: {user}, password as above.', 'conn.guide.ftps.curl.caption': 'Upload and download', 'conn.guide.ftps.curl.sslReqd': '--ssl-reqd is not optional: it makes curl REQUIRE TLS instead of falling back to plaintext. This server refuses plaintext anyway, but the habit protects you against the servers that do not.', 'conn.guide.ftps.lftp.caption': 'Connect', 'conn.guide.ftps.lftp.protectData': 'ssl-protect-data encrypts the FILE as well as the sign-in. Without it lftp signs in over TLS and then sends your file in the clear - which is the FTPS misconfiguration people actually ship.', 'conn.guide.ftps.rclone.useCaption': 'Use it', 'conn.guide.ftps.printer.tab': 'Scanner / printer', 'conn.guide.ftps.printer.s1': 'In the device\'s scan-to-FTP settings: server {host}, port {port}.', 'conn.guide.ftps.printer.s2': 'User: {user}, password as above. Create an API key for the device rather than using your own password - it can be revoked without changing anything else.', 'conn.guide.ftps.printer.s3': 'Path: {path} - or a folder inside it that you created first. The device cannot create a storage.', 'conn.guide.ftps.printer.s4': 'Turn ON "SSL/TLS" or "FTPS explicit", and PASSIVE mode.', 'conn.guide.ftps.printer.noTLS': 'Plenty of scan-to-FTP firmware cannot do TLS at all. This server will not talk to such a device, and that is deliberate - the alternative is your documents and your password crossing the office network in the clear.', 'conn.guide.ftps.note.tls': 'TLS is mandatory and there is no switch to turn it off. Plain FTP sends your password in the clear and your file after it.', 'conn.guide.ftps.note.passive': 'Passive mode only. Active mode has the server dial back to the client, which does not survive NAT and is blocked by most firewalls.', 'conn.guide.ftps.note.storages': 'The root is not a home directory: it lists the storages you may open, and the first path segment names one.', 'conn.guide.ftps.note.trash': 'A delete goes to the filex trash, the same as everywhere else, and is recoverable until the retention policy sweeps it.', 'conn.guide.ftps.note.prefer': 'If the client can speak SFTP, prefer it: one connection, one port, no passive-mode surprises.', 'conn.guide.ftps.note.selfSigned': 'This server is using a self-signed certificate. It encrypts the channel but proves nothing about who is on the other end - most clients will ask you to accept it once. Supply a real certificate for anything that matters.', 'conn.guide.ftps.note.disabled': 'The FTPS endpoint is switched off on this server. These instructions will work once an operator enables it.', // ── NFS ────────────────────────────────────────────────────────── 'conn.nfs.title': 'NFS exports', 'conn.nfs.lead': 'An export lets a machine on your network mount filex as a drive - a media player, a build server, a backup box.', 'conn.nfs.pathIsSecret': '⚠ The export path IS the password. NFS cannot ask a client who it is without Kerberos, so filex puts 32 random bytes in the path instead: whoever knows it can mount as you. Treat the mount line like a credential - /etc/fstab is world-readable on most systems.', 'conn.nfs.disabled': 'The NFS endpoint is switched off on this server (FILEX_NFS). An export created here will not mount until an operator turns it back on.', 'conn.nfs.cannotMint': 'You are not signed in with an account that can create exports.', 'conn.nfs.label': 'What is it for? (media player, backup box, …)', 'conn.nfs.defaultLabel': 'nfs export', 'conn.nfs.everyStorage': 'Every storage I can see', 'conn.nfs.prefix': 'Folder inside the storage (optional)', 'conn.nfs.allowCidrs': 'Allowed addresses, e.g. 192.168.1.0/24 (optional)', 'conn.nfs.readOnly': 'Read-only', 'conn.nfs.readOnlyHint': 'Read-only is the safer default for a machine: it refuses every write through this mount whatever your own permissions are. An address list narrows it further - outside it, the mount is refused.', 'conn.nfs.mint': 'Create export', 'conn.nfs.once': 'Copy this now - the path is shown only once and cannot be recovered.', 'conn.nfs.dismiss': 'I have copied it', 'conn.nfs.col.label': 'Label', 'conn.nfs.col.scope': 'Limited to', 'conn.nfs.col.mode': 'Mode', 'conn.nfs.col.lastUsed': 'Last mounted', 'conn.nfs.scopeAll': 'everything you can see', 'conn.nfs.modeRead': 'read-only', 'conn.nfs.modeWrite': 'read/write', 'conn.nfs.noLabel': '(no label)', 'conn.nfs.neverUsed': 'never', 'conn.nfs.enable': 'Enable', 'conn.nfs.disable': 'Disable', 'conn.nfs.revoke': 'Revoke', 'conn.nfs.confirm': 'Sure?', 'conn.nfs.empty': 'No exports yet.', 'conn.guide.nfs.summary': 'NFS mounts filex as a drive on a machine in your own network - the NAS protocol, for the devices that expect one.', 'conn.guide.nfs.pathPlaceholder': 'create an export above', 'conn.guide.nfs.fact.host': 'Host', 'conn.guide.nfs.fact.hostHint': 'The same machine as the web app, on a port of its own.', 'conn.guide.nfs.fact.port': 'Port', 'conn.guide.nfs.fact.portHint': 'Both port= and mountport= must be set to this; filex serves the mount and NFS services on one port.', 'conn.guide.nfs.fact.export': 'Export path', 'conn.guide.nfs.fact.exportHint': 'This is the credential. It is shown once, when you create the export, and is stored hashed - filex cannot show it again.', 'conn.guide.nfs.fact.options': 'Mount options', 'conn.guide.nfs.fact.optionsHint': 'nolock because filex does not run the NFS lock manager; nfsvers=3 because that is what this server speaks.', 'conn.guide.nfs.linux.mountCaption': 'Mount it', 'conn.guide.nfs.linux.fstabSecret': 'An /etc/fstab line containing this path is a password in a world-readable file. Use a credentials-protected automount, or keep the mount in a root-only unit, if that matters where you are.', 'conn.guide.nfs.mac.mountCaption': 'Mount it', 'conn.guide.nfs.mac.resvport': 'macOS needs resvport: its client insists on a privileged source port and refuses the mount without it.', 'conn.guide.nfs.win.s1': 'Turn on "Services for NFS" → "Client for NFS" in Windows Features (Pro and Enterprise only; Home does not have it).', 'conn.guide.nfs.win.s2': 'Open a Command Prompt as administrator.', 'conn.guide.nfs.win.s3': 'Map the export to a drive letter with the command below.', 'conn.guide.nfs.win.cmdCaption': 'Map it to Z:', 'conn.guide.nfs.win.port': 'Windows has no way to say which port the mount service is on, so it can only reach an NFS server on the standard port 2049. If this server is on another port, use SFTP or the filex desktop app instead.', 'conn.guide.nfs.nas.tab': 'NAS / media player', 'conn.guide.nfs.nas.s1': 'In the device\'s NFS settings: server {host}, port {port} (set both the NFS and the mount port if it asks for them separately).', 'conn.guide.nfs.nas.s2': 'Remote path: the export path above, exactly as shown.', 'conn.guide.nfs.nas.s3': 'NFS version 3, no locking. Create the export read-only unless the device genuinely needs to write.', 'conn.guide.nfs.note.unencrypted': 'NFSv3 is not encrypted. Anyone who can read the traffic sees your files, and anyone who learns the path can mount them. Use it on a home or office network, or over a VPN - never across the internet.', 'conn.guide.nfs.note.pathIsSecret': 'The export path is the whole credential. Revoke it from the list above if it leaks; there is nothing else to change.', 'conn.guide.nfs.note.noPortmapper': 'There is no portmapper on port 111, so a client that is not told the port cannot find the server. That is why every command here carries port= and mountport=.', 'conn.guide.nfs.note.uid': 'The user and group ids your client sends are ignored: the mount already knows whose it is. The permissions you see come from your access in filex.', 'conn.guide.nfs.note.trash': 'A delete goes to the filex trash, the same as everywhere else, and is recoverable until the retention policy sweeps it.', 'conn.guide.nfs.note.revoke': 'Revoking takes effect on the next request, not instantly: NFS has no session to end, so a client with the mount open sees its next operation fail.', 'conn.guide.nfs.note.disabled': 'The NFS endpoint is switched off on this server. These instructions will work once an operator enables it.', 'conn.tokens.title': 'API keys', 'conn.tokens.lead': 'FTPS, WebDAV and filex mount all sign in with an API key instead of your account password. Create one here - it can be revoked on its own, and an account with two-factor sign-in cannot use its password on these at all.', 'conn.tokens.mint': 'Create API key', 'conn.tokens.once': 'Copy it now - this is the only time it is shown. Only a hash is stored, so it cannot be shown again.', 'conn.tokens.dismiss': 'I have copied it', 'conn.tokens.cannotMint': 'This session cannot create API keys. Sign in with your own account to create one.', 'conn.tokens.empty': 'No API keys yet.', 'conn.tokens.neverUsed': 'never', 'conn.tokens.revoke': 'Revoke', 'conn.tokens.confirm': 'Sure?', 'conn.tokens.col.label': 'Name', 'conn.tokens.col.scopes': 'Permissions', 'conn.tokens.col.comments': 'Comments', 'conn.tokens.col.used': 'Last used', 'conn.tokens.revokeHint': 'Revoking stops a connection that is already open, not just the next sign-in: an SFTP or FTPS session is cut and a mount stops working within about half a minute.', 'conn.guide.mount.summary': 'filex mount attaches a remote filex server to a folder on this machine, over the same HTTPS the browser uses. It is the only one of these that works from anywhere - no LAN, no extra server, no third-party client.', 'conn.guide.mount.fact.url': 'Server URL', 'conn.guide.mount.fact.urlHint': 'The same address you use in the browser. Nothing else has to be reachable.', 'conn.guide.mount.fact.token': 'API key', 'conn.guide.mount.fact.tokenPlaceholder': 'create one under API keys', 'conn.guide.mount.fact.tokenHint': 'An API key, not your password - it can be revoked on its own, and an account with 2FA cannot use its password here at all.', 'conn.guide.mount.fact.remote': 'What to mount', 'conn.guide.mount.fact.remoteHint': 'Leave --remote off to see every storage as a folder, or name one storage - or a folder inside it - to mount just that.', 'conn.guide.mount.linux.mountCaption': 'Mount it', 'conn.guide.mount.linux.umountCaption': 'Unmount it', 'conn.guide.mount.linux.umountWarn': 'Unmount with fusermount, not by killing the process. A mount whose process died without detaching leaves a folder where every ls hangs until somebody runs fusermount by hand.', 'conn.guide.mount.linux.systemdCaption': 'Mount it at sign-in (systemd user unit)', 'conn.guide.mount.win.winfsp': 'Windows needs WinFsp installed once - it is free and open source: https://winfsp.dev. Nothing else, and no administrator rights after that.', 'conn.guide.mount.win.mountCaption': 'Mount it as a drive', 'conn.guide.mount.win.freeLetter': 'Pick a drive letter that is FREE. The letter is created by the mount, not attached to something that already exists, and pointing it at one that is in use fails with a message that does not say so.', 'conn.guide.mount.win.stop': 'Stop it with Ctrl-C in that window. The drive disappears and nothing is left behind on this machine.', 'conn.guide.mount.mac.unsupported': 'filex mount does not work on macOS. It needs macFUSE, whose license does not allow a program like filex to install it for you, and whose Go binding needs a C compiler filex deliberately does not require. The command refuses here rather than appearing to work and doing nothing.', 'conn.guide.mount.mac.alternatives': 'On macOS, use the filex desktop app with folder sync (keeps the files on disk), or SFTP with a client that mounts drives.', 'conn.guide.mount.note.notASync': 'This is not a sync. Nothing is copied to this machine except a small read cache, so a mount opens one file out of a hundred thousand without downloading the rest. If you want the files when you are offline, use folder sync instead.', 'conn.guide.mount.note.reachable': 'It reaches the server through whatever proxy or tunnel the browser goes through, because underneath it is the same API. Your permissions and your storages come with it.', 'conn.guide.mount.note.wholeFileWrites': 'A file you write through the mount is uploaded when the program closes it, not while it is being written. Editing a very large file in place is slower here than a local disk; copying it in and out is not.', 'conn.guide.mount.note.trash': 'A delete goes to the filex trash, the same as everywhere else, and is recoverable until the retention policy sweeps it.', 'conn.guide.mount.note.revoke': 'Revoke the API key to stop a mount. It stops serving within half a minute, even if the mount is still attached.', 'storages.driver.ftp': 'FTP / FTPS', 'storages.driver.local': 'Local filesystem', 'storages.driver.s3': 'S3 / Hetzner / MinIO', 'storages.driver.sftp': 'SFTP', 'storages.driver.smb': 'SMB / CIFS (NAS)', 'storages.driver.webdav': 'WebDAV', 'storages.fieldHelp.smbShare': 'The share name alone, without the server: `media`, not `\\\\nas\\media`.', 'storages.fieldHelp.smbDomain': 'Only for a Windows domain account. Leave empty for a NAS.', 'storages.fieldHelp.smbRoot': 'Sub-folder inside the share. Leave empty for the whole share.', 'storages.fields.share': 'Share', 'storages.fields.domain': 'Domain / workgroup', 'storages.fieldHelp.disablePresign': 'On by default: uploads and the downloads behind public share links stream through filex, so the bucket endpoint never has to be reachable from a browser (a LAN-only MinIO just works). Turn it off only when the endpoint is reachable from your users\' browsers (AWS, a public MinIO) and you want them to talk to the bucket directly - faster for very large files, and the store must accept SDK-signed URLs (Ceph RGW / some Hetzner setups answer SignatureDoesNotMatch).', 'storages.fieldHelp.endpoint': 'Leave empty for AWS S3. Any S3-compatible store needs its endpoint.', 'storages.fieldHelp.hostKey': 'A single public key in authorized_keys / known_hosts line form.', 'storages.fieldHelp.insecureSkipHostKey': 'Accepts any host key. Only for throwaway hosts.', 'storages.fieldHelp.keyPath': 'Path to a key file on the server, read when the storage starts. Used when the PEM field is empty.', 'storages.fieldHelp.knownHosts': 'OpenSSH known_hosts path for strict host-key checking. Default is trust-on-first-use in ~/.filex/known_hosts.', 'storages.fieldHelp.passive': 'Off switches to active mode, which needs the server to dial back into this host.', 'storages.fieldHelp.path': 'Directory on the server. It is created if missing; filex never mounts /.', 'storages.fieldHelp.pathStyle': 'On for every non-AWS store. It is turned on automatically when an endpoint is set and this was never touched.', 'storages.fieldHelp.prefix': 'Sub-folder inside the bucket. Required: filex never takes ownership of the bucket root.', 'storages.fieldHelp.region': 'Defaults to "auto" when left empty.', 'storages.fieldHelp.root': 'Sub-folder on the backend. Required: filex never mounts the account root.', 'storages.fieldHelp.sftpAuth': 'Either a password or a private key is required.', 'storages.fieldHelp.tls': 'Plain FTP sends credentials in the clear - turn this on whenever the server supports it.', 'storages.fields.accessKey': 'Access key', 'storages.fields.basePath': 'Base path', 'storages.fields.bucket': 'Bucket', 'storages.fields.disablePresign': 'Stream transfers through filex', 'storages.fields.endpoint': 'Endpoint', 'storages.fields.host': 'Host', 'storages.fields.hostKey': 'Pinned host key', 'storages.fields.insecureSkipHostKey': 'Skip host-key verification (insecure)', 'storages.fields.keyPath': 'Private key file', 'storages.fields.knownHosts': 'known_hosts file', 'storages.fields.name': 'Display name', 'storages.fields.namePlaceholder': 'Personal photos', 'storages.fields.passive': 'Passive mode (PASV)', 'storages.fields.password': 'Password', 'storages.fields.path': 'Filesystem path', 'storages.fields.pathStyle': 'Use path-style URLs (Hetzner, MinIO)', 'storages.fields.port': 'Port', 'storages.fields.prefix': 'Prefix', 'storages.fields.privateKey': 'Private key (PEM)', 'storages.fields.rbac': 'Per-item access control (RBAC)', 'storages.fields.rbacHint': 'When on, non-admins see only the files and folders granted to them (listed under Folder access). When off, everyone opens the storage according to their role.', 'storages.fields.readOnly': 'Read-only mount', 'storages.fields.region': 'Region', 'storages.fields.root': 'Base path', 'storages.fields.secretKey': 'Secret key', 'storages.fields.tls': 'FTPS (explicit AUTH TLS)', 'storages.fields.url': 'Base URL', 'storages.fields.user': 'User', 'storages.fields.s3AttemptTimeout': 'Attempt timeout (seconds)', 'storages.fields.s3MaxAttempts': 'Attempts per request', 'storages.fields.s3TotalTimeout': 'Give up after (seconds)', 'storages.fieldHelp.s3AttemptTimeout': 'How long one attempt may wait for a sign of life from the store: connecting, the TLS handshake, the answer after the request is sent, and each next piece of the answer. A transfer that keeps moving is never cut, however long it takes; an upload the store stops taking is cut after 60 seconds, or after this if it is longer. Copies and renames wait up to 10 minutes for the answer, because the store answers them only when the copy is done.', 'storages.fieldHelp.s3MaxAttempts': 'How many times a request is tried in all when the failure can pass: a network error, a timeout, a 5xx answer, throttling. 1 turns retrying off. A refusal (403, a missing bucket, a host name that does not resolve) is never retried.', 'storages.fieldHelp.s3TotalTimeout': 'No new attempt starts unless it could finish within this many seconds of the first, so an upload or a listing on a store that is down reports the outage within this time. A transfer that is under way is not cut. A request that timed out is tried again only when this is at least twice the attempt timeout.', 'storages.fields.attemptTimeout': 'Attempt timeout (seconds)', 'storages.fields.maxAttempts': 'Attempts per request', 'storages.fields.totalTimeout': 'Give up after (seconds)', 'storages.fieldHelp.attemptTimeout': 'How long one attempt may wait for a sign of life from the server: connecting, logging in, the answer to each request, and each next piece of a transfer. A transfer that keeps moving is never cut, however long it takes; an upload the server stops taking is cut after 60 seconds, or after this if it is longer.', 'storages.fieldHelp.webdavAttemptTimeout': 'How long one attempt may wait for a sign of life from the server: connecting, logging in, the answer to each request, and each next piece of a transfer. A transfer that keeps moving is never cut, however long it takes; an upload the server stops taking is cut after 60 seconds, or after this if it is longer. Copies, moves and deletes wait up to 10 minutes for the answer, because the server answers them only when the work is done.', 'storages.fieldHelp.maxAttempts': 'How many times a request is tried in all when the failure can pass: the connection is refused or drops, no answer comes in time, the server answers that it is unavailable (5xx). 1 turns retrying off. A refusal (a wrong password, a missing folder, a certificate that does not verify) is never retried, and neither is an upload that has started sending.', 'storages.fieldHelp.totalTimeout': 'No new attempt starts unless it could finish within this many seconds of the first, so a server that is down is reported within this time. A transfer that is under way is not cut. A request that timed out is tried again only when this is at least twice the attempt timeout.', /* === gezinti:g1 - navigation panel (SideNav) === */ 'sidenav.title': 'Navigation', 'sidenav.views': 'Views', 'sidenav.storages': 'Storages', 'sidenav.home': 'Home', 'sidenav.myfiles': 'My files', 'sidenav.recent': 'Recent', 'sidenav.starred': 'Starred', 'sidenav.shared': 'Shared with me', // The mirror of the row above, and it sits right under it: what came in, // and what went out. ⚠ "My shares", not "Shared by me" - the page lists // LINKS the person minted, not files they granted somebody access to. 'sidenav.myshares': 'My shares', 'sidenav.trash': 'Trash', 'sidenav.collapse': 'Collapse navigation', 'sidenav.expand': 'Expand navigation', 'sidenav.close': 'Close navigation', // ⚠ `open`/`close` are the DRAWER's pair, `expand`/`collapse` the docked // panel's, and they are not interchangeable - see the note on // `navToggleLabel` in Toolbar.vue. Below 560px the panel is a drawer over // the listing: it is not narrowed to a rail, it is not on screen at all, so // "expand" would promise a width change to something that has no width. 'sidenav.open': 'Open navigation', 'sidenav.storage.shared': 'Shared', 'sidenav.storage.readOnly': 'Read-only', // #57 - a storage row's order menu (right click, a long press, Shift+F10). // "Sort by name" writes an order the person can keep adjusting; it is not a // mode. "Use default order" lets the person's own order go: the panel then // follows the administrator's order (or, with none, the server's). The two // `.done`/`.none` lines are the reason a greyed row gives. 'sidenav.storage.moveUp': 'Move up', 'sidenav.storage.moveDown': 'Move down', 'sidenav.storage.sortName': 'Sort by name', 'sidenav.storage.sortName.done': 'Already sorted by name', 'sidenav.storage.defaultOrder': 'Use default order', 'sidenav.storage.defaultOrder.none': 'Already in the default order', // ⚠ `toolbar.nav` is GONE, and nothing replaced it. It was the one label on // the panel's collapse control, first as the noun "Navigation" - which names // the panel and never says the button does anything to it, so the owner // could not find how to collapse the panel (2026-09-13: "yan menüyü kısıp // açabilir olalım ya bence") - and then as the static stopgap "Show or hide // navigation". The four `sidenav.*` verbs above are the real fix: the label // is bound to `navOpen`, so it says *collapse* when it will collapse and // *expand* when it will expand. 'node.home': 'Home', 'node.recent': 'Recent', 'node.starred': 'Starred', 'node.shared': 'Shared with me', 'empty.recent.title': 'Nothing opened yet', 'empty.recent.hint': 'Files you open show up here', 'empty.starred.title': 'Nothing starred yet', 'empty.starred.hint': 'Star a file to find it here', 'empty.shared.title': 'Nothing has been shared with you', 'empty.shared.hint': 'Folders and files other people share appear here', /* etiket:t1 */ 'sidenav.tags': 'Tags', 'sidenav.tags.empty': 'No tags yet - add one from a file’s right-click menu.', 'sidenav.tags.more': 'Show {count} more', 'sidenav.tags.less': 'Show fewer', 'sidenav.tags.personal': 'Personal', 'sidenav.tags.team': 'Team', 'empty.tag.title': 'Nothing is tagged “{tag}”', 'empty.tag.hint': 'Right-click a file and choose Tags to put it here', 'sidenav.connections': 'Connections', 'sidenav.apps': 'Apps', // #162 - the store screen: the catalog of the stores an administrator turned // on, where a person asks for an app. 'sidenav.appstore': 'App store', 'sidenav.connect': 'How to connect', 'sidenav.apikeys': 'API keys', 'overlay.close': 'Close', 'conn.tokens.scopes': 'Permissions', 'conn.tokens.root': 'Limit to one folder (optional)', 'conn.tokens.rootPlaceholder': 'storage://folder', 'conn.tokens.expiry': 'Expires in (days)', 'conn.tokens.expiryNever': 'never', 'conn.tokens.defaultName': 'API key {date}', 'conn.tokens.namePlaceholder': 'Name - e.g. backup script', 'conn.tokens.capNote': 'Your own access is the ceiling - a permission you do not have is refused, not granted.', 'conn.tokens.scopesRequired': 'Choose at least one permission - an API key is never issued with none.', 'conn.tokens.comments': 'Comments', 'conn.tokens.commentsRead': 'Read', 'conn.tokens.commentsRw': 'Read and write', 'conn.tokens.commentsHint': 'Adding and deleting comments is a permission of its own - “write” does not include it. Every API key reads them.', 'conn.tokens.commentsToRw': 'Comments: allow writing', 'conn.tokens.commentsToRead': 'Comments: read only', /* === /gezinti:g1 === */ /* === surucu:d1 - the shell (GitHub #14); every profile, no longer a `uiProfile: 'drive'` opt-in === */ 'drive.new': 'New', 'drive.new.upload': 'Upload files', 'drive.new.folder': 'New folder', 'drive.new.request': 'Request files', 'drive.new.document': 'New document', /* === belge:n1 - "New document": the picker under + New ================= Type names are NOT listed here. A tile reads its words from lib/fileIcons `typeLabelFor`, the same table the listing's Type column uses, so ".docx" is called the same thing in both places and a new type needs no string at all. Only this dialog's own chrome lives below. */ 'newdoc.title': 'New document', 'newdoc.type.label': 'Document type', 'newdoc.group.document': 'Documents', 'newdoc.group.text': 'Text and code', 'newdoc.group.diagram': 'Diagrams', 'newdoc.group.app': 'Apps', /* ⚠ One name per service, the name its own project uses: draw.io (not "drawio", not "diagrams.net") and ONLYOFFICE - the QA sweep of 2026-09-21 found draw.io called three things on three screens. */ 'newdoc.withheld.onlyoffice': 'Office documents need a document server (ONLYOFFICE), which is not set up here.', 'newdoc.withheld.drawio': 'Diagrams need draw.io, which is not set up here.', 'newdoc.withheld_admin': 'Set them up in the admin panel under External services.', 'newdoc.empty.title': 'No document types are available', 'newdoc.empty.body': 'This server did not offer any type this app can create.', 'newdoc.empty.blocked': 'Every type this server can create needs an editor service that is not configured here.', 'newdoc.name': 'Name', 'newdoc.name.placeholder': 'File name, e.g. notes.txt or LICENSE', 'newdoc.untitled': 'Untitled', 'newdoc.err.slash': 'A name cannot contain a slash.', 'newdoc.err.exists': '{name} is already here. Choose another name.', 'newdoc.err.bare_ext': 'Give the file a name, not only an extension.', 'newdoc.err.ext_needs_type': 'A .{ext} file has to be created as its own type - an empty one would not open. Choose that type, or another extension.', 'newdoc.hint.ext_added': 'This type keeps its extension, so the file will be created as {name}.', // Drafts (issue #71): a new document is a draft until its first save. 'sidenav.drafts': 'Drafts', 'sidenav.drafts.count': '{n} drafts', 'sidenav.drafts.count_one': '{n} draft', 'node.drafts': 'Drafts', 'empty.drafts.title': 'No drafts', 'empty.drafts.hint': 'A new document waits here until you save it where it belongs.', 'drafts.lead': 'New documents that have not been saved yet. Only you can see them.', 'drafts.count_of': '{n} of {limit} drafts', 'drafts.col.target': 'Save to', 'drafts.col.storage': 'Storage', 'drafts.action.save': 'Save to disk', 'drafts.open_hint': 'Open {name}', 'drafts.no_match': 'No draft matches the filter.', 'draft.badge': 'Draft', 'draft.bar.target': 'will be saved to {folder}', 'draft.save': 'Save', 'draft.saved_to': '{name} was saved to {folder}.', 'draft.discarded': '{name} was moved to the trash.', 'draft.kept': 'Kept in Drafts', 'draft.editing': 'Editing…', 'draft.close.title': 'Close this draft?', 'draft.close.body': '{name} is a draft for {folder} and has not been saved there yet.', 'draft.close.hint': 'A kept draft waits in Drafts. Discard moves it to the trash.', 'draft.close.save': 'Save to disk', 'draft.close.keep': 'Keep in Drafts', 'draft.close.discard': 'Discard', 'outside.title': 'This file changed outside filex', 'outside.body': '{name} was changed somewhere else while it was open here, and this editor has changes of its own. Which version should stay?', 'outside.theirs': 'Keep the outside version', 'outside.theirs_hint': 'the changes made here are dropped and the outside version is loaded.', 'outside.mine': 'Write mine', 'outside.mine_hint': 'your version replaces the outside one when it is saved.', 'outside.both': 'Keep both', 'outside.both_hint': 'the outside version stays where it is, and yours is saved beside it as a separate copy (name.filex-conflict-time).', 'outside.hint': 'Until you choose, nothing is written over either version.', 'outside.pending': 'This file changed outside filex. Nothing is written over either version until you choose which one stays.', 'outside.choose': 'Choose…', 'outside.note.reloaded': 'The file was updated outside filex; the new version is loaded.', 'outside.note.theirs': 'The outside version is loaded; the changes made here were dropped.', 'outside.note.mine': 'Your version will replace the outside one when it is saved.', 'outside.note.both': 'The outside version stays; yours will be saved beside it as a separate copy.', 'draft.taken.title': 'A file with this name is already there', 'draft.taken.body': '{folder} already has a file called {name}. Save the draft as {suggested} instead?', 'draft.taken.confirm': 'Save as {name}', 'upload.taken.body': '{folder} already has something called {name}, and a vault keeps no earlier version. Upload it as {suggested} instead?', 'upload.taken.confirm': 'Upload as {name}', 'newdoc.hint.draft': 'It opens as a draft: nothing is created in the folder until you save it.', 'newdoc.err.draft_limit': 'You already keep as many drafts as this server allows ({limit}). Save or delete some in Drafts first.', 'newdoc.err.draft_limit_any': 'You already keep as many drafts as this server allows. Save or delete some in Drafts first.', 'newdoc.open_drafts': 'Open Drafts', 'newdoc.location': 'Location', 'newdoc.location.none': 'Choose a folder', 'newdoc.location.change': 'Change', 'newdoc.location.noaccess': 'You cannot save into this folder.', 'newdoc.create': 'Create', 'newdoc.creating': 'Creating…', 'newdoc.cancel': 'Cancel', // ⚠ The top search field searches the WHOLE storage (and every storage at // the root) - never only the open folder. The scope named here is therefore // the storage, not the folder; "Filter in this folder…" (FilterBar) is the // folder-scoped one. It used to say "Search in Photos" for a folder called // Photos, which was a lie (2026-09-19). 'drive.search.placeholder': 'Search in {scope}', 'drive.search.placeholder_all': 'Search all storages', 'drive.search.hint_title': 'Search everywhere and run commands ({combo})', 'drive.storage.used': '{used} of {total} used', 'drive.storage.used_unlimited': '{used} used', 'drive.storage.used_partial': 'at least {used} used', 'drive.storage.label': 'Storage', /* === gorunum:v3-shell - the Home view (the overview, inside the shell) == * The section headings are `sidenav.storages` / `sidenav.recent` / * `sidenav.starred` and the two empty states are `empty.recent.*` / * `empty.starred.*`, on purpose: the block headed "Recent" on Home and the * panel row labelled "Recent" beside it are the same thing, and a second * string for it is how the two drift apart one translation at a time. Only * what exists nowhere else is below. */ 'home.title': 'Home', 'home.storages.empty': 'No storages yet', 'home.storages.hint': 'A storage is a place filex reads and writes - an administrator adds them.', 'drive.section.folders': 'Folders', 'drive.section.files': 'Files', 'filter.aria': 'Filters', 'filter.type': 'Type', 'filter.type.any': 'Any type', 'filter.type.folder': 'Folders', 'filter.type.document': 'Documents', 'filter.type.spreadsheet': 'Spreadsheets', 'filter.type.presentation': 'Presentations', 'filter.type.pdf': 'PDFs', 'filter.type.image': 'Images', 'filter.type.video': 'Videos', 'filter.type.audio': 'Audio', 'filter.type.archive': 'Archives', 'filter.type.code': 'Code', 'filter.modified': 'Modified', 'filter.modified.any': 'Any time', 'filter.modified.today': 'Today', 'filter.modified.7d': 'Last 7 days', 'filter.modified.30d': 'Last 30 days', 'filter.modified.year': 'This year', 'filter.size': 'Size', 'filter.size.any': 'Any size', 'filter.size.lt1': 'Under 1 MB', 'filter.size.1to10': '1 - 10 MB', 'filter.size.10to100': '10 - 100 MB', 'filter.size.gt100': 'Over 100 MB', /* surucu:d1-actions - the ⋮ menu at the end of the filter row. Only its own NAME is new: every row inside it reuses the string that verb already has (`toolbar.new_folder`, `toolbar.upload`, `ctx.paste`, `shortcuts.select_all`, `selection.clear`), because a menu that renames a command is a menu the reader has to learn twice. */ 'filter.actions': 'Listing actions', 'filter.clear': 'Clear filters', 'filter.empty.title': 'Nothing here matches those filters', 'filter.empty.hint': 'Clear a filter, or search everywhere with the field above.', 'filter.count': '{shown} of {total}', 'inspector.tab.details': 'Details', 'inspector.tab.activity': 'Activity', 'inspector.people': 'People with access', 'inspector.people.you': 'You', 'inspector.people.inherited': 'from a parent folder', 'inspector.people.empty': 'Only you, and anyone with a link below.', 'inspector.people.manage': 'Manage access', 'inspector.link': 'Shared link', 'inspector.link.none': 'Not shared', 'inspector.link.create': 'Create link', 'inspector.link.copy': 'Copy link', 'inspector.activity.empty': 'No activity recorded for this item yet.', 'inspector.activity.hint': 'Versions are written when a file changes; comments are written by people.', 'inspector.activity.version': 'Version {n} saved', 'inspector.activity.comment': 'Comment by {who}', 'inspector.activity.select': 'Select a file or folder to see its activity.', /* === /surucu:d1 === */ /* === gorunum:v1-chrome - the filter row's name box === */ 'filter.find': 'Filter in this folder…', /* surucu:d1-scope - the same box where the rows are not a folder's contents. It has to say what it narrows: at the drive list "this folder" names nothing, and on Home it would name three blocks at once. */ 'filter.find.storages': 'Filter storages…', 'filter.find.home': 'Filter Home…', /* === gorunum:v1-viewer - the full-bleed overlay's own chrome === */ 'viewer.share': 'Share', 'viewer.nav_prev': 'Previous file', 'viewer.nav_next': 'Next file', /* The counter in the top bar's meta line: "246.3 KB • Sep 9, 2026 • 1 of 9". */ 'viewer.counter': '{i} of {n}', 'viewer.zoom_reset': 'Reset zoom', 'viewer.fullscreen': 'Full screen', 'viewer.exit_fullscreen': 'Exit full screen', 'viewer.md_placeholder': '# Markdown here…', /* === gorunum:v1-selbar - the selection bar that replaces the filter row === */ 'selection.count': '{n} selected', 'selection.clear': 'Clear selection', /* === gorunum:v1-preview - the kind, said in words ====================== The Type column used to print the extension in caps. These are what it prints instead; the table that picks one is in `lib/fileIcons.ts` (`typeLabelKey`), so this list and that one are the only two places a kind is named. Anything unmapped still falls back to the uppercased extension - these names improve on that fallback, they do not replace it. `Folder` is NOT here: it is `node.folder`, which the grid card's caption already prints. */ 'ftype.typescript': 'TypeScript', 'ftype.javascript': 'JavaScript', 'ftype.vue': 'Vue component', 'ftype.python': 'Python', 'ftype.go': 'Go', 'ftype.rust': 'Rust', 'ftype.php': 'PHP', 'ftype.ruby': 'Ruby', 'ftype.java': 'Java', 'ftype.kotlin': 'Kotlin', 'ftype.swift': 'Swift', 'ftype.c': 'C source', 'ftype.cpp': 'C++ source', 'ftype.csharp': 'C# source', 'ftype.stylesheet': 'Stylesheet', 'ftype.html': 'HTML document', 'ftype.json': 'JSON data', 'ftype.yaml': 'YAML', 'ftype.xml': 'XML', 'ftype.toml': 'TOML', 'ftype.sql': 'SQL', 'ftype.shell': 'Shell script', 'ftype.powershell': 'PowerShell script', 'ftype.markdown': 'Markdown', 'ftype.plaintext': 'Plain text', 'ftype.log': 'Log file', 'ftype.config': 'Configuration', 'ftype.sheet': 'Spreadsheet', 'ftype.figma': 'Figma design', 'ftype.drawio': 'draw.io diagram', 'ftype.design': 'Design file', 'ftype.image': 'Image', 'ftype.video': 'Video', 'ftype.audio': 'Audio', 'ftype.pdf': 'PDF document', 'ftype.document': 'Document', 'ftype.slides': 'Presentation', 'ftype.archive': 'Archive', 'ftype.code': 'Code', /* === gorunum:v1-advsearch - the Advanced search dialog ================== * Two `filter.*` keys are added here rather than beside their siblings * because they are new members of shared unions the dialog introduced * (`modified: 'around'`, `size: 'range'`); the filter row never selects * them, but `chipLabel` would print the raw key if one ever reached it. */ 'filter.modified.around': 'Around a date', 'filter.size.range': 'Custom range', 'advsearch.open': 'Advanced search', 'advsearch.title': 'Advanced search', 'advsearch.subtitle': 'Find files by name, content, path, or tags.', 'advsearch.close': 'Close', 'advsearch.content.heading': 'Content search', 'advsearch.viewall': 'View all results', 'advsearch.where.any_short': 'Anywhere', 'advsearch.where.here_short': 'Only here', 'advsearch.where.skip_short': 'Skip this', 'advsearch.server.legend': 'What the server searches', 'advsearch.client.legend': 'Narrow the results that come back', 'advsearch.query.label': 'Words', 'advsearch.query.placeholder': 'Part of a name, or words inside a file', 'advsearch.scope.label': 'Look in', 'advsearch.scope.name': 'Names and paths', 'advsearch.scope.content': 'File contents', 'advsearch.scope.all': 'Both', 'advsearch.scope.hint': 'Contents are searched from the index, which covers text-like files up to 200 KB.', 'advsearch.people.name_only': 'Owner is read off the rows that come back, and only a name search returns rows that carry one.', 'advsearch.scope.name_only': 'Only names and paths here: a content hit reaches the explorer without the storage it came from, so content search is offered on single-storage deployments only.', 'advsearch.tags.label': 'Tags', 'advsearch.tags.placeholder': 'invoice, quarterly report', 'advsearch.tags.exclude': 'Without tags', 'advsearch.tags.exclude_placeholder': 'archive', 'advsearch.tags.hint': 'Separate with commas. Tags narrow: several tags means files carrying all of them, and a tag nobody has applied returns nothing. A name matches your personal tag and your team’s tag of that name alike.', 'advsearch.where.label': 'Folder', 'advsearch.where.any': 'Anywhere in this storage', 'advsearch.where.here': 'Only in {folder}', 'advsearch.where.skip': 'Everywhere except {folder}', 'advsearch.around.label': 'Within', 'advsearch.around.date': 'Date and time', 'advsearch.around.h1': '1 hour', 'advsearch.around.d1': '1 day', 'advsearch.around.w1': '1 week', 'advsearch.size.range_label': 'Between', 'advsearch.size.from': 'From', 'advsearch.size.to': 'To', 'advsearch.count.idle': 'Type something, or pick a tag.', 'advsearch.count.counting': 'Counting…', 'advsearch.count.result': '{n} matching items', 'advsearch.count.capped': '{n} matching items in the first page of hits', 'advsearch.count.result_one': '{n} matching item', 'advsearch.count.capped_one': '{n} matching item in the first page of hits', 'advsearch.count.error': 'The count could not be run.', 'advsearch.count.cost': 'The count runs this search. Type, owner, date, size and folder narrow the results it finds.', 'advsearch.wire': 'Type this in the search box next time:', 'advsearch.reset': 'Reset', 'advsearch.cancel': 'Cancel', 'advsearch.submit': 'Search', /* === gorunum:v2-topbar - the page bar is gone; the explorer's own header and breadcrumb row carry what it used to. === */ 'breadcrumb.subfolders': 'Subfolders', 'breadcrumb.subfolders.empty': 'No subfolders here', 'header.admin': 'Admin panel', 'header.settings': 'Settings', 'header.signout': 'Sign out', 'ai.assistant': 'AI assistant', 'ai.soon': 'Coming soon', 'ai.assistant.soon': 'AI assistant - coming soon', /* gorunum:v2-share - the Share / Permissions dialog's own chrome. The controls inside it keep the strings they already had; these are the new shell: the title, the one switch, the sentence that says who can open the item right now, and the three named sections it all folds into. */ 'access.title': 'Share "{name}"', 'access.close': 'Close', 'access.done': 'Done', 'access.copy': 'Copy', 'access.copied': 'Copied', 'access.link.switch': 'Link sharing', 'access.who.private': 'Only people with access can open it.', 'access.who.link': 'Anyone with the link can open it.', 'access.who.pin': 'Anyone with the link and the PIN can open it.', 'access.who.existing': 'Link sharing is on - {n} links already exist.', 'access.who.existing_one': 'Link sharing is on - {n} link already exists.', 'access.section.link': 'Link options', 'access.section.people': 'People with access', 'access.section.drop': 'Request files', 'access.sum.pin_on': 'PIN on', 'access.sum.pin_off': 'No PIN', 'access.sum.people': '{n} people', 'access.sum.people_one': '{n} person', 'access.sum.people_none': 'No one yet', 'access.sum.groups': '{n} groups', 'access.sum.groups_one': '{n} group', 'access.sum.drop': '{n} upload links', 'access.sum.drop_one': '{n} upload link', 'access.sum.drop_none': 'No upload link', /* Ownership - the Owner column and the People chip. "System" is the honest word for a row nobody put here through filex (the scanner found it, or it was written straight into the bucket); it is a real answer, not a blank. */ 'col.owner': 'Owner', 'owner.you': 'You', 'owner.system': 'System', 'owner.unknown': 'Unknown', 'owner.external': 'Uploaded through an upload link', 'owner.last_actor': 'Last changed by {who}', 'filter.people': 'Owner', 'filter.people.any': 'Anyone', 'filter.people.me': 'You', 'filter.people.system': 'System', 'filter.people.someone': 'Someone else', /* surucu:d1-sort - the listing sort control at the trailing edge of the filter row. The four key names are `col.*`: the menu offers exactly the words the list view's own column headers carry, so the two controls that drive one sort cannot name it differently. */ 'sort.by': 'Sort by', 'sort.asc': 'Ascending', 'sort.desc': 'Descending', /* The order a SEARCH RESULT is in. It is not a fifth sort key - it is what the control prints instead of a key while the rows on screen were ranked by the server, so the button stops claiming a sort it is not performing. `_why` is the reason the control is closed, and the owner asked for the reason to be written rather than for the control to go quietly inert. */ 'sort.relevance': 'Relevance', 'sort.relevance_why': 'Search results are listed by how well they match. Your sort comes back when you leave the search.', /* === tablo:t1 - the table's own configuration ========================== Since v0.43 everything about how a folder looks - view, sort AND columns - belongs to the folder it was changed in; a folder nobody changed opens with the person's default (their settings), else the instance's. `folder_hint` is that rule in one sentence, written where the person who is about to be surprised by it can read it. */ 'col.location': 'Location', 'col.deleted': 'Deleted', 'col.deleted_from': 'Deleted from', 'col.deleted_by': 'Deleted by', 'col.remaining': 'Time left', 'cols.menu': 'Column options', 'cols.title': 'Columns', 'cols.resize': 'Resize {col}', 'cols.move_left': 'Move {col} left', 'cols.move_right': 'Move {col} right', 'cols.reset': 'Reset columns', 'cols.folder_title': 'Folder view', 'cols.folder_hint': 'A change you make here stays in this folder. Folders you have never changed open with your default view (Settings → Default folder view).', 'cols.forget_folder': "Forget this folder's view", 'cols.apply_all': 'Make this my default for all folders ({count} remembered)', /* === tablo:t3 - THE ONE TABLE (components/DataTable.vue) ================ Every table in the product speaks these, so a column menu or a pager is never the one English thing on a Turkish page. */ 'table.empty': 'Nothing here yet', 'table.prev': 'Previous page', 'table.next': 'Next page', 'table.sort_paged': 'This list is split into pages. Sorting would only re-order the page on screen, so it is off here - narrow the list with the search or filters instead.', /* === tablo:t1 - the trash banner ====================================== ⚠ `retention` is only used when the deployment has TOLD us the number (GET /api/admin/protection). Everywhere else `retention_unknown` says the same thing without naming a period we cannot verify: a banner that states the wrong retention is worse than no banner, because people act on it. */ 'trash.retention': 'Items in the trash are permanently deleted after {days} days.', 'trash.retention_one': 'Items in the trash are permanently deleted after {days} day.', 'trash.retention_unknown': 'Items in the trash are permanently deleted after a retention period set by your administrator.', 'trash.empty_action': 'Empty trash', 'trash.empty_confirm_title': 'Empty the trash?', /* 0.54 (finding D1): the confirmation waits for the server's count of what "Empty trash" deletes, and the Trash view is paged. Every sentence about the trash itself is the server's (server.trash.*). */ 'trash.empty_counting': 'Counting what is in the trash…', 'trash.show_more': 'Show more', 'trash.shown_of': '{shown} of {total} shown', 'trash.days_remaining': '{n} days', 'trash.days_remaining_one': '{n} day', 'trash.days_remaining_due': 'Due for deletion', 'trash.deleted_by_nobody': 'Not recorded: quarantined by the virus scan, or deleted before filex kept this', 'empty.trash.hint': 'Files you delete land here first, so you can put them back.', /* tasi:m1 - the destination picker (modals/DestinationPickerModal.vue) and the two selection verbs built on it. */ 'destpicker.title.move': 'Move to', 'destpicker.title.copy': 'Copy to', 'destpicker.title.choose': 'Choose a folder', 'destpicker.confirm.move': 'Move here', 'destpicker.confirm.copy': 'Copy here', 'destpicker.confirm.choose': 'Choose this folder', 'destpicker.title.choose_file': 'Choose a file', 'destpicker.confirm.choose_file': 'Choose this file', 'destpicker.title.save': 'Save to', 'destpicker.confirm.save': 'Save here', 'destpicker.pick_a_file': 'Select a file from the list.', 'destpicker.empty_files': 'This folder is empty', 'destpicker.cancel': 'Cancel', 'destpicker.up': 'Up one level', 'destpicker.crumbs': 'Location', 'destpicker.drives': 'Storages', 'destpicker.loading': 'Loading…', 'destpicker.empty': 'No subfolders here', 'destpicker.unreadable': 'This folder cannot be opened.', 'destpicker.readonly': 'Read-only', 'destpicker.readonly_here': 'You cannot write into this folder.', 'destpicker.pick_a_drive': 'Open a storage to choose a folder inside it.', 'destpicker.target': 'Destination: {name}', 'destpicker.tag.blocked': 'Not allowed', 'destpicker.blocked.self': 'A folder cannot be moved into itself.', 'destpicker.blocked.descendant': 'A folder cannot be moved into one of its own subfolders.', 'destpicker.tag.vault': 'Vault', 'destpicker.blocked.vault_in': 'Nothing goes into a vault from here: upload into it from inside the vault.', 'destpicker.blocked.vault_out': 'What is in a vault moves only inside that vault. Download it to take it out.', 'ctx.move_to': 'Move to…', 'ctx.copy_to': 'Copy to…', 'ctx.access.one_only': 'Sharing works on one item at a time.', 'toast.archive.preparing': 'Preparing the archive…', 'toast.archive.started': 'Downloading {name} ({count} files)', 'toast.archive.started_one': 'Downloading {name} ({count} file)', 'toast.archive.empty': 'Nothing to download - the selection contains no readable file.', 'toast.moved_to': 'Move to {name} queued', 'toast.copied_to': 'Copy to {name} queued', 'toast.already_there': 'The selected items are already in {name} - nothing was sent', /* ── dil:paket - strings that used to be inline `en ? … : …` pairs in FileExplorer / RecentlyOpened, where no language pack could reach them (and where a pack's language fell through to TURKISH). */ 'ctx.tags_menu': 'Tags…', 'toast.node_id_copied': 'Node id {id} copied', 'toast.read_only_here': 'Read-only here', 'recents.title': 'Recently opened', 'recents.refresh': 'Refresh', 'recents.empty': 'Nothing here yet.', 'recents.loading': 'Loading…', 'recents.close': 'Close', 'tags.title': 'Tags', 'tags.close': 'Close', 'share.ttl.never': 'This link does not expire.', 'share.ttl.until': 'This link is valid until {when}.', 'share.ttl.ceiling': 'Links can be valid for at most {days} days (server setting).', 'share.ttl.ceiling_one': 'Links can be valid for at most {days} day (server setting).', /* ── dil:paket - the share / access dialog (modals/PermissionsModal.vue). These were ~90 inline (tr, en) pairs: no language pack could reach them, and under any third language the dialog spoke TURKISH. access.ui.emails_comma_separated / access.ui.send / access.ui.mail_not_set_up are the mail-row lines another branch rewrote in the same release, converted at the v0.43.0 merge. */ 'access.ui.level_viewer': 'Viewer', 'access.ui.level_viewer_desc': 'view + download', 'access.ui.level_editor': 'Editor', 'access.ui.level_editor_desc': 'read + write + delete', 'access.ui.level_owner': 'Owner', 'access.ui.level_owner_desc': 'edit + manage access', 'access.ui.never': 'Never', 'access.ui.days': '{days} days', 'access.ui.days_one': '{days} day', 'access.ui.unlimited': 'Unlimited', 'access.ui.downloads': '{count} downloads', 'access.ui.downloads_one': '{count} download', 'access.ui.inherited_from': 'Inherited from', 'access.ui.access_granted': 'Access granted.', 'access.ui.enter_a_valid_email': 'Enter a valid email.', 'access.ui.recipient_lang': 'Recipient\'s language', 'access.ui.recipient_lang_server': 'The server\'s language', 'access.ui.user_created_invite_emailed': 'User created, invite emailed.', 'access.ui.user_created_share_the_temp_password': 'User created. Share the temp password.', 'access.ui.server_limit_applied': '(server limit applied)', 'access.ui.protect_with_a_pin': 'Protect with a PIN', 'access.ui.expiry': 'Expiry', 'access.ui.download_limit': 'Download limit', 'access.ui.create_link': 'Create link', 'access.ui.replace_link': 'Replace the link with these settings', 'access.ui.replace_link_hint': 'The address changes: the current link stops working.', 'access.ui.create_then_send': 'Create a link, then it will be sent to {email}.', 'access.ui.command_line': 'Command line', 'access.ui.share': 'Share', 'access.ui.existing_links': 'Existing links', 'access.ui.rbac_off_here': 'Per-item access control is off on this storage - everyone opens it according to their role, so people added here would change nothing. Turn it on in the admin panel under Storages (this storage → Per-item access control).', 'access.ui.other_links': 'Other links', 'access.ui.revoke': 'Revoke', 'access.ui.loading': 'Loading…', 'access.ui.name_or_email': 'Name or email', 'access.ui.add': 'Add', 'access.ui.no_account_for_this_email_what_next': 'No account for this email - what next?', 'access.ui.user': 'User', 'access.ui.viewer': 'Viewer', 'access.ui.create_user_grant': 'Create user + grant', 'access.ui.just_send_a_share_link': 'Just send a share link →', 'access.ui.temp_password': 'Temp password:', 'access.ui.people_with_access': 'Who has access', 'access.ui.group': 'Group', 'access.ui.group_title': 'The group “{name}” - everyone in it', 'access.ui.group_owner_confirm': 'Owner lets everyone in “{name}” manage who has access here - including sharing it with other people and groups. Give the group Owner?', 'access.ui.group_owner_give': 'Give owner access', 'access.ui.not_shared_with_anyone_yet': 'Not shared with anyone yet.', 'access.ui.remove': 'Remove', 'access.ui.a_public_link_that_lets_anyone_upload_fi': 'A public link that lets anyone UPLOAD files into this folder. Uploaders never see the folder\'s existing files.', 'access.ui.hide_upload_limits': 'Hide upload limits', 'access.ui.upload_limits': 'Upload limits', 'access.ui.max_files': 'Max files', 'access.ui.mb_file': 'MB / file', 'access.ui.allowed_types': 'Allowed types', 'access.ui.all_e_g_pdf_jpg': 'all (e.g. pdf, jpg)', 'access.ui.ask_uploader_name': 'Ask uploader name', 'access.ui.emails_comma_separated': 'email(s) - comma separated', 'access.ui.send': 'Send', 'access.ui.mail_not_set_up': 'Email is not set up - set it up in the admin panel under Settings (Email / SMTP).', /* ── wiring:e2 fxe - single encrypted files (.fxe), streamed downloads ── */ 'e2e.fxe.type': 'Encrypted file', 'e2e.fxe.ctx_encrypt': 'Encrypt with E2EE…', 'e2e.fxe.ctx_download_raw': 'Download encrypted file', 'e2e.fxe.ctx_password': 'Change password…', 'e2e.fxe.ctx_remove': 'Remove encryption…', 'e2e.fxe.encrypt_title': 'Encrypt this file', 'e2e.fxe.encrypt_lead': '“{name}” is encrypted in this browser with a password of its own. The server keeps only ciphertext. The password or the recovery key opens it - here, or offline with filex decrypt.', 'e2e.fxe.pw_label': 'File password', 'e2e.fxe.hide_label': 'Hide the file name too', 'e2e.fxe.hide_on_hint': 'Stored as “{stored}”: the server sees neither the name nor the type. The real name is sealed inside the file and shown once you open it here.', 'e2e.fxe.hide_off_hint': 'Stored as “{stored}”: the name stays readable to the server; the content does not.', 'e2e.fxe.seen_title': 'What the server has already seen', 'e2e.fxe.seen_lead': 'Until now this file was stored in the clear, and encrypting it cannot take that back:', 'e2e.fxe.seen_trash': 'The original goes to the trash and stays there until the trash retention period ends or an administrator empties it. You cannot delete it for good yourself.', 'e2e.fxe.seen_versions': 'Its earlier versions stay in its version history; only an administrator can delete them.', 'e2e.fxe.seen_thumb': 'A thumbnail made from it stays on the server until the original is deleted for good. Its search-index entry is removed when it goes to the trash.', 'e2e.fxe.seen_backups': 'Backups, copies and downloads made before now still hold it.', 'e2e.fxe.warn_body': 'This file opens only with this password or the recovery key shown once after it is encrypted. filex keeps neither. Lose both and the contents are gone for good.', 'e2e.fxe.escrow_body': 'Key escrow is enabled on this installation: its operator holds a key that opens this file without your password.', 'e2e.fxe.encrypt_submit': 'Encrypt', 'e2e.fxe.encrypt_busy': 'Encrypting and uploading… {percent}%', 'e2e.fxe.size_unknown': 'The size of this file is not known yet. Refresh the folder and try again.', 'e2e.fxe.bad_name': 'This name cannot be sealed into an encrypted file (it is over 255 bytes, or holds a slash or a control character). Rename the file first.', 'e2e.fxe.name_too_long': 'The name is too long to add “.fxe” to it. Tick “Hide the file name too”, or rename the file first.', 'e2e.fxe.encrypted': '“{name}” is encrypted. The original is in the trash.', 'e2e.fxe.original_kept': 'The encrypted copy is saved, but “{name}” could not be moved to the trash. Delete the original yourself.', 'e2e.fxe.upload_too_big': 'This server has no chunked upload, and the file is too large to send in one piece from this browser.', 'e2e.fxe.unlock_title_open': 'Open an encrypted file', 'e2e.fxe.unlock_title_download': 'Download decrypted', 'e2e.fxe.unlock_title_remove': 'Remove encryption', 'e2e.fxe.unlock_lead': '“{name}” is encrypted. Its password is checked here, in this browser, and is never sent to the server.', 'e2e.fxe.known_note': 'Already opened in this tab - no password needed.', 'e2e.fxe.use_password': 'Use the password instead', 'e2e.fxe.remove_warn_title': 'The plaintext goes back to the server', 'e2e.fxe.remove_warn_body': 'The file is decrypted here and uploaded as a plain file under its original name: the server, its administrators, thumbnails, search and backups can read it again. The encrypted file goes to the trash.', 'e2e.fxe.unlock_open': 'Open', 'e2e.fxe.unlock_download': 'Download', 'e2e.fxe.unlock_remove': 'Remove encryption', 'e2e.fxe.unlock_busy': 'Working…', 'e2e.fxe.save_again': 'Unlocked. Your browser wants one more click before it asks where to save the file.', 'e2e.fxe.save_button': 'Save…', 'e2e.fxe.progress': '{percent}% done', 'e2e.fxe.wrong_password': 'Wrong password.', 'e2e.fxe.wrong_recovery': 'That recovery key does not open this file.', 'e2e.fxe.damaged': 'This file is damaged or was tampered with (or it changed since it was opened). Nothing was saved.', 'e2e.fxe.not_readable': 'This is not a filex encrypted file, or its header is damaged.', 'e2e.fxe.unsupported': 'This file needs a newer filex (it requires: {features}).', 'e2e.fxe.downloaded': '“{name}” saved.', 'e2e.fxe.removed': 'Encryption removed: “{name}” is a plain file again. The encrypted file is in the trash.', 'e2e.fxe.password_title': 'Change the file password', 'e2e.fxe.password_cost': 'Only the file’s header changes: the content is sent back byte for byte, and the recovery key keeps working.', 'e2e.fxe.password_old_copies': 'An earlier version of this file - its version history, a backup, a copy someone downloaded - still opens with the OLD password.', 'e2e.fxe.password_done': 'Password changed. The old password no longer opens this file.', 'e2e.recovery.warn_body_file': 'Anyone holding this key can read the file. Keep it somewhere separate from the password - a key stored next to the password protects you from forgetting, not from anyone else.', 'e2e.recovery.lead_file': 'This key opens the file without its password. It is shown once - filex does not store it and cannot show it again.', 'e2e.dl.ctx_encrypted_copy': 'Download encrypted copy', 'e2e.dl.too_big': 'This browser can save at most {limit} of decrypted data at once, and this is {size}. Use Chrome or Edge (they save straight to disk), the filex desktop app, or download the encrypted file and run filex decrypt.', 'e2e.dl.click_again': 'Click Download again to choose where to save it.', 'e2e.dl.zip_started': 'Decrypting into “{name}”…', 'e2e.dl.zip_done': '“{name}” saved - decrypted, with the real names.', 'e2e.dl.zip_done_plain': '“{name}” saved. {n} files in it were never encrypted and are in it as they were.', 'e2e.dl.zip_done_plain_one': '“{name}” saved. {n} file in it was never encrypted and is in it as it was.', 'e2e.dl.zip_damaged': 'A file in the folder is damaged or was tampered with. The download stopped and nothing was saved.', 'e2e.upload.streaming_unsupported': 'This file is over 200 MB, and this server has no chunked upload to send it encrypted piece by piece.', /* wiring:e2 fxe escrow - the escrow key opens a single file, and its owner is told */ 'e2e.fxe.use_escrow': 'Use the escrow key', 'e2e.fxe.escrow_warn_title': 'The file’s owner will be told', 'e2e.fxe.escrow_warn_body': 'Opening a file with the escrow key notifies its owner, before the file is opened. Use it only when you are entitled to.', 'e2e.fxe.escrow_predates': 'This installation has an escrow key, but this file was encrypted without it (before escrow was turned on here), so the escrow key does not open it. Use the password or the recovery key.', 'e2e.fxe.escrow_other_key': 'This file is sealed to the escrow key of a DIFFERENT installation, so this installation’s escrow key does not open it.', 'e2e.fxe.wrong_escrow': 'That escrow key does not open this file.', 'e2e.fxe.escrow_notify_failed': 'Could not notify the file’s owner, so the file was not opened. Escrow use is always announced.', 'e2e.fxe.escrow_done': 'Opened with the escrow key - the owner has been notified', /* wiring:e2 fxe purge - an administrator deletes the original for good */ 'e2e.fxe.seen_trash_admin': 'The original goes to the trash and stays there until the trash retention period ends - unless you delete it for good below.', 'e2e.fxe.seen_versions_admin': 'Its earlier versions stay in its version history - unless you delete them for good below.', 'e2e.fxe.purge_label': 'Delete the original for good (administrator)', 'e2e.fxe.purge_hint': 'Its earlier versions and its trash entry are deleted as soon as the encrypted copy is saved, so no plaintext of it stays on this server. There is no undo. Backups and copies made before now are not reached.', 'e2e.fxe.purge_others': 'This file belongs to {owner}, not to you. Delete their original and its versions for good.', 'e2e.fxe.purge_others_unknown': 'This file has no recorded owner - it is not yours. Delete the original and its versions for good.', 'e2e.fxe.purge_others_required': 'Confirm that you are deleting someone else’s file for good.', 'e2e.fxe.purge_no_id': 'This file is not in the catalog yet, so it cannot be deleted for good. Refresh the folder and try again.', 'e2e.fxe.purged': '“{name}” is encrypted. The original, its versions and its trash entry are deleted for good.', 'e2e.fxe.purge_failed': 'The encrypted copy of “{name}” is saved, but the original could not be deleted for good ({reason}). Delete it from the trash and its version history.', /* wiring:e2 fxe big - a decrypted download too large for this browser's memory */ 'e2e.big.title': 'Too large to decrypt in this browser', 'e2e.big.lead': '“{name}” is {size} once decrypted. This browser decrypts a download in its memory and can hold at most {limit} of it, so nothing was downloaded.', 'e2e.big.lead_grew': '“{name}” grew past {limit} while it was being decrypted. This browser decrypts a download in its memory and cannot hold more, so nothing was saved.', 'e2e.big.instead': 'Decrypt it on your own computer instead:', 'e2e.big.step_file': 'Download the encrypted file, as it is (the button below).', 'e2e.big.step_folder': 'Download the encrypted folder as a zip (the button below) - it carries the folder’s key file.', 'e2e.big.step_run': 'In the folder you saved it to, run filex decrypt and give it the password:', 'e2e.big.copy': 'Copy', 'e2e.big.copied': 'Copied', 'e2e.big.other_ways': 'Chrome, Edge and the filex desktop app decrypt straight to disk, whatever the size.', 'e2e.big.close': 'Close', 'e2e.big.download_file': 'Download encrypted file', 'e2e.big.download_folder': 'Download encrypted folder (zip)', /* /wiring:e2 fxe */ /* ── dil:paket - accessible names that were English literals */ 'breadcrumb.aria': 'Breadcrumb', 'e2e.recovery_key_aria': 'Recovery key', 'modal.close': 'Close', 'modal.busy_close.keep': 'Keep going', 'modal.busy_close.confirm': 'Stop and close', /* ── the bell and the account menu (2026-09-27: moved here from the admin app so the desktop app's explorer draws the same ones). ⚠ SHARED keys: the admin app's catalogue has every one of them under the same name, with the same English and Turkish (web/tests/i18n/langPackCatalogue.test.ts), so a language pack translates each once for both screens. */ 'notifications.bell': 'Notifications', 'notifications.unreadCount': '{n} unread', 'notifications.title': 'Notifications', 'notifications.markAllRead': 'Mark all read', 'notifications.markRead': 'Mark read', 'notifications.empty': 'No notifications yet', 'notifications.viewAll': 'View all', 'notifications.manageAdmin': 'Manage notifications', 'notifications.openTarget': 'Open what this is about', 'notifications.unreadOnly': 'Unread only', 'notifications.pageOf': 'Page {page} of {pages} · {total} in total', 'notifications.severity.info': 'Info', 'notifications.severity.warning': 'Warning', 'notifications.severity.error': 'Error', 'notifications.severity.critical': 'Critical', 'common.prev': 'Previous', 'common.next': 'Next', 'explore.account': 'Account', /* ── the user settings dialog (2026-09-27: moved here from the admin app so the desktop app opens the same dialog inside its window). ⚠ SHARED keys: the admin app's catalogue has each under the same name with the same English and Turkish (web/tests/i18n/langPackCatalogue.test.ts). An account field's refusal is the server's sentence (POST /api/auth/account/check, lib/accountRules), not a key here. */ 'common.cancel': "Cancel", 'common.close': "Close", 'common.confirm': "Confirm", 'common.currentPassword': "Current password", 'common.email': "Email", 'common.loading': "Loading…", 'common.newPassword': "New password", 'common.remove': "Remove", 'common.save': "Save", 'common.saving': "Saving…", 'errors.generic': "Something went wrong", 'errors.validationFailed': "Please check the highlighted fields", 'install.desktopAllDownloads': "All downloads and release notes", 'install.desktopSubtitle': "Sync folders to this computer and keep them up to date in the background. Available for {platform}.", 'install.install': "Install", 'install.menuInstructions': "Open your browser's menu and choose “Install app” or “Add to Home screen”.", 'install.iosInstructions': "Tap Share (on iOS 26: ⋯, then Share), then “Add to Home Screen” and Add.", 'nav.themeAuto': "Auto", 'nav.themeDark': "Dark", 'nav.themeLight': "Light", 'notifications.prefs.browser': "Browser notifications", 'notifications.prefs.browserHint': "Raise a notification outside the tab when something new arrives. Clicking it opens the file, folder or share it is about.", 'notifications.prefs.desktopHandled': "The desktop app shows these itself", 'notifications.prefs.enableBrowser': "Allow notifications", 'notifications.prefs.inApp': "In-app bell", 'notifications.prefs.inAppHint': "Turning this off empties your bell. Nothing stops being recorded - an admin still sees every event.", 'notifications.prefs.iosHomeScreen': "On an iPhone or iPad, notifications work in filex added to the Home Screen (iOS 16.4 or later), not in a browser tab.", 'notifications.prefs.movedToSettings': "Your own notification settings - the bell, browser pop-ups, which events - are in your user settings.", 'notifications.prefs.openSettings': "Open my notification settings", 'notifications.prefs.permDefault': "Permission not asked yet", 'notifications.prefs.permDenied': "Blocked by this browser", 'notifications.prefs.permDeniedHint': "Re-allow notifications for this site in your browser settings.", 'notifications.prefs.permGranted': "Allowed by this browser", 'notifications.prefs.permUnsupported': "This browser cannot show notifications", 'notifications.prefs.push': "Push notifications on this device", 'notifications.prefs.pushAdded': "Added {date}", 'notifications.prefs.pushDevices': "Devices that receive push notifications", 'notifications.prefs.pushDisabled': "Turned off on the server (FILEX_PUSH_ENABLED).", 'notifications.prefs.pushFailed': "Push notifications could not be turned on for this device.", 'notifications.prefs.pushHint': "What your bell tells you reaches this phone or browser even while filex is closed - the same notifications, at the same moment.", 'notifications.prefs.pushKeyUnreadable': "The server's push key no longer opens (FILEX_SECRET_KEY changed). Rotate it under Admin → Notifications.", 'notifications.prefs.pushNoSecretKey': "Push notifications need FILEX_SECRET_KEY on the server: the key they are signed with is stored encrypted with it.", 'notifications.prefs.pushOn': "On for this device", 'notifications.prefs.pushRemove': "Remove", 'notifications.prefs.pushRemoveLabel': "Remove {device}", 'notifications.prefs.pushTest': "Send a test", 'notifications.prefs.pushTestNone': "No device took the test.", 'notifications.prefs.pushTestSent': "Test sent to {count} devices", 'notifications.prefs.pushTestSent_one': "Test sent to {count} device", 'notifications.prefs.pushThisDevice': "This device", 'notifications.prefs.pushUnavailable': "Not available on this server", 'notifications.prefs.pushUnnamed': "A device", 'notifications.prefs.pushUnsupported': "This browser cannot receive push notifications", 'notifications.prefs.saved': "Preference saved", 'notifications.prefs.title': "Your notifications", 'profile.avatar.change': "Change photo", 'profile.avatar.failed': "That image could not be processed - try another one.", 'profile.avatar.help': "Shown next to your name, and in the file explorer's collaboration bar - on every client signed in as you. Resized to 160px automatically.", 'profile.avatar.label': "Profile picture", 'profile.avatar.notImage': "Please choose an image file.", 'profile.locale': "Language", 'profile.passwordChanged': "Password changed", 'profile.saved': "Profile saved", 'profile.totp.code': "Verification code", 'profile.totp.disable': "Disable 2FA", 'profile.totp.disabled': "Disabled", 'profile.totp.enable': "Enable 2FA", 'profile.totp.enabled': "Enabled", 'profile.totp.recoveryHint': "Save these now - each one signs you in once if you lose your authenticator. They are shown only this time.", 'profile.totp.recoveryTitle': "Recovery codes", 'profile.totp.scanHint': "Scan this QR code with your authenticator app, then enter the 6-digit code.", 'profile.totp.title': "Two-factor authentication", 'profile.username.label': "Username", 'quota.title': "Storage quota", 'quota.tooltip': "{used} of {limit} used ({percent})", 'quota.unlimitedTooltip': "{used} used · unlimited", 'userSettings.adminBadge': "Admin", 'userSettings.ai.body': "This release has no per-user assistant settings. The AI features filex does ship are configured for the whole instance by an administrator, so there is nothing here for you to turn on or off yet.", 'userSettings.ai.soon': "Coming soon", 'userSettings.demoReadOnly': "This is a shared demo account, so its profile, password and second factor cannot be changed.", 'userSettings.footNote.ai': "There is nothing on this tab to save.", 'userSettings.footNote.notifications': "Saved as you change them.", 'userSettings.footNote.preferences': "Saved as you change them.", 'userSettings.footNote.profile': "Changes on this tab are saved when you press Save.", 'userSettings.footNote.security': "Each action here applies on its own.", 'userSettings.heading': "User settings", 'userSettings.headingSub': "Manage your profile, preferences, and security.", 'userSettings.notifications.adminAlerts': "Administrator alerts", 'userSettings.notifications.adminAlertsHint': "Updates, replicas, sign-in providers, tenant domains and the other alerts for administrators", 'userSettings.notifications.digestHint': "Kinds marked urgent reach you at once. The rest are held for {minutes} min and arrive as one summary, folder by folder.", 'userSettings.notifications.digestOffHint': "Every kind reaches you at once. Turn Urgent off for a kind to get it in one summary instead, folder by folder.", 'userSettings.notifications.events.archive_created': "An archive finishes being created", 'userSettings.notifications.events.archive_extracted': "An archive finishes extracting", 'userSettings.notifications.events.comment_added': "Someone comments on a file", 'userSettings.notifications.events.drop_received': "A file arrives through a request link", 'userSettings.notifications.events.e2e_escrow_used': "An encrypted folder is opened with the escrow key", 'userSettings.notifications.events.e2e_password_changed': "The password of your encrypted folder is changed", 'userSettings.notifications.events.e2e_request_created': "Someone asks to encrypt a folder or a file", 'userSettings.notifications.events.e2e_request_decided': "Your encryption request is answered", 'userSettings.notifications.events.file_deleted': "A file is deleted for good", 'userSettings.notifications.events.file_infected': "A virus is found in a file", 'userSettings.notifications.events.file_moved': "A file is moved or renamed", 'userSettings.notifications.events.file_trashed': "A file goes to the trash", 'userSettings.notifications.events.file_updated': "A file is changed", 'userSettings.notifications.events.file_upload_failed': "An upload does not finish", 'userSettings.notifications.events.file_uploaded': "A new file arrives", 'userSettings.notifications.events.notification_digest': "A summary of the notifications I did not mark urgent", 'userSettings.notifications.events.plugin_notice': "An installed app sends you a message", 'userSettings.notifications.events.share_created': "Someone creates a share link", 'userSettings.notifications.eventsHint': "Turning one off keeps it out of your bell. Nothing stops being recorded - an administrator still sees every event.", 'userSettings.notifications.eventsTitle': "What to tell me about", 'userSettings.notifications.urgent': "Urgent", 'userSettings.notifications.urgentFor': "Tell me at once: {event}", 'userSettings.open': "User settings", 'userSettings.prefs.appearance': "Appearance", 'userSettings.prefs.compact': "Use compact file list", 'userSettings.prefs.compactHint': "Tighter rows in the file explorer.", 'userSettings.prefs.desktopApp': "Desktop app", 'userSettings.prefs.desktopAppHint': "The reminder in the corner of the app can be closed for good - these downloads stay here.", 'userSettings.prefs.folderView': "Default folder view", 'userSettings.prefs.folderViewHint': "How a folder you have never changed opens. A folder you have changed keeps its own view - changing this does not touch it.", 'userSettings.prefs.fvColumns': "Your default columns are customized (set with “Make this my default for all folders”).", 'userSettings.prefs.fvColumnsReset': "Reset them", 'userSettings.prefs.fvDir': "Direction", 'userSettings.prefs.fvDir_asc': "Ascending", 'userSettings.prefs.fvDir_desc': "Descending", 'userSettings.prefs.fvForget': "Forget them all", 'userSettings.prefs.fvInherit': "Server default ({value})", 'userSettings.prefs.fvMode': "View", 'userSettings.prefs.fvSort': "Sort by", 'userSettings.prefs.fvSort_modified': "Modified", 'userSettings.prefs.fvSort_name': "Name", 'userSettings.prefs.fvSort_size': "Size", 'userSettings.prefs.fvSort_type': "Type", 'userSettings.prefs.fvView_gallery': "Gallery", 'userSettings.prefs.fvView_grid': "Grid", 'userSettings.prefs.fvView_list': "List", 'userSettings.prefs.installApp': "Install as a web app", 'userSettings.prefs.installAppLead': "Put filex on this device's home screen: it opens in a window of its own, like an app.", 'userSettings.prefs.languageHint': "Applies here right away, and is saved on your account for the next browser you sign in from.", 'userSettings.prefs.mode': "Light or dark", 'userSettings.prefs.modeHint': "Which variant is painted. Auto follows your operating system.", 'userSettings.prefs.openTrigger': "Open files with", 'userSettings.prefs.openTriggerDouble': "Double-click", 'userSettings.prefs.openTriggerHint': "How a mouse opens a file. On a touchscreen a tap always opens, and the checkbox always selects.", 'userSettings.prefs.openTriggerSingle': "Single-click", 'userSettings.prefs.palette': "Color palette", 'userSettings.prefs.paletteHint': "Which colors that variant is made of. Every palette has a light and a dark version, so this and the setting above work together.", 'userSettings.prefs.startPage': "Start page", 'userSettings.prefs.startPageHint': "Where filex opens when you sign in or go to the front door. Following a link straight to a page still takes you there.", 'userSettings.prefs.startPage_admin': "Admin panel", 'userSettings.prefs.startPage_files': "Files", 'userSettings.prefs.startPage_home': "Home", 'userSettings.prefs.timezone': "Time zone", 'userSettings.prefs.timezoneHint': "Dates are stored as a moment in time and shown on the clock you pick here, so everyone sees the same instant on their own clock. Saved to your account, so it follows you to another browser.", 'userSettings.prefs.timezoneNow': "Right now in {zone}: {time}", 'userSettings.saveChanges': "Save changes", 'userSettings.security.passwordTitle': "Change password", 'userSettings.security.totpDisabled': "Two-factor authentication is off", 'userSettings.security.totpEnabled': "Two-factor authentication is on", 'userSettings.subtitle.ai': "Nothing for you to set here yet.", 'userSettings.subtitle.notifications': "What reaches your bell, and what reaches your desktop.", 'userSettings.subtitle.preferences': "How this app looks and reads on your devices.", 'userSettings.subtitle.profile': "Your name, email and picture - what other people see.", 'userSettings.subtitle.security': "Your password and second factor.", 'userSettings.tabs.ai': "AI assistant", 'userSettings.tabs.notifications': "Notifications", 'userSettings.tabs.preferences': "Preferences", 'userSettings.tabs.profile': "Profile", 'userSettings.tabs.security': "Security", 'userSettings.apps.title': "Default apps", 'userSettings.apps.lead': "Choose one in a file's menu: Open with, Choose an app…, then tick \"Always use this app\". Only the apps your administrator left on for a kind are offered.", 'userSettings.apps.empty': "You have not chosen an app for any kind of file yet: every file opens with what your administrator put first.", 'userSettings.apps.reset': "Reset", 'userSettings.apps.resetAll': "Reset all", 'userSettings.apps.unavailable': "No longer available: it opens with {app} until you choose again.", 'userSettings.apps.change': "The app that opens {ext} files", 'userSettings.title': "Settings", 'users.fields.displayName': "Display name", 'profile.username.helpText': "Your username. You can sign in with it or with your email - and connection clients (SFTP, FTP) need it, because an @ in the name they sign in with has to be escaped in their config files.", 'userSettings.prefs.fvKeptCount': "{count} folders keep a view of their own.", 'userSettings.prefs.fvKeptCount_one': "{count} folder keeps a view of its own.", };