/** 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.convert': 'Convert', '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': '1 item will be moved to trash.', 'modal.delete.confirm': 'Move to Trash', 'modal.delete.cancel': 'Cancel', 'modal.rename.title': 'Rename', 'modal.rename.save': 'Save', 'modal.rename.cancel': 'Cancel', 'modal.newfolder.title': 'New folder', 'modal.newfolder.placeholder': 'Folder name', 'modal.newfolder.create': 'Create', 'modal.newfolder.cancel': 'Cancel', 'modal.share.title': 'Share Link', '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.committing': 'Finishing', 'upload.transferring': 'Moving to 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', 'viewer.peer_not_installed': 'Optional viewer library is not installed. Install the peer dependency or use the download button.', 'viewer.format_unsupported_3d': 'This 3D format is not supported in the browser preview (model-viewer only reads .glb / .gltf / .usdz). Please download and open with a local tool.', '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', 'viewer.drawio.disabled': 'diagrams.net embed is not configured for this filex instance — operator must wire FILEX_DRAWIO_URL to enable the editor.', 'viewer.archive.entries': '{n} files', 'viewer.archive.entries_one': '1 file', 'viewer.archive.empty': 'Archive is empty.', 'viewer.archive.error': 'Could not read archive contents.', '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': 'Hidden folders', // ——— 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.undo_failed': 'Could not undo', 'toast.renamed': 'Renamed', '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', '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': '1 item restored', 'toast.restore_taken': '{n} items were not restored: something already has their names. Rename what is there, then restore again.', 'toast.restore_taken_one': '“{name}” was not restored: something already has that name. Rename what is there, then restore again.', '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.', 'dropzone.hint': 'Drop files here', 'modal.newfolder.invalid': 'Invalid character', 'viewer.office_unconfigured': 'OnlyOffice is not configured', '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': '1 row', 'presence.others': '{n} people', 'presence.others_one': '1 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.saved': 'Saved searches', 'palette.save': 'Save search', 'palette.saved.delete': 'Delete saved search', 'search.in_content': 'In content', /* === 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': '1 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', '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': '1 item, {size} total', 'inspector.folder_items': '{n} items', 'inspector.folder_items_one': '1 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.cancel': 'Cancel', 'inspector.versions.take_snapshot': 'Snapshot current state', '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 colour 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': '1 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.percent': '{n}%', '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.convert': 'Convert', 'opc.kind.archive': '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, People, 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 / Permissions" 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', '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 / permissions', 'shortcuts.tags': 'Tags', 'shortcuts.convert': 'Convert', '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.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.', '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.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', 'e2e.locked_toast': 'Folder locked', 'e2e.upload.too_big': 'Files over 200 MB cannot be uploaded to an encrypted folder (MVP limit)', '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. Folders created before escrow was enabled have no escrow key, and cannot be given one.', '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': 'Connect {host} to a backend, or connect your computer to {host}.', 'conn.close': 'Close', 'conn.tab.storages': 'Storages', 'conn.tab.connect': 'How to connect', 'conn.loading': 'Loading…', 'conn.visibleOnly': 'you can browse this one', 'conn.denied.title': 'Only an administrator can add storages here', 'conn.denied.none': 'Your account may browse files but not change what this server is connected to. Ask an administrator of this server to add or edit a storage.', 'conn.denied.anonymous': 'You are not signed in on this server.', 'conn.denied.unreachable': 'The server did not answer: {error}', 'conn.denied.guideHint': 'You do not need administrator rights to connect your own computer to the storages you can already see.', 'conn.denied.guideCta': 'Show me how to connect', 'conn.list.count': '{n} storages', 'conn.list.count_one': '1 storage', 'conn.list.add': 'Add a storage', 'conn.list.empty': 'No storage is configured yet. Add one and the files show up in the explorer.', 'conn.list.edit': 'Edit', 'conn.list.remove': 'Remove', 'conn.list.confirm': 'Really remove?', 'conn.list.readOnly': 'read-only', 'conn.list.disabled': 'disabled', 'conn.form.newTitle': 'New storage', 'conn.form.editTitle': 'Edit “{name}”', 'conn.form.name': 'Display name', 'conn.form.namePlaceholder': 'photos', 'conn.form.nameHelp': 'What this storage is called everywhere: in the explorer, in paths (name://folder) and in WebDAV URLs.', 'conn.form.driver': 'Type', 'conn.form.driverLocked': 'A storage\'s type cannot change after it is created — the paths already point at it.', 'conn.form.readOnly': 'Read-only (nothing may be written to this storage)', 'conn.form.enabled': 'Enabled', 'conn.form.test': 'Test connection', 'conn.form.testing': 'Testing…', 'conn.form.testOk': 'Connected. {count} items at the root.', 'conn.form.testOk_one': 'Connected. 1 item at the root.', 'conn.form.testFail': 'Could not connect: {error}', 'conn.form.save': 'Save', 'conn.form.saving': 'Saving…', 'conn.form.cancel': 'Cancel', 'conn.form.nameRequired': 'Give the storage a name.', 'conn.form.fillRequired': 'Fill in the fields marked with *.', 'conn.form.required': 'Required', 'conn.form.advanced': 'Advanced settings', '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-token', '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 filex account e-mail — not a display name.', 'conn.guide.webdav.passwordHint': 'Your account password, or an API token (Settings → API tokens). An account with two-factor authentication MUST use a token: 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, your tenant, 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 short login name. An @ in a login has to be quoted in most client config files, which is what this 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 token works as a password too, and is revocable on its own. An account with two-factor sign-in must use a key or a token.', '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 a key, or use an API token 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 short login name, or your e-mail. An API token works as the password too and can be revoked on its own.', 'conn.guide.ftps.fact.passwordHint': 'Your account password, or an API token. An account with two-factor sign-in must use a token — 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 login. Without it lftp logs 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 token 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 tokens', 'conn.tokens.lead': 'FTPS, WebDAV and filex mount all sign in with a token instead of your account password. Mint 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 token', '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 tokens. Sign in with your own account to make one.', 'conn.tokens.empty': 'No tokens yet.', 'conn.tokens.neverUsed': 'never', 'conn.tokens.revoke': 'Revoke', 'conn.tokens.confirm': 'Sure?', 'conn.tokens.col.label': 'Name', 'conn.tokens.col.scopes': 'Can do', '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 token', 'conn.guide.mount.fact.tokenPlaceholder': 'create one under Tokens', 'conn.guide.mount.fact.tokenHint': 'A token, 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 login (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 licence 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, your storages and — on a multi-tenant server — your tenant 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 token 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.fields.dialTimeout': 'Connect timeout (seconds)', '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': 'Disable presigned URLs', '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 files/folders explicitly granted to them via the permissions panel. When off, the storage is open to all users (capability by 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', /* === 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', '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', // ⚠ `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', '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.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 account and its permissions are the ceiling — asking for more than you have is refused, not granted.', /* === /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.withheld.onlyoffice': 'Office documents need a document server (OnlyOffice), which is not configured here.', 'newdoc.withheld.drawio': 'Diagrams need a drawio service, which is not configured here.', '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': 'Document name', 'newdoc.untitled': 'Untitled', 'newdoc.err.slash': 'A name cannot contain a slash.', 'newdoc.err.exists': '{name} is already here. Choose another name.', '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.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 drive 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 === */ /* i18n:hardcoded — the convert modal shipped with no keys at all: every label was a Turkish literal behind an optional `t` prop nobody passed. */ 'convert.title': 'Convert', 'convert.loading': 'Loading the converter…', 'convert.done': 'Converted and uploaded to this folder.', 'convert.close': 'Close', 'convert.from': 'Source', 'convert.search_format': 'Search a target format (pdf, mp4, png…)', 'convert.no_format': 'No matching format.', 'convert.unsupported_input': 'This file type has no source format the converter can read.', 'convert.converting': 'Converting…', 'convert.convert': 'Convert', /* === 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.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 drive 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.', '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': '1 matching item', 'advsearch.count.capped_one': '1 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 are applied to the rows that come back, not by the server.', 'advsearch.wire': 'Sent as', '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 — 1 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': '1 person', 'access.sum.people_none': 'No one yet', 'access.sum.drop': '{n} upload links', 'access.sum.drop_one': '1 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': 'People', '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 ========================== Column widths and visibility are a preference about YOUR SCREEN; the view a folder opens in is a fact about the FOLDER. Both are set from here, and `folder_hint` is the rule in one sentence, written where the person who is about to be surprised by it can read it. */ 'col.location': 'Location', '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': 'Folders you set up keep their own view. Your last choice is the default everywhere else.', 'cols.forget_folder': "Forget this folder's view", 'cols.apply_all': 'Apply to all folders ({count} remembered)', /* === 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 1 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?', 'trash.empty_confirm_body_one': 'This permanently deletes 1 item ({size}). It cannot be undone.', 'trash.empty_confirm_body': 'This permanently deletes {count} items ({size}). It cannot be undone.', 'trash.empty_confirm_body_nosize_one': 'This permanently deletes 1 item. It cannot be undone.', 'trash.empty_confirm_body_nosize': 'This permanently deletes {count} items. It cannot be undone.', 'trash.emptied': 'Trash emptied', '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.cancel': 'Cancel', 'destpicker.up': 'Up one level', 'destpicker.crumbs': 'Location', 'destpicker.drives': 'Drives', '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.', '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} (1 file)', 'toast.archive.empty': 'Nothing to download — the selection contains no readable file.', 'toast.moved_to': 'Moved to {name}', 'toast.copied_to': 'Copy to {name} queued', };