Repository: getumbrel/umbrel Branch: master Commit: 3e4ad453ad63 Files: 901 Total size: 3.9 MB Directory structure: gitextract_9b_v3mll/ ├── .gitattributes ├── .github/ │ └── workflows/ │ ├── ci.yml │ └── update-translations-in-pr.yml ├── .gitignore ├── .prettierrc.js ├── .umbrel ├── CONTRIBUTING.md ├── LICENSE.md ├── README.md ├── containers/ │ ├── app-auth/ │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── README.md │ │ ├── bin/ │ │ │ └── www │ │ ├── middleware/ │ │ │ ├── handle_error.js │ │ │ └── validate_token.js │ │ ├── package.json │ │ ├── routes/ │ │ │ └── auth.js │ │ ├── test/ │ │ │ ├── docker-compose.yml │ │ │ ├── fixtures/ │ │ │ │ └── app-data/ │ │ │ │ └── mempool/ │ │ │ │ └── umbrel-app.yml │ │ │ ├── global.js │ │ │ ├── test.sh │ │ │ └── utils/ │ │ │ └── hmac.js │ │ ├── utils/ │ │ │ ├── app.js │ │ │ ├── const.js │ │ │ ├── dashboard.js │ │ │ ├── express.js │ │ │ ├── hmac.js │ │ │ ├── host_resolution.js │ │ │ ├── manager.js │ │ │ ├── safe_handler.js │ │ │ └── token.js │ │ └── views/ │ │ └── pages/ │ │ └── redirect.ejs │ ├── app-proxy/ │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── Dockerfile │ │ ├── Dockerfile.dev │ │ ├── README.md │ │ ├── bin/ │ │ │ └── www │ │ ├── middleware/ │ │ │ └── handle_error.js │ │ ├── package.json │ │ ├── routes/ │ │ │ └── umbrel.js │ │ ├── test/ │ │ │ ├── .gitignore │ │ │ ├── docker-compose.app1.yml │ │ │ ├── docker-compose.app2.yml │ │ │ ├── docker-compose.bleskomat.yml │ │ │ ├── docker-compose.error.yml │ │ │ ├── docker-compose.mempool.yml │ │ │ ├── docker-compose.nextcloud.yml │ │ │ ├── docker-compose.proxy.yml │ │ │ ├── docker-compose.proxyhttps.yaml │ │ │ ├── docker-compose.sse.yml │ │ │ ├── docker-compose.suredbits.yml │ │ │ ├── docker-compose.ws.yml │ │ │ ├── docker-compose.yml │ │ │ ├── fixtures/ │ │ │ │ └── mempool-umbrel-app.yml │ │ │ ├── global.js │ │ │ ├── sse-test-server/ │ │ │ │ ├── .dockerignore │ │ │ │ ├── Dockerfile │ │ │ │ ├── bin/ │ │ │ │ │ └── www │ │ │ │ └── package.json │ │ │ ├── test/ │ │ │ │ └── Caddyfile-https │ │ │ ├── test.sh │ │ │ └── utils/ │ │ │ ├── express.js │ │ │ └── tor.js │ │ ├── utils/ │ │ │ ├── const.js │ │ │ ├── express.js │ │ │ ├── hmac.js │ │ │ ├── manager.js │ │ │ ├── proxy.js │ │ │ ├── safe_handler.js │ │ │ ├── token.js │ │ │ └── tor.js │ │ └── views/ │ │ └── pages/ │ │ └── error.ejs │ └── tor/ │ ├── Dockerfile │ ├── README.md │ └── test/ │ ├── .gitignore │ ├── docker-compose.entrypoint.yml │ ├── docker-compose.yml │ ├── entrypoint.sh │ ├── test-entrypoint.sh │ ├── test.sh │ └── torrc ├── info.json ├── package.json ├── packages/ │ ├── os/ │ │ ├── .gitignore │ │ ├── README.md │ │ ├── build-steps/ │ │ │ ├── initialize.sh │ │ │ ├── setup-raspberrypi/ │ │ │ │ ├── cmdline.txt │ │ │ │ ├── config.txt │ │ │ │ ├── raspberrypi.gpg.key │ │ │ │ └── raspberrypi.list │ │ │ └── setup-raspberrypi.sh │ │ ├── build.sh │ │ ├── builder.Dockerfile │ │ ├── mender.cfg │ │ ├── overlay-amd64/ │ │ │ └── umbrelOS │ │ ├── overlay-arm64/ │ │ │ ├── etc/ │ │ │ │ └── systemd/ │ │ │ │ └── system/ │ │ │ │ └── umbrel-external-storage.service │ │ │ └── opt/ │ │ │ └── umbrel-external-storage/ │ │ │ └── umbrel-external-storage │ │ ├── overlay-common/ │ │ │ ├── etc/ │ │ │ │ ├── NetworkManager/ │ │ │ │ │ ├── NetworkManager.conf │ │ │ │ │ └── conf.d/ │ │ │ │ │ └── 10-cloudflaredns.conf │ │ │ │ ├── acpi/ │ │ │ │ │ ├── events/ │ │ │ │ │ │ └── power-button │ │ │ │ │ └── power-button.sh │ │ │ │ ├── fstab │ │ │ │ ├── hostname │ │ │ │ ├── hosts │ │ │ │ ├── issue │ │ │ │ ├── locale.conf │ │ │ │ ├── motd │ │ │ │ ├── sudoers.d/ │ │ │ │ │ └── umbrel │ │ │ │ ├── sudoers.lecture │ │ │ │ ├── sysctl.d/ │ │ │ │ │ └── 99-vm-zram-parameters.conf │ │ │ │ └── systemd/ │ │ │ │ ├── logind.conf.d/ │ │ │ │ │ ├── lid-switch.conf │ │ │ │ │ └── power-button.conf │ │ │ │ ├── system/ │ │ │ │ │ ├── umbrel-dns-sync.service │ │ │ │ │ ├── umbrel-ssh-host-key-hydration.service │ │ │ │ │ ├── umbrel-tty-message.service │ │ │ │ │ └── umbrel.service │ │ │ │ ├── timesyncd.conf.d/ │ │ │ │ │ └── cloudflare.conf │ │ │ │ └── zram-generator.conf │ │ │ ├── opt/ │ │ │ │ ├── umbrel-data/ │ │ │ │ │ └── umbrel-data-mount │ │ │ │ ├── umbrel-dns-sync/ │ │ │ │ │ └── umbrel-dns-sync │ │ │ │ ├── umbrel-ssh-host-key-hydration/ │ │ │ │ │ └── umbrel-ssh-host-key-hydration │ │ │ │ └── umbrel-tty-message/ │ │ │ │ └── umbrel-tty-message │ │ │ └── umbrelOS │ │ ├── package.json │ │ ├── rugix/ │ │ │ ├── .gitignore │ │ │ ├── fix-umbrelos-pi-mbr.sh │ │ │ ├── layers/ │ │ │ │ ├── umbrelos-amd64.toml │ │ │ │ ├── umbrelos-mender-amd64.toml │ │ │ │ ├── umbrelos-pi.toml │ │ │ │ ├── umbrelos-pi4.toml │ │ │ │ ├── umbrelos-root-amd64.toml │ │ │ │ └── umbrelos-root-arm64.toml │ │ │ ├── recipes/ │ │ │ │ ├── fix-overlay/ │ │ │ │ │ ├── files/ │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ └── .gitkeep │ │ │ │ │ ├── recipe.toml │ │ │ │ │ └── steps/ │ │ │ │ │ └── 00-install.sh │ │ │ │ ├── setup-rugix/ │ │ │ │ │ ├── files/ │ │ │ │ │ │ ├── bootstrapping-amd64.toml │ │ │ │ │ │ ├── bootstrapping-arm64.toml │ │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ │ └── state-reset/ │ │ │ │ │ │ │ └── prepare.sh │ │ │ │ │ │ ├── state-data.toml │ │ │ │ │ │ └── system.toml │ │ │ │ │ ├── recipe.toml │ │ │ │ │ └── steps/ │ │ │ │ │ └── 00-install.sh │ │ │ │ ├── setup-rugix-mender/ │ │ │ │ │ ├── files/ │ │ │ │ │ │ ├── init │ │ │ │ │ │ ├── migrate-state.sh │ │ │ │ │ │ └── system.toml │ │ │ │ │ ├── recipe.toml │ │ │ │ │ └── steps/ │ │ │ │ │ └── 00-install.sh │ │ │ │ ├── umbrelos-boot/ │ │ │ │ │ ├── files/ │ │ │ │ │ │ └── grub.cfg │ │ │ │ │ ├── recipe.toml │ │ │ │ │ └── steps/ │ │ │ │ │ └── 00-install.sh │ │ │ │ ├── umbrelos-cleanup/ │ │ │ │ │ ├── recipe.toml │ │ │ │ │ └── steps/ │ │ │ │ │ └── 00-install.sh │ │ │ │ └── umbrelos-prepare/ │ │ │ │ ├── recipe.toml │ │ │ │ └── steps/ │ │ │ │ └── 00-install.sh │ │ │ ├── rugix-bakery.toml │ │ │ └── run-bakery │ │ ├── rugpi-image │ │ ├── trigger-change │ │ ├── umbrelos.Dockerfile │ │ ├── usb-installer/ │ │ │ ├── .gitignore │ │ │ ├── build.sh │ │ │ ├── builder.Dockerfile │ │ │ ├── overlay/ │ │ │ │ ├── etc/ │ │ │ │ │ └── systemd/ │ │ │ │ │ └── system/ │ │ │ │ │ └── custom-tty.service │ │ │ │ └── opt/ │ │ │ │ └── custom-tty │ │ │ ├── run.sh │ │ │ └── usb-installer.Dockerfile │ │ └── vm.sh │ ├── ui/ │ │ ├── .dockerignore │ │ ├── .gitignore │ │ ├── .prettierignore │ │ ├── .prettierrc.js │ │ ├── Dockerfile │ │ ├── app-auth/ │ │ │ ├── README.md │ │ │ ├── index.html │ │ │ ├── src/ │ │ │ │ ├── login-with-umbrel.tsx │ │ │ │ └── main.tsx │ │ │ └── vite.config.ts │ │ ├── components.json │ │ ├── eslint.config.js │ │ ├── index.html │ │ ├── package.json │ │ ├── public/ │ │ │ ├── assets/ │ │ │ │ ├── onboarding/ │ │ │ │ │ └── onboarding-bg.webm │ │ │ │ └── whats-new/ │ │ │ │ ├── backups.webm │ │ │ │ ├── external-storage.webm │ │ │ │ ├── network-devices.webm │ │ │ │ ├── restore.webm │ │ │ │ └── rewind.webm │ │ │ ├── locales/ │ │ │ │ ├── de.json │ │ │ │ ├── en.json │ │ │ │ ├── es.json │ │ │ │ ├── fr.json │ │ │ │ ├── hu.json │ │ │ │ ├── it.json │ │ │ │ ├── ja.json │ │ │ │ ├── ko.json │ │ │ │ ├── nl.json │ │ │ │ ├── pt.json │ │ │ │ ├── tr.json │ │ │ │ └── uk.json │ │ │ └── site.webmanifest │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── app-icon.tsx │ │ │ │ ├── caret-right.tsx │ │ │ │ ├── chevron-down.tsx │ │ │ │ ├── cmdk-providers.tsx │ │ │ │ ├── cmdk.tsx │ │ │ │ ├── darken-layer.tsx │ │ │ │ ├── fade-scroller.tsx │ │ │ │ ├── iframe-checker.tsx │ │ │ │ ├── install-button-connected.tsx │ │ │ │ ├── install-button.tsx │ │ │ │ ├── markdown.tsx │ │ │ │ ├── onboarding-background.tsx │ │ │ │ ├── progress-button.tsx │ │ │ │ ├── ui/ │ │ │ │ │ ├── alert-dialog.tsx │ │ │ │ │ ├── alert.tsx │ │ │ │ │ ├── animated-number.tsx │ │ │ │ │ ├── arc.tsx │ │ │ │ │ ├── badge.tsx │ │ │ │ │ ├── button-link.tsx │ │ │ │ │ ├── button.tsx │ │ │ │ │ ├── card.tsx │ │ │ │ │ ├── carousel.tsx │ │ │ │ │ ├── checkbox.tsx │ │ │ │ │ ├── command.tsx │ │ │ │ │ ├── context-menu.tsx │ │ │ │ │ ├── copy-button.tsx │ │ │ │ │ ├── copyable-field.tsx │ │ │ │ │ ├── cover-message.tsx │ │ │ │ │ ├── debug-only.tsx │ │ │ │ │ ├── dialog-close-button.tsx │ │ │ │ │ ├── dialog.tsx │ │ │ │ │ ├── drawer.tsx │ │ │ │ │ ├── dropdown-menu.tsx │ │ │ │ │ ├── error-boundary-card-fallback.tsx │ │ │ │ │ ├── error-boundary-page-fallback.tsx │ │ │ │ │ ├── fade-in-img.tsx │ │ │ │ │ ├── form.tsx │ │ │ │ │ ├── generic-error-text.tsx │ │ │ │ │ ├── icon-button-link.tsx │ │ │ │ │ ├── icon-button.tsx │ │ │ │ │ ├── icon.tsx │ │ │ │ │ ├── immersive-dialog.tsx │ │ │ │ │ ├── input.tsx │ │ │ │ │ ├── label.tsx │ │ │ │ │ ├── list.tsx │ │ │ │ │ ├── loading.tsx │ │ │ │ │ ├── notification-badge.tsx │ │ │ │ │ ├── numbered-list.tsx │ │ │ │ │ ├── pagination.tsx │ │ │ │ │ ├── pin-input.tsx │ │ │ │ │ ├── popover.tsx │ │ │ │ │ ├── progress.tsx │ │ │ │ │ ├── radio-group.tsx │ │ │ │ │ ├── root-error-fallback.tsx │ │ │ │ │ ├── scroll-area.tsx │ │ │ │ │ ├── segmented-control.tsx │ │ │ │ │ ├── separator.tsx │ │ │ │ │ ├── shared/ │ │ │ │ │ │ ├── dialog.ts │ │ │ │ │ │ └── menu.ts │ │ │ │ │ ├── sheet-scroll-area.tsx │ │ │ │ │ ├── sheet.tsx │ │ │ │ │ ├── switch.tsx │ │ │ │ │ ├── table.tsx │ │ │ │ │ ├── tabs.tsx │ │ │ │ │ ├── toast.tsx │ │ │ │ │ └── tooltip.tsx │ │ │ │ ├── umbrel-logo.tsx │ │ │ │ └── widget-check-icon.tsx │ │ │ ├── constants/ │ │ │ │ ├── index.ts │ │ │ │ └── links.ts │ │ │ ├── features/ │ │ │ │ ├── backups/ │ │ │ │ │ ├── cmdk-search-provider.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── backup-device-icon.tsx │ │ │ │ │ │ ├── backup-location-dropdown.tsx │ │ │ │ │ │ ├── backups-exclusions.tsx │ │ │ │ │ │ ├── configure-wizard.tsx │ │ │ │ │ │ ├── floating-island/ │ │ │ │ │ │ │ ├── expanded.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── minimized.tsx │ │ │ │ │ │ ├── modals/ │ │ │ │ │ │ │ ├── already-configured-modal.tsx │ │ │ │ │ │ │ └── connect-existing-modal.tsx │ │ │ │ │ │ ├── restore-location-dropdown.tsx │ │ │ │ │ │ ├── restore-wizard.tsx │ │ │ │ │ │ ├── review-card.tsx │ │ │ │ │ │ ├── setup-wizard.tsx │ │ │ │ │ │ ├── tab-switcher.tsx │ │ │ │ │ │ └── tiles.tsx │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ ├── use-apps-auto-excluded-paths.ts │ │ │ │ │ │ ├── use-apps-backup-ignore.ts │ │ │ │ │ │ ├── use-backup-ignored-paths.ts │ │ │ │ │ │ ├── use-backups.ts │ │ │ │ │ │ └── use-existing-backup-detection.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── utils/ │ │ │ │ │ ├── backup-location-helpers.ts │ │ │ │ │ ├── error-messages.ts │ │ │ │ │ ├── filepath-helpers.ts │ │ │ │ │ └── sort.ts │ │ │ │ ├── files/ │ │ │ │ │ ├── assets/ │ │ │ │ │ │ ├── add-folder-icon.tsx │ │ │ │ │ │ ├── apps-icon.tsx │ │ │ │ │ │ ├── caret-right.tsx │ │ │ │ │ │ ├── chevron-left.tsx │ │ │ │ │ │ ├── chevron-right.tsx │ │ │ │ │ │ ├── copy-icon.tsx │ │ │ │ │ │ ├── cursor-text-icon.tsx │ │ │ │ │ │ ├── empty-folder-icon.tsx │ │ │ │ │ │ ├── file-items-thumbnails/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── flame-icon.tsx │ │ │ │ │ │ ├── grid-layout-icon.tsx │ │ │ │ │ │ ├── home-icon.tsx │ │ │ │ │ │ ├── list-layout-icon.tsx │ │ │ │ │ │ ├── recents-icon.tsx │ │ │ │ │ │ ├── rewind-icon.tsx │ │ │ │ │ │ ├── search-icon.tsx │ │ │ │ │ │ ├── shared-folder-badge.tsx │ │ │ │ │ │ └── trash-icon.tsx │ │ │ │ │ ├── cmdk-search-provider.tsx │ │ │ │ │ ├── components/ │ │ │ │ │ │ ├── cards/ │ │ │ │ │ │ │ └── server-cards.tsx │ │ │ │ │ │ ├── dialogs/ │ │ │ │ │ │ │ ├── add-network-share-dialog/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── external-storage-unsupported-dialog/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── format-drive-dialog/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── permanently-delete-confirmation-dialog/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ └── share-info-dialog/ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── platform-instructions/ │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ ├── inline-copyable-field.tsx │ │ │ │ │ │ │ │ ├── instruction.tsx │ │ │ │ │ │ │ │ ├── ios-instructions.tsx │ │ │ │ │ │ │ │ ├── macos-instructions.tsx │ │ │ │ │ │ │ │ ├── umbrelos-instructions.tsx │ │ │ │ │ │ │ │ └── windows-instructions.tsx │ │ │ │ │ │ │ ├── platform-selector.tsx │ │ │ │ │ │ │ └── share-toggle.tsx │ │ │ │ │ │ ├── embedded/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── file-viewer/ │ │ │ │ │ │ │ ├── audio-viewer/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── downloader/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── image-viewer/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── pdf-viewer/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── video-viewer/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ └── viewer-wrapper.tsx │ │ │ │ │ │ ├── files-dnd-wrapper/ │ │ │ │ │ │ │ ├── files-dnd-overlay.tsx │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── floating-islands/ │ │ │ │ │ │ │ ├── audio-island/ │ │ │ │ │ │ │ │ ├── equalizer.tsx │ │ │ │ │ │ │ │ ├── expanded.tsx │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ └── minimized.tsx │ │ │ │ │ │ │ ├── formatting-island/ │ │ │ │ │ │ │ │ ├── expanded.tsx │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ └── minimized.tsx │ │ │ │ │ │ │ ├── operations-island/ │ │ │ │ │ │ │ │ ├── expanded.tsx │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ └── minimized.tsx │ │ │ │ │ │ │ └── uploading-island/ │ │ │ │ │ │ │ ├── expanded.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ └── minimized.tsx │ │ │ │ │ │ ├── listing/ │ │ │ │ │ │ │ ├── actions-bar/ │ │ │ │ │ │ │ │ ├── actions-bar-context.tsx │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ ├── mobile-actions.tsx │ │ │ │ │ │ │ │ ├── navigation-controls.tsx │ │ │ │ │ │ │ │ ├── path-bar/ │ │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ │ ├── path-bar-desktop.tsx │ │ │ │ │ │ │ │ │ ├── path-bar-mobile.tsx │ │ │ │ │ │ │ │ │ └── path-input.tsx │ │ │ │ │ │ │ │ ├── search-input.tsx │ │ │ │ │ │ │ │ ├── sort-dropdown.tsx │ │ │ │ │ │ │ │ └── view-toggle.tsx │ │ │ │ │ │ │ ├── apps-listing/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── directory-listing/ │ │ │ │ │ │ │ │ ├── empty-state.tsx │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── file-item/ │ │ │ │ │ │ │ │ ├── circular-progress.tsx │ │ │ │ │ │ │ │ ├── editable-name.tsx │ │ │ │ │ │ │ │ ├── icons-view-file-item.tsx │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ ├── list-view-file-item.css │ │ │ │ │ │ │ │ ├── list-view-file-item.tsx │ │ │ │ │ │ │ │ └── truncated-filename.tsx │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── listing-and-file-item-context-menu.tsx │ │ │ │ │ │ │ ├── listing-body.tsx │ │ │ │ │ │ │ ├── marquee-selection.tsx │ │ │ │ │ │ │ ├── recents-listing/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── search-listing/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ ├── trash-listing/ │ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ │ └── virtualized-list.tsx │ │ │ │ │ │ ├── mini-browser/ │ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ │ ├── rewind/ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ ├── overlay-context.tsx │ │ │ │ │ │ │ ├── prerewind-dialog.tsx │ │ │ │ │ │ │ ├── restore-grouping.ts │ │ │ │ │ │ │ ├── restore-progress-dialog.tsx │ │ │ │ │ │ │ ├── snapshot-carousel.tsx │ │ │ │ │ │ │ ├── snapshot-date-label.ts │ │ │ │ │ │ │ ├── timeline-bar.tsx │ │ │ │ │ │ │ └── tooltip.tsx │ │ │ │ │ │ ├── shared/ │ │ │ │ │ │ │ ├── circular-progress.tsx │ │ │ │ │ │ │ ├── drag-and-drop.tsx │ │ │ │ │ │ │ ├── file-item-icon/ │ │ │ │ │ │ │ │ ├── animated-folder-icon.tsx │ │ │ │ │ │ │ │ ├── embedded-overlay-icons.tsx │ │ │ │ │ │ │ │ ├── folder-icon.tsx │ │ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ │ │ └── unknown-file-thumbnail.tsx │ │ │ │ │ │ │ ├── file-upload-drop-zone.tsx │ │ │ │ │ │ │ └── upload-input.tsx │ │ │ │ │ │ └── sidebar/ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── mobile-sidebar-wrapper.tsx │ │ │ │ │ │ ├── sidebar-apps.tsx │ │ │ │ │ │ ├── sidebar-external-storage-item.tsx │ │ │ │ │ │ ├── sidebar-external-storage.tsx │ │ │ │ │ │ ├── sidebar-favorites.tsx │ │ │ │ │ │ ├── sidebar-home.tsx │ │ │ │ │ │ ├── sidebar-item.tsx │ │ │ │ │ │ ├── sidebar-network-share-item.tsx │ │ │ │ │ │ ├── sidebar-network-storage.tsx │ │ │ │ │ │ ├── sidebar-recents.tsx │ │ │ │ │ │ ├── sidebar-shares.tsx │ │ │ │ │ │ └── sidebar-trash.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── hooks/ │ │ │ │ │ │ ├── use-drag-and-drop.ts │ │ │ │ │ │ ├── use-external-storage.ts │ │ │ │ │ │ ├── use-favorites.ts │ │ │ │ │ │ ├── use-files-keyboard-shortcuts.ts │ │ │ │ │ │ ├── use-files-operations.ts │ │ │ │ │ │ ├── use-home-directory-name.ts │ │ │ │ │ │ ├── use-is-touch-device.ts │ │ │ │ │ │ ├── use-item-click.ts │ │ │ │ │ │ ├── use-list-directory.ts │ │ │ │ │ │ ├── use-list-recents.ts │ │ │ │ │ │ ├── use-navigate.ts │ │ │ │ │ │ ├── use-network-device-type.ts │ │ │ │ │ │ ├── use-network-storage.ts │ │ │ │ │ │ ├── use-new-folder.ts │ │ │ │ │ │ ├── use-preferences.ts │ │ │ │ │ │ ├── use-rewind-action.ts │ │ │ │ │ │ ├── use-rewind.ts │ │ │ │ │ │ ├── use-search-files.ts │ │ │ │ │ │ └── use-shares.ts │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── providers/ │ │ │ │ │ │ └── files-capabilities-context.tsx │ │ │ │ │ ├── routes.tsx │ │ │ │ │ ├── store/ │ │ │ │ │ │ ├── slices/ │ │ │ │ │ │ │ ├── clipboard-slice.ts │ │ │ │ │ │ │ ├── drag-and-drop-slice.ts │ │ │ │ │ │ │ ├── file-viewer-slice.ts │ │ │ │ │ │ │ ├── interaction-slice.ts │ │ │ │ │ │ │ ├── new-folder-slice.ts │ │ │ │ │ │ │ ├── rename-slice.ts │ │ │ │ │ │ │ └── selection-slice.ts │ │ │ │ │ │ └── use-files-store.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ ├── utils/ │ │ │ │ │ │ ├── error-messages.ts │ │ │ │ │ │ ├── format-filesystem-date.ts │ │ │ │ │ │ ├── format-filesystem-name.ts │ │ │ │ │ │ ├── format-filesystem-size.ts │ │ │ │ │ │ ├── get-grid-column-count.ts │ │ │ │ │ │ ├── get-item-key.ts │ │ │ │ │ │ ├── is-directory-a-network-device-or-share.ts │ │ │ │ │ │ ├── is-directory-an-external-drive-partition.ts │ │ │ │ │ │ ├── is-directory-an-umbrel-backup.ts │ │ │ │ │ │ ├── path-alias.ts │ │ │ │ │ │ └── sort-filesystem-items.ts │ │ │ │ │ └── widgets.tsx │ │ │ │ └── storage/ │ │ │ │ ├── components/ │ │ │ │ │ ├── dialogs/ │ │ │ │ │ │ ├── add-to-raid-dialog.tsx │ │ │ │ │ │ ├── install-ssd-dialog.tsx │ │ │ │ │ │ ├── install-tips-collapsible.tsx │ │ │ │ │ │ ├── operation-in-progress-banner.tsx │ │ │ │ │ │ ├── replace-failed-drive-dialog.tsx │ │ │ │ │ │ ├── shutdown-confirmation-dialog.tsx │ │ │ │ │ │ ├── ssd-health-dialog.tsx │ │ │ │ │ │ └── swap-dialog.tsx │ │ │ │ │ ├── floating-island/ │ │ │ │ │ │ ├── data-stream-icon.tsx │ │ │ │ │ │ ├── expanded.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ └── minimized.tsx │ │ │ │ │ ├── ssd-shape.tsx │ │ │ │ │ ├── storage-donut-chart.tsx │ │ │ │ │ └── storage-mode-display.tsx │ │ │ │ ├── hooks/ │ │ │ │ │ ├── use-active-raid-operation.ts │ │ │ │ │ ├── use-raid-progress.ts │ │ │ │ │ └── use-storage.ts │ │ │ │ ├── index.tsx │ │ │ │ ├── providers/ │ │ │ │ │ └── pending-operation-context.tsx │ │ │ │ └── utils.ts │ │ │ ├── hooks/ │ │ │ │ ├── use-2fa.ts │ │ │ │ ├── use-app-install.ts │ │ │ │ ├── use-apps-with-updates.ts │ │ │ │ ├── use-auto-height-animation.tsx │ │ │ │ ├── use-color-thief.ts │ │ │ │ ├── use-cpu-temperature.ts │ │ │ │ ├── use-cpu.ts │ │ │ │ ├── use-debug-install-random-apps.ts │ │ │ │ ├── use-device-info.ts │ │ │ │ ├── use-disk.ts │ │ │ │ ├── use-is-externaldns.ts │ │ │ │ ├── use-is-home-or-pro.ts │ │ │ │ ├── use-is-mobile.ts │ │ │ │ ├── use-is-umbrel-home.tsx │ │ │ │ ├── use-is-umbrel-pro.ts │ │ │ │ ├── use-language.ts │ │ │ │ ├── use-launch-app.ts │ │ │ │ ├── use-memory.ts │ │ │ │ ├── use-notifications.ts │ │ │ │ ├── use-password.ts │ │ │ │ ├── use-prefixed-local-storage.ts │ │ │ │ ├── use-query-params.ts │ │ │ │ ├── use-scroll-restoration.ts │ │ │ │ ├── use-settings-notification-count.ts │ │ │ │ ├── use-software-update.ts │ │ │ │ ├── use-temperature-unit.ts │ │ │ │ ├── use-tor-enabled.ts │ │ │ │ ├── use-update-all-apps.ts │ │ │ │ ├── use-user-name.ts │ │ │ │ ├── use-version.ts │ │ │ │ └── use-widgets.ts │ │ │ ├── index.css │ │ │ ├── init.tsx │ │ │ ├── layouts/ │ │ │ │ ├── README.md │ │ │ │ ├── app-store.tsx │ │ │ │ ├── bare/ │ │ │ │ │ ├── bare-page.tsx │ │ │ │ │ ├── bare.tsx │ │ │ │ │ ├── onboarding-page.tsx │ │ │ │ │ ├── onboarding.tsx │ │ │ │ │ └── shared.tsx │ │ │ │ ├── desktop.tsx │ │ │ │ └── sheet.tsx │ │ │ ├── lib/ │ │ │ │ └── utils.ts │ │ │ ├── main.tsx │ │ │ ├── modules/ │ │ │ │ ├── app-store/ │ │ │ │ │ ├── app-page/ │ │ │ │ │ │ ├── about-section.tsx │ │ │ │ │ │ ├── app-content.tsx │ │ │ │ │ │ ├── app-settings-dialog.tsx │ │ │ │ │ │ ├── default-credentials-dialog.tsx │ │ │ │ │ │ ├── dependencies.tsx │ │ │ │ │ │ ├── get-recommendations.ts │ │ │ │ │ │ ├── info-section.tsx │ │ │ │ │ │ ├── recommendations-section.tsx │ │ │ │ │ │ ├── release-notes-section.tsx │ │ │ │ │ │ ├── settings-section.tsx │ │ │ │ │ │ ├── shared.tsx │ │ │ │ │ │ └── top-header.tsx │ │ │ │ │ ├── app-store-nav.tsx │ │ │ │ │ ├── community-app-store-dialog.tsx │ │ │ │ │ ├── constants.ts │ │ │ │ │ ├── discover/ │ │ │ │ │ │ ├── apps-grid-section.tsx │ │ │ │ │ │ ├── apps-row-section.tsx │ │ │ │ │ │ └── apps-three-column-section.tsx │ │ │ │ │ ├── gallery-section.tsx │ │ │ │ │ ├── os-update-required.tsx │ │ │ │ │ ├── select-dependencies-dialog.tsx │ │ │ │ │ ├── shared.tsx │ │ │ │ │ ├── updates-button.tsx │ │ │ │ │ ├── updates-dialog.tsx │ │ │ │ │ └── utils.ts │ │ │ │ ├── auth/ │ │ │ │ │ ├── ensure-backend-available.tsx │ │ │ │ │ ├── ensure-logged-in.tsx │ │ │ │ │ ├── ensure-no-raid-mount-failure.tsx │ │ │ │ │ ├── ensure-pro-device.tsx │ │ │ │ │ ├── ensure-user-exists.tsx │ │ │ │ │ ├── redirects.tsx │ │ │ │ │ ├── shared.ts │ │ │ │ │ └── use-auth.tsx │ │ │ │ ├── bare/ │ │ │ │ │ ├── alert.tsx │ │ │ │ │ ├── failed-layout.tsx │ │ │ │ │ ├── progress-layout.tsx │ │ │ │ │ ├── progress.tsx │ │ │ │ │ ├── shared.tsx │ │ │ │ │ └── success-layout.tsx │ │ │ │ ├── community-app-store/ │ │ │ │ │ └── community-badge.tsx │ │ │ │ ├── desktop/ │ │ │ │ │ ├── app-grid/ │ │ │ │ │ │ ├── app-grid.tsx │ │ │ │ │ │ ├── app-pagination-utils.tsx │ │ │ │ │ │ └── paginator.tsx │ │ │ │ │ ├── app-icon.tsx │ │ │ │ │ ├── blur-below-dock.tsx │ │ │ │ │ ├── desktop-content.tsx │ │ │ │ │ ├── desktop-context-menu.tsx │ │ │ │ │ ├── desktop-misc.tsx │ │ │ │ │ ├── desktop-preview.tsx │ │ │ │ │ ├── dock-item.tsx │ │ │ │ │ ├── dock.tsx │ │ │ │ │ ├── greeting-message.ts │ │ │ │ │ ├── header.tsx │ │ │ │ │ ├── install-first-app.tsx │ │ │ │ │ ├── logout-dialog.tsx │ │ │ │ │ ├── uninstall-confirmation-dialog.tsx │ │ │ │ │ └── uninstall-these-first-dialog.tsx │ │ │ │ ├── floating-island/ │ │ │ │ │ ├── bare-island.tsx │ │ │ │ │ └── container.tsx │ │ │ │ ├── immersive-picker/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── migrate/ │ │ │ │ │ ├── migrate-image.tsx │ │ │ │ │ └── migrate-inner.tsx │ │ │ │ ├── sheet-top-fixed.tsx │ │ │ │ ├── widgets/ │ │ │ │ │ ├── four-stats-widget.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── list-emoji-widget.tsx │ │ │ │ │ ├── list-widget.tsx │ │ │ │ │ ├── shared/ │ │ │ │ │ │ ├── backdrop-blur-context.tsx │ │ │ │ │ │ ├── constants.ts │ │ │ │ │ │ ├── shared.tsx │ │ │ │ │ │ ├── stat-text.tsx │ │ │ │ │ │ ├── tabler-icon.tsx │ │ │ │ │ │ └── widget-wrapper.tsx │ │ │ │ │ ├── text-with-buttons-widget.tsx │ │ │ │ │ ├── text-with-progress-widget.tsx │ │ │ │ │ ├── three-stats-widget.tsx │ │ │ │ │ └── two-stats-with-guage-widget.tsx │ │ │ │ └── wifi/ │ │ │ │ ├── desktop-wifi-button-connected.tsx │ │ │ │ ├── icon.tsx │ │ │ │ ├── wifi-drawer-or-dialog.tsx │ │ │ │ ├── wifi-item-content.tsx │ │ │ │ └── wifi-list-row-connected-description.tsx │ │ │ ├── providers/ │ │ │ │ ├── apps.tsx │ │ │ │ ├── auth-bootstrap.tsx │ │ │ │ ├── available-apps.tsx │ │ │ │ ├── confirmation/ │ │ │ │ │ ├── confirmation-context.tsx │ │ │ │ │ ├── confirmation-provider.tsx │ │ │ │ │ ├── generic-confirmation-dialog.tsx │ │ │ │ │ ├── index.ts │ │ │ │ │ ├── types.ts │ │ │ │ │ └── use-confirmation.ts │ │ │ │ ├── global-files.tsx │ │ │ │ ├── global-system-state/ │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── migrate.tsx │ │ │ │ │ ├── reset.tsx │ │ │ │ │ ├── restart.tsx │ │ │ │ │ ├── restore.tsx │ │ │ │ │ ├── shutdown.tsx │ │ │ │ │ └── update.tsx │ │ │ │ ├── immersive-dialog.tsx │ │ │ │ ├── language.tsx │ │ │ │ ├── prefetch.tsx │ │ │ │ ├── sheet-sticky-header.tsx │ │ │ │ └── wallpaper.tsx │ │ │ ├── router.tsx │ │ │ ├── routes/ │ │ │ │ ├── README.md │ │ │ │ ├── app-store/ │ │ │ │ │ ├── app-page/ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ ├── category-page.tsx │ │ │ │ │ ├── discover.tsx │ │ │ │ │ └── use-discover-query.tsx │ │ │ │ ├── community-app-store/ │ │ │ │ │ ├── app-page/ │ │ │ │ │ │ └── index.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── edit-widgets/ │ │ │ │ │ ├── index.tsx │ │ │ │ │ └── widget-selector.tsx │ │ │ │ ├── factory-reset/ │ │ │ │ │ ├── _components/ │ │ │ │ │ │ ├── confirm-with-password.tsx │ │ │ │ │ │ ├── misc.tsx │ │ │ │ │ │ └── review-data.tsx │ │ │ │ │ └── index.tsx │ │ │ │ ├── live-usage.tsx │ │ │ │ ├── login.tsx │ │ │ │ ├── not-found.tsx │ │ │ │ ├── notifications.tsx │ │ │ │ ├── onboarding/ │ │ │ │ │ ├── account-created.tsx │ │ │ │ │ ├── create-account.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── onboarding-footer.tsx │ │ │ │ │ ├── raid/ │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ ├── raid-error.tsx │ │ │ │ │ │ ├── setup.tsx │ │ │ │ │ │ ├── ssd-health-dialog.tsx │ │ │ │ │ │ ├── ssd-tray.tsx │ │ │ │ │ │ └── use-raid-setup.ts │ │ │ │ │ ├── restore.tsx │ │ │ │ │ └── use-onboarding-device.ts │ │ │ │ ├── raid-error/ │ │ │ │ │ └── index.tsx │ │ │ │ ├── settings/ │ │ │ │ │ ├── 2fa-disable.tsx │ │ │ │ │ ├── 2fa-enable.tsx │ │ │ │ │ ├── 2fa.tsx │ │ │ │ │ ├── _components/ │ │ │ │ │ │ ├── app-store-preferences-content.tsx │ │ │ │ │ │ ├── cpu-card-content.tsx │ │ │ │ │ │ ├── cpu-temperature-card-content.tsx │ │ │ │ │ │ ├── device-info-content.tsx │ │ │ │ │ │ ├── device-info-umbrel-home.tsx │ │ │ │ │ │ ├── device-info-umbrel-pro.tsx │ │ │ │ │ │ ├── language-dropdown.tsx │ │ │ │ │ │ ├── laser-engraving.tsx │ │ │ │ │ │ ├── list-row.tsx │ │ │ │ │ │ ├── memory-card-content.tsx │ │ │ │ │ │ ├── no-forgot-password-message.tsx │ │ │ │ │ │ ├── progress-card-content.tsx │ │ │ │ │ │ ├── settings-content-mobile.tsx │ │ │ │ │ │ ├── settings-content.tsx │ │ │ │ │ │ ├── settings-summary.tsx │ │ │ │ │ │ ├── shared.tsx │ │ │ │ │ │ ├── software-update-list-row.tsx │ │ │ │ │ │ ├── storage-card-content.tsx │ │ │ │ │ │ └── wallpaper-picker.tsx │ │ │ │ │ ├── advanced.tsx │ │ │ │ │ ├── app-store-preferences.tsx │ │ │ │ │ ├── change-name.tsx │ │ │ │ │ ├── change-password.tsx │ │ │ │ │ ├── device-info.tsx │ │ │ │ │ ├── file-sharing.tsx │ │ │ │ │ ├── index.tsx │ │ │ │ │ ├── migration-assistant.tsx │ │ │ │ │ ├── mobile/ │ │ │ │ │ │ ├── account.tsx │ │ │ │ │ │ ├── app-store-preferences.tsx │ │ │ │ │ │ ├── backups-mobile-drawer.tsx │ │ │ │ │ │ ├── device-info.tsx │ │ │ │ │ │ ├── language.tsx │ │ │ │ │ │ ├── software-update.tsx │ │ │ │ │ │ ├── start-migration-drawer-or-dialog.tsx │ │ │ │ │ │ ├── tor.tsx │ │ │ │ │ │ └── wallpaper.tsx │ │ │ │ │ ├── restart.tsx │ │ │ │ │ ├── shutdown.tsx │ │ │ │ │ ├── software-update-confirm.tsx │ │ │ │ │ ├── terminal/ │ │ │ │ │ │ ├── _shared.tsx │ │ │ │ │ │ ├── app.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ └── umbrelos.tsx │ │ │ │ │ ├── troubleshoot/ │ │ │ │ │ │ ├── _shared.tsx │ │ │ │ │ │ ├── app.tsx │ │ │ │ │ │ ├── index.tsx │ │ │ │ │ │ └── umbrelos.tsx │ │ │ │ │ ├── wifi-unsupported.tsx │ │ │ │ │ └── wifi.tsx │ │ │ │ └── whats-new-modal.tsx │ │ │ ├── trpc/ │ │ │ │ ├── loading-indicator.tsx │ │ │ │ ├── trpc-provider.tsx │ │ │ │ └── trpc.ts │ │ │ ├── types.d.ts │ │ │ └── utils/ │ │ │ ├── call-every-interval.ts │ │ │ ├── date-time.ts │ │ │ ├── dialog.ts │ │ │ ├── element-classes.ts │ │ │ ├── i18n.ts │ │ │ ├── language.ts │ │ │ ├── logs.ts │ │ │ ├── misc.ts │ │ │ ├── number.ts │ │ │ ├── pretty-bytes.ts │ │ │ ├── search.ts │ │ │ ├── seconds-to-eta.ts │ │ │ ├── system.ts │ │ │ ├── temperature.ts │ │ │ ├── tw.ts │ │ │ └── wifi.ts │ │ ├── tailwind.config.ts │ │ ├── tsconfig.json │ │ ├── tsconfig.node.json │ │ ├── update-translations.js │ │ └── vite.config.ts │ └── umbreld/ │ ├── .gitignore │ ├── .prettierignore │ ├── package.json │ ├── scripts/ │ │ └── validate-manifests.ts │ ├── source/ │ │ ├── cli.ts │ │ ├── constants.ts │ │ ├── index.ts │ │ └── modules/ │ │ ├── apps/ │ │ │ ├── app-repository.integration.test.ts │ │ │ ├── app-repository.ts │ │ │ ├── app-store.integration.test.ts │ │ │ ├── app-store.ts │ │ │ ├── app.ts │ │ │ ├── apps.integration.test.ts │ │ │ ├── apps.ts │ │ │ ├── legacy-compat/ │ │ │ │ ├── app-environment.ts │ │ │ │ ├── app-script │ │ │ │ ├── app-script.ts │ │ │ │ ├── bin/ │ │ │ │ │ ├── bitcoin-cli │ │ │ │ │ └── lncli │ │ │ │ ├── docker-compose.app_proxy.yml │ │ │ │ ├── docker-compose.common.yml │ │ │ │ ├── docker-compose.tor.yml │ │ │ │ ├── docker-compose.yml │ │ │ │ ├── tor-entrypoint.sh │ │ │ │ ├── tor-proxy-torrc │ │ │ │ └── tor-server-torrc │ │ │ ├── routes.ts │ │ │ └── schema.ts │ │ ├── backups/ │ │ │ ├── backups.backupProgress.test.ts │ │ │ ├── backups.integration.test.ts │ │ │ ├── backups.ts │ │ │ └── routes.ts │ │ ├── blacklist-uas/ │ │ │ └── blacklist-uas.ts │ │ ├── cli-client.ts │ │ ├── dbus/ │ │ │ └── dbus.ts │ │ ├── development.ts │ │ ├── event-bus/ │ │ │ ├── event-bus.ts │ │ │ └── routes.ts │ │ ├── files/ │ │ │ ├── api.download.integration.test.ts │ │ │ ├── api.thumbnail.integration.test.ts │ │ │ ├── api.ts │ │ │ ├── api.upload.integration.test.ts │ │ │ ├── api.view.integration.test.ts │ │ │ ├── archive.integration.test.ts │ │ │ ├── archive.ts │ │ │ ├── external-storage.integration.test.ts │ │ │ ├── external-storage.ts │ │ │ ├── favorites.integration.test.ts │ │ │ ├── favorites.ts │ │ │ ├── files-reflink-copy.vm.test.ts │ │ │ ├── files.copy.integration.test.ts │ │ │ ├── files.createDirectory.integration.test.ts │ │ │ ├── files.delete.test.ts │ │ │ ├── files.emptyTrash.test.ts │ │ │ ├── files.list.integration.test.ts │ │ │ ├── files.move.integration.test.ts │ │ │ ├── files.operationProgress.test.ts │ │ │ ├── files.preferences.integration.test.ts │ │ │ ├── files.rename.integration.test.ts │ │ │ ├── files.restore.test.ts │ │ │ ├── files.trash.test.ts │ │ │ ├── files.ts │ │ │ ├── fixtures/ │ │ │ │ └── thumbnails/ │ │ │ │ └── master-lossless-video.mkv │ │ │ ├── network-storage.integration.test.ts │ │ │ ├── network-storage.ts │ │ │ ├── recents.test.ts │ │ │ ├── recents.ts │ │ │ ├── routes.ts │ │ │ ├── samba.integration.test.ts │ │ │ ├── samba.ts │ │ │ ├── search.integration.test.ts │ │ │ ├── search.ts │ │ │ ├── thumbnails.integration.test.ts │ │ │ ├── thumbnails.ts │ │ │ ├── watcher.ts │ │ │ └── widgets.ts │ │ ├── hardware/ │ │ │ ├── hardware.ts │ │ │ ├── internal-storage-rounding.vm.test.ts │ │ │ ├── internal-storage-slot-detection.vm.test.ts │ │ │ ├── internal-storage.ts │ │ │ ├── raid-failsafe-space-reporting.vm.test.ts │ │ │ ├── raid-failsafe.vm.test.ts │ │ │ ├── raid-foreign-pool.vm.test.ts │ │ │ ├── raid-operations-different-sizes.vm.test.ts │ │ │ ├── raid-preused-drives.vm.test.ts │ │ │ ├── raid-recovery-mode.vm.test.ts │ │ │ ├── raid-replace-larger-capacity.vm.test.ts │ │ │ ├── raid-replace.vm.test.ts │ │ │ ├── raid-size-rounding.vm.test.ts │ │ │ ├── raid-slot-swap.vm.test.ts │ │ │ ├── raid-storage.vm.test.ts │ │ │ ├── raid-transition-different-size.vm.test.ts │ │ │ ├── raid-transition-full-storage.vm.test.ts │ │ │ ├── raid-transition.vm.test.ts │ │ │ ├── raid.getRoundedDeviceSize.unit.test.ts │ │ │ ├── raid.ts │ │ │ ├── routes.ts │ │ │ └── umbrel-pro.ts │ │ ├── is-umbrel-home.ts │ │ ├── jwt.ts │ │ ├── migration/ │ │ │ ├── migration.ts │ │ │ └── routes.ts │ │ ├── notifications/ │ │ │ ├── notifications.integration.test.ts │ │ │ ├── notifications.ts │ │ │ └── routes.ts │ │ ├── server/ │ │ │ ├── index.ts │ │ │ ├── terminal-socket.ts │ │ │ └── trpc/ │ │ │ ├── common.ts │ │ │ ├── context.ts │ │ │ ├── index.ts │ │ │ ├── is-authenticated.ts │ │ │ ├── trpc.ts │ │ │ └── websocket-logger.ts │ │ ├── startup-migrations/ │ │ │ ├── index.ts │ │ │ └── startup-migrations.integration.test.ts │ │ ├── system/ │ │ │ ├── factory-reset.ts │ │ │ ├── routes.ts │ │ │ ├── system-widgets.ts │ │ │ ├── system.integration.test.ts │ │ │ ├── system.ts │ │ │ ├── system.unit.test.ts │ │ │ ├── update.ts │ │ │ └── wifi-routes.ts │ │ ├── test-utilities/ │ │ │ ├── create-test-umbreld.ts │ │ │ ├── fixtures/ │ │ │ │ ├── another-community-repo/ │ │ │ │ │ ├── another-sparkles-hello-world/ │ │ │ │ │ │ ├── docker-compose.yml │ │ │ │ │ │ └── umbrel-app.yml │ │ │ │ │ └── umbrel-app-store.yml │ │ │ │ └── community-repo/ │ │ │ │ ├── app-with-invalid-id/ │ │ │ │ │ ├── docker-compose.yml │ │ │ │ │ └── umbrel-app.yml │ │ │ │ ├── app-with-invalid-manifest/ │ │ │ │ │ ├── docker-compose.yml │ │ │ │ │ └── umbrel-app.yml │ │ │ │ ├── sparkles-hello-world/ │ │ │ │ │ ├── docker-compose.yml │ │ │ │ │ └── umbrel-app.yml │ │ │ │ └── umbrel-app-store.yml │ │ │ └── run-git-server.ts │ │ ├── user/ │ │ │ ├── routes.ts │ │ │ ├── user.integration.test.ts │ │ │ └── user.ts │ │ ├── utilities/ │ │ │ ├── copy-with-progress.ts │ │ │ ├── dependencies.ts │ │ │ ├── docker-pull.ts │ │ │ ├── file-store.integration.test.ts │ │ │ ├── file-store.ts │ │ │ ├── get-directory-size.ts │ │ │ ├── get-or-create-file.ts │ │ │ ├── logger.ts │ │ │ ├── package-directory.ts │ │ │ ├── random-token.ts │ │ │ ├── regexp.ts │ │ │ ├── run-every.ts │ │ │ ├── temporary-directory.ts │ │ │ └── totp.ts │ │ └── widgets/ │ │ ├── routes.ts │ │ └── widget.integration.test.ts │ ├── trigger-change │ ├── tsconfig.json │ └── umbreld └── scripts/ ├── data-export ├── install ├── remote-builder ├── umbrel-dev └── update-script ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitattributes ================================================ # On Windows, Git defaults to checkout Windows-style and commit Unix-style. # As such, line endings of bash scripts are converted from LF to CRLF, with # the effect that when mounting the checkout into a Linux container, the # bash scripts can't execute because bash does not handle CR. To mitigate, # conservatively force ALL line endings to be retained. * -text ================================================ FILE: .github/workflows/ci.yml ================================================ name: CI on: push jobs: # Detect if only UI files changed to skip heavy tests detect-changes: name: Detect changes runs-on: ubuntu-24.04 outputs: ui-only: ${{ steps.check.outputs.ui-only }} steps: - uses: actions/checkout@v3 with: fetch-depth: 0 - id: check run: | DEFAULT_BRANCH="${{ github.event.repository.default_branch }}" # On default branch, always run all tests if [[ "${{ github.ref }}" == "refs/heads/${DEFAULT_BRANCH}" ]]; then echo "ui-only=false" >> $GITHUB_OUTPUT exit 0 fi # Get changed files compared to the previous push event CHANGED_FILES=$(git diff --name-only ${{ github.event.before }} ${{ github.sha }} 2>/dev/null || git diff --name-only HEAD~1 HEAD) # Check if all changed files are in packages/ui/ UI_ONLY="true" while IFS= read -r file; do if [[ -n "$file" && ! "$file" =~ ^packages/ui/ ]]; then UI_ONLY="false" break fi done <<< "$CHANGED_FILES" echo "Changed files:" echo "$CHANGED_FILES" echo "UI only: $UI_ONLY" echo "ui-only=$UI_ONLY" >> $GITHUB_OUTPUT # These jobs simply serve as architecture native cache steps to load up the Docker cache for umbrelOS. # We must cache to unique scopes per architecture otherwise only one of the architectures gets cached. umbrelos-amd64-cache: name: Build umbrelOS amd64 needs: detect-changes if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubicloud-standard-4-ubuntu-2404 steps: - uses: actions/checkout@v3 - uses: docker/setup-buildx-action@v3 - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3 - name: Build amd64 Docker image working-directory: packages/os run: docker buildx build --platform linux/amd64 --file umbrelos.Dockerfile --cache-from type=gha,scope=umbrelos-amd64 --cache-to type=gha,mode=max,scope=umbrelos-amd64 ../../ umbrelos-arm64-cache: name: Build umbrelOS arm64 needs: detect-changes if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubicloud-standard-4-ubuntu-2404 steps: - uses: actions/checkout@v3 - uses: docker/setup-buildx-action@v3 - uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3 - name: Build arm64 Docker image working-directory: packages/os run: docker buildx build --platform linux/arm64 --file umbrelos.Dockerfile --cache-from type=gha,scope=umbrelos-arm64 --cache-to type=gha,mode=max,scope=umbrelos-arm64 ../../ # Build the image for the VM tests # We run this in a seperate step so we only build it once and reuse for all VM runners to reduce billed minutes. umbrelos-amd64-vm-image-build: name: Build umbrelOS amd64 VM image needs: [detect-changes, umbrelos-amd64-cache] if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubicloud-standard-4-ubuntu-2404 steps: - name: Checkout code uses: actions/checkout@v3 with: submodules: recursive - name: Setup node uses: actions/setup-node@v3 with: node-version: 22 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Expose GitHub Actions runtime for Docker cache uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3 - name: Build OS image working-directory: packages/os run: npm run build:amd64:rugix # Hack to pass the image to the next job. We used to use upload-artifact but network performance # is terrible between GitHub <> Ubicloud. Just abuse the cache for now which is local and fast. - name: Cache OS image uses: actions/cache/save@v4 with: path: packages/os/build/umbrelos-amd64.img key: umbrelos-amd64-image-${{ github.run_id }} # Discover all MV test files so we can run the result as a build matrix discover-vm-tests: name: Discover VM tests needs: detect-changes if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubuntu-24.04 outputs: tests: ${{ steps.find.outputs.tests }} steps: - uses: actions/checkout@v3 - id: find run: | tests=$(find packages/umbreld/source -name "*.vm.test.ts" | sed 's|packages/umbreld/||' | jq -R -s -c 'split("\n") | map(select(length > 0)) | map({path: ., name: (. | split("/") | last | sub("\\.vm\\.test\\.ts$"; ""))})') echo "tests=$tests" >> $GITHUB_OUTPUT # Run each VM test in a different runner umbrelos-amd64-vm: name: VM test (${{ matrix.test.name }}) needs: [detect-changes, umbrelos-amd64-vm-image-build, discover-vm-tests] if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubicloud-standard-4-ubuntu-2404 strategy: fail-fast: false matrix: test: ${{ fromJSON(needs.discover-vm-tests.outputs.tests) }} steps: - name: Checkout code uses: actions/checkout@v3 with: submodules: recursive - name: Setup node uses: actions/setup-node@v3 with: node-version: 22 - name: Restore OS image from cache uses: actions/cache/restore@v4 with: path: packages/os/build/umbrelos-amd64.img key: umbrelos-amd64-image-${{ github.run_id }} fail-on-cache-miss: true - name: Install QEMU run: sudo apt-get update && sudo apt-get install -y qemu-system-x86 - name: Install umbreld dependencies working-directory: packages/umbreld run: npm clean-install - name: Run VM test working-directory: packages/umbreld run: npm run test -- ${{ matrix.test.path }} # Discover all integration test files so we can run the result as a build matrix discover-integration-tests: name: Discover integration tests needs: detect-changes if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubuntu-24.04 outputs: tests: ${{ steps.find.outputs.tests }} steps: - uses: actions/checkout@v3 - id: find run: | tests=$(find packages/umbreld/source -name "*.integration.test.ts" | sed 's|packages/umbreld/||' | jq -R -s -c 'split("\n") | map(select(length > 0)) | map({path: ., name: (. | split("/") | last | sub("\\.integration\\.test\\.ts$"; ""))})') echo "tests=$tests" >> $GITHUB_OUTPUT # Run each integration test in a different runner umbreld-integration: name: Integration test (${{ matrix.test.name }}) needs: [detect-changes, discover-integration-tests, umbrelos-amd64-cache] if: needs.detect-changes.outputs.ui-only != 'true' runs-on: ubicloud-standard-4-ubuntu-2404 strategy: fail-fast: false matrix: test: ${{ fromJSON(needs.discover-integration-tests.outputs.tests) }} steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup node uses: actions/setup-node@v3 with: node-version: 18 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Expose GitHub Actions runtime for Docker cache uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3 - run: npm run dev rebuild - run: npm run dev start - run: npm run --prefix packages/umbreld test:umbrel-dev:prepare - run: npm run --prefix packages/umbreld test:umbrel-dev ${{ matrix.test.path }} # Run umbreld checks umbreld: name: umbreld checks runs-on: ubuntu-24.04 defaults: run: working-directory: packages/umbreld strategy: fail-fast: false matrix: task: - format:check - typecheck - test:unit -- --coverage steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup node uses: actions/setup-node@v3 with: node-version: 18 - name: Install dependencies run: sudo npm clean-install - run: sudo npm run ${{ matrix.task }} # Run ui checks ui: name: ui checks runs-on: ubuntu-24.04 defaults: run: working-directory: packages/ui strategy: fail-fast: false matrix: task: - lint - format:check - typecheck steps: - name: Checkout code uses: actions/checkout@v3 - name: Setup node uses: actions/setup-node@v3 with: node-version: 22 - name: Install Umbreld dependencies if: ${{ matrix.task == 'typecheck' }} run: npm --prefix ../umbreld clean-install - name: Install dependencies run: npm clean-install - run: npm run ${{ matrix.task }} # If the current build is tagged, build all release assets, push to Cloudflare R2 and create a GitHub Release create-release: name: Create release on tag if: startsWith(github.ref, 'refs/tags/') needs: [umbrelos-amd64-cache, umbrelos-arm64-cache] runs-on: ubicloud-standard-16-ubuntu-2404 defaults: run: working-directory: packages/os steps: - uses: actions/checkout@v3 - name: Set up Docker Buildx uses: docker/setup-buildx-action@v3 - name: Expose GitHub Actions runtime for Docker cache uses: crazy-max/ghaction-github-runtime@3cb05d89e1f492524af3d41a1c98c83bc3025124 # v3 - run: echo "VERSION=${GITHUB_REF#refs/*/}" >> $GITHUB_ENV # We need this to namespace Docker images on forks - run: echo "VERSION_IS_SEMVER=$(if [[ '${{ env.VERSION }}' =~ ^[0-9]+\.[0-9]+\.[0-9]+ ]]; then echo 'true'; else echo 'false'; fi)" >> $GITHUB_ENV - run: echo "PREFIX=$(if [ '${{ env.VERSION_IS_SEMVER }}' = 'true' ]; then echo ''; else echo $(basename ${{ github.repository }})-; fi)" >> $GITHUB_ENV - run: echo "TAG=${{ github.repository_owner }}/${{ env.PREFIX }}umbrelos:${{ env.VERSION }}" >> $GITHUB_ENV - run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ghcr.io -u "${{ github.repository_owner }}" --password-stdin - name: Build and push Docker image run: docker buildx build --platform linux/amd64,linux/arm64 --file umbrelos.Dockerfile --tag ghcr.io/${{env.TAG }} --push --cache-from type=gha,scope=umbrelos-amd64 --cache-from type=gha,scope=umbrelos-arm64 ../../ - run: mkdir -p build && docker buildx imagetools inspect ghcr.io/${{ env.TAG }} > build/docker-umbrelos-${{ env.VERSION }} # Build OS images - uses: actions/setup-node@v3 with: node-version: 18 - name: Build OS images # Awkward hack to run in parallel but correctly handle errors run: | npm run build:amd64 "${{ env.VERSION }}" & pid1=$! npm run build:arm64 "${{ env.VERSION }}" & pid2=$! wait $pid1 || exit 1 wait $pid2 || exit 1 # TODO: Use .img.xz for all release assets once https://github.com/balena-io/etcher/issues/4064 is fixed - name: Compress release assets # Awkward hack to run in parallel but correctly handle errors run: | cd build zip umbrelos-pi4.img.zip umbrelos-pi4.img & pid1=$! zip umbrelos-pi5.img.zip umbrelos-pi5.img & pid2=$! sudo xz --keep --threads=0 umbrelos-amd64.img & pid3=$! wait $pid1 || exit 1 wait $pid2 || exit 1 wait $pid3 || exit 1 - name: Create USB installer run: npm run build:amd64:usb-installer - name: Create release directory run: | mkdir -p release mv build/docker-umbrelos-* release/ mv build/*.update release/ mv build/*.img.zip release/ mv build/*.img.xz release/ mv build/*.img release/ mv usb-installer/build/*.iso release/ - name: Create SHASUM run: cd release && shasum -a 256 * | tee SHA256SUMS - name: OpenTimestamps run: npm ci && npx ots-cli.js stamp release/SHA256SUMS - name: Nuke uncompressed images (we just wanted them covered by the SHASUMs) run: rm -rf release/*.img - name: Upload to R2 uses: ryand56/r2-upload-action@b801a390acbdeb034c5e684ff5e1361c06639e7c # v1.4 with: r2-account-id: ${{ secrets.R2_ACCOUNT_ID }} r2-access-key-id: ${{ secrets.R2_ACCESS_KEY_ID }} r2-secret-access-key: ${{ secrets.R2_SECRET_ACCESS_KEY }} r2-bucket: ${{ secrets.R2_BUCKET }} source-dir: packages/os/release destination-dir: ./${{ env.VERSION }} - name: Create GitHub Release uses: softprops/action-gh-release@de2c0eb89ae2a093876385947365aca7b0e5f844 # v0.1.15 with: draft: true name: umbrelOS ${{ github.ref_name }} files: | packages/os/release/SHA256SUMS* ================================================ FILE: .github/workflows/update-translations-in-pr.yml ================================================ name: Update Translations in PR on: pull_request: types: [opened, synchronize, reopened] paths: - 'packages/ui/public/locales/en.json' concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true jobs: update-translations: timeout-minutes: 10 permissions: contents: write runs-on: ubuntu-22.04 steps: - name: Check if enabled run: | if [[ "${{ secrets.TRANSLATIONS_ACTION_IS_ENABLED }}" != "true" ]]; then echo "Translation generation is disabled." exit 1 fi - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 # Fetch full history for git comparisons ref: ${{ github.head_ref }} # Check out the PR's head branch - name: Fetch base branch run: | git fetch origin ${{ github.base_ref }}:${{ github.base_ref }} - name: Setup node uses: actions/setup-node@v4 with: node-version: '18' - name: Install dependencies run: | npm install working-directory: packages/ui - name: Update translations env: CI: 'true' GITHUB_BASE_REF: ${{ github.base_ref }} TRANSLATIONS_OPENAI_API_KEY: ${{ secrets.TRANSLATIONS_OPENAI_API_KEY }} TRANSLATIONS_OPENAI_MODEL: ${{ secrets.TRANSLATIONS_OPENAI_MODEL }} TRANSLATIONS_SYSTEM_PROMPT: ${{ secrets.TRANSLATIONS_SYSTEM_PROMPT }} TRANSLATIONS_USER_PROMPT: ${{ secrets.TRANSLATIONS_USER_PROMPT }} run: | node update-translations.js working-directory: packages/ui - name: Push changes uses: stefanzweifel/git-auto-commit-action@8621497c8c39c72f3e2a999a26b4ca1b5058a842 # v5.0.1 with: commit_message: Update translations ================================================ FILE: .gitignore ================================================ # Ignore node_modules anywhere they may be node_modules # Ignore all the bash stuff .bash_history .bash_logout .bashrc .profile .ssh .viminfo .DS_Store # Python bytecode __pycache__ *.py[cod] # umbrel-dev docker-compose.override.yml # Files and data directories created by services # that we shouldn't accidently commit *.dat *.log *.cookie *.pid *.env bitcoin/* db/* electrs/* nginx/* events/signals/* lnd/* logs/* statuses/* tor/* app-data/* data/ # Commit these files !statuses/update-status.json # Commit these empty directories !db/.gitkeep !events/signals/.gitkeep !lnd/.gitkeep !logs/.gitkeep !tor/data/.gitkeep !tor/run/.gitkeep .umbrel-dev jwt ./bin ================================================ FILE: .prettierrc.js ================================================ /** * @type {import('prettier').Config} */ export default { "printWidth": 120, "semi": false, "useTabs": true, "trailingComma": "all", "singleQuote": true, "bracketSpacing": false, "jsxSingleQuote": true, } ================================================ FILE: .umbrel ================================================ ================================================ FILE: CONTRIBUTING.md ================================================ Contributing to Umbrel ====================== Umbrel is an open project and we love to receive contributions from our community! There are many ways to contribute, from writing tutorials or blog posts, improving the documentation, submitting bug reports and feature requests or writing code which can be incorporated into Umbrel itself. Bug reports ----------- If you think you have found a bug in Umbrel, first make sure that you are on the [latest version of Umbrel](https://github.com/getumbrel/umbrel/releases/latest) because your issue may already have been fixed. If not, search our [issues list](https://github.com/getumbrel/umbrel/issues) on GitHub in case a similar issue has already been opened. If there's no existing issue, please open a new issue and provide us as much information about the bug as you can. It would be very helpful if you can list down the steps for us to reproduce the bug, because the easier it is for us to recreate the bug, the faster it is likely to be fixed. Feature requests ---------------- If you find yourself wishing for a feature that doesn't exist in Umbrel, you are probably not alone. There are bound to be others out there with similar needs. Please search our [issues list](https://github.com/getumbrel/umbrel/issues) on GitHub and our [community forum](https://community.umbrel.com). If you can't find an existing feature request, please open a new topic on the [community forum](https://community.umbrel.com) with your feature request. Contributing code and documentation changes ------------------------------------------- If you would like to contribute a new feature or a bugfix, please discuss your idea first on a GitHub issue. If there is no existing GitHub issue for your idea, please open one. There are often a number of ways to fix a problem and it is important to find the right approach before spending time on a PR that cannot be merged. So we request you to only start the work on implementing a feature once you received a green light from one of our maintainers on your idea and its implementation. We add the [help wanted](https://github.com/getumbrel/umbrel/labels/help%20wanted) label to existing GitHub issues for which community contributions are particularly welcome, and we use the [good first issue](https://github.com/getumbrel/umbrel/labels/good%20first%20issue) label to mark issues that we think will be suitable for new contributors. The process for contributing to any of the [Umbrel repositories](https://github.com/getumbrel/) is similar. ### Contributor License By submitting your contribution, you agree that all of your present and past contributions to us are licensed from you under the MIT license (text below) and do not require us to include your copyright notice. However, if you want to be on our contributor list, please leave us a message [here](https://keybase.io/team/getumbrel). ``` Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ``` ================================================ FILE: LICENSE.md ================================================ > Umbrel is licensed under the PolyForm Noncommercial License 1.0.0. Please refer to our [License FAQ](https://github.com/getumbrel/umbrel/wiki/License-FAQ) if you have any questions or reach out to us directly at support@umbrel.com. # PolyForm Noncommercial License 1.0.0 ## Acceptance In order to get any license under these terms, you must agree to them as both strict obligations and conditions to all your licenses. ## Copyright License The licensor grants you a copyright license for the software to do everything you might do with the software that would otherwise infringe the licensor's copyright in it for any permitted purpose. However, you may only distribute the software according to [Distribution License](#distribution-license) and make changes or new works based on the software according to [Changes and New Works License](#changes-and-new-works-license). ## Distribution License The licensor grants you an additional copyright license to distribute copies of the software. Your license to distribute covers distributing the software with changes and new works permitted by [Changes and New Works License](#changes-and-new-works-license). ## Notices You must ensure that anyone who gets a copy of any part of the software from you also gets a copy of these terms or the URL for them above, as well as copies of any plain-text lines beginning with `Required Notice:` that the licensor provided with the software. For example: > Required Notice: Copyright Yoyodyne, Inc. (http://example.com) ## Changes and New Works License The licensor grants you an additional copyright license to make changes and new works based on the software for any permitted purpose. ## Patent License The licensor grants you a patent license for the software that covers patent claims the licensor can license, or becomes able to license, that you would infringe by using the software. ## Noncommercial Purposes Any noncommercial purpose is a permitted purpose. ## Personal Uses Personal use for research, experiment, and testing for the benefit of public knowledge, personal study, private entertainment, hobby projects, amateur pursuits, or religious observance, without any anticipated commercial application, is use for a permitted purpose. ## Noncommercial Organizations Use by any charitable organization, educational institution, public research organization, public safety or health organization, environmental protection organization, or government institution is use for a permitted purpose regardless of the source of funding or obligations resulting from the funding. ## Fair Use You may have "fair use" rights for the software under the law. These terms do not limit them. ## No Other Rights These terms do not allow you to sublicense or transfer any of your licenses to anyone else, or prevent the licensor from granting licenses to anyone else. These terms do not imply any other licenses. ## Patent Defense If you make any written claim that the software infringes or contributes to infringement of any patent, your patent license for the software granted under these terms ends immediately. If your company makes such a claim, your patent license ends immediately for work on behalf of your company. ## Violations The first time you are notified in writing that you have violated any of these terms, or done anything with the software not covered by your licenses, your licenses can nonetheless continue if you come into full compliance with these terms, and take practical steps to correct past violations, within 32 days of receiving notice. Otherwise, all your licenses end immediately. ## No Liability ***As far as the law allows, the software comes as is, without any warranty or condition, and the licensor will not be liable to you for any damages arising out of these terms or the use or nature of the software, under any kind of legal claim.*** ## Definitions The **licensor** is the individual or entity offering these terms, and the **software** is the software the licensor makes available under these terms. **You** refers to the individual or entity agreeing to these terms. **Your company** is any legal entity, sole proprietorship, or other kind of organization that you work for, plus all organizations that have control over, are under the control of, or are under common control with that organization. **Control** means ownership of substantially all the assets of an entity, or the power to direct its management and policies by vote, contract, or otherwise. Control can be direct or indirect. **Your licenses** are all the licenses granted to you for the software under these terms. **Use** means anything you do with the software requiring one of your licenses. ================================================ FILE: README.md ================================================ [![umbrelOS](https://github.com/user-attachments/assets/cabf8af7-51ce-45df-ad3a-a664cc91c610)](https://umbrel.com/umbrelos)

umbrelOS

A beautiful home server OS for self-hosting
umbrel.com »

Get an Umbrel Pro or Umbrel Home for the full experience, or install umbrelOS on a Raspberry Pi 5 or any x86 system for free.


At Umbrel, we believe that everyone should be able to enjoy the convenience and benefits of the cloud, without giving up ownership and control of their data.

To achieve our vision, we're building a new kind of a home server OS. Instead of paying ransoms for storing your data on someone else's computer while they auction it off to advertisers — you can now easily spin up a server and self-host your data and services at home.

Just like the cloud, but one that you own and control.


## Installing umbrelOS umbrelOS is designed for the [Umbrel Pro](https://umbrel.com/umbrel-pro) and [Umbrel Home](https://umbrel.com/umbrel-home), where it includes first-class support for all features. On other devices (like Raspberry Pi or x86 systems), it’s freely available with core functionality, but support and feature availability are best-effort due to hardware differences. For a detailed feature breakdown, see our [comparison guide](https://github.com/getumbrel/umbrel/wiki/umbrelOS-on-Umbrel-Home-vs.-DIY). ### Installation guides - [Install umbrelOS on a Raspberry Pi 5](https://github.com/getumbrel/umbrel/wiki/Install-umbrelOS-on-a-Raspberry-Pi-5) - [Install umbrelOS on any x86 system](https://github.com/getumbrel/umbrel/wiki/Install-umbrelOS-on-x86-Systems) - [Install umbrelOS in a VM](https://github.com/getumbrel/umbrel/wiki/Install-umbrelOS-on-a-Linux-VM) [![umbrelOS use cases](https://github.com/user-attachments/assets/284feee7-15a1-48f2-a694-c968f1cc702f)](https://umbrel.com/umbrelos) [![Umbrel App Store](https://github.com/user-attachments/assets/3d7846c7-d896-48f5-8a30-3578554702fa)](https://apps.umbrel.com) [![Files on umbrelOS](https://github.com/user-attachments/assets/6c501256-47a0-4ce1-89ad-4ba02f4c9f2d)](https://umbrel.com/umbrelos) [![umbrelOS Features](https://github.com/user-attachments/assets/6828da74-2b64-4b56-a7b7-5db603d023c8)](https://umbrel.com/umbrelos) [![Backups in umbrelOS](https://github.com/user-attachments/assets/39778824-ed18-4f6f-a865-1d77bbfce833)](https://umbrel.com/umbrelos) [![External Storage & NAS in umbrelOS](https://github.com/user-attachments/assets/4841c2dc-4ba4-4d47-bf0a-0e342bf60166)](https://umbrel.com/umbrelos) ## Building apps for umbrelOS If you're interested in building an app for umbrelOS or packaging an existing one, please refer to the [Umbrel App Framework documentation](https://github.com/getumbrel/umbrel-apps/blob/master/README.md). ## License umbrelOS is licensed under the PolyForm Noncommercial 1.0.0 license. TL;DR — You're free to use, fork, modify, and redistribute Umbrel for personal and nonprofit use under the same license. If you're interested in using umbrelOS for commercial purposes, such as selling plug-and-play home servers with umbrelOS, etc — please reach out to us at partner@umbrel.com. [![License](https://img.shields.io/badge/license-PolyForm%20Noncommercial%201.0.0-%235351FB)](https://github.com/getumbrel/umbrel/blob/master/LICENSE.md) [umbrel.com](https://umbrel.com) ================================================ FILE: containers/app-auth/.dockerignore ================================================ Dockerfile node_modules .git .github test dist *.log ================================================ FILE: containers/app-auth/.gitignore ================================================ .DS_Store node_modules /dist # Log files npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw? # Local dev env .env.development # Local todo file .todo ================================================ FILE: containers/app-auth/Dockerfile ================================================ # UI build stage FROM node:18.19.1-buster-slim AS umbrel-app-auth-ui-builder # Set the working directory WORKDIR /app # Copy the package.json and package-lock.json COPY packages/ui/package.json ./ COPY packages/ui/package-lock.json ./ # Install the dependencies RUN npm ci # Copy the rest of the files COPY packages/ui/ . # Build the app RUN npm run app-auth:build # Expose the port EXPOSE 2003 # Start the app CMD ["npm", "run", "app-auth:start"] # Build Stage FROM node:16-buster-slim AS umbrel-app-auth-builder # Create app directory WORKDIR /app # Copy 'yarn.lock' and 'package.json' COPY containers/app-auth/yarn.lock containers/app-auth/package.json ./ # Install dependencies RUN yarn # Copy project files and folders to the current working directory (i.e. '/app') COPY containers/app-auth . # Final image FROM node:16-buster-slim AS umbrel-app-auth # Copy built code from build stage to '/app' directory COPY --from=umbrel-app-auth-builder /app /app # Copy built ui to /app/dist COPY --from=umbrel-app-auth-ui-builder /app/dist-app-auth /app/dist # Change directory to '/app' WORKDIR /app CMD [ "yarn", "start" ] ================================================ FILE: containers/app-auth/README.md ================================================ [![Umbrel App Auth](https://static.getumbrel.com/github/github-banner-umbrel-app-auth.svg)](https://github.com/getumbrel/umbrel-app-auth) [![Docker Build](https://img.shields.io/github/workflow/status/getumbrel/umbrel-app-auth/Docker%20build%20on%20push?color=%235351FB)](https://github.com/getumbrel/umbrel-app-auth/actions?query=workflow%3A"Docker+build+on+push") [![Docker Pulls](https://img.shields.io/docker/pulls/getumbrel/app-auth?color=%235351FB)](https://hub.docker.com/repository/registry-1.docker.io/getumbrel/app-auth/tags?page=1) # ☂️ App Auth App-auth is a simple authentication and redirection system for Umbrel apps. It ensures (where applicable) that apps are password (and OTP) protected. It runs by-default as a containerized service. ## 🚀 Getting started If you are looking to run Umbrel on your hardware, you do not need to run this service on it's own. Just download [Umbrel OS](https://github.com/getumbrel/umbrel-os/releases) and you're good to go. ## 🛠 Running app-auth Make sure [`umbrel-manager`](https://github.com/getumbrel/umbrel-manager) are running and available. ### Development and testing ```sh cd $UMBREL_ROOT/containers/app-auth/test ./test.sh ``` ### Environment variables (dev/testing) The following environment variables are set in `.env` file of the project's root: | Variable | Description | Default | | ------------- | ------------- | ------------- | | `PORT` | Web server port within container | `2000` | | `UMBREL_AUTH_SECRET` | A shared secret for manager, app-auth and app-proxy | `umbrel` | | `MANAGER_IP` | Umbrel's manager IP | `10.21.21.4` | | `MANAGER_PORT` | Umbrel's manager container port | `9005` | ================================================ FILE: containers/app-auth/bin/www ================================================ #!/usr/bin/env node const cookieParser = require("cookie-parser"); const express = require('express'); const { StatusCodes } = require('http-status-codes'); const authRoutes = require('../routes/auth.js'); const handleErrorMiddleware = require('../middleware/handle_error.js'); const CONSTANTS = require('../utils/const.js'); const app = express(); app.disable('x-powered-by'); app.set('view engine', 'ejs'); app.use(cookieParser(CONSTANTS.UMBREL_AUTH_SECRET)); app.use('/', authRoutes); app.use(handleErrorMiddleware); app.use((req, res) => { res.status(StatusCodes.NOT_FOUND).json(); }); app.listen(CONSTANTS.PORT, () => { console.log(`Listening on port: ${CONSTANTS.PORT}`); }); ================================================ FILE: containers/app-auth/middleware/handle_error.js ================================================ function handleError(error, req, res, next) { var statusCode = error.statusCode || 500; var route = req.url || ''; var message = error.message || ''; res.status(statusCode).json(message); } module.exports = handleError; ================================================ FILE: containers/app-auth/middleware/validate_token.js ================================================ const url = require('url'); const hmacUtils = require('../utils/hmac.js'); const tokenUtils = require('../utils/token.js'); const expressUtils = require('../utils/express.js'); const appUtils = require("../utils/app.js"); const hostResolution = require('../utils/host_resolution.js'); const CONSTANTS = require('../utils/const.js'); const APP_PROXY_AUTH_TOKEN_PATH = "/umbrel_/api/v1/auth/token"; async function redirectState(token, req) { const app = expressUtils.getQueryParam(req, "app"); const origin = expressUtils.getQueryParam(req, "origin"); const path = expressUtils.getQueryParam(req, "path"); // app ids are only allowed alpha-numeric characters // plus the hyphen (-) const appIdSanitised = appUtils.sanitiseId(app); // This builds up a url as to where // We're going to redirect/POST to const redirectUrl = url.format({ protocol: req.protocol, host: await hostResolution.host(req, appIdSanitised, origin), pathname: APP_PROXY_AUTH_TOKEN_PATH }); return { url: redirectUrl, params: { "r": path, "token": token, "signature": hmacUtils.sign(token, CONSTANTS.UMBREL_AUTH_SECRET) } }; } async function redirect(res, token, req) { res.render("pages/redirect", await redirectState(token, req)); } function mw () { return async function (req, res, next) { const token = req.cookies.UMBREL_PROXY_TOKEN; // If we already have a valid token // Then the user doesn't need to login again // We can redirect to the app with the token if(await tokenUtils.validate(token)) { await redirect(res, token, req); } else { next(); } }; } module.exports = { mw, redirect, redirectState }; ================================================ FILE: containers/app-auth/package.json ================================================ { "name": "app-auth", "version": "0.0.1", "private": true, "scripts": { "lint": "eslint", "start": "node ./bin/www", "test": "mocha 'test/**/*.js'", "coverage": "nyc --all mocha 'test/**/*.js'", "postcoverage": "codecov", "build": "docker buildx build --platform linux/amd64,linux/arm64 --tag getumbrel/auth-server --file Dockerfile ../../" }, "dependencies": { "animate.css": "^3.7.2", "axios": "^0.19.2", "bootstrap-vue": "^2.11.0", "cookie-parser": "^1.4.6", "core-js": "^3.4.4", "express": "^4.17.3", "http-status-codes": "^2.2.0", "js-yaml": "^4.1.0", "jsonwebtoken": "^9.0.2", "vue": "^2.6.10", "vue-router": "^3.1.3", "vuex": "^3.1.2" }, "devDependencies": { "@vue/cli-plugin-babel": "^4.1.0", "@vue/cli-plugin-eslint": "^4.1.0", "@vue/cli-plugin-router": "^4.1.0", "@vue/cli-plugin-vuex": "^4.1.0", "@vue/cli-service": "^4.1.0", "@vue/eslint-config-prettier": "^5.0.0", "babel-eslint": "^10.0.3", "chai": "^4.1.2", "chai-http": "^4.2.0", "codecov": "^3.7.1", "eslint": "^5.16.0", "eslint-plugin-prettier": "^3.1.1", "eslint-plugin-vue": "^5.0.0", "mocha": "^7.1.2", "nyc": "15.0.1", "prettier": "^1.19.1", "sass": "^1.23.7", "sass-loader": "^8.0.0", "vue-template-compiler": "^2.6.10" }, "eslintConfig": { "root": true, "env": { "node": true }, "extends": [ "plugin:vue/essential", "@vue/prettier" ], "rules": { "no-console": "off" }, "parserOptions": { "parser": "babel-eslint" } }, "browserslist": [ "> 1%", "last 2 versions" ] } ================================================ FILE: containers/app-auth/routes/auth.js ================================================ const express = require("express"); const axios = require("axios"); const { StatusCodes } = require("http-status-codes"); const fs = require("fs").promises; const yaml = require("js-yaml"); // const CONSTANTS = require("../utils/const.js"); const manager = require("../utils/manager.js"); const dashboard = require("../utils/dashboard.js"); const safeHandler = require("../utils/safe_handler.js"); const expressUtils = require("../utils/express.js"); const appUtils = require("../utils/app.js"); const validateToken = require("../middleware/validate_token.js"); const router = express.Router(); router.use(express.json()); // --- Public paths --- const publicPaths = [ // "/app-auth", "/assets", "/favicon", "/figma-exports", "/locales", "/wallpapers", // not needed // "/generated-tabler-icons" ]; publicPaths.forEach((path) => { router.use(path, express.static(`/app/dist${path}`)); }); router.get("/", safeHandler(validateToken.mw()), (req, res) => { res.sendFile("/app/dist/index.html"); }); // --- router.post( "/v1/account/login", safeHandler(async (req, res) => { let response; try { response = await axios.post( `http://${process.env.UMBRELD_RPC_HOST}/trpc/user.login`, req.body ); } catch (e) { console.log({ e }); if (e.isAxiosError === true) { return res.status(e.response.status).send(e.response.data); } throw e; } let proxyToken = ""; const setCookieHeader = response.headers["set-cookie"]; if (setCookieHeader) { // `set-cookie` header can be an array if multiple cookies are set setCookieHeader.forEach((cookie) => { if (cookie.startsWith("UMBREL_PROXY_TOKEN=")) { proxyToken = cookie.split(";")[0].split("=")[1]; } }); } if (proxyToken) { const ONE_SECOND = 1000; const ONE_MINUTE = 60 * ONE_SECOND; const ONE_HOUR = 60 * ONE_MINUTE; const ONE_DAY = 24 * ONE_HOUR; const ONE_WEEK = 7 * ONE_DAY; const expires = new Date(Date.now() + ONE_WEEK); res .cookie("UMBREL_PROXY_TOKEN", proxyToken, { httpOnly: true, expires, sameSite: "lax", }) .json(await validateToken.redirectState(proxyToken, req)); } else { // This case should never happen as an error is thrown // if the credentials are bad and is handled above (catch block) res.status(StatusCodes.UNAUTHORIZED).send("Failed to authenticate"); } }) ); // Get wallpaper (public) router.get( "/v1/account/wallpaper", safeHandler(async (req, res) => { const store = yaml.load(await fs.readFile("/data/umbrel.yaml")); const { wallpaper } = store.user; res.send(wallpaper); }) ); // Get basic info for an app router.get( "/v1/apps", safeHandler(async (req, res) => { const appIdSanitised = appUtils.sanitiseId( expressUtils.getQueryParam(req, "app") ); res.send(await appUtils.getBasicInfo(appIdSanitised)); }) ); // TODO: remove router.get( "/wallpapers/:filename(\\d+[.]\\w+)", safeHandler(async (req, res) => { const response = await dashboard.wallpaper.get(req.params.filename); response.data.pipe(res); }) ); module.exports = router; ================================================ FILE: containers/app-auth/test/docker-compose.yml ================================================ version: '3.7' services: auth: image: getumbrel/app-auth1 user: "1000:1000" build: context: .. dockerfile: Dockerfile.dev ports: - "2001:2000" environment: PORT: 2000 UMBREL_AUTH_SECRET: umbrel MANAGER_IP: $MANAGER_IP MANAGER_PORT: 3006 volumes: - ..:/app - ./fixtures/tor/data:/var/lib/tor:ro - ./fixtures/app-data:/app-data:ro networks: default: external: name: umbrel_main_network ================================================ FILE: containers/app-auth/test/fixtures/app-data/mempool/umbrel-app.yml ================================================ id: mempool category: Explorers name: mempool version: 2.3.1 tagline: A self-hosted explorer for the Bitcoin community description: |- Trusted third parties are security holes. Self-host your own instance of mempool.space on Umbrel for maximum privacy. Features: - Live dashboard visualizing the mempool and blockchain - Live transaction tracking - Search any transaction, block or address - Fee estimations - Mempool historical data - TV View for larger displays as a TV in a cafe or bar - View transaction scripts and op_return messages - Audio notifications on transaction confirmed and address balance change - Multiple languages support - JSON APIs developer: Mempool Space K.K. website: https://mempool.space/about dependencies: - bitcoind - electrum repo: https://github.com/mempool/mempool support: https://mempool.support port: 4006 gallery: - 1.jpg - 2.jpg - 3.jpg path: '' defaultUsername: '' defaultPassword: '' ================================================ FILE: containers/app-auth/test/global.js ================================================ const chai = require('chai'); const chaiHttp = require('chai-http'); chai.use(chaiHttp); chai.should(); global.expect = chai.expect; global.assert = chai.assert; before(() => { }); global.reset = () => { }; after(() => { }); ================================================ FILE: containers/app-auth/test/test.sh ================================================ #!/bin/bash export MANAGER_IP="10.21.21.4" docker-compose up ================================================ FILE: containers/app-auth/test/utils/hmac.js ================================================ const hmac = require("../../utils/hmac.js"); describe('hmac', () => { it('should sign the message', () => { assert.equal("4oCtD/Y2Xfb8J/tvCw9mrsRmMekbirseumiW4JrFahI=", hmac.sign("hello world", "my-secret-123")); assert.equal("qENA22U3zGY2ZhBPh9Tes+Fjt/SS8pjvL6d2Z0ZMTJk=", hmac.sign("https://xkcd.com/386/", "my-secret-123")); assert.equal("+fSwPHNg4EtsNpso1Iope7g3A7pPbTZubygel/9WdYc=", hmac.sign("https://xkcd.com/386/", "another-secret")); }); it('should verify the signature for a message', () => { assert.isTrue(hmac.verify("https://xkcd.com/386/", "my-secret-123", "qENA22U3zGY2ZhBPh9Tes+Fjt/SS8pjvL6d2Z0ZMTJk=")); assert.isTrue(hmac.verify("https://xkcd.com/386/", "another-secret", "+fSwPHNg4EtsNpso1Iope7g3A7pPbTZubygel/9WdYc=")); assert.isFalse(hmac.verify("https://xkcd.com/386/something/random", "another-secret", "+fSwPHNg4EtsNpso1Iope7g3A7pPbTZubygel/9WdYc=")); }); }); ================================================ FILE: containers/app-auth/utils/app.js ================================================ const fs = require('fs').promises; const path = require('path'); const yaml = require('js-yaml'); const CONSTANTS = require('./const.js'); async function getBasicInfo(app){ try { const manifestFile = path.join(CONSTANTS.APP_DATA_PATH, app, 'umbrel-app.yml'); const manifestYaml = await fs.readFile(manifestFile, "utf-8"); const manifest = yaml.load(manifestYaml, 'utf8'); return { id: manifest.id, name: manifest.name }; } catch(e) { throw new Error("App not found"); } } // App IDs are only allowed // Alpha-numeric characters with hyphens function sanitiseId(appId){ return appId.replace(/[^a-zA-Z0-9-]/g, ""); } module.exports = { getBasicInfo, sanitiseId }; ================================================ FILE: containers/app-auth/utils/const.js ================================================ function readFromEnvOrTerminate(key) { const value = process.env[key]; if(typeof(value) !== "string" || value.trim().length === 0) { console.error(`The env. variable '${key}' is not set. Terminating...`); process.exit(0); } return value; } module.exports = Object.freeze({ UMBREL_COOKIE_NAME: "UMBREL_SESSION", LOG_LEVEL: process.env.LOG_LEVEL || "info", PORT: parseInt(process.env.PORT) || 2000, UMBREL_AUTH_SECRET: readFromEnvOrTerminate("UMBREL_AUTH_SECRET"), TOR_PATH: process.env.TOR_PATH || "/var/lib/tor", APP_DATA_PATH: process.env.APP_DATA_PATH || "/app-data", MANAGER_IP: readFromEnvOrTerminate("MANAGER_IP"), MANAGER_PORT: parseInt(readFromEnvOrTerminate("MANAGER_PORT")), DASHBOARD_IP: readFromEnvOrTerminate("DASHBOARD_IP"), DASHBOARD_PORT: parseInt(readFromEnvOrTerminate("DASHBOARD_PORT")), }); ================================================ FILE: containers/app-auth/utils/dashboard.js ================================================ const axios = require('axios'); const package = require('../package.json'); const CONSTANTS = require('./const.js'); const axiosInstance = axios.create({ baseURL: `http://${CONSTANTS.DASHBOARD_IP}:${CONSTANTS.DASHBOARD_PORT}`, headers: { common: { "User-Agent": `${package.name}/${package.version}` } } }); const wallpaper = { get: async function(filename) { return axiosInstance({ method: 'GET', url: `/wallpapers/${filename}`, responseType: 'stream' }); } }; module.exports = { wallpaper }; ================================================ FILE: containers/app-auth/utils/express.js ================================================ function getQueryParam(req, key) { const value = req.query[key]; if(typeof(value) !== "string" || value.trim().length == 0) { throw new Error(`'${key}' is missing`); } return value; } module.exports = { getQueryParam }; ================================================ FILE: containers/app-auth/utils/hmac.js ================================================ const crypto = require('crypto'); function sign(input, secret) { return crypto .createHmac('sha256', secret) .update(input) .digest('base64'); }; function verify(input, secret, signature){ const inputSignature = Buffer.from( sign(input, secret) ); const testSignature = Buffer.from( signature ); return inputSignature.length === testSignature.length && crypto.timingSafeEqual(inputSignature, testSignature); }; module.exports = { sign, verify }; ================================================ FILE: containers/app-auth/utils/host_resolution.js ================================================ const fs = require('fs').promises; const path = require('path'); const yaml = require('js-yaml'); const CONSTANTS = require('./const.js'); async function getTorHostname(app) { const torHostnameFile = path.join(CONSTANTS.TOR_PATH, `app-${app}`, "hostname"); return (await fs.readFile(torHostnameFile, "utf-8")).trim(); } async function getAppPort(app) { const appManifestFile = path.join(CONSTANTS.APP_DATA_PATH, app, 'umbrel-app.yml'); const appManifestYaml = await fs.readFile(appManifestFile, "utf-8"); const appManifest = yaml.load(appManifestYaml, 'utf8'); return appManifest.port; } async function host(req, app, origin) { try { switch(origin) { case "tor": return (await getTorHostname(app)); case "host": const appPort = (await getAppPort(app)); return `${req.hostname}:${appPort}`; } } catch (e) { throw new Error("Failed to determine host"); } throw new Error("Unsupported origin"); } module.exports = { host }; ================================================ FILE: containers/app-auth/utils/manager.js ================================================ const axios = require('axios'); const package = require('../package.json'); const CONSTANTS = require('./const.js'); const axiosInstance = axios.create({ baseURL: `http://${CONSTANTS.MANAGER_IP}:${CONSTANTS.MANAGER_PORT}`, headers: { common: { "User-Agent": `${package.name}/${package.version}` } } }); const account = { login: async function(body) { return axiosInstance.post('/v1/account/login', body); }, token: async function(token) { return axiosInstance.get('/v1/account/token', { params: { token } }); }, wallpaper: async function(token) { return axiosInstance.get('/v1/account/wallpaper'); } }; module.exports = { account }; ================================================ FILE: containers/app-auth/utils/safe_handler.js ================================================ // this safe handler is used to wrap our api methods // so that we always fallback and return an exception if there is an error // inside of an async function // Mostly copied from vault/server/utils/safeHandler.js function safeHandler(handler) { return async (req, res, next) => { try { return await handler(req, res, next); } catch (err) { return next(err); } }; } module.exports = safeHandler; ================================================ FILE: containers/app-auth/utils/token.js ================================================ const jwt = require("jsonwebtoken"); const JWT_ALGORITHM = "HS256"; const secret = process.env.JWT_SECRET; function validate(token) { if (typeof token !== "string") return false; console.log(`Validating token: ${token.substr(0, 12)} ...`); const payload = jwt.verify(token, secret, { algorithms: [JWT_ALGORITHM], }); return payload.proxyToken === true; } module.exports = { validate, }; ================================================ FILE: containers/app-auth/views/pages/redirect.ejs ================================================ Redirecting...
<% for (var key in params ) { %> <% } %>
================================================ FILE: containers/app-proxy/.dockerignore ================================================ Dockerfile node_modules .git .github test ================================================ FILE: containers/app-proxy/.gitignore ================================================ .DS_Store node_modules /dist # Log files npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw? # Local dev env .env.development # Local todo file .todo ================================================ FILE: containers/app-proxy/Dockerfile ================================================ # Build Stage FROM node:16-buster-slim AS umbrel-app-proxy-builder # Create app directory WORKDIR /app # Copy 'yarn.lock' and 'package.json' COPY yarn.lock package.json ./ # Install dependencies RUN yarn install --production # Copy project files and folders to the current working directory (i.e. '/app') COPY . . # Final image FROM node:16-buster-slim AS umbrel-app-proxy # Copy built code from build stage to '/app' directory COPY --from=umbrel-app-proxy-builder /app /app # Change directory to '/app' WORKDIR /app CMD [ "yarn", "start" ] ================================================ FILE: containers/app-proxy/Dockerfile.dev ================================================ FROM node:16-buster-slim # make the 'app' folder the current working directory WORKDIR /app ENTRYPOINT ["bash"] CMD ["-c", "yarn && yarn start"] ================================================ FILE: containers/app-proxy/README.md ================================================ [![Umbrel App Proxy](https://static.getumbrel.com/github/github-banner-umbrel-app-proxy.svg)](https://github.com/getumbrel/umbrel-app-proxy) [![Docker Build](https://img.shields.io/github/workflow/status/getumbrel/umbrel-app-proxy/Docker%20build%20on%20push?color=%235351FB)](https://github.com/getumbrel/umbrel-app-proxy/actions?query=workflow%3A"Docker+build+on+push") [![Docker Pulls](https://img.shields.io/docker/pulls/getumbrel/app-proxy?color=%235351FB)](https://hub.docker.com/repository/registry-1.docker.io/getumbrel/app-proxy/tags?page=1) # ☂️ App Proxy App-proxy is a transparent HTTP proxy to add authentication to Umbrel apps. Every HTTP request and Websocket connection goes through the proxy and each request has the session token checked for validity. The session token is set via [App-auth](https://github.com/getumbrel/umbrel/tree/master/containers/app-auth). It runs by-default as a containerized service. ## 🚀 Getting started If you are looking to run Umbrel on your hardware, you do not need to run this service on it's own. Just download [Umbrel OS](https://github.com/getumbrel/umbrel-os/releases) and you're good to go. ## 🛠 Running app-proxy Make sure [`umbrel-manager`](https://github.com/getumbrel/umbrel-manager) and [`app-auth`](https://github.com/getumbrel/umbrel/tree/master/containers/app-auth) are running and available. ### Development and testing ```sh cd $UMBREL_ROOT/containers/app-proxy/test ./test.sh docker-compose.app1.yml ``` Within the `test` directory there are several test apps to test different functionality such as Websocket and SSE with the proxy. ### Environment variables (dev/testing) The following environment variables are set in `.env` file of the project's root: | Variable | Description | Default | | --------------------------------- | ----------------------------------------------------------------------------- | ---------------------------- | | `LOG_LEVEL` | Log level for the proxy (`http-proxy-middleware`) | `info` | | `PROXY_PORT` | HTTP proxy container port | `4000` | | `PROXY_AUTH_ADD` | `true`/`false` as to whether the app should be protected with authentication | `true` | | `PROXY_AUTH_WHITELIST` | A comma seperated list of paths that are whitelisted (e.g. `/public/*`) | | | `PROXY_AUTH_BLACKLIST` | A comma seperated list of paths that are whitelisted (e.g. `/admin/*,/api/*`) | | | `APP_HOST` | App's frontend container hostname/IP | | | `APP_PORT` | App's frontend container port | | | `APP_MANIFEST_FILE` | Location of app's manifest file | `/extra/umbrel-app.yml` | | `UMBREL_AUTH_PORT` | App-auth's exposed (port-forwarded) port | `2000` | | `UMBREL_AUTH_SECRET` | A shared secret for manager, app-auth and app-proxy | `umbrel` | | `UMBREL_AUTH_HIDDEN_SERVICE_FILE` | Location of app-auth's Tor HS hostname | `/var/lib/tor/auth/hostname` | | `MANAGER_IP` | Umbrel's manager IP | `10.21.21.4` | | `MANAGER_PORT` | Umbrel's manager container port | `9005` | ================================================ FILE: containers/app-proxy/bin/www ================================================ #!/usr/bin/env node const cookieParser = require('cookie-parser'); const express = require('express'); const waitPort = require('wait-port'); const proxy = require('../utils/proxy.js'); const umbrelRoutes = require('../routes/umbrel.js'); const handleErrorMiddleware = require('../middleware/handle_error.js'); const CONSTANTS = require('../utils/const.js'); const app = express(); app.disable('x-powered-by'); app.set('view engine', 'ejs'); app.use(cookieParser(CONSTANTS.UMBREL_AUTH_SECRET)); app.use('/umbrel_', umbrelRoutes); app.use(handleErrorMiddleware); const middleware = proxy.apply(app); // We'll only open the app proxy's port // Once the app's port is open console.log(`Waiting for ${CONSTANTS.APP_HOST}:${CONSTANTS.APP_PORT} to open...`); const delay = ms => new Promise(resolve => setTimeout(resolve, ms)); (async () => { while(true) { try { await waitPort({ host: CONSTANTS.APP_HOST, port: CONSTANTS.APP_PORT, output: "silent", // Wait indefinitely for the app to start timeout: 0 }); // Exit loop on success break; } catch (error) { console.log(`Error waiting for port: "${error.message}"`); // Wait before retrying await delay(100); console.log('Retrying...'); } } console.log(`${CONSTANTS.APP.name} is now ready...`); const server = app.listen(CONSTANTS.PROXY_PORT, () => { console.log(`Listening on port: ${CONSTANTS.PROXY_PORT}`); }); // This allows it to proxy WebSockets without the initial http request server.on('upgrade', middleware.upgrade); })(); ================================================ FILE: containers/app-proxy/middleware/handle_error.js ================================================ function handleError(error, req, res, next) { var statusCode = error.statusCode || 500; var route = req.url || ''; var message = error.message || ''; res.status(statusCode).json(message); } module.exports = handleError; ================================================ FILE: containers/app-proxy/package.json ================================================ { "name": "app-proxy", "version": "0.0.1", "private": true, "scripts": { "lint": "eslint", "start": "node ./bin/www", "test": "mocha 'test/**/*.js'", "coverage": "nyc --all mocha 'test/**/*.js'", "postcoverage": "codecov", "build": "docker buildx build --platform linux/amd64,linux/arm64 --tag getumbrel/app-proxy ." }, "dependencies": { "axios": "^0.26.1", "cookie-parser": "^1.4.6", "dotenv": "^16.0.0", "ejs": "^3.1.6", "express": "^4.17.3", "express-validator": "^6.14.0", "http-proxy-middleware": "^2.0.4", "http-status-codes": "^2.2.0", "js-yaml": "^4.1.0", "jsonwebtoken": "^9.0.2", "wait-port": "^0.2.9" }, "devDependencies": { "babel-eslint": "^10.1.0", "chai": "^4.1.2", "chai-http": "^4.2.0", "codecov": "^3.7.1", "eslint": "^7.0.0", "mocha": "^7.1.2", "node-mocks-http": "^1.11.0", "nyc": "15.0.1" } } ================================================ FILE: containers/app-proxy/routes/umbrel.js ================================================ const { StatusCodes } = require("http-status-codes"); const bodyParser = require("body-parser"); const express = require("express"); const validator = require("express-validator"); const router = express.Router(); const CONSTANTS = require("../utils/const.js"); const tokenUtils = require("../utils/token.js"); const hmacUtils = require("../utils/hmac.js"); const safeHandler = require("../utils/safe_handler.js"); const ONE_SECOND = 1000; const ONE_MINUTE = 60 * ONE_SECOND; const ONE_HOUR = 60 * ONE_MINUTE; const ONE_DAY = 24 * ONE_HOUR; const ONE_WEEK = 7 * ONE_DAY; const parseForm = bodyParser.urlencoded({ extended: false }); router.use(parseForm); router.post( "/api/v1/auth/token", [ validator.body("token").isString(), validator.body("signature").isString(), validator.body("r").isString(), ], safeHandler(async (req, res) => { const errors = validator.validationResult(req); if (!errors.isEmpty()) { return res.status(StatusCodes.BAD_REQUEST).json({ errors: errors.array(), }); } const token = req.body.token; const signature = req.body.signature; const redirectTo = req.body.r; // Before we validate the token, lets check the hmac if (!hmacUtils.verify(token, CONSTANTS.UMBREL_AUTH_SECRET, signature)) { return res .status(StatusCodes.INTERNAL_SERVER_ERROR) .send(`The signature is invalid`); } // Check that the token is valid before setting cookie... if (!(await tokenUtils.validate(token))) { return res .status(StatusCodes.INTERNAL_SERVER_ERROR) .send(`The token is invalid`); } const expires = new Date(Date.now() + ONE_WEEK); res.cookie("UMBREL_PROXY_TOKEN", token, { httpOnly: true, expires, sameSite: "lax", }); res.redirect(redirectTo); }) ); module.exports = router; ================================================ FILE: containers/app-proxy/test/.gitignore ================================================ apps/ ================================================ FILE: containers/app-proxy/test/docker-compose.app1.yml ================================================ version: '3.7' services: app_proxy: environment: APP_HOST: nginxdemo APP_PORT: 80 PROXY_AUTH_WHITELIST: "*" PROXY_AUTH_BLACKLIST: "/admin/*,/admin2/*" nginxdemo: image: nginxdemos/hello ================================================ FILE: containers/app-proxy/test/docker-compose.app2.yml ================================================ version: '3.7' services: app_proxy: environment: APP_HOST: frontend APP_PORT: 8888 frontend: image: mendhak/http-https-echo environment: HTTP_PORT: 8888 ================================================ FILE: containers/app-proxy/test/docker-compose.bleskomat.yml ================================================ version: "3.7" services: app_proxy: environment: APP_HOST: bleskomat_web APP_PORT: 3333 PROXY_AUTH_ADD: "false" bleskomat_db: image: postgres:10.20-stretch@sha256:130e08bb19199bd055e585e8938c5ebb0555dc13b445fad5b0bd727e4b75149c user: "1000:1000" restart: on-failure stop_grace_period: 1m volumes: - ./apps/bleskomat/data/db:/var/lib/postgresql/data environment: - POSTGRES_USER=bleskomat_server - POSTGRES_DB=bleskomat_server - POSTGRES_PASSWORD=moneyprintergobrrr bleskomat_web: image: bleskomat/bleskomat-server:1.3.4@sha256:7bd91b896c5ca4f69b7c9509b40ccfae273cc46120ec66b2e27b295b0186f230 user: "1000:1000" restart: on-failure stop_grace_period: 1m depends_on: - bleskomat_db volumes: - ./apps/bleskomat/data/web:/usr/src/app/data - ./apps/bleskomat/data/lnd:/lnd:ro ports: - "3334:3333" environment: DEBUG: "bleskomat-server*,lnurl*" BLESKOMAT_SERVER_HOST: "0.0.0.0" BLESKOMAT_SERVER_PORT: "3333" BLESKOMAT_SERVER_URL: "test.onion" BLESKOMAT_SERVER_ENDPOINT: "/u" BLESKOMAT_SERVER_AUTH_API_KEYS: '[]' BLESKOMAT_SERVER_LIGHTNING: '{"backend":"lnd","config":{"cert":"/lnd/tls.cert","protocol":"https","hostname":"lnd:12345","macaroon":"/lnd/admin.macaroon"}}' BLESKOMAT_SERVER_STORE: '{"backend":"knex","config":{"client":"postgres","connection":{"host":"bleskomat_db","port":5432,"user":"bleskomat_server","password":"moneyprintergobrrr","database":"bleskomat_server"}}}' BLESKOMAT_SERVER_COINRATES_DEFAULTS_PROVIDER: "coinbase" BLESKOMAT_SERVER_ADMIN_WEB: "true" BLESKOMAT_SERVER_ADMIN_PASSWORD_PLAINTEXT: "$APP_PASSWORD" BLESKOMAT_SERVER_ENV_FILEPATH: "./data/.env" ================================================ FILE: containers/app-proxy/test/docker-compose.error.yml ================================================ version: '3.7' services: app_proxy: environment: APP_HOST: app_wrong APP_PORT: 80 PROXY_AUTH_WHITELIST: "*" app: image: nginxdemos/hello ================================================ FILE: containers/app-proxy/test/docker-compose.mempool.yml ================================================ version: "3.7" services: app_proxy: environment: APP_HOST: web_mempool APP_PORT: 3006 PROXY_AUTH_WHITELIST: "/admin/" web_mempool: image: mempool/frontend:v2.3.1@sha256:38c955caeb58014b266904b059bfabbdab8321d20b11e7cccb139be6dfc8e36e user: "1000:1000" init: true restart: on-failure stop_grace_period: 1m command: "./wait-for mariadb:3306 --timeout=720 -- nginx -g 'daemon off;'" environment: FRONTEND_HTTP_PORT: 3006 BACKEND_MAINNET_HTTP_HOST: "api" api: image: mempool/backend:v2.3.1@sha256:f7b16a6b00ea8aabf3b71a34ec05bb373fa0b6f1d31c7981b767edb2d1b7cf89 user: "1000:1000" init: true restart: on-failure stop_grace_period: 1m command: "./wait-for-it.sh mariadb:3306 --timeout=720 --strict -- ./start.sh" volumes: - ./apps/mempool/data:/backend/cache environment: ELECTRUM_TLS: "false" DATABASE_HOST: "mariadb" DATABASE_PORT: "3306" DATABASE_DATABASE: "mempool" DATABASE_USERNAME: "mempool" DATABASE_PASSWORD: "mempool" MEMPOOL_HTTP_PORT: "8999" MEMPOOL_CACHE_DIR: "/backend/cache" MEMPOOL_CLEAR_PROTECTION_MINUTES: "20" mariadb: image: mariadb:10.5.12@sha256:dfcba5641bdbfd7cbf5b07eeed707e6a3672f46823695a0d3aba2e49bbd9b1dd user: "1000:1000" restart: on-failure stop_grace_period: 1m volumes: - ./apps/mempool/mysql/data:/var/lib/mysql environment: MYSQL_DATABASE: "mempool" MYSQL_USER: "mempool" MYSQL_PASSWORD: "mempool" MYSQL_ROOT_PASSWORD: "moneyprintergobrrr" ================================================ FILE: containers/app-proxy/test/docker-compose.nextcloud.yml ================================================ version: "3.7" services: app_proxy: environment: - APP_HOST=web - APP_PORT=80 db: image: mariadb:10.5.12@sha256:dfcba5641bdbfd7cbf5b07eeed707e6a3672f46823695a0d3aba2e49bbd9b1dd user: "1000:1000" command: --transaction-isolation=READ-COMMITTED --binlog-format=ROW restart: on-failure volumes: - ./apps/nextcloud/data/db:/var/lib/mysql environment: - MYSQL_ROOT_PASSWORD=moneyprintergobrrr - MYSQL_PASSWORD=moneyprintergobrrr - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud redis: image: redis:6.2.2-buster@sha256:e10f55f92478715698a2cef97c2bbdc48df2a05081edd884938903aa60df6396 user: "1000:1000" restart: on-failure volumes: - "./apps/nextcloud/data/redis:/data" web: image: nextcloud:22.1.1-apache@sha256:99d94124b2024c9f7f38dc12144a92bc0d68d110bcfd374169ebb7e8df0adf8e # Currently needs to be run as root, if we run as uid 1000 this fails # https://github.com/nextcloud/docker/blob/05026b029d37fc5cd488d4a4a2a79480e39841ba/21.0/apache/entrypoint.sh#L53-L77 # user: "1000:1000" restart: on-failure volumes: - ./apps/nextcloud/data/nextcloud:/var/www/html environment: - MYSQL_HOST=db - REDIS_HOST=redis - MYSQL_PASSWORD=moneyprintergobrrr - MYSQL_DATABASE=nextcloud - MYSQL_USER=nextcloud - NEXTCLOUD_ADMIN_USER=umbrel - NEXTCLOUD_ADMIN_PASSWORD=${APP_PASSWORD} - NEXTCLOUD_TRUSTED_DOMAINS=${APP_DOMAIN}:${APP_PORT} depends_on: - db - redis cron: image: nextcloud:22.0.0-apache@sha256:55de721417c16ff110720217406778e16f1b63154d2e8d42fc7913c37dbe6d50 # Currently needs to be run as root, if we run as uid 1000 this fails # https://github.com/nextcloud/docker/blob/05026b029d37fc5cd488d4a4a2a79480e39841ba/21.0/apache/entrypoint.sh#L53-L77 # user: "1000:1000" restart: on-failure volumes: - ./apps/nextcloud/data/nextcloud:/var/www/html entrypoint: /cron.sh depends_on: - db - redis ================================================ FILE: containers/app-proxy/test/docker-compose.proxy.yml ================================================ version: '3.7' services: caddy: image: caddy:2.5.1 command: caddy reverse-proxy --from :4007 --to app_proxy:4000 ports: - "4007:4007" app_proxy: environment: APP_HOST: frontend APP_PORT: 8888 PROXY_AUTH_WHITELIST: "*" PROXY_TRUST_UPSTREAM: "true" frontend: image: mendhak/http-https-echo environment: HTTP_PORT: 8888 ================================================ FILE: containers/app-proxy/test/docker-compose.proxyhttps.yaml ================================================ version: '3.7' services: caddy: image: caddy:2.5.1 volumes: - "./test/Caddyfile-https:/etc/caddy/Caddyfile" ports: - "4007:4007" app_proxy: environment: APP_HOST: frontend APP_PORT: 8888 PROXY_AUTH_WHITELIST: "*" PROXY_TRUST_UPSTREAM: "true" frontend: image: mendhak/http-https-echo environment: HTTP_PORT: 8888 ================================================ FILE: containers/app-proxy/test/docker-compose.sse.yml ================================================ version: '3.7' services: app_proxy: environment: APP_HOST: sse_server APP_PORT: 80 PROXY_AUTH_WHITELIST: "*" sse_server: image: getumbrel/sse-test-server build: ./sse-test-server ================================================ FILE: containers/app-proxy/test/docker-compose.suredbits.yml ================================================ version: "3.7" services: app_proxy: environment: APP_HOST: web APP_PORT: 3002 web: image: bitcoinscala/wallet-server-ui:1.9.1@sha256:3eb479b106811d523c4e0cfde244949f6c76a27c7d1fe59be9b8b51ba2372649 user: "1000:1000" restart: on-failure stop_grace_period: 1m volumes: - ./apps/suredbits/data/wallet:/home/bitcoin-s/.bitcoin-s - ./apps/suredbits/data/log:/log environment: LOG_PATH: "/log/" BITCOIN_S_HOME: "/home/bitcoin-s/.bitcoin-s/" MEMPOOL_API_URL: "http://umbrel.local:3004/api" WALLET_SERVER_API_URL: "http://walletserver:9999/" WALLET_SERVER_WS: "ws://walletserver:19999/events" TOR_PROXY: socks5://localhost:5555 DEFAULT_UI_PASSWORD: "password123" BITCOIN_S_SERVER_RPC_PASSWORD: "password123" depends_on: - walletserver walletserver: image: bitcoinscala/bitcoin-s-server:1.9.1-34-3dc70938-SNAPSHOT@sha256:1cd82d19059382f740f7b8acbc2d3aaeaf0c1fd7c662bdbc3ef7b97a27ee181f user: "1000:1000" restart: on-failure volumes: - ./apps/suredbits/data/wallet:/home/bitcoin-s/.bitcoin-s environment: BITCOIN_S_NODE_MODE: "bitcoind" BITCOIN_S_NETWORK: "regtest" BITCOIN_S_KEYMANAGER_ENTROPY: "a75a58071bd4c65a1e87c1b970e9d736d9185a427a4f3110d250ea3945d9108d" BITCOIN_S_PROXY_ENABLED: "false" BITCOIN_S_TOR_ENABLED: "false" BITCOIN_S_TOR_PROVIDED: "true" BITCOIN_S_DLCNODE_PROXY_ENABLED: "true" BITCOIN_S_DLCNODE_PROXY_SOCKS5: "localhost:5555" BITCOIN_S_DLCNODE_EXTERNAL_IP: "hiddenservice.onion" BITCOIN_S_BITCOIND_HOST: "bitcoind" BITCOIN_S_BITCOIND_PORT: "18443" BITCOIN_S_BITCOIND_USER: "umbrel" BITCOIN_S_BITCOIND_PASSWORD: "bitcoinbitcoin" BITCOIN_S_SERVER_RPC_PASSWORD: "password123" ports: - "2862:2862" bitcoind: image: lncm/bitcoind:v22.0@sha256:37a1adb29b3abc9f972f0d981f45e41e5fca2e22816a023faa9fdc0084aa4507 command: "${APP_BITCOIN_COMMAND}" restart: on-failure stop_grace_period: 15m30s volumes: - ./apps/suredbits/data/bitcoin:/data/.bitcoin ================================================ FILE: containers/app-proxy/test/docker-compose.ws.yml ================================================ version: '3.7' services: app_proxy: environment: APP_HOST: ws_server APP_PORT: 8010 ws_server: image: ksdn117/web-socket-test ================================================ FILE: containers/app-proxy/test/docker-compose.yml ================================================ version: '3.7' services: app_proxy: image: getumbrel/app-proxy build: context: .. dockerfile: Dockerfile.dev user: "1000:1000" restart: on-failure ports: - "${APP_PORT}:4000" volumes: - ..:/app - ./fixtures/mempool-umbrel-app.yml:/extra/umbrel-app.yml:ro - ./fixtures/tor/data:/var/lib/tor:ro - ./data:/app-data:ro environment: LOG_LEVEL: debug PROXY_PORT: 4000 PROXY_AUTH_ADD: "true" PROXY_AUTH_WHITELIST: PROXY_AUTH_BLACKLIST: PROXY_TRUST_UPSTREAM: APP_HOST: APP_PORT: APP_MANIFEST_FILE: "/extra/umbrel-app.yml" UMBREL_AUTH_PORT: "${AUTH_PORT}" UMBREL_AUTH_SECRET: "${UMBREL_AUTH_SECRET}" UMBREL_AUTH_HIDDEN_SERVICE_FILE: "/var/lib/tor/auth/hostname" MANAGER_IP: "${MANAGER_IP}" MANAGER_PORT: 3006 networks: default: external: name: umbrel_main_network ================================================ FILE: containers/app-proxy/test/fixtures/mempool-umbrel-app.yml ================================================ id: mempool category: Explorers name: mempool version: 2.3.1 tagline: A self-hosted explorer for the Bitcoin community description: |- Trusted third parties are security holes. Self-host your own instance of mempool.space on Umbrel for maximum privacy. Features: - Live dashboard visualizing the mempool and blockchain - Live transaction tracking - Search any transaction, block or address - Fee estimations - Mempool historical data - TV View for larger displays as a TV in a cafe or bar - View transaction scripts and op_return messages - Audio notifications on transaction confirmed and address balance change - Multiple languages support - JSON APIs developer: Mempool Space K.K. website: https://mempool.space/about dependencies: - bitcoind - electrum repo: https://github.com/mempool/mempool support: https://mempool.support port: 4006 gallery: - 1.jpg - 2.jpg - 3.jpg path: '' defaultUsername: '' defaultPassword: '' ================================================ FILE: containers/app-proxy/test/global.js ================================================ const chai = require('chai'); const chaiHttp = require('chai-http'); chai.use(chaiHttp); chai.should(); global.expect = chai.expect; global.assert = chai.assert; before(() => { }); global.reset = () => { }; after(() => { }); ================================================ FILE: containers/app-proxy/test/sse-test-server/.dockerignore ================================================ Dockerfile node_modules .git .github ================================================ FILE: containers/app-proxy/test/sse-test-server/Dockerfile ================================================ # Build Stage FROM node:16-buster-slim AS umbrel-sse-test-server-builder # Create app directory WORKDIR /app # Copy 'yarn.lock' and 'package.json' COPY yarn.lock package.json ./ # Install dependencies RUN yarn install --production # Copy project files and folders to the current working directory (i.e. '/app') COPY . . # Final image FROM node:16-buster-slim AS umbrel-sse-test-server # Copy built code from build stage to '/app' directory COPY --from=umbrel-sse-test-server-builder /app /app # Change directory to '/app' WORKDIR /app CMD [ "yarn", "start" ] ================================================ FILE: containers/app-proxy/test/sse-test-server/bin/www ================================================ #!/usr/bin/env node const express = require('express'); const PORT = process.env.PORT || 80; const app = express(); app.get('/clock', function(req, res) { res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' }); const clockInterval = setInterval(() => { const data = (new Date()).toString(); res.write("data: " + data + "\n\n"); }, 1000); req.on("close", () => { clearInterval(clockInterval); }); }); app.get('/', (req, res) => { res.end(`

Status:

Data


	
	`);
});

app.listen(PORT, () => {
	console.log(`Listening on port: ${PORT}`);
});

================================================
FILE: containers/app-proxy/test/sse-test-server/package.json
================================================
{
  "name": "umbrel-sse-test-server",
  "version": "0.0.1",
  "private": true,
  "scripts": {
    "start": "node ./bin/www"
  },
  "dependencies": {
    "express": "^4.17.3"
  }
}


================================================
FILE: containers/app-proxy/test/test/Caddyfile-https
================================================
https://umbrel-dev.local:4007 {
	reverse_proxy app_proxy:4000
	tls internal
}

================================================
FILE: containers/app-proxy/test/test.sh
================================================
#!/usr/bin/env bash
set -euo pipefail

UMBREL_ENV_FILE="$(readlink -f $(dirname "${BASH_SOURCE[0]}")/../../../.env)"

COMPOSE_FILE="${1}"

# Some test env vars. for nextcloud
export APP_DOMAIN="localhost"
export APP_PASSWORD="password"

# Test env vars. for bitcoind
BIN_ARGS=()
BIN_ARGS+=( "-chain=regtest" )
BIN_ARGS+=( "-rpcport=18443" )
BIN_ARGS+=( "-rpcbind=0.0.0.0" )
BIN_ARGS+=( "-rpcallowip=0.0.0.0/0" )
BIN_ARGS+=( "-rpcuser=umbrel" )
BIN_ARGS+=( "-rpcpassword=bitcoinbitcoin" )
BIN_ARGS+=( "-txindex=1" )
BIN_ARGS+=( "-blockfilterindex=1" )
BIN_ARGS+=( "-peerbloomfilters=1" )
BIN_ARGS+=( "-peerblockfilters=1" )
BIN_ARGS+=( "-deprecatedrpc=addresses" )
BIN_ARGS+=( "-rpcworkqueue=128" )

export APP_BITCOIN_COMMAND=$(IFS=" "; echo "${BIN_ARGS[@]}")

# Env vars. specific to app proxy
export APP_PORT=$(cat fixtures/mempool-umbrel-app.yml | yq '.port')

echo "Proxy booting on port: ${APP_PORT}"

# Generate random project id
PROJECT=$(echo -n "${COMPOSE_FILE}" | sha256sum)

docker-compose --env-file "${UMBREL_ENV_FILE}" --project-name "${PROJECT}" -f ./docker-compose.yml -f "${COMPOSE_FILE}" up

================================================
FILE: containers/app-proxy/test/utils/express.js
================================================
const httpMocks = require('node-mocks-http');

const express = require("../../utils/express.js");

describe('express', () => {
  it('should attempt to remove a cookie even if that cookie does not exist', () => {
    const req = httpMocks.createRequest({
      method: 'GET',
      protocol: "http",
      headers: {
        host: "bitcoin.org:4444",
        cookie: "session=abc123; csrf=a_value.das384jfdjsi4r2hf29f"
      }
    });

    const cookieHeader = express.removeCookie(req, "abc");

    assert.equal("session=abc123; csrf=a_value.das384jfdjsi4r2hf29f", cookieHeader);
  });

  it('should attempt to remove a cookie even if there are no cookies', () => {
    const req = httpMocks.createRequest({
      method: 'GET',
      protocol: "http",
      headers: {
        host: "bitcoin.org:4444"
      }
    });

    const cookieHeader = express.removeCookie(req, "does_not_exist");

    assert.equal("", cookieHeader);
  });

  it('should remove the cookie when the cookie exists in the request header', () => {
    const req = httpMocks.createRequest({
      method: 'GET',
      protocol: "http",
      headers: {
        host: "bitcoin.org:4444",
        cookie: "session=abc123; another_cookie=some_value;csrf=a_value.das384jfdjsi4r2hf29f"
      }
    });

    const cookieHeader = express.removeCookie(req, "session");

    assert.equal("another_cookie=some_value; csrf=a_value.das384jfdjsi4r2hf29f", cookieHeader);
  });

  it('should remove the cookie when that 1 cookie exists in the request header', () => {
    const req = httpMocks.createRequest({
      method: 'GET',
      protocol: "http",
      headers: {
        host: "bitcoin.org:4444",
        cookie: "session=abc123"
      }
    });

    const cookieHeader = express.removeCookie(req, "session");

    assert.equal("", cookieHeader);
  });

  it('should remove the cookie when that 1 cookie exists with delimiter in the request header', () => {
    const req = httpMocks.createRequest({
      method: 'GET',
      protocol: "http",
      headers: {
        host: "bitcoin.org:4444",
        cookie: "session=abc123; "
      }
    });

    const cookieHeader = express.removeCookie(req, "session");

    assert.equal("", cookieHeader);
  });
});


================================================
FILE: containers/app-proxy/test/utils/tor.js
================================================
const tor = require("../../utils/tor.js");

describe('tor', () => {
  it('should return the auth HS url', async () => {
    const url = await tor.authHsUrl();

    assert.equal("the-auth-hs-url.onion", url);
  });
});


================================================
FILE: containers/app-proxy/utils/const.js
================================================
const yaml = require('js-yaml');
const fs   = require('fs');

const APP_MANIFEST_FILE = process.env.APP_MANIFEST_FILE || "/extra/umbrel-app.yml";
const CUSTOM_DOTENV_FILE = process.env.CUSTOM_DOTENV_FILE || "/data/.env.app_proxy";

if(fs.existsSync(CUSTOM_DOTENV_FILE)) {
	require('dotenv').config({
		path: CUSTOM_DOTENV_FILE,
		override: true
	});
}

function readUmbrelAppManifest() {
	try {
		return yaml.load(fs.readFileSync(APP_MANIFEST_FILE, 'utf8'));
	} catch (e) {
		console.error("Failed to open app manifest file", e);

		process.exit(0);
	}
}

function readFromEnvOrTerminate(key) {
	const value = process.env[key];

	if(typeof(value) !== "string" || value.trim().length === 0) {
		console.error(`The env. variable '${key}' is not set. Terminating...`);

		process.exit(0);
	}

	return value;
}

function cleanHttpPaths(str) {
	return str.split(/[, ]+/)
		.map(path => path.trim())
		.filter(path => path.length > 0);
}

module.exports = Object.freeze({
	UMBREL_COOKIE_NAME: "UMBREL_SESSION",

	LOG_LEVEL: process.env.LOG_LEVEL || "info",

	PROXY_PORT: parseInt(process.env.PROXY_PORT) || 4000,
	PROXY_TIMEOUT: parseInt(process.env.PROXY_TIMEOUT) || 0, // milliseconds or 0 for disabled
	PROXY_AUTH_ADD: (typeof(process.env.PROXY_AUTH_ADD) === "string") ? (process.env.PROXY_AUTH_ADD === "true") : true,
	PROXY_AUTH_WHITELIST: cleanHttpPaths(process.env.PROXY_AUTH_WHITELIST || ""),
	PROXY_AUTH_BLACKLIST: cleanHttpPaths(process.env.PROXY_AUTH_BLACKLIST || ""),
	PROXY_TRUST_UPSTREAM: (typeof(process.env.PROXY_TRUST_UPSTREAM) === "string") ? (process.env.PROXY_TRUST_UPSTREAM === "true") : false,

	APP: readUmbrelAppManifest(),
	APP_PROTOCOL: process.env.APP_PROTOCOL || "http",
	APP_HOST: readFromEnvOrTerminate("APP_HOST"),
	APP_PORT: parseInt(readFromEnvOrTerminate("APP_PORT")),

	UMBREL_AUTH_HIDDEN_SERVICE_FILE: process.env.UMBREL_AUTH_HIDDEN_SERVICE_FILE || "/var/lib/tor/auth/hostname",

	UMBREL_AUTH_SECRET: readFromEnvOrTerminate("UMBREL_AUTH_SECRET"),
	UMBREL_AUTH_PORT: parseInt(process.env.UMBREL_AUTH_PORT) || 2000,

	MANAGER_IP: readFromEnvOrTerminate("MANAGER_IP"),
	MANAGER_PORT: parseInt(process.env.MANAGER_PORT) || 3006,
});

================================================
FILE: containers/app-proxy/utils/express.js
================================================
function removeCookie(req, cookieName) {
	const allCookies = req.headers.cookie || "";

	// Split on '; ' (where space is optional)
	// More details re http cookie delimter:
	// https://www.rfc-editor.org/rfc/rfc6265#section-4.2.1
	const cookiePairs = allCookies.split(/; */g).filter(pair => pair.length > 0);

	// Filter out cookie and re-join
	// to build http cookie string
	// (using cookie delimiter)
	return cookiePairs.filter(pair => ! pair.startsWith(`${cookieName}=`)).join("; ");
}

module.exports = {
	removeCookie
};

================================================
FILE: containers/app-proxy/utils/hmac.js
================================================
const crypto = require('crypto');

function sign(input, secret) {
	return crypto
		.createHmac('sha256', secret)
		.update(input)
		.digest('base64');
};

function verify(input, secret, signature){
	const inputSignature = Buffer.from( sign(input, secret) );
	const testSignature = Buffer.from( signature );

	return inputSignature.length === testSignature.length && crypto.timingSafeEqual(inputSignature, testSignature);
};

module.exports = {
	sign,
	verify
};

================================================
FILE: containers/app-proxy/utils/manager.js
================================================
const axios = require('axios');
const package = require('../package.json');

const CONSTANTS = require('./const.js');

const axiosInstance = axios.create({
	baseURL: `http://${CONSTANTS.MANAGER_IP}:${CONSTANTS.MANAGER_PORT}`,
	headers: {
		common: {
			"User-Agent": `${package.name}/${package.version}`
		}
	}
});

const account = {
	login: async function(body) {
		return axiosInstance.post('/v1/account/login', body);
	},
	token: async function(token) {
		return axiosInstance.get('/v1/account/token', {
			params: {
				token
			}
		});
	}
};

module.exports = {
	account
};

================================================
FILE: containers/app-proxy/utils/proxy.js
================================================
const { createProxyMiddleware } = require("http-proxy-middleware");
const { StatusCodes } = require("http-status-codes");
const url = require("url");

const expressUtils = require("./express.js");
const tokenUtils = require("./token.js");
const torUtils = require("./tor.js");
const CONSTANTS = require("./const.js");
const safeHandler = require("./safe_handler.js");

function onProxyReq(proxyReq, req, res, config) {
  // "Value may be undefined if the socket is destroyed (for example, if the client disconnected)."
  // More details here: https://nodejs.org/api/net.html#socketremoteaddress
  if (req.socket.remoteAddress === undefined) {
    return res.end();
  }

  // If we don't trust the upstream, we'll set the x-forwarded headers
  // Upstream could be a proxy and therefore trusted
  // So we'll accept the incoming x-forwarded headers
  if (!CONSTANTS.PROXY_TRUST_UPSTREAM) {
    proxyReq.setHeader("x-forwarded-proto", req.protocol);
    proxyReq.setHeader("x-forwarded-host", req.headers.host);
    proxyReq.setHeader("x-forwarded-for", req.socket.remoteAddress);
  }

  // Remove umbrel session cookie from proxied request
  const cookies = expressUtils.removeCookie(req, CONSTANTS.UMBREL_COOKIE_NAME);
  if (cookies.trim().length === 0) {
    // "the user agent sends a Cookie request header to the origin server if it has cookies"
    // More info: https://datatracker.ietf.org/doc/html/rfc2109#section-4.3.4
    proxyReq.removeHeader("cookie");
  } else {
    proxyReq.setHeader("cookie", cookies);
  }
}

function onError(err, req, res, target) {
  // ENOTFOUND = The proxy could not reach the target (check APP_HOST and APP_PORT)
  // ETIMEDOUT = The proxy could reach the target, but the target was too slow to respond (potentially PROXY_TIMEOUT is too low)

  console.error(`Proxy error: ${err.message}`);

  if (typeof res.status === "function") {
    res.status(StatusCodes.BAD_GATEWAY).render("pages/error", {
      app: CONSTANTS.APP,
      err,
    });
  }
}

function proxy() {
  const proxyTarget = `${CONSTANTS.APP_PROTOCOL}://${CONSTANTS.APP_HOST}:${CONSTANTS.APP_PORT}`;

  const proxyConfig = {
    onProxyReq: onProxyReq,
    onError: onError,
    target: proxyTarget,
    // Don't change the origin
    // Pass through the origin ('host' header) from the browser
    changeOrigin: false,
    // Add websocket support, but this option assumes that
    // an initial http request is made before the websocket connection
    ws: true,
    // If this is true, this will chain the x-forwarded header values
    // Many applications don't handle multiple header values (e.g. BTC Pay Server)
    xfwd: false,
    logLevel: CONSTANTS.LOG_LEVEL,
    proxyTimeout: CONSTANTS.PROXY_TIMEOUT,
    // The proxy shouldn't follow redirect
    // The browser should, therefore this must be off
    followRedirects: false,
  };

  return createProxyMiddleware(proxyConfig);
}

function whitelist() {
  return function (req, res, next) {
    req.ignoreAuth = true;

    next();
  };
}

function blacklist() {
  return function (req, res, next) {
    req.ignoreAuth = false;

    next();
  };
}

function apply(app) {
  if (CONSTANTS.PROXY_AUTH_ADD) {
    if (CONSTANTS.PROXY_AUTH_WHITELIST.length > 0)
      app.use(CONSTANTS.PROXY_AUTH_WHITELIST, whitelist());
    if (CONSTANTS.PROXY_AUTH_BLACKLIST.length > 0)
      app.use(CONSTANTS.PROXY_AUTH_BLACKLIST, blacklist());
  }

  const middleware = proxy();

  app.use(
    safeHandler(async (req, res, next) => {
      // If route is part of the auth whitelist
      // Then we ignore handling auth
      if (CONSTANTS.PROXY_AUTH_ADD && req.ignoreAuth !== true) {
        const token = req.cookies.UMBREL_PROXY_TOKEN;

        // token could be false if hmac fails (ie. someone tampered with the token)
        if (typeof token !== "string" || !(await tokenUtils.validate(token))) {
          const origin = req.hostname.endsWith(".onion") ? "tor" : "host";

          // Get the raw query string
          // This could be null if there is no query string
          let query = url.parse(req.url).query;
          if (typeof query == "string") {
            query = `?${query}`;
          } else {
            query = "";
          }

          const searchParams = new URLSearchParams({
            origin: origin,
            app: CONSTANTS.APP.id,
            path: `${req.path}${query}`,
          });

          // If request came over Tor
          // Then redirect to auth HS hosted on Tor
          if (origin === "tor") {
            const authHsUrl = await torUtils.authHsUrl();

            return res.redirect(
              `${req.protocol}://${authHsUrl}/?${searchParams.toString()}`
            );
          } else {
            return res.redirect(
              `${req.protocol}://${req.hostname}:${
                CONSTANTS.UMBREL_AUTH_PORT
              }/?${searchParams.toString()}`
            );
          }
        }
      }

      middleware(req, res, next);
    })
  );

  return middleware;
}

module.exports = {
  proxy,
  whitelist,
  blacklist,
  apply,
};


================================================
FILE: containers/app-proxy/utils/safe_handler.js
================================================
// this safe handler is used to wrap our api methods
// so that we always fallback and return an exception if there is an error
// inside of an async function
// Mostly copied from vault/server/utils/safeHandler.js
function safeHandler(handler) {
  return async (req, res, next) => {
    try {
      return await handler(req, res, next);
    } catch (err) {
      return next(err);
    }
  };
}

module.exports = safeHandler;


================================================
FILE: containers/app-proxy/utils/token.js
================================================
const jwt = require("jsonwebtoken");

const JWT_ALGORITHM = "HS256";

const secret = process.env.JWT_SECRET;

function validate(token) {
  const payload = jwt.verify(token, secret, {
    algorithms: [JWT_ALGORITHM],
  });

  return payload.proxyToken === true;
}

module.exports = {
  validate,
};


================================================
FILE: containers/app-proxy/utils/tor.js
================================================
const fs = require("fs").promises;

const CONSTANTS = require("./const.js");

async function authHsUrl() {
  // Here is technically a race condition
  // As the auth hs url may not yet be generated
  try {
    return (
      await fs.readFile(CONSTANTS.UMBREL_AUTH_HIDDEN_SERVICE_FILE, "utf-8")
    ).trim();
  } catch (e) {
    return "not-yet-generated.onion";
  }
}

module.exports = {
  authHsUrl,
};


================================================
FILE: containers/app-proxy/views/pages/error.ejs
================================================



   
   

   

   Error


   
<%= app.name %>

Oops, there was an error

There was an error connecting to <%= app.name %>. Error code: <%= err.code %>

================================================ FILE: containers/tor/Dockerfile ================================================ # Based on https://github.com/lncm/docker-tor/tree/927ebac9fb43ba4d09249ee27688a4612b7a1707 FROM debian:11-slim AS build ARG VERSION=0.4.7.8 # Add Tor keys ENV KEYS 514102454D0A87DB0767A1EBBE6A0531C18A9179 B74417EDDF22AC9F9E90F49142E86A2A11F48D36 7A02B3521DC75C542BA015456AFEE6D49E92B601 RUN apt update && \ # Packages for verification apt -y install gpg gpg-agent wget && \ # Packages for Tor runtime and compilation apt -y install libevent-dev libssl-dev zlib1g-dev build-essential # Download Tor source and checksum RUN wget https://dist.torproject.org/tor-$VERSION.tar.gz.sha256sum.asc && \ wget https://dist.torproject.org/tor-$VERSION.tar.gz.sha256sum && \ wget https://dist.torproject.org/tor-$VERSION.tar.gz # Verify source RUN gpg --keyserver keyserver.ubuntu.com --recv-keys $KEYS && \ gpg --list-keys | tail -n +3 | tee /tmp/keys.txt && \ gpg --list-keys $KEYS | diff - /tmp/keys.txt && \ gpg --verify tor-$VERSION.tar.gz.sha256sum.asc && \ sha256sum -c tor-$VERSION.tar.gz.sha256sum # Extract source RUN tar -xzf "/tor-$VERSION.tar.gz" WORKDIR /tor-$VERSION/ # Build Tor RUN ./configure --sysconfdir=/etc --datadir=/var/lib && \ make -j$(nproc) && \ make install FROM debian:11-slim # Copy linked libraries COPY --from=build /usr/lib /usr/lib # Copy Tor binaries COPY --from=build /usr/local/bin/tor* /usr/local/bin/ ENTRYPOINT ["tor"] ================================================ FILE: containers/tor/README.md ================================================ [![Umbrel Tor](https://static.getumbrel.com/github/github-banner-umbrel-tor.svg)](https://github.com/getumbrel/umbrel-tor) [![Docker Build](https://img.shields.io/github/workflow/status/getumbrel/umbrel-tor/Docker%20build%20on%20push?color=%235351FB)](https://github.com/getumbrel/umbrel-tor/actions?query=workflow%3A"Docker+build+on+push") [![Docker Pulls](https://img.shields.io/docker/pulls/getumbrel/tor?color=%235351FB)](https://hub.docker.com/repository/registry-1.docker.io/getumbrel/tor/tags?page=1) # ☂️ Tor A simple Docker image for Tor ## 🛠 Build Tor Docker image ### Build ```sh docker build -t getumbrel/tor . ``` ### Run ```sh docker run --rm -u 1000:1000 -e HOME=/tmp getumbrel/tor ``` ================================================ FILE: containers/tor/test/.gitignore ================================================ data ================================================ FILE: containers/tor/test/docker-compose.entrypoint.yml ================================================ version: '3.7' services: web: image: mendhak/http-https-echo environment: HTTP_PORT: 8888 tor: image: getumbrel/tor build: .. user: 1000:1000 environment: HOME: /tmp HS_DIR: "web2" HS_VIRTUAL_PORT: "80" HS_HOST: "web" HS_PORT: "8888" entrypoint: /umbrel/entrypoint.sh volumes: - ./data:/data - ./entrypoint.sh:/umbrel/entrypoint.sh ================================================ FILE: containers/tor/test/docker-compose.yml ================================================ version: '3.7' services: web: image: mendhak/http-https-echo environment: HTTP_PORT: 8888 tor: image: getumbrel/tor build: .. user: 1000:1000 environment: HOME: /tmp volumes: - ./torrc:/etc/tor/torrc - ./data:/data ================================================ FILE: containers/tor/test/entrypoint.sh ================================================ #!/bin/bash TORRC_PATH="/tmp/torrc" echo "HiddenServiceDir /data/${HS_DIR}" > "${TORRC_PATH}" echo "HiddenServicePort ${HS_VIRTUAL_PORT} ${HS_HOST}:${HS_PORT}" >> "${TORRC_PATH}" tor -f "${TORRC_PATH}" ================================================ FILE: containers/tor/test/test-entrypoint.sh ================================================ #!/bin/bash docker-compose -f docker-compose.entrypoint.yml up --detach web docker-compose -f docker-compose.entrypoint.yml up --detach tor echo echo "Hostname:" cat ./data/web2/hostname ================================================ FILE: containers/tor/test/test.sh ================================================ #!/bin/bash docker-compose up --detach web docker-compose up --detach tor echo echo "Hostname:" cat ./data/web/hostname ================================================ FILE: containers/tor/test/torrc ================================================ HiddenServiceDir /data/web HiddenServicePort 80 web:8888 ================================================ FILE: info.json ================================================ { "NOTE": "We must keep this file here forever to allow old umbrelOS 0.5.x Umbrel Homes to find the 1.0.0 update and bootstrap themselves into the new mender based update system.", "version": "1.0.0", "name": "umbrelOS 1.0", "requires": ">=0.5.3", "notes": "umbrelOS 1.0 brings a ground-up rebuild with a host of new features, a completely revamped architecture, and a brand new interface.\n\nLearn more: https://link.umbrel.com/os\n\n- Raspberry Pi users: Please follow the instructions at https://link.umbrel.com/pi-update to update to umbrelOS 1.0.\n\n- Umbrel Home users: You're ready to update now by clicking the 'Install Now' button below.\n\n- Linux users: Your update is on the horizon and will be available in April 2024: https://link.umbrel.com/linux-update.\n\nNote: Updates may overwrite any custom CLI scripts, files, packages, or settings (eg. WiFi) that you've manually installed or modified via command-line (SSH).\n\nWhat's new:\n\n- New UI: A visually stunning environment with seamless navigation, intuitive interactions, and a home screen you can personalize with widgets\n\n- Search (⌘K / Ctrl + K): Instantly find system settings, apps, or initiate actions with a simple keyboard shortcut.\n\n- Quick Actions: Interact with apps and system settings faster than ever with right-click shortcuts.\n\n- Architectural Overhaul: Re-engineered system for better stability, speed, and simplicity. umbrelOS 1.0 now sends device type information during the update check to ensure customized updates for different devices.\n\n- Live Usage: Stay informed with live updates on your device's storage, memory, and CPU usage.\n\n- Multilingual Support: Choose from 8 different system languages." } ================================================ FILE: package.json ================================================ { "type": "module", "scripts": { "dev": "./scripts/umbrel-dev", "dev:help": "npm run dev help", "test:vm": "npm --prefix packages/os run build:amd64:rugix && rm -rf packages/os/rugix/build && npm --prefix packages/umbreld run test:vm --", "build:remote": "./scripts/remote-builder build", "test:remote": "./scripts/remote-builder test" } } ================================================ FILE: packages/os/.gitignore ================================================ build vm-state ================================================ FILE: packages/os/README.md ================================================ # umbrelOS ## Build Process The following diagram visualizes the build process and various build artifacts: ```mermaid graph TD subgraph "Docker" root-amd64 root-arm64 end subgraph "Rugix (Pi)" pi --> pi4 pi --> pi-tryboot pi --> pi-mbr end subgraph "Rugix (AMD64)" amd64 mender-amd64 end root-amd64 --> amd64 root-amd64 --> mender-amd64 root-arm64 --> pi amd64 --> amd64-img([amd64.img]) amd64 --> amd64-rugixb([amd64.rugixb]) mender-amd64 --> mender-amd64-mender([mender-amd64.mender]) mender-amd64 --> mender-amd64-rugixb([mender-amd64.rugixb]) pi-mbr --> pi-mbr-mender([pi.mender]) pi4 --> pi4-img([pi4.img]) pi-tryboot --> pi-tryboot-img([pi5.img]) pi-tryboot --> pi-tryboot-rugixb([pi.rugixb]) ``` ### OS Variants There are three main umbrelOS *variants*: - `umbrelos-pi`: Rugix-native umbrelOS for Raspberry Pi. - `umbrelos-amd64`: Rugix-native umbrelOS for AMD64. - `umbrelos-mender-amd64`: Rugix-based but Mender-compatible umbrelOS for AMD64. > [!IMPORTANT] > **Legacy devices provisioned with Mender require the `umbrelos-mender-amd64` variant.** This variant includes a Rugix configuration to enable a safe migration from Mender to Rugix. Rugix will interface with GRUB in the same way Mender does to facilitate A/B switching. In addition, a Rugix hook is installed to migrate state into Rugix's state management mechanism. This enables factory resets and all other Rugix state management features. ### Build Artifacts The build process produces the following artifacts. #### Images Images for provisioning new umbrelOS devices. - `umbrelos-amd64.img`: Image for provisioning AMD64 devices and VMs. - `umbrelos-pi4.img`: Image for provisioning Raspberry Pi 4 devices (GPT-based). - `umbrelos-pi5.img`: Image for provisioning Raspberry Pi 5 devices (GPT-based). The image for Raspberry Pi 4 includes a firmware update to enable the `tryboot` mechanism used for A/B switching. Otherwise, the image is identical to the image for Raspberry Pi 5. #### Mender Update Artifacts Mender update artifacts for updating existing systems through Mender: - `umbrelos-pi.mender`: Mender update artifact for Raspberry Pi. - `umbrelos-mender-amd64.mender`: Mender update artifact for AMD64 devices. The update artifact for Raspberry Pi works for Raspberry Pi 4 and 5. #### Rugix Update Bundles For each of the umbrelOS variants, there is a respective Rugix update bundle: - `umbrelos-pi.rugixb`: Rugix update bundle for Raspberry Pi. - `umbrelos-amd64.rugixb`: Rugix update bundle for Rugix-native AMD64 devices. - `umbrelos-mender-amd64.rugixb`: Rugix update bundle for legacy Mender devices. ## Mender to Rugix Migration Devices can be migrated to Rugix by installing the respective Mender update artifact. ### Raspberry Pi As umbrelOS for Raspberry Pi has always been based on Rugix, no special migration is needed. ### AMD64 In case of Mender-based AMD64 devices, the directory structure on the data partition must be migrated such that Rugix's state management can be used. This migration is performed by a `boot/post-init` Rugix hook: [`10-migrate-state.sh`](./rugix/recipes/setup-rugix-mender/files/migrate-state.sh). This hook works as follows: Initially, a symlink `/data/umbrel-os` is placed in the `/data` directory managed by Rugix linking back to the bare data partition. This way, after booting, all the bind mounts to `/data/umbrel-os` are set up correctly. The migration hook replaces this symlink atomically with the directory from the data partition, **but only after the system has been committed**. This is done to leave the state intact, in case there is a rollback. Note that the system needs to be rebooted once after the commit to trigger the migration. To this end, after committing, `umbreld` may check whether `/data/umbrel-os` is a symlink and reboot the system if it is. ## Factory Resets Factory resets can be triggered through Rugix Ctrl's state management mechanism as usual. To trigger a factory reset, run `rugix-ctrl state reset`. This will reboot the system and remove the state on the data partition in the process. In case of a RAID configuration, a [`state-reset/prepare` hook](./rugix/recipes/setup-rugix/files/factory-reset.sh) is used to remove the RAID configuration and reset the main data partition. Note that Rugix only supports resetting the state on the actively used data partition (which is the RAID, if a RAID has been configured), hence, we need to use the hook here to make sure that the main data partition is wiped as well. Removing state can take some time during the boot process. It is therefore recommended to use Rugix's state reset mechanism with the `--backup` flag. This will simply rename the old state directory according to the following pattern: ``` /run/rugix/mounts/data/state/default -> /run/rugix/mounts/data/state/default.XXXXXXXXXXXXXX ``` Here, `XXXXXXXXXXXXXX` is the date and time of the reset. The residual state can then removed after booting by `umbreld`. ================================================ FILE: packages/os/build-steps/initialize.sh ================================================ #!/bin/bash set -euo pipefail SNAPSHOT_DATE=${1:-} # Disable the resume from SWAP functionality. This takes significant time during the boot # process, as it tries to resume using a swap device which never shows up. mkdir -p /etc/initramfs-tools/conf.d/ echo "RESUME=none" >/etc/initramfs-tools/conf.d/resume rm /etc/apt/sources.list.d/debian.sources # All apt packages are pinned to a specific date to ensure reproducibility. # This means building the same umbrelOS git tag always results in the same # package versions. # We should update this to the current date with each release to ensure we # are always using the latest packages. cat >/etc/apt/sources.list < The Raspberry Pi 5 is not certified for Gen 3.0 speeds. PCIe Gen 3.0 connections may be unstable. # - https://www.raspberrypi.com/documentation/computers/raspberry-pi.html#pcie-gen-3-0 # dtparam=pciex1_gen=3 ================================================ FILE: packages/os/build-steps/setup-raspberrypi/raspberrypi.gpg.key ================================================ -----BEGIN PGP PUBLIC KEY BLOCK----- Version: GnuPG v1.4.12 (GNU/Linux) mQENBE/d7o8BCACrwqQacGJfn3tnMzGui6mv2lLxYbsOuy/+U4rqMmGEuo3h9m92 30E2EtypsoWczkBretzLUCFv+VUOxaA6sV9+puTqYGhhQZFuKUWcG7orf7QbZRuu TxsEUepW5lg7MExmAu1JJzqM0kMQX8fVyWVDkjchZ/is4q3BPOUCJbUJOsE+kK/6 8kW6nWdhwSAjfDh06bA5wvoXNjYoDdnSZyVdcYCPEJXEg5jfF/+nmiFKMZBraHwn eQsepr7rBXxNcEvDlSOPal11fg90KXpy7Umre1UcAZYJdQeWcHu7X5uoJx/MG5J8 ic6CwYmDaShIFa92f8qmFcna05+lppk76fsnABEBAAG0IFJhc3BiZXJyeSBQaSBB cmNoaXZlIFNpZ25pbmcgS2V5iQE4BBMBAgAiBQJP3e6PAhsDBgsJCAcDAgYVCAIJ CgsEFgIDAQIeAQIXgAAKCRCCsSmSf6MwPk6vB/9pePB3IukU9WC9Bammh3mpQTvL OifbkzHkmAYxzjfK6D2I8pT0xMxy949+ThzJ7uL60p6T/32ED9DR3LHIMXZvKtuc mQnSiNDX03E2p7lIP/htoxW2hDP2n8cdlNdt0M9IjaWBppsbO7IrDppG2B1aRLni uD7v8bHRL2mKTtIDLX42Enl8aLAkJYgNWpZyPkDyOqamjijarIWjGEPCkaURF7g4 d44HvYhpbLMOrz1m6N5Bzoa5+nq3lmifeiWKxioFXU+Hy5bhtAM6ljVb59hbD2ra X4+3LXC9oox2flmQnyqwoyfZqVgSQa0B41qEQo8t1bz6Q1Ti7fbMLThmbRHiuQEN BE/d7o8BCADNlVtBZU63fm79SjHh5AEKFs0C3kwa0mOhp9oas/haDggmhiXdzeD3 49JWz9ZTx+vlTq0s+I+nIR1a+q+GL+hxYt4HhxoA6vlDMegVfvZKzqTX9Nr2VqQa S4Kz3W5ULv81tw3WowK6i0L7pqDmvDqgm73mMbbxfHD0SyTt8+fk7qX6Ag2pZ4a9 ZdJGxvASkh0McGpbYJhk1WYD+eh4fqH3IaeJi6xtNoRdc5YXuzILnp+KaJyPE5CR qUY5JibOD3qR7zDjP0ueP93jLqmoKltCdN5+yYEExtSwz5lXniiYOJp8LWFCgv5h m8aYXkcJS1xVV9Ltno23YvX5edw9QY4hABEBAAGJAR8EGAECAAkFAk/d7o8CGwwA CgkQgrEpkn+jMD5Figf/dIC1qtDMTbu5IsI5uZPX63xydaExQNYf98cq5H2fWF6O yVR7ERzA2w33hI0yZQrqO6pU9SRnHRxCFvGv6y+mXXXMRcmjZG7GiD6tQWeN/3wb EbAn5cg6CJ/Lk/BI4iRRfBX07LbYULCohlGkwBOkRo10T+Ld4vCCnBftCh5x2OtZ TOWRULxP36y2PLGVNF+q9pho98qx+RIxvpofQM/842ZycjPJvzgVQsW4LT91KYAE 4TVf6JjwUM6HZDoiNcX6d7zOhNfQihXTsniZZ6rky287htsWVDNkqOi5T3oTxWUo m++/7s3K3L0zWopdhMVcgg6Nt9gcjzqN1c0gy55L/g== =mNSj -----END PGP PUBLIC KEY BLOCK----- ================================================ FILE: packages/os/build-steps/setup-raspberrypi/raspberrypi.list ================================================ deb http://archive.raspberrypi.com/debian/ RELEASE main # Uncomment line below then 'apt-get update' to enable 'apt-get source' #deb-src http://archive.raspberrypi.com/debian/ RELEASE main ================================================ FILE: packages/os/build-steps/setup-raspberrypi.sh ================================================ #!/bin/bash set -euo pipefail # Install GPG (required for dearmoring the key). apt-get install -y gpg # Remove any existing firmware and kernels. rm -rf /boot/firmware mkdir -p /boot/firmware # Configure APT with Raspberry Pi sources. install -m 644 "/build-steps/setup-raspberrypi/raspberrypi.list" "/etc/apt/sources.list.d/" sed -i "s/RELEASE/trixie/g" "/etc/apt/sources.list.d/raspberrypi.list" gpg --dearmor \ < "/build-steps/setup-raspberrypi/raspberrypi.gpg.key" \ > "/etc/apt/trusted.gpg.d/raspberrypi-archive-stable.gpg" chmod 644 "/etc/apt/trusted.gpg.d/raspberrypi-archive-stable.gpg" apt-get update -y apt-get install -y raspberrypi-archive-keyring # Install kernel and firmware for Pi 4 and 5. apt-get install -y \ initramfs-tools \ raspi-firmware \ firmware-brcm80211 \ linux-image-rpi-v8 \ linux-headers-rpi-v8 \ linux-image-rpi-2712 \ linux-headers-rpi-2712 # Install boot configuration files. install -m 644 "/build-steps/setup-raspberrypi/cmdline.txt" "/boot/firmware/" install -m 644 "/build-steps/setup-raspberrypi/config.txt" "/boot/firmware/" ================================================ FILE: packages/os/build.sh ================================================ #!/usr/bin/env bash set -euo pipefail # Pin the Rugix Docker image. export RUGIX_BAKERY_IMAGE="ghcr.io/silitics/rugix-bakery@sha256:1abcf7791548aa441c06a8bc9b97acf170356cca8cd269b3fa8df4cc762d0251" # v0.8.15 + progress reporting for local delta hits (git-0c91222) # export RUGIX_VERSION="branch-main" # export RUGIX_DEV=true # Allow running from anywhere cd "$(dirname $(readlink -f "${BASH_SOURCE[0]}"))" docker_buildx() { docker buildx build --load $@ } mender_artifact() { docker run --rm -v "$(pwd):/data" umbrelos:builder /usr/bin/mender-artifact "$@" } # Run a command with sudo only in GitHub Actions # These commands fail in GHA without sudo but they aren't needed locally and it's # annoying for the script to get blocked and be prompted. maybe_sudo() { if [ "${GITHUB_ACTIONS:-}" = "true" ]; then sudo "$@" else "$@" fi } # Main entrypoint. function main() { release="${1:-}" dev="false" if [[ "${release}" == "" ]] then local git_hash git_hash="$(git rev-parse --short HEAD 2>/dev/null || echo "dev")" release="${git_hash}-$(date +%s)" dev="true" fi # Enable QEMU/binfmt-based multi-platform support for building arm64 on # amd64 or vice versa, e.g., to build for Pi 5 on an x86 system. docker run --privileged --rm tonistiigi/binfmt --install all if [ -z "${SKIP_ROOTS:-}" ]; then if [ -z "${SKIP_ARM64:-}" ]; then build_root_fs arm64 "${release}" fi if [ -z "${SKIP_AMD64:-}" ]; then build_root_fs amd64 "${release}" fi fi if [ -z "${SKIP_RUGIX_ARTIFACTS:-}" ]; then build_rugix_artifacts "${release}" "${dev}" fi if [ -z "${SKIP_MENDER_ARTIFACTS:-}" ]; then docker_buildx \ --platform "linux/amd64" \ --cache-from type=gha,scope=builder \ --cache-to type=gha,mode=max,scope=builder \ --file builder.Dockerfile \ --tag umbrelos:builder \ . build_mender_artifacts "${release}" fi # Rename artifacts # TODO: Maybe do this a cleaner way # *.update are the new rugix native artifacts # *-legacy.update are rugix update artifacts for legacy mender formatted devices # *-legacy-migration.update are mender update artifacts to allow mender based update # systems to migrate to the new rugix based update system. mv build/umbrelos-amd64.rugixb build/umbrelos-amd64.update 2>/dev/null || true mv build/umbrelos-mender-amd64.mender build/umbrelos-amd64-legacy-migration.update 2>/dev/null || true mv build/umbrelos-mender-amd64.rugixb build/umbrelos-amd64-legacy.update 2>/dev/null || true mv build/umbrelos-pi.mender build/umbrelos-pi-legacy-migration.update 2>/dev/null || true mv build/umbrelos-pi.rugixb build/umbrelos-pi.update 2>/dev/null || true # To boot from QEMU # qemu-system-x86_64 -net nic -net user,hostfwd=tcp::2222-:22 -machine accel=tcg -cpu max -smp 4 -m 8192 -hda build/umbrelos.img -bios OVMF.fd } # Build the root filesystem. # # Arguments: function build_root_fs() { local arch=$1; local release=$2; echo "Ensuring the build dir exists..." mkdir -p build # Ensure that the overlay directory exists. mkdir -p "overlay-${arch}" echo "Building Umbrel OS Docker image..." # Note that we run the build context in ../../ so the build process has access to the # entire repo to copy in umbreld stuff. docker_buildx \ --cache-from type=gha,scope=umbrelos-${arch} \ --cache-to type=gha,mode=max,scope=umbrelos-${arch} \ --platform "linux/${arch}" \ --file umbrelos.Dockerfile \ --tag "umbrelos-${arch}" \ ../../ echo "Dumping Umbrel OS Docker image filesystem into a tar archive..." umbrel_os_container_id=$(docker run --platform "linux/${arch}" --detach "umbrelos-${arch}" /bin/true) docker export --output "build/umbrelos-root-${arch}.tar" "${umbrel_os_container_id}" docker rm "${umbrel_os_container_id}" } # Build the Rugix artifacts. # # Arguments: function build_rugix_artifacts() { local release="$1" local dev="$2" # Make sure that the Rugix build directory exists. mkdir -p rugix/build/umbrelos-root # Copy the root filesystems previously build with Docker. cp build/*.tar rugix/build/umbrelos-root # Copy `/etc/hostname` and `/etc/hosts` such that Rugix can fix them. cp overlay-common/etc/{hostname,hosts} rugix/recipes/fix-overlay/files local compression="compression = { type = \"xz\", level = 9 }" if [ "$dev" == "true" ]; then compression="" fi pushd rugix # Clean Rugix cache to force a clean build. rm -rf .rugix || true if [ -z "${SKIP_ARM64:-}" ] && [ -z "${SKIP_PI4:-}" ]; then build_rugix_system "umbrelos-pi4" "$release" "$dev" maybe_sudo mv -f "build/umbrelos-pi4/system.img" "../build/umbrelos-pi4.img" fi if [ -z "${SKIP_ARM64:-}" ] && [ -z "${SKIP_PI_TRYBOOT:-}" ]; then build_rugix_system "umbrelos-pi-tryboot" "$release" "$dev" maybe_sudo mv -f "build/umbrelos-pi-tryboot/system.img" "../build/umbrelos-pi5.img" maybe_sudo mv -f "build/umbrelos-pi-tryboot/system.rugixb" "../build/umbrelos-pi.rugixb" fi if [ -z "${SKIP_ARM64:-}" ] && [ -z "${SKIP_PI_MBR:-}" ]; then build_rugix_system "umbrelos-pi-mbr" "$release" "$dev" # Truncate the image to the end of the last partition. This is required for # compatibility with the legacy Mender-Rugpi update module. popd docker_buildx \ --platform "linux/amd64" \ --cache-from type=gha,scope=builder \ --cache-to type=gha,mode=max,scope=builder \ --file builder.Dockerfile \ --tag umbrelos:builder \ . docker run --rm -v "$(pwd)/rugix:/data" umbrelos:builder /data/fix-umbrelos-pi-mbr.sh pushd rugix fi if [ -z "${SKIP_AMD64:-}" ] && [ -z "${SKIP_AMD64_RUGIX:-}" ]; then build_rugix_system "umbrelos-amd64" "$release" "$dev" maybe_sudo mv -f "build/umbrelos-amd64/system.img" "../build/umbrelos-amd64.img" maybe_sudo mv -f "build/umbrelos-amd64/system.rugixb" "../build/umbrelos-amd64.rugixb" fi if [ -z "${SKIP_AMD64:-}" ] && [ -z "${SKIP_AMD64_MENDER:-}" ]; then ./run-bakery bake image --release-version "$release" "umbrelos-mender-amd64" maybe_sudo mkdir -p build/umbrelos-mender-amd64/bundle maybe_sudo ln -s ../filesystems build/umbrelos-mender-amd64/bundle/payloads cat < /dev/null update-type = "full" hash-algorithm = "sha512-256" [[payloads]] filename = "partition-1.img" [payloads.delivery] type = "slot" slot = "system" [payloads.block-encoding] hash-algorithm = "sha512-256" chunker = "casync-64" $compression deduplication = true EOF ./run-bakery bundler bundle build/umbrelos-mender-amd64/bundle build/umbrelos-mender-amd64/system.rugixb maybe_sudo mv -f "build/umbrelos-mender-amd64/system.rugixb" "../build/umbrelos-mender-amd64.rugixb" fi popd } # Build the image and update bundle for a given system. # # Arguments: function build_rugix_system() { local system="$1" local release="$2" local dev="$3" local compression="" if [ "$dev" == "true" ]; then compression="--without-compression" fi ./run-bakery bake bundle --release-version "$release" $compression "$system" } # Build the Mender update artifacts. # # Arguments: function build_mender_artifacts() { local release="$1" if [ -z "${SKIP_ARM64:-}" ] && [ -z "${SKIP_PI:-}" ]; then if [ ! -e "rugix/build/umbrelos-pi-mbr/system.img" ]; then echo "'umbrelos-pi-mbr' image is required to build Raspberry Pi Mender artifact." exit 1 fi echo "Build Raspberry Pi Mender artifact..." mender_artifact write module-image \ --artifact-name "${release}" \ -t raspberrypi \ -T rugpi-image \ -f /data/rugix/build/umbrelos-pi-mbr/system.img \ -o /data/build/umbrelos-pi.mender fi if [ -z "${SKIP_AMD64:-}" ] && [ -z "${SKIP_AMD64_MENDER:-}" ]; then if [ ! -e "rugix/build/umbrelos-mender-amd64/filesystems/partition-1.img" ]; then echo "'umbrelos-mender-amd64' image is required to build AMD64 Mender artifact." exit 1 fi echo "Build AMD64 Mender artifact..." mender_artifact write rootfs-image \ --artifact-name "${release}" \ -t amd64 \ -f /data/rugix/build/umbrelos-mender-amd64/filesystems/partition-1.img \ -o /data/build/umbrelos-mender-amd64.mender fi } main "$@" ================================================ FILE: packages/os/builder.Dockerfile ================================================ FROM debian:bullseye RUN apt-get -y update # Install os image builder deps RUN apt-get -y install fdisk gdisk qemu-utils dosfstools tree # Install mender-convert RUN apt-get -y install git RUN git clone -b 4.0.1 https://github.com/mendersoftware/mender-convert.git /mender RUN apt-get install -y sudo gdisk $(cat /mender/requirements-deb.txt) RUN wget -q -O /usr/bin/mender-artifact https://downloads.mender.io/mender-artifact/3.10.0/linux/mender-artifact RUN chmod +x /usr/bin/mender-artifact ================================================ FILE: packages/os/mender.cfg ================================================ DEPLOY_IMAGE_NAME="umbrelos" MENDER_DEVICE_TYPE="amd64" # This gives us: # - 200Mb EFI # - 2x ~10GB OS partitions # - 512MB data partition (so that mkfs.ext4 can fit a 128MB journal contiguosly in one flex-group) # We'll expand the data partition to consume 100% of the block device on first boot. MENDER_STORAGE_TOTAL_SIZE_MB="$((1024 * 20))" MENDER_BOOT_PART_SIZE_MB="200" MENDER_DATA_PART_SIZE_MB="512" # We don't want the Mender systemd cloud service. MENDER_ENABLE_SYSTEMD="n" # We don't want to let mender-convert inject mender-client # since it appears to be broken on bookworm. Instead we # install via apt in the image. MENDER_CLIENT_INSTALL="n" MENDER_CLIENT_VERSION="3.4.0" # Rreasonably fast and offers good compression MENDER_ARTIFACT_COMPRESSION="gzip" # If we don't disable this the image is unbootable MENDER_COPY_BOOT_GAP="n" # We'll disable this and implement our own expansion logic. # This successfulyl expands the filesystem to 100% of the partition # but it doesn't expand the partition to 100% of the block device. MENDER_DATA_PART_GROWFS="n" MENDER_DATA_PART_FSTAB_OPTS="${MENDER_DATA_PART_FSTAB_OPTS},x-systemd.growfs" MENDER_ROOT_PART_FSTAB_OPTS="${MENDER_ROOT_PART_FSTAB_OPTS},x-systemd.growfs" # mkfs.ext4 options for the initial 128 MB Mender data partition # We later grow this partition to 100% of the block device, so we must override # mkfs.ext4’s size-based heuristics; otherwise it will default to values that are # fine for a small 128 MB filesystem, but sub-optimal once the partition is expanded to # real-world sized drives. # # -b 4096: 4 KB blocks. This would default to 1KB for a 128MB partition. # -I 256: 256-byte inodes. This would default to 128 bytes for a 128MB partition. # -i 65536: 1 inode per 64 KB of data → On a 1.8TB partition this is ~30 million inodes, # which take up ~7 GB for inode tables. # -m 0: Reserve 0 % of blocks for root processes. Custom -m percentage will not scale correctly # during fs expansion, so to set a custom reserve we would need to set this via tune2fs after expansion. # -J size=128: Creates a 128MB journal. We set the initial image partition size to 512MB to ensure a contiguous 128MB of free space in one flex-group for the journal. # -O ...: Force-enable all ext4 features we rely on, even if some would already be on by default. MENDER_DATA_PART_MKFS_OPTS="-b 4096 -I 256 -i 65536 -m 0 \ -J size=128 \ -O extent,flex_bg,sparse_super,large_file,huge_file,dir_index,filetype,64bit,metadata_csum,large_dir,extra_isize,has_journal \ -L data" # Dealing with partition UUIDs instead of device paths # allows us to produce a single image that is bootable # on both QEMU (/dev/sda) and Umbrel Home (/dev/nvme0n1p). MENDER_ENABLE_PARTUUID="y" MENDER_BOOT_PART="/dev/disk/by-partuuid/14a31e9d-a8d7-4da0-9eb2-f268dd9d7ad9" MENDER_ROOTFS_PART_A="/dev/disk/by-partuuid/2fe5a278-9b55-4266-8220-6665aa96940b" MENDER_ROOTFS_PART_B="/dev/disk/by-partuuid/f5e6d27c-4a25-447b-8e08-a9d2e738345a" MENDER_DATA_PART="/dev/disk/by-partuuid/d1d36e34-2753-4dc7-96eb-3c9b5584e867" # Reduce noise on TTY MENDER_GRUB_KERNEL_BOOT_ARGS="loglevel=3" # Don't disable this for now since it's much faster since # changing to gzip # # Speed up development builds # if [[ "${UMBREL_OS_DEV_BUILD}" == "true" ]] # then # MENDER_ARTIFACT_COMPRESSION="none" # fi ================================================ FILE: packages/os/overlay-amd64/umbrelOS ================================================ ================================================ FILE: packages/os/overlay-arm64/etc/systemd/system/umbrel-external-storage.service ================================================ # Umbrel External Storage Mounter # Installed at /etc/systemd/system/umbrel-external-storage.service [Unit] Description=External Storage Mounter Before=docker.service umbrel.service [Service] Type=oneshot Restart=no ExecStart=/opt/umbrel-external-storage/umbrel-external-storage TimeoutStartSec=45min User=root Group=root StandardOutput=syslog StandardError=syslog SyslogIdentifier=external storage mounter RemainAfterExit=yes [Install] WantedBy=multi-user.target ================================================ FILE: packages/os/overlay-arm64/opt/umbrel-external-storage/umbrel-external-storage ================================================ #!/usr/bin/env bash set -euo pipefail # This script will: # - Look for external storage devices # - Check if they contain an Umbrel install # - If yes # - - Mount it # - If no # - - Format it # - - Mount it # - - Install Umbrel on it # - Bind mount the external installation on top of the local installation UMBREL_ROOT="/home/umbrel/umbrel" MOUNT_POINT="/mnt/data" EXTERNAL_UMBREL_ROOT="${MOUNT_POINT}/umbrel" DOCKER_DIR="/var/lib/docker" EXTERNAL_DOCKER_DIR="${MOUNT_POINT}/docker" SWAP_DIR="/swap" SWAP_FILE="${SWAP_DIR}/swapfile" check_root () { if [[ $UID != 0 ]]; then echo "This script must be run as root" exit 1 fi } check_dependencies () { for cmd in "$@"; do if ! command -v $cmd >/dev/null 2>&1; then echo "This script requires \"${cmd}\" to be installed" exit 1 fi done } running_off_sdcard() { if df -h | grep --silent /dev/mmcblk0 then echo "true" else echo "false" fi } # Returns a list of block device paths list_block_devices () { # We need to run sync here to make sure the filesystem is reflecting the # the latest changes in /sys/block/sd* sync # We use "2>/dev/null || true" to swallow errors if there are # no block devices. In that case the function just returns nothing # instead of an error which is what we want. # # sed 's!.*/!!' is to return the device path so we get sda # instead of /sys/block/sda (ls -d /sys/block/sd* /sys/block/nvme0n* 2>/dev/null || true) | sed 's!.*/!!' } # Returns the vendor and model name of a block device get_block_device_model () { device="${1}" if [[ "${device}" == nvme* ]]; then vendor=$(cat "/sys/block/${device}/device/device/vendor") else vendor=$(cat "/sys/block/${device}/device/vendor") fi model=$(cat "/sys/block/${device}/device/model") # We echo in a subshell without quotes to strip surrounding whitespace echo "$(echo $vendor) $(echo $model)" } # Returns the path of the first partition of a block device get_first_partition_path () { device_path="${1}" if [[ "${device_path}" == /dev/nvme* ]]; then echo "${device_path}p1" else echo "${device_path}1" fi } # Check if a block device contains partition layout that looks like # an umbrelOS install is_device_umbrelos_install () { device_path="${1}" # Having a 7th partition with the label "data" is a good indicator # this is an umbrelOS install if blkid | grep "${device_path}.*7: " | grep --silent 'LABEL="data"' then echo "true" else echo "false" fi } is_partition_ext4 () { partition_path="${1}" # We need to run sync here to make sure the filesystem is reflecting the # the latest changes in /dev/* sync blkid -o value -s TYPE "${partition_path}" | grep --quiet '^ext4$' } # Wipes a block device and reformats it with a single EXT4 partition format_block_device () { device="${1}" device_path="/dev/${device}" partition_path=$(get_first_partition_path "${device_path}") wipefs -a "${device_path}" parted --script "${device_path}" mklabel gpt parted --script "${device_path}" mkpart primary ext4 0% 100% # We need to run sync here to make sure the filesystem is reflecting the # the latest changes in /dev/* sync mkfs.ext4 -F -L umbrel "${partition_path}" } # Mounts the device given in the first argument at $MOUNT_POINT mount_partition () { partition_path="${1}" mkdir -p "${MOUNT_POINT}" mount "${partition_path}" "${MOUNT_POINT}" } # Unmounts $MOUNT_POINT unmount_partition () { umount "${MOUNT_POINT}" } # Formats and sets up a new device setup_new_device () { block_device="${1}" partition_path="${2}" echo "Formatting device..." format_block_device $block_device echo "Mounting partition..." mount_partition "${partition_path}" echo "Creating Umbrel data directory on external storage..." mkdir -p "${EXTERNAL_UMBREL_ROOT}" echo "Touching dotfile on external storage so we recognise this device in the future..." touch "${EXTERNAL_UMBREL_ROOT}"/.umbrel } # Copy Docker data dir to external storage copy_docker_to_external_storage () { mkdir -p "${EXTERNAL_DOCKER_DIR}" cp --recursive \ --archive \ --no-target-directory \ "${DOCKER_DIR}" "${EXTERNAL_DOCKER_DIR}" } main () { echo "Running external storage mount script..." check_root check_dependencies sed wipefs parted mount sync umount if [[ "$(running_off_sdcard)" == "false" ]] then echo "This script should only run when umbrelOS boots from an SD card, exiting..." exit fi no_of_block_devices=$(list_block_devices | wc -l) retry_for_block_devices=1 while [[ $no_of_block_devices -lt 1 ]]; do echo "No block devices found" echo "Waiting for 5 seconds before checking again..." sleep 5 no_of_block_devices=$(list_block_devices | wc -l) retry_for_block_devices=$(( $retry_for_block_devices + 1 )) if [[ $retry_for_block_devices -gt 20 ]]; then echo "No block devices found in 20 tries..." echo "Exiting mount script without doing anything" exit 1 fi done if [[ $no_of_block_devices -gt 1 ]]; then echo "Multiple block devices found, only one drive is supported" echo "Exiting mount script without doing anything" exit 1 fi # Check if device is running with uas driver, if so balcklist it and reboot echo "Checking if we need to blacklist UAS" blacklist_uas_output=$(umbreld blacklist-uas || true) # Check output includes text "mount-script-halt" which means we are rebooting and should not mount if [[ "${blacklist_uas_output}" == *"mount-script-halt"* ]]; then echo "UAS was blacklisted and device is rebooting, exiting" return fi # At this point we know there is only one block device attached block_device=$(list_block_devices) block_device_path="/dev/${block_device}" partition_path=$(get_first_partition_path "${block_device_path}") block_device_model=$(get_block_device_model $block_device) echo "Found device \"${block_device_model}\"" echo "Checking if the device contains an umbrelOS install..." if [[ $(is_device_umbrelos_install "${block_device_path}") == "true" ]] then echo "Yes, it looks like this device is an umbrelOS install not a data drive, refusing to wipe it and exiting..." exit 1 fi echo "No, it's not" echo "Checking if the device is ext4..." if is_partition_ext4 "${partition_path}" ; then echo "Yes, it is ext4" echo "Checking filesystem for corruption..." # Swallow non-zero exit because successful recovery returns 1 and # we still want to attempt a best effort boot on a failed recovery. fsck.ext4 -y "${partition_path}" || true echo "Mounting partition..." mount_partition "${partition_path}" || { echo "Error mounting partition" exit 1 } echo "Checking if device contains an Umbrel install..." if [[ -f "${EXTERNAL_UMBREL_ROOT}"/.umbrel ]]; then echo "Yes, it contains an Umbrel install" else echo "No, it doesn't contain an Umbrel install" echo "Unmounting partition..." unmount_partition setup_new_device $block_device $partition_path fi else echo "No, it's not ext4" setup_new_device $block_device $partition_path fi if [[ ! -d "${EXTERNAL_DOCKER_DIR}" ]]; then echo "Copying Docker data directory to external storage..." copy_docker_to_external_storage fi echo "Bind mounting external storage over local Umbrel installation..." mkdir -p "${UMBREL_ROOT}" # Create the directory if it doesn't exist mount --bind "${EXTERNAL_UMBREL_ROOT}" "${UMBREL_ROOT}" echo "Bind mounting external storage over local Docker data dir..." mount --bind "${EXTERNAL_DOCKER_DIR}" "${DOCKER_DIR}" echo "Bind mounting external storage to ${SWAP_DIR}" mkdir -p "${MOUNT_POINT}/swap" "${SWAP_DIR}" mount --bind "${MOUNT_POINT}/swap" "${SWAP_DIR}" echo "Bind mounting SD card root at /sd-card..." [[ ! -d "/sd-root" ]] && mkdir -p "/sd-root" mount --bind "/" "/sd-root" echo "Checking Umbrel root is now on external storage..." sync sleep 1 df -h "${UMBREL_ROOT}" | grep --quiet '/dev/sd\|/dev/nvme' echo "Checking ${DOCKER_DIR} is now on external storage..." df -h "${DOCKER_DIR}" | grep --quiet '/dev/sd\|/dev/nvme' echo "Checking ${SWAP_DIR} is now on external storage..." df -h "${SWAP_DIR}" | grep --quiet '/dev/sd\|/dev/nvme' echo "Setting up swapfile" rm "${SWAP_FILE}" || true fallocate -l 4G "${SWAP_FILE}" chmod 600 "${SWAP_FILE}" mkswap "${SWAP_FILE}" swapon "${SWAP_FILE}" echo "Checking SD Card root is bind mounted at /sd-root..." df -h "/sd-root" | grep --quiet "overlay" echo "Mount script completed successfully!" } main ================================================ FILE: packages/os/overlay-common/etc/NetworkManager/NetworkManager.conf ================================================ [main] plugins=ifupdown,keyfile [ifupdown] managed=false ================================================ FILE: packages/os/overlay-common/etc/NetworkManager/conf.d/10-cloudflaredns.conf ================================================ # This is important, we use Cloudflare for DNS because some users have routers that provide # unreliable DNS that results in Docker errors when pulling like: # Get "https://registry-1.docker.io/v2/tailscale/tailscale/manifests/sha256:d488853664499d792b359ea8c18f9a918b92e805b403733fe1c9aac9006ac8c1": dial tcp [2600:1f18:2148:bc01:571f:e759:a87a:2961]:443: connect: network is unreachable [global-dns-domain-*] servers=1.1.1.1,1.0.0.1 ================================================ FILE: packages/os/overlay-common/etc/acpi/events/power-button ================================================ event=button/power.*PBTN action=systemd-cat -t umbrel-power-button /etc/acpi/power-button.sh & ================================================ FILE: packages/os/overlay-common/etc/acpi/power-button.sh ================================================ #!/bin/bash # Configuration RECOVERY_SEQUENCE_COUNT=10 LISTEN_TIME=1 STATE_FILE="/tmp/power_button_state" PASSWORD_RESET_FLAG="/tmp/password_reset_flag" reset_umbrel_password() { yaml_file="/home/umbrel/umbrel/umbrel.yaml" echo "umbrel:umbrel" | chpasswd if ! [ -f "$yaml_file" ]; then echo "Error: File not found." return fi JSON=$(cat "$user_json" 2>/dev/null) if ! yq eval . "${yaml_file}" >/dev/null 2>&1; then echo "Error: Invalid YAML file." return fi if ! yq -e .user.hashedPassword "${yaml_file}" >/dev/null 2>&1 <<<"$JSON"; then echo "Error: Password property not found in the YAML file." return fi yq eval '.user.hashedPassword = "$2b$10$PDwSSnPmfCQJh3x72KjKs.Nb7NgU62gftuic991GkRyFMcIowpTv2"' -i "${yaml_file}" yq eval 'del(.user.totpUri)' -i "${yaml_file}" echo "Password updated successfully." } # Function to handle power button presses handle_press() { # Append the current timestamp to the state file echo "$(date +%s)" >> "${STATE_FILE}" # Check if the last n button presses happened recently num_entries=$(wc -l < "${STATE_FILE}") last_timestamps=$(tail -n "${RECOVERY_SEQUENCE_COUNT}" "${STATE_FILE}") first_timestamp=$(echo "${last_timestamps}" | head -n 1) last_timestamp=$(echo "${last_timestamps}" | tail -n 1) total_allowed_duration=$((LISTEN_TIME * RECOVERY_SEQUENCE_COUNT)) if [[ "${num_entries}" -ge "${RECOVERY_SEQUENCE_COUNT}" ]] && [[ $((last_timestamp - first_timestamp)) -lt "${total_allowed_duration}" ]]; then echo "Power button pressed! Recovery sequence detected. Initiating factory reset." # This flag indicates that a password reset has been initiated so the previous button presses # don't also initiate a reset touch "${PASSWORD_RESET_FLAG}" reset_umbrel_password # Remove the password reset flag after all previous button press event handlers have died # so future resets will work. sleep "${LISTEN_TIME}" rm "${PASSWORD_RESET_FLAG}" exit fi # Listen for additional button presses echo "Power button pressed! Listening for additional button presses for ${LISTEN_TIME} seconds..." sleep "${LISTEN_TIME}" # Read the latest timestamp latest_timestamp=$(tail -n 1 "${STATE_FILE}") new_num_entries=$(wc -l < "${STATE_FILE}") if [[ "${num_entries}" != "${new_num_entries}" ]] || [[ -e "${PASSWORD_RESET_FLAG}" ]]; then # Another button press has been registered or a recovery has just been initiated. # Exit this handler. exit fi } # Check if we should do any special handling and exit early if we do. handle_press # If we get here no special handling is needed and we should trigger a shutdown. echo "Nothing else happened. Shutting down the system." poweroff ================================================ FILE: packages/os/overlay-common/etc/fstab ================================================ # / /mnt/root none bind 0 0 /data/umbrel-os/var/log /var/log none bind 0 0 /data/umbrel-os/var/lib/docker /var/lib/docker none bind 0 0 /data/umbrel-os/home /home none bind 0 0 /data/umbrel-os/var/lib/systemd/timesync /var/lib/systemd/timesync none bind 0 0 /data/umbrel-os/kopia /kopia none bind 0 0 ================================================ FILE: packages/os/overlay-common/etc/hostname ================================================ umbrel ================================================ FILE: packages/os/overlay-common/etc/hosts ================================================ 127.0.0.1 umbrel 127.0.0.1 localhost ================================================ FILE: packages/os/overlay-common/etc/issue ================================================ ================================================ FILE: packages/os/overlay-common/etc/locale.conf ================================================ # Fixes locale warnings when logging in via SSH LANG=C.UTF-8 ================================================ FILE: packages/os/overlay-common/etc/motd ================================================ ,;###GGGGGGGGGGl#Sp ,##GGGlW""^' '`""%GGGG#S, ,#GGG" "lGG#o #GGl^ '$GG# ,#GGb \GGG, lGG" "GGG #GGGlGGGl##p,,p##lGGl##p,,p###ll##GGGG !GGGlW"""*GGGGGGG#""""WlGGGGG#W""*WGGGGS "" "^ '" "" - Warning --------------------------------------------------------------------- | Terminal access is only enabled for debugging purposes. Any modifications | | made to the umbrelOS system will not be persisted between software updates. | | For use-cases where you want to run custom software in a Linux environment, | | consider using the Portainer app available in the Umbrel App Store. | ------------------------------------------------------------------------------- ================================================ FILE: packages/os/overlay-common/etc/sudoers.d/umbrel ================================================ # Remove the silly outdated warning from sudo the first time it's used: # # We trust you have received the usual lecture from the local System # Administrator. It usually boils down to these three things: # # #1) Respect the privacy of others. # #2) Think before you type. # #3) With great power comes great responsibility. Defaults lecture_file = /etc/sudoers.lecture ================================================ FILE: packages/os/overlay-common/etc/sudoers.lecture ================================================ ================================================ FILE: packages/os/overlay-common/etc/sysctl.d/99-vm-zram-parameters.conf ================================================ # Optimise swap for zram # Our swap is super fast in-memory via zram so we can afford to be more aggressive with swappiness. # https://docs.kernel.org/admin-guide/sysctl/vm.html#swappiness vm.swappiness = 180 # With zstd zram the decompression adds enough overhead that there's essentially zero throughput gain # from readahead. Use vm.page-cluster=0. # (This is default on ChromeOS and Android) # https://old.reddit.com/r/Fedora/comments/mzun99/new_zram_tuning_benchmarks/ # https://issues.chromium.org/issues/41028506#comment17 # https://cs.android.com/search?q=page-cluster&start=21 vm.page-cluster = 0 # Watermark boosting pre-emptively frees up memory to prevent a page allocation miss # Broken feature that causes page thrashing, disabled by setting to "0" # (This is default on Ubuntu) # https://groups.google.com/g/linux.debian.user/c/YcDYu-jM-to # https://lists.ubuntu.com/archives/kernel-team/2020-March/108587.html vm.watermark_boost_factor = 0 # Controls the aggressiveness of kswapd. It defines the amount of memory left in a node/system before # kswapd is woken up and how much memory needs to be free before kswapd goes back to sleep. # PopOS did a lot of testing with users and arrived at this value to optimise for zram swap. # https://wiki.archlinux.org/title/Zram#Optimizing_swap_on_zram # https://www.reddit.com/r/pop_os/comments/104kbs4/zram_now_enabled_by_default_in_pop/ # https://github.com/pop-os/default-settings/pull/163/files#diff-8e1248486dec1681fa98c577efaaf729cb8655c9bb18ae19cc68f5a1baa8ab6bR3 vm.watermark_scale_factor = 125 ================================================ FILE: packages/os/overlay-common/etc/systemd/logind.conf.d/lid-switch.conf ================================================ # Ignore lid switch events to allow users running umbrelOS on laptops to keep the device on when the lid is closed. # The following settings result in ignoring lid switch events when the device is on battery power, when the device is on external power, and when the device is docked or connected to more than one display. [Login] HandleLidSwitch=ignore # HandleLidSwitchExternalPower=ignore (optional, HandleLidSwitch is used if not specified) # HandleLidSwitchDocked=ignore (default is set to ignore) ================================================ FILE: packages/os/overlay-common/etc/systemd/logind.conf.d/power-button.conf ================================================ # We want logind to ignore the power button press events. # We will register custom acpi event handlers to handle this # ourselves. [Login] HandlePowerKey=ignore ================================================ FILE: packages/os/overlay-common/etc/systemd/system/umbrel-dns-sync.service ================================================ [Unit] Description=Synchronize DNS configuration before starting NetworkManager Before=NetworkManager.service [Service] ExecStart=bash /opt/umbrel-dns-sync/umbrel-dns-sync Type=oneshot [Install] WantedBy=multi-user.target ================================================ FILE: packages/os/overlay-common/etc/systemd/system/umbrel-ssh-host-key-hydration.service ================================================ [Unit] Description=Hydrate SSH Host Keys Before=ssh.service [Service] Type=oneshot ExecStart=/opt/umbrel-ssh-host-key-hydration/umbrel-ssh-host-key-hydration [Install] WantedBy=multi-user.target ================================================ FILE: packages/os/overlay-common/etc/systemd/system/umbrel-tty-message.service ================================================ [Unit] Description=Display Umbrel access information on TTY After=umbrel.service [Service] ExecStart=/opt/umbrel-tty-message/umbrel-tty-message Type=oneshot [Install] WantedBy=multi-user.target ================================================ FILE: packages/os/overlay-common/etc/systemd/system/umbrel.service ================================================ [Unit] Description=Umbrel daemon After=network-online.target docker.service [Service] TimeoutStopSec=15min ExecStart=umbreld --data-directory=/home/umbrel/umbrel Restart=always # This prevents us hitting restart rate limits and ensures we keep restarting # indefinitely. StartLimitInterval=0 [Install] WantedBy=multi-user.target ================================================ FILE: packages/os/overlay-common/etc/systemd/timesyncd.conf.d/cloudflare.conf ================================================ # We default to Cloudflare for NTP because some users have issues # connecting to the default Debian ntp pool. If Cloudflare fails # the Debian ntp pool is still used as a fallback. [Time] NTP=time.cloudflare.com ================================================ FILE: packages/os/overlay-common/etc/systemd/zram-generator.conf ================================================ # We create a virtual in-memory swap device that is 75% of the RAM and compress it # with zstd which generally gives a ~3:1 compression ratio. # # In a 16GB RAM device this gives us 24GB of usable memory before hitting OOM errors. # 16-((16*0.75)/3)+(16*0.75) = 16GB RAM - 4GB compressed swap device in RAM + 12GB usable swap = 24GB # # The zram device is allocated ondemand so the full 16GB of RAM is still usable up until swap is actually needed. [zram0] zram-size=ram * 0.75 compression-algorithm=zstd ================================================ FILE: packages/os/overlay-common/opt/umbrel-data/umbrel-data-mount ================================================ #!/bin/bash set -euo pipefail CONFIG_PARTITION=${CONFIG_PARTITION:-"/run/rugix/mounts/config"} CONFIG_FILE="$CONFIG_PARTITION/umbrel.yaml" MOUNT_POINT="$1" DEFAULT_PARTITION="${2:-}" wait_for_devices() { local devices=("$@") echo ">>> Waiting for devices to appear: ${devices[*]}" # 50 checks with 0.1s sleep = 5 second timeout for i in {1..50}; do local all_devices_present="true" for dev in "${devices[@]}"; do if [ ! -b "$dev" ]; then all_devices_present="false" break fi done if [ "$all_devices_present" = "true" ]; then break fi sleep 0.1 done } # Handle migration from storage to failsafe mode # This does the minimum at boot: final sync and pool rename # The rest of the migration is completed by umbreld after boot handle_failsafe_transition() { local pool_name="$1" local migration_pool="${pool_name}-migration" local previous_pool="${pool_name}-previous-migration" echo ">>> Migration pool detected, performing final sync" # Import both pools echo ">>> Importing ${pool_name} pool" zpool import -o cachefile=none -f "$pool_name" echo ">>> Importing ${migration_pool} pool" zpool import -o cachefile=none -f "$migration_pool" # Create final snapshot and sync incrementally # Using --raw to preserve encryption (sends encrypted blocks without needing key loaded) echo ">>> Creating final snapshot" zfs snapshot -r "${pool_name}@migration-final" echo ">>> Sending incremental changes to migration pool" zfs send --raw --replicate --large-block --compressed -i @migration "${pool_name}@migration-final" | zfs receive -Fu "$migration_pool" # Rename pools # umbrelos > umbrelos-previous-migration # umbrelos-migration > umbrelos # If anything before this goes wrong, we boot back into the old pool. # After the first rename succeeds, if the second rename fails, we rollback # by renaming umbrelos-previous-migration back to umbrelos. echo ">>> Renaming pools for migration" zpool export "$pool_name" zpool export "$migration_pool" zpool import -o cachefile=none "$pool_name" "$previous_pool" if zpool import -o cachefile=none "$migration_pool" "$pool_name"; then echo ">>> Pool rename complete, umbreld will finish migration after boot" else # TODO: Should we signal some error in the raid config here? echo ">>> ERROR: Failed to rename migration pool, rolling back" zpool export "$previous_pool" zpool import -o cachefile=none "$previous_pool" "$pool_name" echo ">>> Rollback complete, migration aborted" fi # Export the pool so we can import it again in the usual mount process zpool export "$pool_name" } # Parse YAML config to get RAID settings if config file exists POOL_NAME="" DEVICES=() RAID_STATE="" if [ -f "$CONFIG_FILE" ]; then POOL_NAME=$(yq '.raid.poolName' "$CONFIG_FILE" 2>/dev/null || true) mapfile -t DEVICES < <(yq '.raid.devices[]' "$CONFIG_FILE" 2>/dev/null || true) RAID_STATE=$(yq '.raid.state' "$CONFIG_FILE" 2>/dev/null || true) fi if [ -n "$POOL_NAME" ] && [ ${#DEVICES[@]} -gt 0 ]; then echo ">>> Found RAID config for pool '${POOL_NAME}' with ${#DEVICES[@]} devices" # Load zfs modprobe zfs # Attempt to wait for devices # Continue if timeout is reached to allow mounting array with missing devices wait_for_devices "${DEVICES[@]}" # Check if we're in the middle of a failsafe transition if [ "$RAID_STATE" = "transitioning-to-failsafe" ]; then handle_failsafe_transition "$POOL_NAME" || true fi # Import the pool normally # -o cachefile=none means we don't read/write the cache files since # we only have the read only image at this point. # -f force import if it thinks the pool is active elsewhere. This often # happens after ota updates where it thinks we're on a new machine. echo ">>> Importing ${POOL_NAME} pool" zpool import -o cachefile=none -f "$POOL_NAME" # Load the encryption key for the data dataset # We use a hardcoded encryption password for now. This obviously doesn't provide any security. # However initialising encryption now means we can enable full disk encryption in the future # by simply updating the password to something secure without requiring an entire backup and restore # of all data into a new encrypted dataset. echo ">>> Loading encryption key for ${POOL_NAME}/data" echo "umbrelumbrel" | zfs load-key "${POOL_NAME}/data" 2>/dev/null echo ">>> Mounting RAID array to '$MOUNT_POINT'" mkdir -p "$MOUNT_POINT" mount -t zfs "${POOL_NAME}/data" "$MOUNT_POINT" else echo ">>> No RAID config found, falling back to default data partition" if [ -z "$DEFAULT_PARTITION" ]; then echo "ERROR: No default partition provided" exit 1 fi echo ">>> Running fsck on '$DEFAULT_PARTITION'" fsck -p "$DEFAULT_PARTITION" echo ">>> Mounting '$DEFAULT_PARTITION' to '$MOUNT_POINT'" mkdir -p "$MOUNT_POINT" mount "$DEFAULT_PARTITION" "$MOUNT_POINT" fi ================================================ FILE: packages/os/overlay-common/opt/umbrel-dns-sync/umbrel-dns-sync ================================================ #!/bin/bash UMBREL_YAML=/home/umbrel/umbrel/umbrel.yaml CLOUDFLARE_CONF=/etc/NetworkManager/conf.d/10-cloudflaredns.conf CLOUDFLARE_CONF_DISABLED=/etc/NetworkManager/conf.d/10-cloudflaredns.conf.disabled # Use CloudFlare DNS unless the setting is explicitly set to `false` EXTERNAL_DNS=$(yq eval ".settings.externalDns != false" "$UMBREL_YAML" 2>/dev/null || echo "true") if [[ "$EXTERNAL_DNS" == "false" ]]; then if [[ -f "$CLOUDFLARE_CONF" ]]; then mv -f "$CLOUDFLARE_CONF" "$CLOUDFLARE_CONF_DISABLED" || { echo "Failed to move $CLOUDFLARE_CONF to $CLOUDFLARE_CONF_DISABLED" exit 1 } fi else if [[ ! -f "$CLOUDFLARE_CONF" ]]; then mv -f "$CLOUDFLARE_CONF_DISABLED" "$CLOUDFLARE_CONF" || { echo "Failed to move $CLOUDFLARE_CONF_DISABLED to $CLOUDFLARE_CONF" exit 1 } fi fi ================================================ FILE: packages/os/overlay-common/opt/umbrel-ssh-host-key-hydration/umbrel-ssh-host-key-hydration ================================================ #!/bin/bash set -euo pipefail SSH_STATE_DIR=${SSH_STATE_DIR:-"/data/ssh"} if [ ! -f "${SSH_STATE_DIR}"/ssh_host_rsa_key ]; then rm -f /etc/ssh/ssh_host_*_key* ssh-keygen -A # Copy the keys to the data partition. mkdir -p "${SSH_STATE_DIR}" cp /etc/ssh/ssh_host_*_key* "${SSH_STATE_DIR}" fi # Restore the keys from the data partition. cp "${SSH_STATE_DIR}"/ssh_host_*_key* /etc/ssh/ ================================================ FILE: packages/os/overlay-common/opt/umbrel-tty-message/umbrel-tty-message ================================================ #!/bin/bash get_addresses() { # Get all active wifi and ethernet interfaces local active_interfaces=$(nmcli --terse --fields TYPE,DEVICE con show --active | grep 'ethernet\|wireless' | cut -d ':' -f 2) for interface in $active_interfaces; do # Get the interface IP local ip=$(nmcli --terse --fields IP4.ADDRESS dev show "${interface}" | grep 'IP4.ADDRESS' | cut -d':' -f2 | cut -d'/' -f1) # Return the IP echo "${ip}" # Return the avahi address avahi-resolve -a "${ip}" | cut -f 2 done } # Wait for addresses to be assigned while true do addresses=$(get_addresses | sort -r | uniq) [[ "${addresses}" != "" ]] && break sleep 1 done # Format addresses for printing formatted_addresses=$(echo "${addresses}" | sed 's/^/ http:\/\//') # Clear TTY echo -e "\033c" > /dev/tty1 # Write TTY message echo -n "Your Umbrel is now accessible at: ${formatted_addresses} umbrel login: " > /dev/tty1 ================================================ FILE: packages/os/overlay-common/umbrelOS ================================================ ================================================ FILE: packages/os/package.json ================================================ { "scripts": { "build": "./build.sh", "build:amd64": "SKIP_ARM64=true npm run build", "build:amd64:rugix": "SKIP_AMD64_MENDER=true SKIP_MENDER_ARTIFACTS=true npm run build:amd64", "build:amd64:usb-installer:prepare": "xz --keep --force --threads=0 build/umbrelos-amd64.img", "build:amd64:usb-installer": "cd usb-installer && ./run.sh", "build:arm64": "SKIP_AMD64=true npm run build", "build:pi5": "SKIP_AMD64=true SKIP_PI4=true npm run build", "vm": "./vm.sh" }, "devDependencies": { "opentimestamps": "^0.4.9" } } ================================================ FILE: packages/os/rugix/.gitignore ================================================ /.rugix /build ================================================ FILE: packages/os/rugix/fix-umbrelos-pi-mbr.sh ================================================ #!/usr/bin/env bash set -euo pipefail LAST_USED_SECTOR=$(sfdisk -l /data/build/umbrelos-pi-mbr/system.img -o end | tail -n1) TARGET_SIZE=$(( (LAST_USED_SECTOR + 1) * 512 )) truncate -s ${TARGET_SIZE} "/data/build/umbrelos-pi-mbr/system.img" ================================================ FILE: packages/os/rugix/layers/umbrelos-amd64.toml ================================================ parent = "umbrelos-root-amd64" recipes = [ # Prepare umbrelOS base image for Rugix. "umbrelos-prepare", # Copy umbrelOS boot files to boot partition. "umbrelos-boot", # Install and configure Rugix. "setup-rugix", # Fix `/etc/hostname` and `/etc/hosts`. "fix-overlay", ] [parameters."core/rugix-ctrl"] use_musl = false ================================================ FILE: packages/os/rugix/layers/umbrelos-mender-amd64.toml ================================================ parent = "umbrelos-root-amd64" recipes = [ # Prepare umbrelOS base image for Rugix. "umbrelos-prepare", # Copy umbrelOS boot files to boot partition. "umbrelos-boot", # Install and configure Rugix. "setup-rugix", # Configure Rugix for compatibility with Mender-based legacy systems. "setup-rugix-mender", # Fix `/etc/hostname` and `/etc/hosts`. "fix-overlay", ] [parameters."core/rugix-ctrl"] use_musl = false ================================================ FILE: packages/os/rugix/layers/umbrelos-pi.toml ================================================ parent = "umbrelos-root-arm64" recipes = [ # Prepare umbrelOS base image for Rugix. "umbrelos-prepare", # Copy umbrelOS boot files to boot partition. "umbrelos-boot", # Install and configure Rugix. "setup-rugix", # Fix `/etc/hostname` and `/etc/hosts`. "fix-overlay", ] [parameters."core/rugix-ctrl"] use_musl = false ================================================ FILE: packages/os/rugix/layers/umbrelos-pi4.toml ================================================ parent = "umbrelos-pi" recipes = [ # Include the firmware update for Raspberry Pi 4. "core/rpi-include-firmware", ] [parameters."core/rpi-include-firmware"] model = "pi4" ================================================ FILE: packages/os/rugix/layers/umbrelos-root-amd64.toml ================================================ url="file:///build/umbrelos-root/umbrelos-root-amd64.tar" ================================================ FILE: packages/os/rugix/layers/umbrelos-root-arm64.toml ================================================ url="file:///build/umbrelos-root/umbrelos-root-arm64.tar" ================================================ FILE: packages/os/rugix/recipes/fix-overlay/files/.gitignore ================================================ hostname hosts ================================================ FILE: packages/os/rugix/recipes/fix-overlay/files/.gitkeep ================================================ ================================================ FILE: packages/os/rugix/recipes/fix-overlay/recipe.toml ================================================ description = "fix `/etc/hostname` and `/etc/hosts`" ================================================ FILE: packages/os/rugix/recipes/fix-overlay/steps/00-install.sh ================================================ #!/bin/bash set -euo pipefail install -m 644 "${RECIPE_DIR}/files/hostname" "/etc/" install -m 644 "${RECIPE_DIR}/files/hosts" "/etc/" ================================================ FILE: packages/os/rugix/recipes/setup-rugix/files/bootstrapping-amd64.toml ================================================ [layout] type = "gpt" partitions = [ { name = "EFI", size = "256M", type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, { name = "boot-a", size = "512MiB" }, { name = "boot-b", size = "512MiB" }, { name = "system-a", size = "10GiB" }, { name = "system-b", size = "10GiB" }, # For the data partition, we reserve 0.5% of blocks (-m 0.5) for root-only writes to prevent # full-disk deadlocks and keep logs/Docker alive if the FS hits 100%. # The ext4 default of 5% is excessive on multi-TB disks (10s to 100s of GB wasted). # At 0.5%, we reserve around 2.5GB for 0.5TB, 5GB for 1TB, 10GB for 2TB, and 20GB for 4TB, # which is a small cost that gives us enough headroom for safe recovery. { name = "data", filesystem = { type = "ext4", label = "data", additional-options = ["-m", "0.5"] } }, ] ================================================ FILE: packages/os/rugix/recipes/setup-rugix/files/bootstrapping-arm64.toml ================================================ [layout] type = "gpt" partitions = [ { name = "EFI", size = "256M", type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" }, { name = "boot-a", size = "128MiB", type = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" }, { name = "boot-b", size = "128MiB", type = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7" }, { name = "system-a", size = "5GiB" }, { name = "system-b", size = "5GiB" }, # For the data partition, we reserve 0.5% of blocks (-m 0.5) for root-only writes to prevent # full-disk deadlocks and keep logs/Docker alive if the FS hits 100%. # The ext4 default of 5% is excessive on multi-TB disks (10s to 100s of GB wasted). # At 0.5%, we reserve around 2.5GB for 0.5TB, 5GB for 1TB, 10GB for 2TB, and 20GB for 4TB, # which is a small cost that gives us enough headroom for safe recovery. { name = "data", filesystem = { type = "ext4", label = "data", additional-options = ["-m", "0.5"] } }, ] ================================================ FILE: packages/os/rugix/recipes/setup-rugix/files/hooks/state-reset/prepare.sh ================================================ #!/bin/bash # Rugix `state-reset/prepare` hook to reset the RAID and main disk data partition. By # default Rugix resets the state on the active data partition only. If the system is # running from the RAID, then this does only reset the state on the RAID but not the # RAID config on the config partition itself. This script checks whether a RAID has # been configured and reformats the main disk data partition, and removes a RAID # configuration from the config partition if one is detected. set -euo pipefail CONFIG_PARTITION=${CONFIG_PARTITION:-"/run/rugix/mounts/config"} CONFIG_FILE="$CONFIG_PARTITION/umbrel.yaml" if [ ! -f "$CONFIG_FILE" ]; then echo "[INFO] no config state file detected, nothing to do" exit 0 fi # Parse YAML config to get devices array if config file exists DEVICES=() mapfile -t DEVICES < <(yq '.raid.devices[]' "$CONFIG_FILE" 2>/dev/null || true) echo ">>> Removing RAID configuration from config partition" if mountpoint -q "$CONFIG_PARTITION"; then # We need to remove the write-protection on the config partition. cleanup() { mount -o remount,ro "$CONFIG_PARTITION" } trap cleanup EXIT mount -o remount,rw "$CONFIG_PARTITION" fi rm -f "$CONFIG_FILE" # If no RAID configuration is detected, nothing to do. if [ ${#DEVICES[@]} -eq 0 ]; then echo "[INFO] no RAID configuration detected, nothing to do" exit 0 fi # If we have a RAID configuration, we need to reformat the main disk data partition. SYSTEM_INFO=$(rugix-ctrl system info) BOOT_FLOW=$(echo "$SYSTEM_INFO" | jq -r ".boot.bootFlow") # Determine the main disk data partition. if [ "$BOOT_FLOW" == "mender-grub" ]; then # On Mender legacy devices, the data partition is the 4th partition on the main disk. MAIN_DATA_PARTITION=$(rugix-ctrl utils resolve-partition 4 | jq -r ".device" || true) else # On Rugix-native devices the main disk data partition is the last partition on the # main disk, which is either the 7th (MBR) or the 6h (GPT) partition. for partition in 7 6; do MAIN_DATA_PARTITION=$(rugix-ctrl utils resolve-partition $partition 2>/dev/null | jq -r ".device" || true) if [ ! -z "${MAIN_DATA_PARTITION}" ]; then break fi done fi if [ -z "${MAIN_DATA_PARTITION}" ]; then echo "[ERROR] unable to determine main data partition" exit 1 fi echo "[INFO] found main disk data partition: '$MAIN_DATA_PARTITION'" # Ensure that the main disk data partition has not been mounted. if [ ! -z $(lsblk -no MOUNTPOINT "$MAIN_DATA_PARTITION") ]; then echo "[ERROR] main disk data partition appears to be mounted" exit 1 fi # At this point, we can either reformat the data partition or remove any state on it. # Reformatting gives us a clean slate, so let's do that. # # We use -m 0.5 to reserve 0.5% of blocks for root-only writes (matching bootstrapping config). mkfs.ext4 -F -m 0.5 -L data "$MAIN_DATA_PARTITION" ================================================ FILE: packages/os/rugix/recipes/setup-rugix/files/state-data.toml ================================================ [[persist]] directory = "/data" ================================================ FILE: packages/os/rugix/recipes/setup-rugix/files/system.toml ================================================ [data-partition] # This is safe to enable on all systems as it mounts the default # data partition if no external RAID has been configured. mount-script = "/opt/umbrel-data/umbrel-data-mount" ================================================ FILE: packages/os/rugix/recipes/setup-rugix/recipe.toml ================================================ description = "setup Rugix for umbrelOS" dependencies = ["core/rugix-ctrl"] ================================================ FILE: packages/os/rugix/recipes/setup-rugix/steps/00-install.sh ================================================ #!/bin/bash set -euo pipefail apt-get install -y fdisk parted install -D -m 644 \ "${RECIPE_DIR}/files/bootstrapping-${RUGIX_ARCH}.toml" \ "/etc/rugix/bootstrapping.toml" install -D -m 644 \ "${RECIPE_DIR}/files/state-data.toml" \ "/etc/rugix/state/data.toml" install -D -m 644 \ "${RECIPE_DIR}/files/system.toml" \ "/etc/rugix/system.toml" # Install the factory reset hook. install -D -m 755 \ "${RECIPE_DIR}/files/hooks/state-reset/prepare.sh" \ "/etc/rugix/hooks/state-reset/prepare/10-umbrel.sh" ================================================ FILE: packages/os/rugix/recipes/setup-rugix-mender/files/init ================================================ #!/bin/sh DATA_DIR="/run/rugix/mounts/data" # If the data directory exists, Rugix Ctrl initialized the system and we can proceed with Systemd. if [ -d "$DATA_DIR" ]; then echo "Directory $DATA_DIR exists, starting 'systemd'..." exec /lib/systemd/systemd else echo "Directory $DATA_DIR does not exist, starting 'rugix-ctrl'..." exec /usr/bin/rugix-ctrl fi ================================================ FILE: packages/os/rugix/recipes/setup-rugix-mender/files/migrate-state.sh ================================================ #!/bin/bash set -euo pipefail # We check whether the old `umbrel-os` directory still exists. If it does not, then the # migration has been completed, and we have nothing further to do. if [ ! -d "/run/rugix/mounts/data/umbrel-os" ]; then echo "State has already been migrated." exit 0 fi # We simply always copy `/data/ssh` here as it is small. if [ ! -d "/data/ssh" ] && [ -d "/run/rugix/mounts/data/ssh" ]; then rm -rf /data/ssh.tmp cp -rp /run/rugix/mounts/data/ssh /data/ssh.tmp # This ensures that the copy is atomic. mv -T /data/ssh.tmp /data/ssh fi # Remove the existing `umbrel-os` symlink/directory and replace with migrated state. rm -rf /data/umbrel-os if [ "$RUGIX_REQUIRES_COMMIT" == "false" ]; then # System has previously been committed. Perform the migration now. # Remove old SSH host keys. rm -rf /run/rugix/mounts/data/ssh # Atomically move the old `umbrel-os` directory to the new place. mv -T /run/rugix/mounts/data/umbrel-os /run/rugix/mounts/data/state/default/persist/data/umbrel-os else # State has not been migrated but system has also not been committed. Make sure that # the `/data/umbrel-os` symlink exists such that the old state is used. ln -s /run/rugix/mounts/data/umbrel-os /data/umbrel-os fi ================================================ FILE: packages/os/rugix/recipes/setup-rugix-mender/files/system.toml ================================================ #:schema https://raw.githubusercontent.com/silitics/rugix/refs/tags/v0.8.0/schemas/rugix-ctrl-system.schema.json [data-partition] partition = 4 # This is safe to enable on all systems as it mounts the default # data partition if no external RAID has been configured. mount-script = "/opt/umbrel-data/umbrel-data-mount" [boot-flow] type = "mender-grub" boot-dir = "/run/rugix/mounts/config" [boot-groups.a] slots = { system = "system-a" } [boot-groups.b] slots = { system = "system-b" } [slots.system-a] type = "block" partition = 2 [slots.system-b] type = "block" partition = 3 ================================================ FILE: packages/os/rugix/recipes/setup-rugix-mender/recipe.toml ================================================ description = "configure system for compatibility with legacy Mender systems" priority = -100 dependencies = ["setup-rugix"] ================================================ FILE: packages/os/rugix/recipes/setup-rugix-mender/steps/00-install.sh ================================================ #!/bin/bash set -euo pipefail # Install custom Rugix system configuration for Mender-compatibility. install -D -m 644 \ "${RECIPE_DIR}/files/system.toml" \ "/etc/rugix/system.toml" # Create kernel and initrd symlinks as required by Mender's Grub configuration. cd /boot ln -s initrd* initrd ln -s vmlinuz* kernel # To enable state management, Rugix Ctrl must run as the init system prior to Systemd. As # we cannot change the Kernel commandline parameters, we instead patch `/sbin/init`. install -D -m 755 \ "${RECIPE_DIR}/files/init" \ "/sbin/init" # Install the state migration hook. install -D -m 755 \ "${RECIPE_DIR}/files/migrate-state.sh" \ "/etc/rugix/hooks/boot/post-init/10-migrate-state.sh" ================================================ FILE: packages/os/rugix/recipes/umbrelos-boot/files/grub.cfg ================================================ load_env -f /boot.grubenv linux /vmlinuz console=ttyS0 console=tty1 loglevel=3 panic=5 ${rugpi_bootargs} initrd /initrd.img boot ================================================ FILE: packages/os/rugix/recipes/umbrelos-boot/recipe.toml ================================================ description = "copy umbrelOS boot files to boot partition" priority = -800_000 ================================================ FILE: packages/os/rugix/recipes/umbrelos-boot/steps/00-install.sh ================================================ #!/bin/bash set -euo pipefail BOOT_DIR="${RUGIX_LAYER_DIR}/roots/boot" mkdir -p "${BOOT_DIR}" case "${RUGIX_ARCH}" in "amd64") echo "Copying kernel and initrd..." cp -L /vmlinuz "${BOOT_DIR}" cp -L /initrd.img "${BOOT_DIR}" echo "Installing second stage boot script..." cp "${RECIPE_DIR}/files/grub.cfg" "${BOOT_DIR}" ;; "arm64") echo "Copying firmware files..." cp -rp /boot/firmware/* "${BOOT_DIR}" ;; *) echo "Unsupported architecture '${RUGIX_ARCH}'." exit 1 esac ================================================ FILE: packages/os/rugix/recipes/umbrelos-cleanup/recipe.toml ================================================ description = "cleanup and restore original umbrelOS configuration" priority = -800_000 ================================================ FILE: packages/os/rugix/recipes/umbrelos-cleanup/steps/00-install.sh ================================================ #!/bin/bash set -euo pipefail mv /etc/resolv.conf.original /etc/resolv.conf rm -rf /var/log ================================================ FILE: packages/os/rugix/recipes/umbrelos-prepare/recipe.toml ================================================ description = "prepare umbrelOS base image for Rugix" priority = 800_000 dependencies = ["umbrelos-cleanup"] ================================================ FILE: packages/os/rugix/recipes/umbrelos-prepare/steps/00-install.sh ================================================ #!/bin/bash set -euo pipefail mv /etc/resolv.conf /etc/resolv.conf.original echo "nameserver 1.1.1.1" > /etc/resolv.conf mkdir -p /var/log/apt # Systemd uses this file to detect that it runs in Docker. This will prevent `reboot` # from working as it should and may also lead to a bunch of other problems. rm -f /.dockerenv ================================================ FILE: packages/os/rugix/rugix-bakery.toml ================================================ #:schema https://raw.githubusercontent.com/silitics/rugix/refs/tags/v0.8.0/schemas/rugix-bakery-project.schema.json # Image for AMD64 EFI systems. [systems.umbrelos-amd64] layer = "umbrelos-amd64" architecture = "amd64" target = "generic-grub-efi" # Configure a GPT layout to enlarge boot partitions to 512 MiB. [systems.umbrelos-amd64.image.layout] type = "gpt" partitions = [ { root = "config", type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", size = "256M", filesystem = { type = "fat32" } }, { root = "boot", size = "512MiB", filesystem = { type = "ext4" } }, { size = "512M" }, { root = "system", filesystem = { type = "ext4", additional-options = [ "-O", "^has_journal", "-E", "hash_seed=035cb65d-0a86-404a-bad7-19c88d05e400", "-U", "12341234-a4ec-4304-a70f-c549ea829da9", ] } }, ] # Image for Raspberry Pi 4 including the required firmware update. [systems.umbrelos-pi4] layer = "umbrelos-pi4" architecture = "arm64" target = "rpi-tryboot" # Configure a GPT layout to support devices disks larger than 2 TiB. [systems.umbrelos-pi4.image.layout] type = "gpt" partitions = [ { root = "config", type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", size = "256M", filesystem = { type = "fat32" } }, { root = "boot", type = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", size = "128M", filesystem = { type = "fat32" } }, { type = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", size = "128M" }, { root = "system", filesystem = { type = "ext4", additional-options = [ "-O", "^has_journal", "-E", "hash_seed=035cb65d-0a86-404a-bad7-19c88d05e400", "-U", "12341234-a4ec-4304-a70f-c549ea829da9", ] } }, ] # Image for Raspberry Pi 4 and 5 without the firmware update. [systems.umbrelos-pi-tryboot] layer = "umbrelos-pi" architecture = "arm64" target = "rpi-tryboot" # Configure a GPT layout to support devices disks larger than 2 TiB. [systems.umbrelos-pi-tryboot.image.layout] type = "gpt" partitions = [ { root = "config", type = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B", size = "256M", filesystem = { type = "fat32" } }, { root = "boot", type = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", size = "128M", filesystem = { type = "fat32" } }, { type = "EBD0A0A2-B9E5-4433-87C0-68B6B72699C7", size = "128M" }, { root = "system", filesystem = { type = "ext4", additional-options = [ "-O", "^has_journal", "-E", "hash_seed=035cb65d-0a86-404a-bad7-19c88d05e400", "-U", "12341234-a4ec-4304-a70f-c549ea829da9", ] } }, ] # Legacy MBR-based image to build Mender update artifacts. [systems.umbrelos-pi-mbr] layer = "umbrelos-pi" architecture = "arm64" target = "rpi-tryboot" # Image for legacy Mender-based devices. [systems.umbrelos-mender-amd64] layer = "umbrelos-mender-amd64" architecture = "amd64" target = "unknown" # We need a custom layout here to create a filesystem compatible with Mender's version of # Grub. In particular, the feature `metadata_csum_seed` is incompatible, so we remove it. # We also do not need/want a journal as the root filesystem is read-only. Note that adding # a journal will also interfere with static delta updates. [systems.umbrelos-mender-amd64.image.layout] type = "gpt" partitions = [ { root = "system", filesystem = { type = "ext4", additional-options = [ "-O", "^metadata_csum_seed,^has_journal", "-E", "hash_seed=035cb65d-0a86-404a-bad7-19c88d05e400", "-U", "12341234-a4ec-4304-a70f-c549ea829da9", ] } }, ] ================================================ FILE: packages/os/rugix/run-bakery ================================================ #!/usr/bin/env bash set -euo pipefail DOCKER=${DOCKER:-"docker"} DOCKER_FLAGS=${DOCKER_FLAGS:-""} RUGIX_DEV=${RUGIX_DEV:-"false"} RUGIX_CONTEXT_DIR=${RUGIX_CONTEXT_DIR:-""} RUGIX_CACHE_VOLUME=${RUGIX_CACHE_VOLUME:-"rugix-build-cache"} if [ "${RUGIX_DEV}" = "false" ]; then RUGIX_VERSION=${RUGIX_VERSION:-"v0.8"} else RUGIX_VERSION=${RUGIX_VERSION:-"dev"} fi RUGIX_BAKERY_IMAGE=${RUGIX_BAKERY_IMAGE:-"ghcr.io/silitics/rugix-bakery:${RUGIX_VERSION}"} if [ "${RUGIX_DEV}" = "false" ]; then $DOCKER pull "${RUGIX_BAKERY_IMAGE}" fi RUGIX_BAKERY_IMAGE=$($DOCKER inspect --format='{{.Id}}' "${RUGIX_BAKERY_IMAGE}") if [ -t 0 ] && [ -t 1 ]; then DOCKER_FLAGS="${DOCKER_FLAGS} -it" fi if [ -n "${RUGIX_CACHE_VOLUME}" ]; then if ! $DOCKER volume inspect "${RUGIX_CACHE_VOLUME}" >/dev/null 2>&1; then $DOCKER volume create "${RUGIX_CACHE_VOLUME}" >/dev/null fi DOCKER_FLAGS="${DOCKER_FLAGS} -v ${RUGIX_CACHE_VOLUME}:/run/rugix/bakery/cache" fi if [ "${1:-}" == "run" ]; then # Add port forwarding for SSH when running a system in a VM. DOCKER_FLAGS="${DOCKER_FLAGS} -p 127.0.0.1:2222:2222 -p [::1]:2222:2222" fi exec $DOCKER run --rm --privileged \ $DOCKER_FLAGS \ -v "$(pwd)":/project \ -v "$(pwd)/${RUGIX_CONTEXT_DIR}":/run/rugix/bakery/context \ -v /dev:/dev \ -e "RUGIX_HOST_PROJECT_DIR=$(pwd)" \ -e "RUGIX_BAKERY_IMAGE=${RUGIX_BAKERY_IMAGE}" \ -e "RUGIX_DEV=${RUGIX_DEV}" \ "${RUGIX_BAKERY_IMAGE}" \ "$@" ================================================ FILE: packages/os/rugpi-image ================================================ #!/usr/bin/env python3 # # Copyright 2023-2024 Silitics GmbH # # This file is part of Rugpi (https://rugpi.io). # # SPDX-License-Identifier: MIT OR Apache-2.0 import pathlib import subprocess import sys try: # Mender provides us with two arguments: # 1. The current state of the update process. # 2. A directory where we can find the files of the artifact. STATE = sys.argv[1] FILES = pathlib.Path(sys.argv[2]) except IndexError: raise RuntimeError(f"usage: {sys.argv[0]} ") def rugpi_commit_system(): """Commit the current partition set.""" subprocess.check_call(["rugpi-ctrl", "system", "commit"]) def rugpi_install_image(image: pathlib.Path): """Install a Rugpi image without rebooting in streaming mode.""" with open(image, "rb") as image_file: subprocess.check_call( [ "rugpi-ctrl", "update", "install", "--stream", "--no-reboot", "-", ], stdin=image_file, ) while True: if not image_file.read(4096): break def query_supports_rollback(): """The `SupportsRollback` query of the update process.""" # We do support rollbacks. print("Yes") def query_needs_artifact_reboot(): """The `NeedsArtifactReboot` query of the update process.""" # We want Mender to take care of rebooting. print("Automatic") def state_download(): """The `Download` state of the update process.""" image_found = False # Commit the present system so that we can overwrite the cold partitions. rugpi_commit_system() with (FILES / "stream-next").open("rt") as stream_next: while True: next_file = stream_next.readline().strip() if not next_file: # No more files left in the stream. break if next_file.strip().endswith(".img"): # We found an image, let's install it. image_found = True rugpi_install_image(FILES / next_file) if not image_found: raise RuntimeError("unable to find image in the artifact") def state_artifact_install(): """The `ArtifactInstall` state of the update process.""" # The image has already been installed in the downloade state. It remains # to create the marker file such that Mender reboots via Rugpi. pathlib.Path("/run/rugpi/.mender-reboot-spare").touch() def state_artifact_rollback(): """The `ArtifactRollback` state of the update process.""" # Rebooting will automatically roll back the system. def state_artifact_verify_reboot(): """The `ArtifactVerifyReboot` state of the update process.""" output = subprocess.check_output(["rugpi-ctrl", "system", "info"]).decode() hot = None default = None for line in output.splitlines(): try: key, _, value = line.partition(":") except ValueError: pass else: key = key.strip() value = value.strip() if key == "Hot": hot = value elif key == "Default": default = value if hot == default: # Something went wrong! sys.exit(1) def state_artifact_commit(): """The `ArtifactCommit` state of the update process.""" rugpi_commit_system() def state_nop(): """Called for all states we do not need to handle.""" { "SupportsRollback": query_supports_rollback, "NeedsArtifactReboot": query_needs_artifact_reboot, "Download": state_download, "ArtifactInstall": state_artifact_install, "ArtifactRollback": state_artifact_rollback, "ArtifactVerifyReboot": state_artifact_verify_reboot, "ArtifactCommit": state_artifact_commit, }.get(STATE, state_nop)() ================================================ FILE: packages/os/trigger-change ================================================ Thu 15 Jan 2026 17:12:57 +07 ================================================ FILE: packages/os/umbrelos.Dockerfile ================================================ ARG DEBIAN_VERSION=trixie ARG SNAPSHOT_DATE=20251229 ARG DOCKER_VERSION=28.5.0 ARG DOCKER_INSTALL_SCRIPT_COMMIT=5c8855edd778525564500337f5ac4ad65a0c168e ARG YQ_VERSION=4.24.5 ARG YQ_SHA256_amd64=c93a696e13d3076e473c3a43c06fdb98fafd30dc2f43bc771c4917531961c760 ARG YQ_SHA256_arm64=8879e61c0b3b70908160535ea358ec67989ac4435435510e1fcb2eda5d74a0e9 ARG NODE_VERSION=22.13.0 ARG NODE_SHA256_amd64=9a33e89093a0d946c54781dcb3ccab4ccf7538a7135286528ca41ca055e9b38f ARG NODE_SHA256_arm64=e0cc088cb4fb2e945d3d5c416c601e1101a15f73e0f024c9529b964d9f6dce5b ARG KOPIA_VERSION=0.19.0 ARG KOPIA_SHA256_amd64=c07843822c82ec752e5ee749774a18820b858215aabd7da448ce665b9b9107aa ARG KOPIA_SHA256_arm64=632db9d72f2116f1758350bf7c20aa57c22c220480aaccb5f839e75669210ed9 ######################################################################### # ui build stage ######################################################################### FROM node:${NODE_VERSION}-bookworm-slim AS ui-build # Set the working directory WORKDIR /app # Copy the package.json and package-lock.json COPY packages/ui/ . # The ui-build stage only has 'packages/ui' in '/app', but the ui imports runtime values # via a relative path ('../../../umbreld/source/modules/server/trpc/common') that resolves outside '/app'. # We copy the target file to the expected path for the build to succeed. COPY packages/umbreld/source/modules/server/trpc/common.ts /umbreld/source/modules/server/trpc/common.ts # Install the dependencies RUN rm -rf node_modules || true RUN npm ci # Build the app RUN npm run build ######################################################################### # umbrelos-base-amd64 build stage ######################################################################### FROM debian:${DEBIAN_VERSION}-${SNAPSHOT_DATE} AS umbrelos-base-amd64 ARG SNAPSHOT_DATE COPY packages/os/build-steps /build-steps RUN /build-steps/initialize.sh "${SNAPSHOT_DATE}" # Install Linux kernel, non-free firmware and ZFS. RUN apt-get install --yes \ zfs-dkms \ zfsutils-linux \ linux-headers-amd64 \ linux-image-amd64 \ intel-microcode \ amd64-microcode \ firmware-linux \ firmware-realtek \ firmware-iwlwifi \ firmware-atheros # Cleanup build steps. RUN rm -rf /build-steps ######################################################################### # umbrelos-base-arm64 build stage ######################################################################### FROM debian:${DEBIAN_VERSION}-${SNAPSHOT_DATE} AS umbrelos-base-arm64 ARG SNAPSHOT_DATE COPY packages/os/build-steps /build-steps RUN /build-steps/initialize.sh "${SNAPSHOT_DATE}" RUN /build-steps/setup-raspberrypi.sh # Cleanup build steps. RUN rm -rf /build-steps ######################################################################### # umbrelos build stage ######################################################################### ARG TARGETARCH # TODO: Instead of using the debian:trixie image as a base we should # build a fresh rootfs from scratch. We can use the same tool the Docker # images use for reproducible Debian builds: https://github.com/debuerreotype/debuerreotype FROM umbrelos-base-${TARGETARCH} AS umbrelos # We need to duplicate this such that we can also use the argument below. ARG TARGETARCH ARG DOCKER_VERSION ARG DOCKER_INSTALL_SCRIPT_COMMIT ARG YQ_VERSION ARG YQ_SHA256_amd64 ARG YQ_SHA256_arm64 ARG NODE_VERSION ARG NODE_SHA256_amd64 ARG NODE_SHA256_arm64 ARG KOPIA_VERSION ARG KOPIA_SHA256_amd64 ARG KOPIA_SHA256_arm64 # Install acpid # We use acpid to implement custom behaviour for power button presses RUN apt-get install --yes acpid RUN systemctl enable acpid # Install zram-generator for swap RUN apt-get install --yes systemd-zram-generator # Install essential networking services RUN apt-get install --yes network-manager systemd-timesyncd openssh-server avahi-daemon avahi-discover avahi-utils libnss-mdns # Install bluetooth stack # The default configuration enables all bluetooth controllers/adapters present on boot and plugged in after boot RUN apt-get install --yes bluez # Install essential system utilities RUN apt-get install --yes sudo nano vim less man iproute2 iputils-ping curl wget ca-certificates usbutils whois build-essential e2fsprogs # Install umbreld dependencies # (many of these can be remove after the apps refactor) RUN apt-get install --yes python3 fswatch jq rsync git gettext-base gnupg procps dmidecode unar imagemagick ffmpeg samba wsdd2 cifs-utils smbclient nvme-cli pciutils # Disable automatically starting smbd and wsdd2 at boot so umbreld can initialize them only when they're needed RUN systemctl disable smbd wsdd2 # Filessystem support RUN apt-get install --yes gdisk parted e2fsprogs exfatprogs # For some reason this always fails on arm64 but it's ok since we # don't support external storage on Pi anyway. RUN [ "${TARGETARCH}" = "amd64" ] && apt-get install --yes ntfs-3g || true # Install Node.js RUN NODE_ARCH=$([ "${TARGETARCH}" = "arm64" ] && echo "arm64" || echo "x64") && \ NODE_SHA256=$(eval echo \$NODE_SHA256_${TARGETARCH}) && \ curl -fsSL https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${NODE_ARCH}.tar.gz -o node.tar.gz && \ echo "${NODE_SHA256} node.tar.gz" | sha256sum -c - && \ tar -xz -f node.tar.gz -C /usr/local --strip-components=1 && \ rm -rf node.tar.gz # Install yq from binary # Debian repos have kislyuk/yq but we want mikefarah/yq RUN YQ_SHA256=$(eval echo \$YQ_SHA256_${TARGETARCH}) && \ curl -L https://github.com/mikefarah/yq/releases/download/v${YQ_VERSION}/yq_linux_${TARGETARCH} -o /usr/bin/yq && \ echo "${YQ_SHA256} /usr/bin/yq" | sha256sum -c && \ chmod +x /usr/bin/yq RUN curl -fsSL https://raw.githubusercontent.com/docker/docker-install/${DOCKER_INSTALL_SCRIPT_COMMIT}/install.sh -o /tmp/install-docker.sh RUN sh /tmp/install-docker.sh --version v${DOCKER_VERSION} RUN rm /tmp/install-docker.sh # Install kopia from binary RUN KOPIA_ARCH=$([ "${TARGETARCH}" = "arm64" ] && echo "arm64" || echo "x64") && \ KOPIA_SHA256=$(eval echo \$KOPIA_SHA256_${TARGETARCH}) && \ curl -L https://github.com/kopia/kopia/releases/download/v${KOPIA_VERSION}/kopia-${KOPIA_VERSION}-linux-${KOPIA_ARCH}.tar.gz -o /tmp/kopia.tar.gz && \ echo "${KOPIA_SHA256} /tmp/kopia.tar.gz" | sha256sum -c && \ tar -xz -f /tmp/kopia.tar.gz -C /tmp && \ mv /tmp/kopia-${KOPIA_VERSION}-linux-${KOPIA_ARCH}/kopia /usr/bin/kopia && \ chmod +x /usr/bin/kopia # kopia also requires fuse3 for mounting snapshots RUN apt-get install --yes fuse3 bindfs # Add Umbrel user RUN adduser --gecos "" --disabled-password umbrel RUN echo "umbrel:umbrel" | chpasswd RUN usermod -aG sudo umbrel # Preload images RUN sudo apt-get install --yes skopeo RUN mkdir -p /images RUN skopeo copy docker://getumbrel/tor@sha256:2ace83f22501f58857fa9b403009f595137fa2e7986c4fda79d82a8119072b6a docker-archive:/images/tor RUN skopeo copy docker://getumbrel/auth-server@sha256:b4a4b37896911a85fb74fa159e010129abd9dff751a40ef82f724ae066db3c2a docker-archive:/images/auth # Install umbreld COPY packages/umbreld /opt/umbreld COPY --from=ui-build /app/dist /opt/umbreld/ui WORKDIR /opt/umbreld RUN rm -rf node_modules || true RUN npm clean-install --omit dev && npm link WORKDIR / # Copy in filesystem overlay COPY packages/os/overlay-common / COPY "packages/os/overlay-${TARGETARCH}" / # Move persistant locations to /data to be bind mounted over the OS. # /data will exist on a seperate partition that survives OS updates. # This step should always be last so things like /var/log/apt/ # exist while installing packages. # Migrataing current data is required to not break journald, otherwise # /var/log/journal will not exist and journald will log to RAM and not # persist between reboots. RUN mkdir -p /data/umbrel-os/var RUN mv /var/log /data/umbrel-os/var/log RUN mv /home /data/umbrel-os/home ================================================ FILE: packages/os/usb-installer/.gitignore ================================================ build ================================================ FILE: packages/os/usb-installer/build.sh ================================================ #!/usr/bin/env bash set -euo pipefail rootfs_dir="/tmp/rootfs" iso_image="/tmp/umbrelos-amd64-usb-installer.iso" echo "Creating directories for ISO image..." mkdir -p "${rootfs_dir}/boot/grub" echo "Extracting rootfs..." tar -xf /data/build/rootfs.tar --directory "${rootfs_dir}" echo "Creating grub.cfg..." cat > "${rootfs_dir}/boot/grub/grub.cfg" < [options] Commands: boot Boot VM from the given image reflash Delete boot disk overlay (simulates reflashing the OS) reset Delete all VM state (overlay, NVMe disks, UEFI vars) nvme list List all NVMe devices and their status nvme add [--size SIZE] Add an NVMe device to slot (1-4) nvme destroy Destroy an NVMe device (deletes data) nvme connect Connect an existing NVMe device to the VM nvme disconnect Disconnect an NVMe device from the VM nvme move Move an NVMe device from one slot to another Boot Options: --memory RAM in MiB (default: ${DEFAULT_MEMORY}) --cores CPU cores (default: ${DEFAULT_CORES}) --disk-size Boot disk size (default: ${DEFAULT_DISK_SIZE}) --ssh-port Local SSH port forward (default: ${DEFAULT_SSH_PORT}) --http-port Local HTTP port forward (default: ${DEFAULT_HTTP_PORT}) NVMe Options: --size NVMe disk size (default: ${DEFAULT_NVME_SIZE}) Environment Variables: VM_STATE_DIR Override state directory (default: ./vm-state) Examples: $0 boot umbrelos.img --memory 4096 --cores 8 $0 nvme add 1 --size 128G $0 nvme add 2 $0 nvme disconnect 2 $0 nvme list EOF } # Initialize state directory and NVMe state file init_state() { mkdir -p "$STATE_DIR" if [[ ! -f "$NVME_STATE_FILE" ]]; then echo '{}' > "$NVME_STATE_FILE" fi } # Get NVMe state for a slot get_nvme_state() { local slot="$1" local key="${2:-}" if [[ -n "$key" ]]; then jq -r ".\"$slot\".$key // empty" "$NVME_STATE_FILE" else jq -r ".\"$slot\" // empty" "$NVME_STATE_FILE" fi } # Set NVMe state for a slot set_nvme_state() { local slot="$1" local key="$2" local value="$3" local tmp tmp=$(mktemp) jq ".\"$slot\".$key = $value" "$NVME_STATE_FILE" > "$tmp" && mv "$tmp" "$NVME_STATE_FILE" } # Initialize NVMe entry init_nvme_entry() { local slot="$1" local size="$2" local serial="$3" local tmp tmp=$(mktemp) jq ".\"$slot\" = {\"size\": \"$size\", \"serial\": \"$serial\", \"connected\": true, \"exists\": true}" "$NVME_STATE_FILE" > "$tmp" && mv "$tmp" "$NVME_STATE_FILE" } # Remove NVMe entry remove_nvme_entry() { local slot="$1" local tmp tmp=$(mktemp) jq "del(.\"$slot\")" "$NVME_STATE_FILE" > "$tmp" && mv "$tmp" "$NVME_STATE_FILE" } # Validate slot number validate_slot() { local slot="$1" if [[ ! "$slot" =~ ^[1-4]$ ]]; then echo "Error: Slot must be 1-4" >&2 exit 1 fi } # Get disk path for a slot get_nvme_disk_path() { local slot="$1" echo "$STATE_DIR/nvme-slot${slot}.qcow2" } # List all NVMe devices nvme_list() { init_state echo "NVMe Devices:" echo "=============" echo printf "%-6s %-12s %-10s %-10s\n" "Slot" "Status" "Connected" "Size" printf "%-6s %-12s %-10s %-10s\n" "----" "------" "---------" "----" for slot in 1 2 3 4; do local exists connected size status exists=$(get_nvme_state "$slot" "exists") connected=$(get_nvme_state "$slot" "connected") size=$(get_nvme_state "$slot" "size") if [[ "$exists" == "true" ]]; then if [[ "$connected" == "true" ]]; then status="present" connected="yes" else status="disconnected" connected="no" fi else status="empty" connected="-" size="-" fi printf "%-6s %-12s %-10s %-10s\n" "$slot" "$status" "$connected" "$size" done echo } # Add NVMe device nvme_add() { local slot="$1" local size="$2" validate_slot "$slot" init_state local disk_path disk_path=$(get_nvme_disk_path "$slot") if [[ -f "$disk_path" ]]; then echo "Error: NVMe device already exists in slot $slot" >&2 echo "Use 'nvme destroy $slot' to remove it first" >&2 exit 1 fi # Generate a unique serial number using timestamp and random suffix local serial="nvme${slot}-$(date +%s)-${RANDOM}" echo "Creating NVMe device in slot $slot (${size})..." qemu-img create -f qcow2 "$disk_path" "$size" >/dev/null init_nvme_entry "$slot" "$size" "$serial" echo "Done. NVMe device created in slot $slot (serial: $serial)" } # Destroy NVMe device nvme_destroy() { local slot="$1" validate_slot "$slot" init_state local disk_path disk_path=$(get_nvme_disk_path "$slot") if [[ ! -f "$disk_path" ]]; then echo "Error: No NVMe device in slot $slot" >&2 exit 1 fi echo "Destroying NVMe device in slot $slot..." rm -f "$disk_path" remove_nvme_entry "$slot" echo "Done. NVMe device in slot $slot destroyed" } # Connect NVMe device nvme_connect() { local slot="$1" validate_slot "$slot" init_state local disk_path disk_path=$(get_nvme_disk_path "$slot") if [[ ! -f "$disk_path" ]]; then echo "Error: No NVMe device in slot $slot" >&2 echo "Use 'nvme add $slot' to create one first" >&2 exit 1 fi local connected connected=$(get_nvme_state "$slot" "connected") if [[ "$connected" == "true" ]]; then echo "NVMe device in slot $slot is already connected" exit 0 fi set_nvme_state "$slot" "connected" "true" echo "NVMe device in slot $slot connected (will be available on next boot)" } # Disconnect NVMe device nvme_disconnect() { local slot="$1" validate_slot "$slot" init_state local exists exists=$(get_nvme_state "$slot" "exists") if [[ "$exists" != "true" ]]; then echo "Error: No NVMe device in slot $slot" >&2 exit 1 fi local connected connected=$(get_nvme_state "$slot" "connected") if [[ "$connected" != "true" ]]; then echo "NVMe device in slot $slot is already disconnected" exit 0 fi set_nvme_state "$slot" "connected" "false" echo "NVMe device in slot $slot disconnected (will be unavailable on next boot)" } # Move NVMe device from one slot to another nvme_move() { local from_slot="$1" local to_slot="$2" validate_slot "$from_slot" validate_slot "$to_slot" init_state if [[ "$from_slot" == "$to_slot" ]]; then echo "Error: Source and destination slots are the same" >&2 exit 1 fi local from_disk_path to_disk_path from_disk_path=$(get_nvme_disk_path "$from_slot") to_disk_path=$(get_nvme_disk_path "$to_slot") if [[ ! -f "$from_disk_path" ]]; then echo "Error: No NVMe device in slot $from_slot" >&2 exit 1 fi if [[ -f "$to_disk_path" ]]; then echo "Error: Slot $to_slot already has an NVMe device" >&2 echo "Use 'nvme destroy $to_slot' to remove it first" >&2 exit 1 fi # Move the disk file mv "$from_disk_path" "$to_disk_path" # Move the state entry local tmp from_state tmp=$(mktemp) from_state=$(get_nvme_state "$from_slot") jq ".\"$to_slot\" = $from_state | del(.\"$from_slot\")" "$NVME_STATE_FILE" > "$tmp" && mv "$tmp" "$NVME_STATE_FILE" echo "NVMe device moved from slot $from_slot to slot $to_slot" } # Build QEMU NVMe arguments for connected devices build_nvme_args() { local nvme_args="" for slot in 1 2 3 4; do local exists connected disk_path pci_slot serial exists=$(get_nvme_state "$slot" "exists") connected=$(get_nvme_state "$slot" "connected") if [[ "$exists" == "true" && "$connected" == "true" ]]; then disk_path=$(get_nvme_disk_path "$slot") pci_slot="${PCI_SLOT_MAP[$slot]}" serial=$(get_nvme_state "$slot" "serial") # Fallback for devices created before serial tracking if [[ -z "$serial" ]]; then serial="nvme${slot}" fi # Create PCIe root port with correct slot number, then attach NVMe nvme_args="$nvme_args -device pcie-root-port,id=rp${slot},slot=${pci_slot},chassis=${slot}" nvme_args="$nvme_args -drive file=${disk_path},format=qcow2,if=none,id=nvme${slot},cache=none,discard=unmap,aio=threads" nvme_args="$nvme_args -device nvme,drive=nvme${slot},serial=${serial},bus=rp${slot}" fi done echo "$nvme_args" } # Detect OVMF firmware paths detect_ovmf() { if [[ -f "/opt/homebrew/share/qemu/edk2-x86_64-code.fd" ]]; then OVMF_CODE="/opt/homebrew/share/qemu/edk2-x86_64-code.fd" OVMF_VARS_TEMPLATE="/opt/homebrew/share/qemu/edk2-i386-vars.fd" elif [[ -f "/usr/local/share/qemu/edk2-x86_64-code.fd" ]]; then OVMF_CODE="/usr/local/share/qemu/edk2-x86_64-code.fd" OVMF_VARS_TEMPLATE="/usr/local/share/qemu/edk2-i386-vars.fd" elif [[ -f "/usr/share/OVMF/OVMF_CODE_4M.fd" ]]; then OVMF_CODE="/usr/share/OVMF/OVMF_CODE_4M.fd" OVMF_VARS_TEMPLATE="/usr/share/OVMF/OVMF_VARS_4M.fd" else echo "Error: OVMF firmware not found. On macOS: brew install qemu" >&2 exit 1 fi } # Boot the VM boot_vm() { local image="$1" local memory="$2" local cores="$3" local disk_size="$4" local ssh_port="$5" local http_port="$6" init_state detect_ovmf if [[ ! -f "$image" ]]; then echo "Error: Image not found: $image" >&2 exit 1 fi command -v qemu-img >/dev/null 2>&1 || { echo "Error: 'qemu-img' not found in PATH" >&2; exit 1; } command -v qemu-system-x86_64 >/dev/null 2>&1 || { echo "Error: 'qemu-system-x86_64' not found in PATH" >&2; exit 1; } # Setup OVMF VARS local ovmf_vars="$STATE_DIR/ovmf-vars.fd" if [[ ! -f "$ovmf_vars" ]]; then cp "$OVMF_VARS_TEMPLATE" "$ovmf_vars" fi # Setup overlay disk local overlay="$STATE_DIR/overlay.qcow2" if [[ ! -f "$overlay" ]]; then echo "Creating overlay image..." local image_abs image_abs="$(cd "$(dirname "$image")" && pwd)/$(basename "$image")" qemu-img create -f qcow2 -F raw -b "$image_abs" "$overlay" "$disk_size" >/dev/null else echo "Using existing overlay image" fi # Build NVMe arguments local nvme_args nvme_args=$(build_nvme_args) # Platform-specific acceleration local accel_args local qemu_sudo="" case "$(uname -s)" in Linux) accel_args="-enable-kvm -machine accel=kvm,type=q35 -cpu host" # Use sudo for KVM access on Linux qemu_sudo="sudo" ;; Darwin) if qemu-system-x86_64 -accel help 2>&1 | grep -q hvf; then accel_args="-machine accel=hvf,type=q35 -cpu max" else echo "WARNING: HVF not available, using TCG (slow)" >&2 accel_args="-machine accel=tcg,type=q35 -cpu max" fi ;; *) echo "Error: Unsupported platform: $(uname -s)" >&2 exit 1 ;; esac echo "Booting VM..." echo " SSH: ssh -p ${ssh_port} umbrel@localhost" echo " HTTP: http://localhost:${http_port}" echo # shellcheck disable=SC2086 exec $qemu_sudo qemu-system-x86_64 \ $accel_args \ -smp "$cores" \ -m "$memory" \ -rtc base=utc \ -nographic -monitor none -chardev stdio,id=char0,signal=off -serial chardev:char0 \ -smbios "type=1,manufacturer=Umbrel,, Inc.,product=Umbrel Pro,sku=U4XN1,family=NAS" \ -drive if=pflash,format=raw,readonly=on,file="$OVMF_CODE" \ -drive if=pflash,format=raw,file="$ovmf_vars" \ -drive file="$overlay",if=none,id=boot,format=qcow2,cache=none,discard=unmap,aio=threads \ -device virtio-blk-pci,drive=boot,bootindex=0 \ -netdev user,id=net0,hostfwd=tcp:127.0.0.1:${ssh_port}-:22,hostfwd=tcp:127.0.0.1:${http_port}-:80 \ -device virtio-net-pci,netdev=net0 \ $nvme_args } # Reflash (delete overlay to simulate fresh OS install) reflash() { local overlay="$STATE_DIR/overlay.qcow2" if [[ -f "$overlay" ]]; then echo "Removing boot disk overlay..." rm -f "$overlay" echo "Done. Next boot will start fresh." else echo "No overlay to remove." fi } # Reset all state reset_state() { if [[ -d "$STATE_DIR" ]]; then echo "Removing VM state directory: $STATE_DIR" rm -rf "$STATE_DIR" echo "Done." else echo "No state to reset." fi } # Main if [[ $# -lt 1 ]]; then show_help exit 1 fi command="$1" shift case "$command" in help|--help|-h) show_help exit 0 ;; reflash) reflash exit 0 ;; reset) reset_state exit 0 ;; nvme) if [[ $# -lt 1 ]]; then echo "Error: nvme requires a subcommand" >&2 echo "Usage: $0 nvme [args]" >&2 exit 1 fi subcommand="$1" shift case "$subcommand" in list) nvme_list ;; add) if [[ $# -lt 1 ]]; then echo "Error: nvme add requires a slot number" >&2 exit 1 fi slot="$1" shift size="$DEFAULT_NVME_SIZE" while [[ $# -gt 0 ]]; do case "$1" in --size) size="$2" shift 2 ;; *) echo "Error: Unknown option: $1" >&2 exit 1 ;; esac done nvme_add "$slot" "$size" ;; destroy) if [[ $# -lt 1 ]]; then echo "Error: nvme destroy requires a slot number" >&2 exit 1 fi nvme_destroy "$1" ;; connect) if [[ $# -lt 1 ]]; then echo "Error: nvme connect requires a slot number" >&2 exit 1 fi nvme_connect "$1" ;; disconnect) if [[ $# -lt 1 ]]; then echo "Error: nvme disconnect requires a slot number" >&2 exit 1 fi nvme_disconnect "$1" ;; move) if [[ $# -lt 2 ]]; then echo "Error: nvme move requires source and destination slot numbers" >&2 echo "Usage: $0 nvme move " >&2 exit 1 fi nvme_move "$1" "$2" ;; *) echo "Error: Unknown nvme subcommand: $subcommand" >&2 echo "Usage: $0 nvme [args]" >&2 exit 1 ;; esac exit 0 ;; boot) if [[ $# -lt 1 ]]; then echo "Error: boot requires an image path" >&2 exit 1 fi image="$1" shift memory="$DEFAULT_MEMORY" cores="$DEFAULT_CORES" disk_size="$DEFAULT_DISK_SIZE" ssh_port="$DEFAULT_SSH_PORT" http_port="$DEFAULT_HTTP_PORT" while [[ $# -gt 0 ]]; do case "$1" in --memory) memory="$2" shift 2 ;; --cores) cores="$2" shift 2 ;; --disk-size) disk_size="$2" shift 2 ;; --ssh-port) ssh_port="$2" shift 2 ;; --http-port) http_port="$2" shift 2 ;; *) echo "Error: Unknown option: $1" >&2 exit 1 ;; esac done boot_vm "$image" "$memory" "$cores" "$disk_size" "$ssh_port" "$http_port" ;; *) echo "Error: Unknown command: $command" >&2 show_help exit 1 ;; esac ================================================ FILE: packages/ui/.dockerignore ================================================ node_modules .git .dockerignore Dockerfile README.md npm-debug.log ================================================ FILE: packages/ui/.gitignore ================================================ # custom public/generated-tabler-icons todo.md # Logs logs *.log npm-debug.log* yarn-debug.log* yarn-error.log* pnpm-debug.log* lerna-debug.log* node_modules dist dist-app-auth dist-ssr *.local # Editor directories and files .idea .DS_Store *.suo *.ntvs* *.njsproj *.sln *.sw? ================================================ FILE: packages/ui/.prettierignore ================================================ package-lock.json node_modules public/locales/*.json ================================================ FILE: packages/ui/.prettierrc.js ================================================ import baseConfig from '../../.prettierrc.js' /** * @type {import('prettier').Config & import("@ianvs/prettier-plugin-sort-imports").PluginConfig} */ export default { ...baseConfig, plugins: [ ...(baseConfig.plugins || []), '@ianvs/prettier-plugin-sort-imports', 'prettier-plugin-css-order', 'prettier-plugin-tailwindcss', // must come last ], // Empty string to separate groups importOrder: ['', '', '^@/', '', '^[../]', '^[./]'], importOrderParserPlugins: ['typescript', 'jsx'], importOrderTypeScriptVersion: '4.4.0', tailwindStylesheet: './src/index.css', } ================================================ FILE: packages/ui/Dockerfile ================================================ FROM node:18.19.1-buster-slim # Set the working directory WORKDIR /app # Copy the package.json and package-lock.json COPY packages/ui/package.json ./ COPY packages/ui/package-lock.json ./ # Install the dependencies RUN npm ci # Copy the rest of the files COPY packages/ui/ . # Build the app RUN npm run app-auth:build # Expose the port EXPOSE 2003 # Start the app CMD ["npm", "run", "app-auth:start"] ================================================ FILE: packages/ui/app-auth/README.md ================================================ # Local testing Make sure umbreld is running ``` cd packages/umbreld npm run dev ``` Then in another terminal ``` cd packages/ui pnpm run app-auth:dev ``` Go to `localhost:3001` and make sure you're logged out. Then, assuming `transmission` is installed and running, open: http://localhost:2001/app-auth/?origin=host&app=transmission&path=%2Ftransmission%2Fweb%2F In production, it would be: http://localhost:2000/?origin=host&app=transmission&path=%2Ftransmission%2Fweb%2F Login with password and 2fa should work and you should be redirected to the right page. ================================================ FILE: packages/ui/app-auth/index.html ================================================ Umbrel
================================================ FILE: packages/ui/app-auth/src/login-with-umbrel.tsx ================================================ import {ReactNode, useEffect, useState} from 'react' import {arrayIncludes} from 'ts-extras' import {AppIcon} from '@/components/app-icon' import {Button} from '@/components/ui/button' import {FadeInImg} from '@/components/ui/fade-in-img' import {PasswordInput} from '@/components/ui/input' import {PinInput} from '@/components/ui/pin-input' import {toast} from '@/components/ui/toast' import {useQueryParams} from '@/hooks/use-query-params' import {cn} from '@/lib/utils' import {useWallpaperCssVars, WallpaperId, wallpaperIds} from '@/providers/wallpaper' import {t} from '@/utils/i18n' type Step = 'password' | '2fa' export default function LoginWithUmbrel() { const [password, setPassword] = useState('') const [step, setStep] = useState('password') const login = useLogin() const handleSubmitPassword = async (e: React.FormEvent) => { e.preventDefault() // alert('submit') try { const data = await login({password, totpToken: ''}) if ('error' in data && data.error) { if (data.error.message === 'Missing 2FA code') { setStep('2fa') } else { toast.error(data.error.message) } } } catch (error: any) { if (error.message === 'Missing 2FA code') { setStep('2fa') } else { toast.error(error?.message) } } } // Specifying return because we want to ensure that the return type is a boolean for the `onCodeCheck` prop const handleSubmit2fa = async (totpToken: string): Promise => { const data = await login({password, totpToken}) return 'error' in data } switch (step) { case 'password': { return (
{/* */}
) } case '2fa': { return (
) } } } function useLogin() { // /v1/account/login const login = ({password, totpToken}: {password: string; totpToken: string}) => { // Forward the query params to the login endpoint return fetch('/v1/account/login' + document.location.search, { method: 'POST', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({password, totpToken}), }).then(async (res) => { const data = (await res.json()) as | { url: string params: {r: string; token: string; signature: string} } | {error?: {code: number; message: string}} // { // "error": { // "message": "Missing 2FA code", // "code": -32001, // "data": { // "code": "UNAUTHORIZED", // "httpStatus": 401, // "stack": "TRPCError: Missing 2FA code... // "path": "user.login", // "zodError": null // } // } // } if ('url' in data) { // const json = { // "url": "http://localhost:3011/umbrel_/api/v1/auth/token", // "params": { // "r": "/", // "token": "eyJhbGciOiJI...", // "signature": "NUH1ZzFEeS..." // } // } const form = document.createElement('form') form.method = 'POST' form.action = data.url form.style.display = 'none' for (const [key, value] of Object.entries(data.params)) { const input = document.createElement('input') input.type = 'hidden' input.name = key input.value = value form.appendChild(input) } document.body.appendChild(form) form.submit() } return data }) } return login } type App = { id: string icon: string name: string } function useApp(appId: string) { const [app, setApp] = useState({id: '', icon: '', name: ''}) // const [searchParams, setSearchParams] = useSearchParams() useEffect(() => { fetch(`/v1/apps?app=${appId}`).then(async (res) => { const data = await res.json() setApp({...data, icon: appId ? `https://getumbrel.github.io/umbrel-apps-gallery/${appId}/icon.svg` : undefined}) }) }, [appId]) return app } function useWallpaperId() { const [wallpaper, setWallpaper] = useState() useEffect(() => { fetch('/v1/account/wallpaper') .then(async (res) => { // `unknown` because `any` is too loose const id = (await res.text()) as unknown const knownId = arrayIncludes(wallpaperIds, id) ? id : '18' setWallpaper(knownId) }) .catch(() => { setWallpaper('18') }) }, []) return wallpaper } function LoginWithLayout({children}: {children: ReactNode}) { const params = useQueryParams<{app: string; path: string; host: string}>() const app = useApp(params.object.app) const wallpaperId = useWallpaperId() useWallpaperCssVars(wallpaperId) return ( <>

{t('login-with-umbrel.title')}

{t('login-with-umbrel.description', {app: app.name})}

{children}
) } ================================================ FILE: packages/ui/app-auth/src/main.tsx ================================================ import {BrowserRouter} from 'react-router-dom' import {init} from '../../src/init' import LoginWithUmbrel from './login-with-umbrel' init( // NOTE: not putting `GlobalSystemStateProvider` here because we don't care. // It doesn't matter for the auth page , ) ================================================ FILE: packages/ui/app-auth/vite.config.ts ================================================ import path from 'node:path' import react from '@vitejs/plugin-react' import {defineConfig} from 'vite' // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], server: { proxy: { '/v1': 'http://localhost:2000', }, }, resolve: { alias: { '@/': `${path.resolve(__dirname, '../src')}/`, }, }, build: { rollupOptions: { input: { index: path.resolve(__dirname, 'index.html'), }, output: { minifyInternalExports: true, }, }, outDir: 'dist-app-auth', }, }) ================================================ FILE: packages/ui/components.json ================================================ { "$schema": "https://ui.shadcn.com/schema.json", "style": "default", "rsc": false, "tsx": true, "tailwind": { "config": "tailwind.config.ts", "css": "src/index.css", "baseColor": "neutral", "cssVariables": false }, "aliases": { "components": "@/components", "ui": "@/components/ui", "utils": "@/lib/utils", "lib": "@/lib", "hooks": "@/hooks" } } ================================================ FILE: packages/ui/eslint.config.js ================================================ import js from '@eslint/js' import pluginQuery from '@tanstack/eslint-plugin-query' import pluginReact from 'eslint-plugin-react' import pluginReactHooks from 'eslint-plugin-react-hooks' import pluginReactRefresh from 'eslint-plugin-react-refresh' import globals from 'globals' import tseslint from 'typescript-eslint' export default [ // Global ignores { ignores: ['dist/**', 'dist-app-auth/**'], }, // Base JS recommended rules js.configs.recommended, // TypeScript recommended rules ...tseslint.configs.recommended, // TanStack Query recommended rules ...pluginQuery.configs['flat/recommended'], // Main config for all JS/TS files { files: ['**/*.{js,jsx,ts,tsx}'], languageOptions: { globals: { ...globals.browser, ...globals.es2020, }, }, plugins: { react: pluginReact, 'react-hooks': pluginReactHooks, 'react-refresh': pluginReactRefresh, }, settings: { react: {version: '19'}, }, rules: { 'react/jsx-key': 'error', // Prettier configured to use tabs, which means smart tabs. We don't manually indent anyways 'no-mixed-spaces-and-tabs': 'off', // Ignore even if it's true that it catches problems fast refresh 'react-refresh/only-export-components': ['off', {allowConstantExport: true}], // https://github.com/prettier/prettier/issues/2800 // Prettier will remove extra semi-colons anyways. Prevent error when prettier puts a semicolon before an IIFE 'no-extra-semi': 'off', // shadcn ui sometimes takes an unused `children` prop so it's not spread into an element that shouldn't take children '@typescript-eslint/no-unused-vars': 'warn', // Allow any '@typescript-eslint/no-explicit-any': 'off', }, }, ] ================================================ FILE: packages/ui/index.html ================================================ Umbrel
================================================ FILE: packages/ui/package.json ================================================ { "name": "ui", "private": true, "version": "0.0.0", "type": "module", "engines": { "node": "^22.13.0" }, "scripts": { "dev": "vite --port 3000", "build": "vite build", "app-auth:dev": "vite --config app-auth/vite.config.js --port 2001", "app-auth:build": "vite build --config app-auth/vite.config.js && mv dist-app-auth/app-auth/index.html dist-app-auth/index.html", "app-auth:start": "serve -p 2003 dist-app-auth", "lint": "eslint .", "typecheck": "tsc --noEmit", "preview": "vite preview", "format": "prettier --write .", "format:check": "prettier --check .", "tsc": "tsc --noEmit", "size": "vite-bundle-visualizer", "copy-tabler-icons": "mkdir -p public/generated-tabler-icons && cp -r ./node_modules/@tabler/icons/icons/. ./public/generated-tabler-icons", "postinstall": "npm run copy-tabler-icons" }, "dependencies": { "@dnd-kit/core": "^6.3.1", "@dnd-kit/modifiers": "^9.0.0", "@dnd-kit/utilities": "^3.2.2", "@hookform/resolvers": "5.2.2", "@radix-ui/react-checkbox": "^1.3.3", "@radix-ui/react-context-menu": "^2.2.16", "@radix-ui/react-dialog": "^1.1.15", "@radix-ui/react-dropdown-menu": "^2.1.16", "@radix-ui/react-label": "^2.1.8", "@radix-ui/react-popover": "^1.1.15", "@radix-ui/react-portal": "^1.1.10", "@radix-ui/react-progress": "^1.1.8", "@radix-ui/react-radio-group": "^1.3.8", "@radix-ui/react-scroll-area": "^1.2.10", "@radix-ui/react-separator": "^1.1.8", "@radix-ui/react-slot": "^1.2.4", "@radix-ui/react-switch": "^1.2.6", "@radix-ui/react-tabs": "^1.1.13", "@radix-ui/react-tooltip": "^1.2.8", "@tanstack/react-query": "5.90.20", "@tanstack/react-query-devtools": "5.91.3", "@trpc/client": "11.1.1", "@trpc/react-query": "11.1.1", "@trpc/server": "11.1.1", "@xterm/addon-fit": "^0.9.0", "@xterm/xterm": "^5.4.0", "bignumber.js": "^9.1.2", "class-variance-authority": "0.7.1", "clsx": "2.1.1", "cmdk": "^1.1.1", "colorthief": "^2.4.0", "compute-scroll-into-view": "^3.1.0", "date-fns": "^3.0.6", "embla-carousel-react": "^8.6.0", "file-saver": "^2.0.5", "filenamify": "^6.0.0", "fuse.js": "^7.0.0", "i18next": "23.6.0", "i18next-browser-languagedetector": "7.1.0", "i18next-http-backend": "2.2.2", "inter-ui": "3.19.3", "lucide-react": "^0.440.0", "match-sorter": "6.3.1", "motion": "^12.33.0", "photoswipe": "^5.4.2", "pretty-bytes": "^6.1.1", "rci": "0.1.0", "react": "^19.0.0", "react-dom": "^19.0.0", "react-dropzone": "^14.3.5", "react-error-boundary": "^4.0.11", "react-hook-form": "7.71.1", "react-i18next": "13.3.1", "react-icons": "4.11.0", "react-json-tree": "^0.20.0", "react-markdown": "^9.0.1", "react-merge-refs": "^2.1.1", "react-qr-code": "^2.0.18", "react-router-dom": "^6.30.3", "react-use": "^17.6.0", "react-video-kit": "^3.0.0", "react-virtualized-auto-sizer": "^1.0.25", "react-window": "^1.8.11", "react-window-infinite-loader": "^1.0.10", "recharts": "^2.15.4", "remark-breaks": "^4.0.0", "remark-gfm": "^4.0.0", "remeda": "^1.28.0", "semver": "^7.6.3", "sonner": "^2.0.7", "tailwind-merge": "^3.0.0", "ts-extras": "^0.11.0", "tw-animate-css": "^1.4.0", "use-is-focused": "0.0.1", "vaul": "^1.1.2", "zod": "4.0.8", "zustand": "^5.0.2" }, "devDependencies": { "@eslint/js": "^9.0.0", "@ianvs/prettier-plugin-sort-imports": "4.7.1", "@tabler/icons": "2.39.0", "@tailwindcss/typography": "^0.5.19", "@tailwindcss/vite": "^4.0.0", "@tanstack/eslint-plugin-query": "^5.0.5", "@types/file-saver": "^2.0.7", "@types/node": "20.19.32", "@types/react": "^19.0.0", "@types/react-dom": "^19.0.0", "@types/react-virtualized-auto-sizer": "^1.0.4", "@types/react-window": "^1.8.8", "@types/react-window-infinite-loader": "^1.0.9", "@types/semver": "^7.5.4", "@vitejs/plugin-react": "^5.1.3", "babel-plugin-react-compiler": "^1.0.0", "eslint": "^9.0.0", "eslint-plugin-react": "^7.37.0", "eslint-plugin-react-hooks": "^5.0.0", "eslint-plugin-react-refresh": "^0.4.19", "fast-glob": "^3.3.2", "globals": "^15.0.0", "openai": "^6.0.0", "prettier": "3.8.1", "prettier-plugin-css-order": "2.2.0", "prettier-plugin-tailwindcss": "^0.7.2", "serve": "14.2.5", "tailwindcss": "^4.1.18", "ts-plugin-sort-import-suggestions": "^1.0.4", "typescript": "^5.8.3", "typescript-eslint": "^8.0.0", "vite": "^6.0.0", "vite-bundle-visualizer": "^1.2.0", "vite-imagetools": "^9.0.0" } } ================================================ FILE: packages/ui/public/locales/de.json ================================================ { "2fa": "2FA", "2fa-description": "Eine zweite Sicherheitsebene für dein Umbrel-Login und Apps", "2fa.disable.title": "Zwei-Faktor-Authentifizierung deaktivieren", "2fa.enable.or-paste": "Oder füge den folgenden Code in deine Authenticator-App ein", "2fa.enable.scan-this": "Scanne diesen QR-Code mit einer Authenticator-App wie Google Authenticator oder Authy", "2fa.enable.title": "Zwei-Faktor-Authentifizierung aktivieren", "2fa.enter-code": "Gib den Code ein, der in deiner Authenticator-App angezeigt wird", "account": "Konto", "account-description": "Dein Name und Passwort", "advanced-settings": "Erweiterte Einstellungen", "advanced-settings-description": "Terminal, umbrelOS-Beta-Programm, Cloudflare DNS und mehr", "app-not-found": "App nicht gefunden: {{app}}", "app-only-over-tor": "{{app}} kann nur über Tor verwendet werden. Bitte rufe dein Umbrel in einem Tor-Browser über deine Remote‑Zugriffs‑URL (Einstellungen > Erweiterte Einstellungen > Remote Tor‑Zugriff) auf, um diese App zu öffnen.", "app-page.section.about": "Über", "app-page.section.credentials.title": "Standardanmeldeinformationen", "app-page.section.dependencies.n-alternatives": "{{count}} Alternativen ansehen", "app-page.section.info.compatibility": "Kompatibilität", "app-page.section.info.compatibility-compatible": "Kompatibel", "app-page.section.info.compatibility-not-compatible": "Nicht kompatibel", "app-page.section.info.developer": "Entwickler", "app-page.section.info.source-code": "Quellcode", "app-page.section.info.source-code.public": "Öffentlich", "app-page.section.info.submitted-by": "Eingereicht von", "app-page.section.info.support": "Support erhalten", "app-page.section.info.title": "Info", "app-page.section.info.version": "Version", "app-page.section.recommendations.title": "Das könnte dir auch gefallen", "app-page.section.release-notes.title": "Neuigkeiten", "app-page.section.release-notes.version": "Version {{version}}", "app-page.section.requires": "Benötigt", "app-picker.search": "Suchen...", "app-picker.select-app": "App auswählen...", "app-settings.connected-to": "{{appName}} ist mit diesen Apps verbunden", "app-settings.save-changes": "Änderungen speichern", "app-settings.title": "Einstellungen", "app-store.browse-category-apps": "{{category}} Apps durchsuchen", "app-store.category.ai": "KI", "app-store.category.all": "Alle Apps", "app-store.category.automation": "Zuhause & Automatisierung", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Krypto", "app-store.category.developer": "Entwicklerwerkzeuge", "app-store.category.discover": "Entdecken", "app-store.category.files": "Dateien & Produktivität", "app-store.category.finance": "Finanzen", "app-store.category.media": "Medien", "app-store.category.networking": "Netzwerk", "app-store.category.social": "Sozial", "app-store.description": "Deine App-Aktualisierungseinstellungen", "app-store.discover.temporarily-unavailable-description": "Durchsuche die Kategorien oben oder verwende die Suche, um Apps zu finden", "app-store.discover.temporarily-unavailable-title": "Ausgewählte Inhalte vorübergehend nicht verfügbar", "app-store.menu.community-app-stores": "Community App Stores", "app-store.search-apps": "Apps suchen", "app-store.search.no-results": "Keine Ergebnisse", "app-store.search.results-for": "Ergebnisse für", "app-store.title": "App Store", "app-store.updates": "Aktualisierungen", "app-updates.less": "weniger", "app-updates.more": "mehr", "app-updates.no-updates": "Alle Apps sind auf dem neuesten Stand!", "app-updates.update": "Aktualisieren", "app-updates.update-all": "Alle aktualisieren", "app-updates.updates-available-count_one": "{{count}} Aktualisierung verfügbar", "app-updates.updates-available-count_other": "{{count}} Aktualisierungen verfügbar", "app-updates.updating": "Aktualisiert...", "app.install": "Installieren", "app.installed": "Installiert", "app.installing": "Installiert", "app.offline": "Nicht in Betrieb", "app.open": "Öffnen", "app.optimized-for-umbrel-home": "Optimiert für Umbrel Home", "app.os-update-required.confirm": "Prüfe auf umbrelOS-Update", "app.os-update-required.description": "{{appName}} erfordert umbrelOS {{version}} oder neuer", "app.os-update-required.title": "umbrelOS aktualisieren", "app.restarting": "Wird neu gestartet", "app.starting": "Wird gestartet", "app.stopping": "Wird gestoppt", "app.uninstall.confirm.description": "Alle mit {{app}} verbundenen Daten werden dauerhaft gelöscht. Diese Aktion kann nicht rückgängig gemacht werden.", "app.uninstall.confirm.submit": "Deinstallieren", "app.uninstall.confirm.title": "{{app}} deinstallieren?", "app.uninstall.deps.used-by.description_one": "Deinstalliere zuerst {{firstAppToUninstall}}, um {{app}} zu deinstallieren.", "app.uninstall.deps.used-by.description_other": "Deinstalliere zuerst diese Apps, um {{app}} zu deinstallieren.", "app.uninstall.deps.used-by.title": "{{app}} wird verwendet von", "app.uninstalling": "Deinstallieren", "app.updating": "Aktualisieren", "app.view": "Ansehen", "app_one": "App", "app_other": "Apps", "apps.uninstall.failed-to-get-required-apps": "Fehler beim Abrufen erforderlicher Apps", "apps.uninstalled-all.success": "Alle Apps deinstalliert", "auth.checking-backend-for-user": "Lädt...", "auth.failed-checking-if-user-logged-in": "Fehler: Auth-Login-Überprüfung fehlgeschlagen", "auth.failed-to-check-if-user-exists": "Fehler: Auth-Existenzprüfung fehlgeschlagen", "back": "Zurück", "backups": "Backups", "backups-configure": "Konfigurieren", "backups-configure.add-backup-location": "Backup-Standort hinzufügen", "backups-configure.available": "Verfügbar", "backups-configure.awaiting-next-backup": "Warten auf das nächste automatische Backup", "backups-configure.back-up-now": "Jetzt sichern", "backups-configure.backing-up-now": "Sicherung läuft...", "backups-configure.connected": "Verbunden", "backups-configure.connection": "Verbindung", "backups-configure.in-progress": "In Bearbeitung", "backups-configure.last-backup": "Letzte Sicherung", "backups-configure.locations": "Standorte", "backups-configure.no-backup-locations": "Füge einen Backup-Standort hinzu, um deine Daten zu sichern", "backups-configure.not-connected": "Nicht verbunden", "backups-configure.path": "Pfad", "backups-configure.remove-backup-location": "Backup-Standort entfernen", "backups-configure.remove-backup-location-confirmation": "Bist du sicher?", "backups-configure.remove-backup-location-confirmation-description": "Dadurch wird '{{device}}' aus deinen Backup-Standorten entfernt. Deine vorhandenen Backups auf diesem Gerät werden nicht gelöscht, aber automatische Backups werden eingestellt.", "backups-configure.status": "Status", "backups-configure.total-backups": "Backups insgesamt", "backups-configure.used": "Belegt", "backups-configure.view": "Ansehen", "backups-description": "Sichere deine Dateien, Apps und Daten auf einem anderen Umbrel, NAS oder einem externen Laufwerk", "backups-error.backup-not-found": "Das Backup konnte nicht gefunden werden.", "backups-error.generic": "Etwas ist schiefgelaufen: {{details}}", "backups-error.in-progress": "Ein Backup-Prozess läuft bereits. Bitte warte, bis er abgeschlossen ist.", "backups-error.invalid-exclusion-path": "Nur Dateien und Ordner in deinem Home-Verzeichnis können von Backups ausgeschlossen werden.", "backups-error.invalid-password": "Das Verschlüsselungspasswort ist falsch.", "backups-error.invalid-path": "Der ausgewählte Speicherort ist für Backups nicht geeignet.", "backups-error.mount-failed": "Auf den Backup-Snapshot konnte nicht zugegriffen werden.", "backups-error.mount-timeout": "Auf den Backup-Snapshot konnte nicht zugegriffen werden. Versuche es erneut oder prüfe, ob das Gerät richtig angeschlossen ist.", "backups-error.not-enough-space": "Auf dem Backup-Gerät ist nicht genug Speicherplatz verfügbar.", "backups-error.not-found": "Das Backup oder der Backup-Speicherort konnten nicht gefunden werden.", "backups-error.repository-exists": "Für diesen Ordner existiert bereits ein Backup-Speicherort.", "backups-error.repository-not-found": "Der Backup-Speicherort konnte nicht gefunden werden.", "backups-exclusions.add": "Hinzufügen", "backups-exclusions.app-paths-cannot-be-modified": "Diese Dateien/Ordner werden vom App-Entwickler festgelegt und können nicht geändert werden:", "backups-exclusions.app-paths-explanation": "Diese App schließt die folgenden Daten vom Backup aus. Diese Pfade enthalten meist nicht essentielle Elemente (wie Caches oder Logs, die neu erzeugt werden können) oder Daten, die Probleme verursachen könnten, wenn sie wiederhergestellt werden (z. B. veraltete App-Zustände, die Konflikte oder Inkonsistenzen auslösen könnten).", "backups-exclusions.auto-excluded": "Automatisch ausgeschlossen", "backups-exclusions.exclude-entire-app": "Ganze App ausschließen", "backups-exclusions.excluded-apps": "Ausgeschlossene Apps", "backups-exclusions.files-and-folders": "Ausgeschlossene Dateien und Ordner", "backups-exclusions.no-excluded-apps": "Keine ausgeschlossenen Apps", "backups-exclusions.no-excluded-files-or-folders": "Keine ausgeschlossenen Dateien oder Ordner", "backups-exclusions.select-item-to-exclude": "Element zum Ausschließen auswählen", "backups-exclusions.stop-excluding": "Ausschluss aufheben", "backups-floating-island.backing-up": "Sicherung läuft...", "backups-floating-island.backing-up-to": "Sichere dein Umbrel...", "backups-restore": "Wiederherstellen", "backups-restore-full": "Vollständige Wiederherstellung", "backups-restore-full-description": "Stelle dein gesamtes Umbrel aus einem Backup wieder her", "backups-restore-header": "Stelle dein Umbrel wieder her", "backups-restore-pro.after-restore": "Nach der Wiederherstellung wird dein temporäres Konto durch dein gesichertes Konto und dessen Daten ersetzt.", "backups-restore-pro.step1": "Schließe die Einrichtung ab, indem du unten auf \"Los geht's\" klickst. Dies wird dein temporäres Konto sein, bis du dein gesichertes Konto wiederherstellst.", "backups-restore-pro.step2": "Sobald die Einrichtung abgeschlossen ist, gehe zu <0>Einstellungen → Backups → Wiederherstellen", "backups-restore-pro.step3": "Folge den Anweisungen des Wiederherstellungsassistenten.", "backups-restore-pro.subtitle": "Das Wiederherstellen eines Backups auf Umbrel Pro erfordert ein paar zusätzliche Schritte", "backups-restore.backup-date": "Backup-Datum", "backups-restore.backup-location": "Backup-Standort", "backups-restore.browse-cloud-subtitle": "Von der Umbrel Private Cloud wiederherstellen (kommt bald)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Von einem externen USB-Laufwerk wiederherstellen", "backups-restore.browse-external-title": "Externe Festplatte", "backups-restore.browse-nas-or-external": "Durchsuche einen anderen Umbrel, NAS oder ein externes Laufwerk, um ein Backup wiederherzustellen", "backups-restore.browse-nas-subtitle": "Von einem anderen Umbrel- oder NAS-Gerät in deinem Netzwerk wiederherstellen", "backups-restore.browse-nas-title": "Anderes Umbrel oder NAS", "backups-restore.choose": "Auswählen", "backups-restore.choose-backup-location": "Wähle einen Backup-Standort", "backups-restore.connect-to-backup-location": "Mit Backup-Standort verbinden", "backups-restore.encryption-password": "Verschlüsselungs-Passwort", "backups-restore.encryption-password-description": "Gib das Verschlüsselungspasswort ein, das du festgelegt hast, als du Backups aktiviert hast.", "backups-restore.enter-password-to-confirm": "Gib dein Umbrel-Passwort ein, um zu bestätigen", "backups-restore.final-confirmation": "Bist du sicher?", "backups-restore.final-confirmation-description": "Das Wiederherstellen aus diesem Backup ersetzt deine aktuellen umbrelOS Apps und Daten durch den Inhalt des ausgewählten Backups. Alle Dateien, Ordner oder Apps, die von diesem Backup ausgeschlossen wurden, werden von deinem Umbrel entfernt. Diese Aktion kann nicht rückgängig gemacht werden.", "backups-restore.invalid-password": "Ungültiges Passwort", "backups-restore.last-backup": "Letztes Backup: {{date}}", "backups-restore.latest": "Neueste", "backups-restore.no-backups-found": "Keine Backups gefunden", "backups-restore.no-backups-yet": "Noch keine Backups", "backups-restore.please-select-backup": "Bitte wähle ein Backup aus", "backups-restore.please-select-repository": "Bitte wähle ein Repository aus", "backups-restore.restore-from-nas-or-external": "Stelle dein Umbrel aus einem Backup wieder her, das sich auf einem anderen Umbrel, einem NAS oder einem externen Laufwerk befindet.", "backups-restore.restore-from-unlisted": "Von einem anderen Ort wiederherstellen", "backups-restore.restore-umbrel": "Umbrel wiederherstellen", "backups-restore.restore-warning": "Das Wiederherstellen aus diesem Backup ersetzt deine aktuellen umbrelOS Apps und Daten durch den Inhalt des ausgewählten Backups. Alle von diesem Backup ausgeschlossenen Dateien, Ordner oder Apps werden von deinem Umbrel entfernt. Öffne <0>Rewind, wenn du stattdessen bestimmte Dateien oder Ordner wiederherstellen möchtest.", "backups-restore.restoring-from": "Du wirst gleich das folgende Backup wiederherstellen:", "backups-restore.review-description": "Beim Wiederherstellen wird dein Umbrel mit dem Konto, den Files, den Apps und den Einstellungen eingerichtet, die zum Zeitpunkt dieses Backups enthalten waren. Das kann einige Zeit dauern. Sobald der Vorgang abgeschlossen ist, wird dein Anmeldepasswort auf das Passwort gesetzt, das du beim Erstellen des Backups verwendet hast.", "backups-restore.select-backup": "Wähle ein Backup", "backups-restore.select-backup-description": "Wähle das Backup aus, von dem du wiederherstellen möchtest", "backups-restore.select-backup-file": "Wähle deine Backup-Datei aus", "backups-restore.select-backup-file-only": "Nur {{backupFileName}} kann ausgewählt werden", "backups-restore.total-size": "Gesamtgröße", "backups-restore.unknown-date": "Unbekanntes Datum", "backups-restore.unknown-repository": "Unbekanntes Repository", "backups-rewind": "Rewind", "backups-rewind-description": "Spring zurück in der Zeit, um bestimmte Dateien und Ordner wiederherzustellen", "backups-rewind.start": "Rewind starten", "backups-setup": "Einrichten", "backups-setup-confirm": "Einrichtung abschließen", "backups-setup-external-description": "Auf ein externes USB-Laufwerk sichern", "backups-setup-nas-or-umbrel-description": "Sichere auf einem anderen Umbrel oder einem NAS-Gerät in deinem Netzwerk", "backups-setup-umbrel-or-nas": "Anderer Umbrel oder NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Erweitere deine Sorgenfreiheit über dein Zuhause hinaus mit Ende-zu-Ende-verschlüsselten Backups in die Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Frühzugang erhalten", "backups-setup-umbrel-private-cloud-description": "Ende-zu-Ende-verschlüsselte Backups in die Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Demnächst", "backups.add-umbrel-or-nas": "Umbrel oder NAS hinzufügen", "backups.all-apps-and-data-will-be-backed-up": "Alle Apps und Daten werden gesichert", "backups.apps-and-data": "Apps & Daten", "backups.backup-location": "Backup-Standort", "backups.browse": "Durchsuchen", "backups.choose-folder-within-device": "Wähle einen Ordner innerhalb von {{device}}, um deine Backups zu speichern", "backups.confirm-password": "Passwort bestätigen", "backups.copy": "Kopieren", "backups.encryption": "Verschlüsselung", "backups.encryption-password-warning": "Stelle sicher, dass dein Verschlüsselungs-Passwort sicher gespeichert ist, z. B. in einem Passwort-Manager. Du wirst es nicht wiedersehen können und benötigst es, um deine Backups wiederherzustellen.", "backups.exclude-from-backups": "Vom Backup ausschließen", "backups.exclude-from-backups-description": "Schließe bestimmte Dateien, Ordner und Apps von deinen Backups aus.", "backups.hide": "Ausblenden", "backups.i-understand": "Ich verstehe", "backups.location": "Standort", "backups.modals.already-in-use.description": "Dieser Backup-Speicherort wird bereits für Backups auf diesem Umbrel verwendet.", "backups.modals.already-in-use.manage": "In Backups verwalten", "backups.modals.already-in-use.title": "Backup-Speicherort bereits in Verwendung", "backups.modals.connect-existing.description": "An diesem Speicherort existiert bereits ein Umbrel-Backup. Gib dessen Verschlüsselungspasswort ein, um es zu diesem Umbrel hinzuzufügen.", "backups.modals.connect-existing.title": "Bestehendes Umbrel-Backup verbinden", "backups.no-external-drives-detected": "Es wurden keine externen Laufwerke erkannt", "backups.no-password-set": "Kein Passwort gesetzt", "backups.password-is-set": "Passwort ist gesetzt", "backups.password-minimum-length": "Das Passwort muss mindestens 8 Zeichen lang sein", "backups.password-safety-warning": "Deine Backups werden mit diesem Passwort verschlüsselt. Bewahre es sicher auf, denn du wirst es nicht wiedersehen können und benötigst es, um deine Backups wiederherzustellen.", "backups.passwords-do-not-match": "Passwörter stimmen nicht überein", "backups.please-choose-folder": "Bitte wähle einen Ordner", "backups.restore-failed.message": "Beim Wiederherstellen deines Umbrel ist ein Fehler aufgetreten. Deine aktuellen Apps und Daten wurden nicht geändert.", "backups.restore-failed.retry": "Zur Wiederherstellung", "backups.restore-failed.title": "Wiederherstellung fehlgeschlagen", "backups.restoring": "Deinen Umbrel wiederherstellen", "backups.restoring-completing": "Fast fertig. Dein Umbrel startet in Kürze neu...", "backups.restoring-progress": "{{percent}}% wiederhergestellt", "backups.restoring-time-remaining": "{{time}} verbleibend", "backups.restoring-warning": "Schalte deinen Umbrel während der Wiederherstellung nicht aus und trenne den Backup-Standort nicht", "backups.review": "Überprüfen und bestätigen", "backups.review-description": "Überprüfe die Details deines Backups und bestätige deine Auswahl", "backups.scanning-for-external-drives": "Scanne nach externen Laufwerken...", "backups.schedule-description": "umbrelOS sichert deine Daten automatisch stündlich. Es behält verschlüsselte stündliche Backups für die letzten 24 Stunden, tägliche Backups für die letzte Woche, wöchentliche Backups für den letzten Monat und monatliche Backups für das letzte Jahr. Backups, die älter als ein Jahr sind, werden automatisch entfernt.", "backups.select-backup-folder": "Backup-Ordner auswählen", "backups.select-backup-folder-description": "Wähle einen Ordner, in dem deine Backups gespeichert werden sollen.", "backups.select-backup-location": "Wähle einen Backup-Standort", "backups.set-encryption-password": "Verschlüsselungs-Passwort festlegen", "backups.set-encryption-password-description": "Schütze deine Backups mit einem Passwort. So bleiben deine Daten privat und können nur mit diesem Passwort wiederhergestellt werden.", "backups.show": "Anzeigen", "backups.storage-capacity-warning": "{{device}} muss über freien Speicherplatz verfügen, der mindestens dem Doppelten der Backup-Größe entspricht", "backups.store-encryption-password-safely": "Speichere dein Verschlüsselungs-Passwort sicher", "beta-program": "umbrelOS Beta Programm", "beta-program-description": "Melde dich an, um Beta-Updates von umbrelOS zu erhalten, erhalte frühen Zugang zu neuen Funktionen und hilf uns, diese zu verbessern, indem du dein Feedback gibst. Beta-Updates können instabil sein und die Fehlerbehebung kann Kenntnisse des Terminals erfordern.", "cancel": "Abbrechen", "change": "Ändern", "change-name": "Name ändern", "change-name.failed.name-required": "Name ist erforderlich", "change-name.input-placeholder": "Dein Name", "change-password": "Passwort ändern", "change-password.callout": "Wenn du dein Passwort verlierst, kannst du dich nicht bei deinem Umbrel anmelden. Stelle sicher, dass du es sicher aufbewahrst.", "change-password.current-password": "Aktuelles Passwort", "change-password.failed.current-required": "Aktuelles Passwort ist erforderlich", "change-password.failed.min-length": "Passwort muss mindestens {{characters}} Zeichen lang sein", "change-password.failed.must-be-unique": "Neues Passwort muss sich vom aktuellen Passwort unterscheiden", "change-password.failed.new-required": "Neues Passwort ist erforderlich", "change-password.failed.no-match": "Passwörter stimmen nicht überein", "change-password.failed.repeat-required": "Passwortwiederholung ist erforderlich", "change-password.new-password": "Neues Passwort", "change-password.repeat-password": "Passwort wiederholen", "check-for-latest-version": "Nach der neuesten umbrelOS Aktualisierung suchen", "clipboard.copied": "Kopiert", "close": "Schließen", "cmdk.change-wallpaper": "Hintergrundbild ändern", "cmdk.frequent-apps": "Häufig verwendet", "cmdk.input-placeholder": "Suche nach Apps, Einstellungen oder Aktionen", "cmdk.live-usage": "Live-Nutzung", "cmdk.restart-umbrel": "Umbrel neu starten", "cmdk.shutdown-umbrel": "Umbrel herunterfahren", "cmdk.update-all-apps": "Alle Apps aktualisieren", "cmdk.widgets": "Widgets", "community-app-store": "Community App Store", "community-app-store.add-error": "Fehler beim Hinzufügen des App Stores: {{message}}", "community-app-store.back-to-umbrel-app-store": "Zurück zum Umbrel App Store", "community-app-store.open-button": "Öffnen", "community-app-store.remove-button": "Entfernen", "community-app-store.remove-error": "Fehler beim Entfernen des App Stores: {{message}}", "community-app-stores.add-button": "Hinzufügen", "community-app-stores.description": "Community App Stores ermöglichen es dir, Apps auf deinem Umbrel zu installieren, die möglicherweise nicht im offiziellen Umbrel App Store verfügbar sind. Sie erleichtern auch das Testen von Beta-Versionen von Umbrel-Apps, bevor Entwickler sie im offiziellen Umbrel App Store veröffentlichen.", "community-app-stores.learn-more": "Mehr erfahren", "community-app-stores.warning": "Community App Stores können von jedem erstellt werden. Die darin veröffentlichten Apps sind nicht vom offiziellen Umbrel App Store-Team verifiziert oder geprüft und können potenziell unsicher oder bösartig sein. Sei vorsichtig und füge nur App-Stores von Entwicklern hinzu, denen du vertraust.", "confirm": "Bestätigen", "connect": "Verbinden", "connecting": "Verbindet...", "connection-lost": "Verbindung verloren", "connection-lost-description": "Das kann passieren, wenn dein Browser-Tab inaktiv war, deine Netzwerkverbindung unterbrochen wurde oder dein Gerät offline ist.", "continue": "Fortsetzen", "continue-to-log-in": "Weiter zur Anmeldung", "cpu": "CPU", "cpu-core-count": "{{cores}} Threads", "default-credentials.close": "Verstanden", "default-credentials.description": "Hier sind die Anmeldeinformationen, die du benötigst, um dich bei der App anzumelden.", "default-credentials.dont-show-again": "Nicht mehr anzeigen", "default-credentials.dont-show-again-notice": "Du kannst diese Anmeldedaten jederzeit zukünftig abrufen, indem du mit der rechten Maustaste auf das App-Symbol klickst.", "default-credentials.open": "{{app}} öffnen", "default-credentials.password": "Standardpasswort", "default-credentials.title": "Anmeldeinformationen für {{app}}", "default-credentials.username": "Standardbenutzername", "desktop.app.context.go-to-store-page": "Im App Store anzeigen", "desktop.app.context.settings": "Einstellungen", "desktop.app.context.show-default-credentials": "Standardanmeldeinformationen anzeigen", "desktop.app.context.uninstall": "Deinstallieren", "desktop.context-menu.change-wallpaper": "Hintergrundbild ändern", "desktop.context-menu.edit-widgets": "Widgets bearbeiten", "desktop.context-menu.logout": "Abmelden", "desktop.greeting.afternoon": "Guten Tag, {{name}}", "desktop.greeting.evening": "Guten Abend, {{name}}", "desktop.greeting.morning": "Guten Morgen, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Für Viber", "desktop.install-first.for-the-bitcoiner": "Für Bitcoiner", "desktop.install-first.for-the-self-hoster": "Für Selbsthoster", "desktop.install-first.for-the-streamer": "Für Streamer", "desktop.install-first.link-to-app-store": "Entdecke mehr im App Store", "desktop.not-enough-room": "Verwende einen größeren Bildschirm, um deine Apps anzuzeigen.", "device": "Gerät", "device-info": "Geräteinformation", "device-info-description": "Informationen über dein Gerät", "device-info.device": "Gerät", "device-info.model-number": "Modellnummer", "device-info.serial-number": "Seriennummer", "device-info.view-info": "Informationen anzeigen", "device-name.home-or-pro": "Umbrel Home oder Umbrel Pro", "disable": "Deaktivieren", "done": "Fertig", "download-logs": "Protokolle herunterladen", "enabling-tor": "Remote-Tor-Zugriff wird aktiviert", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS bietet eine bessere Netzwerkzuverlässigkeit. Deaktiviere es, um die DNS-Einstellungen deines Routers zu verwenden.", "external-dns-error": "Fehler beim Aktualisieren der DNS-Einstellung: {{message}}", "external-drive": "Externes Laufwerk", "factory-reset": "Werkseinstellungen", "factory-reset-description": "Lösche alle deine Daten und Apps, um umbrelOS auf die Standardeinstellungen zurückzusetzen", "factory-reset-failed": "Fehler beim Zurücksetzen deines Geräts: {{message}}", "factory-reset.confirm.body": "Bestätige dein Passwort, um zurückzusetzen", "factory-reset.confirm.ethernet-required-warning": "Stelle sicher, dass dein Gerät über Ethernet (nicht Wi-Fi) mit deinem Router verbunden ist und du von deinem lokalen Netzwerk darauf zugreifst (z.B. http://umbrel.local oder die lokale IP-Adresse deines Geräts).", "factory-reset.confirm.submit": "Alles löschen und zurücksetzen", "factory-reset.confirm.submit-callout": "Diese Aktion kann nicht rückgängig gemacht werden.", "factory-reset.rebooting.message": "Dein Gerät wird neu gestartet und alle Daten werden gelöscht. Bitte schließe diese Seite nicht.", "factory-reset.rebooting.status": "Wird zurückgesetzt...", "factory-reset.rebooting.title": "Werkseinstellungen werden zurückgesetzt", "factory-reset.review.account-info": "Kontoinformationen und Passwort", "factory-reset.review.apps": "Apps", "factory-reset.review.following-will-be-removed": "Folgendes wird von deinem Gerät entfernt", "factory-reset.review.installed-apps_one": "{{count}} installierte App", "factory-reset.review.installed-apps_other": "{{count}} installierte Apps", "factory-reset.review.submit": "Fortfahren", "factory-reset.review.total-data": "Gesamtdaten", "files": "Files", "files-action.add-favorite": "Zu Favoriten hinzufügen", "files-action.add-network-device": "Gerät hinzufügen", "files-action.cancel-upload": "Hochladen abbrechen", "files-action.compress": "Komprimieren", "files-action.copy": "Kopieren", "files-action.cut": "Ausschneiden", "files-action.delete": "Dauerhaft löschen", "files-action.download": "Herunterladen", "files-action.download-items": "Lade {{count}} Elemente herunter", "files-action.drop-to-upload": "Ablegen zum Hochladen", "files-action.eject-disk": "Auswerfen", "files-action.empty-trash": "Papierkorb leeren", "files-action.format-drive": "Formatieren", "files-action.go-to-path": "Gehe zu...", "files-action.new-folder": "Neuer Ordner", "files-action.open": "Öffnen", "files-action.paste": "Einfügen", "files-action.remove-favorite": "Aus Favoriten entfernen", "files-action.remove-network-host": "Netzwerklaufwerk auswerfen", "files-action.remove-network-share": "Netzwerkfreigabe auswerfen", "files-action.rename": "Umbenennen", "files-action.restore": "Wiederherstellen", "files-action.select": "Auswählen", "files-action.share": "Im Netzwerk freigeben...", "files-action.sharing": "Wird freigegeben...", "files-action.show-in-folder": "Im übergeordneten Ordner anzeigen", "files-action.trash": "In den Papierkorb verschieben", "files-action.uncompress": "Entpacken", "files-action.upload": "Hochladen", "files-add-network-share.add-manually": "Manuell hinzufügen", "files-add-network-share.add-share": "Freigabe hinzufügen", "files-add-network-share.back": "Zurück", "files-add-network-share.continue": "Weiter", "files-add-network-share.description": "Verbinde dich mit einem NAS oder einem anderen freigegebenen Laufwerk in deinem Netzwerk, um innerhalb von Files darauf zuzugreifen.", "files-add-network-share.discovering": "Suche...", "files-add-network-share.enter-details-manually": "Serverdetails manuell eingeben", "files-add-network-share.host-label": "Serveradresse", "files-add-network-share.host-required": "Serveradresse erforderlich", "files-add-network-share.manual-share-help": "Gib den genauen Namen der Freigabe ein, wie er auf deinem Server angezeigt wird", "files-add-network-share.no-shares-found": "Auf diesem Server wurden keine Freigaben gefunden", "files-add-network-share.not-seeing-share": "Siehst du deine Freigabe nicht?", "files-add-network-share.password-label": "Passwort", "files-add-network-share.password-required": "Passwort erforderlich", "files-add-network-share.retrieving-shares": "Freigaben werden abgerufen...", "files-add-network-share.retry-discovery": "Netzwerk erneut scannen", "files-add-network-share.select-share": "Wähle eine Freigabe zum Hinzufügen", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Freigabename erforderlich", "files-add-network-share.title": "Netzwerkfreigabe hinzufügen", "files-add-network-share.username-label": "Benutzername", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Benutzername erforderlich", "files-audio-island.now-playing": "Jetzt läuft", "files-audio-island.pause": "Pausieren", "files-audio-island.play": "Abspielen", "files-backend-error.base-directory-not-found": "Das Stammverzeichnis konnte nicht gefunden werden", "files-backend-error.cant-find-root": "Der Dateipfad konnte nicht überprüft werden", "files-backend-error.destination-already-exists": "Am Ziel existiert bereits ein Element mit demselben Namen", "files-backend-error.destination-not-exist": "Der Zielordner existiert nicht", "files-backend-error.does-not-exist": "Die Datei oder der Ordner existiert nicht", "files-backend-error.escapes-base": "Der Pfad liegt außerhalb des erlaubten Verzeichnisses", "files-backend-error.invalid-base": "Der Pfad gehört zu keinem gültigen Verzeichnis", "files-backend-error.invalid-filename": "Der Dateiname ist ungültig", "files-backend-error.invalid-path": "Der Dateipfad ist ungültig", "files-backend-error.mkdir-failed": "Ordner konnte nicht erstellt werden", "files-backend-error.move-failed": "Verschieben des Elements fehlgeschlagen", "files-backend-error.not-enough-space": "Nicht genügend Speicherplatz verfügbar", "files-backend-error.operation-not-allowed": "Diese Aktion ist nicht erlaubt", "files-backend-error.parent-not-directory": "Der übergeordnete Pfad ist kein Ordner", "files-backend-error.parent-not-exist": "Der übergeordnete Ordner existiert nicht", "files-backend-error.path-not-absolute": "Der Dateipfad ist nicht gültig", "files-backend-error.share-already-exists": "Dieser Ordner ist bereits freigegeben", "files-backend-error.share-name-generation-failed": "Konnte keinen eindeutigen Namen für die Freigabe erzeugen", "files-backend-error.source-not-exists": "Die Quelldatei oder der Quellordner existiert nicht", "files-backend-error.subdir-of-self": "Ein Ordner kann nicht in sich selbst verschoben oder kopiert werden", "files-backend-error.trash-meta-not-exists": "Konnte den ursprünglichen Speicherort dieses Elements nicht finden", "files-backend-error.unique-name-index-exceeded": "Konnte keinen eindeutigen Namen generieren. Zu viele Elemente mit ähnlichen Namen vorhanden", "files-backend-error.upload-failed": "Upload fehlgeschlagen", "files-collision.action.keep-both": "Beide behalten", "files-collision.action.replace": "Ersetzen", "files-collision.action.skip": "Überspringen", "files-collision.destination.original-location": "seinem ursprünglichen Speicherort", "files-collision.message": "Möchtest du das vorhandene Element ersetzen oder beide behalten?", "files-collision.title": "\"{{itemName}}\" ist bereits in {{destinationName}} vorhanden", "files-download.confirm": "Herunterladen", "files-download.description": "Files kann diesen Dateityp nicht öffnen. Möchtest du ihn stattdessen herunterladen?", "files-download.title": "„{{name}}“ herunterladen?", "files-empty-trash.confirm": "Leeren", "files-empty-trash.description": "Bist du sicher, dass du alle Elemente im Papierkorb endgültig löschen möchtest? Du kannst diese Aktion nicht rückgängig machen.", "files-empty-trash.title": "Papierkorb leeren?", "files-empty.directory": "Keine Elemente in diesem Ordner", "files-empty.network": "Keine Netzwerkgeräte", "files-empty.network-host-offline": "Netzwerkgerät offline", "files-error.add-favorite": "Hinzufügen zu den Favoriten fehlgeschlagen: {{message}}", "files-error.add-share": "Freigabe des Ordners fehlgeschlagen: {{message}}", "files-error.compress": "Komprimierung fehlgeschlagen: {{message}}", "files-error.copy": "Kopieren fehlgeschlagen: {{message}}", "files-error.create-folder": "Ordner erstellen fehlgeschlagen: {{message}}", "files-error.delete": "Löschen fehlgeschlagen: {{message}}", "files-error.eject-disk": "Auswerfen des Laufwerks fehlgeschlagen: {{message}}", "files-error.empty-trash": "Papierkorb leeren fehlgeschlagen: {{message}}", "files-error.extract": "Entpacken fehlgeschlagen: {{message}}", "files-error.folder-already-exists": "Ein Ordner mit diesem Namen existiert bereits", "files-error.move": "Verschieben fehlgeschlagen: {{message}}", "files-error.remove-favorite": "Entfernen aus den Favoriten fehlgeschlagen: {{message}}", "files-error.remove-share": "Entfernen der Freigabe fehlgeschlagen: {{message}}", "files-error.rename": "Umbenennen fehlgeschlagen: {{message}}", "files-error.restore": "Wiederherstellen fehlgeschlagen: {{message}}", "files-error.trash": "In den Papierkorb verschieben fehlgeschlagen: {{message}}", "files-error.upload": "Upload fehlgeschlagen: {{message}}", "files-error.upload-network-error": "Upload von {{name}} fehlgeschlagen: Ein Netzwerkfehler ist aufgetreten", "files-extension-change.confirm": "Fortfahren", "files-extension-change.description-add": "Bist du sicher, dass du die Dateiendung von „{{fileName}}“ in „{{extension}}“ ändern möchtest? Dadurch kann die Datei möglicherweise unlesbar werden.", "files-extension-change.description-remove": "Bist du sicher, dass du die Dateiendung von „{{fileName}}“ entfernen möchtest?", "files-extension-change.title-add": "Dateiendung in „{{extension}}“ ändern?", "files-extension-change.title-remove": "Dateiendung entfernen?", "files-external-storage.unsupported.description": "Dein angeschlossenes externes Laufwerk lässt sich aufgrund von Stromproblemen nicht an einem Raspberry Pi verwenden. Externer Speicher ist auf dem Umbrel Home, Umbrel Pro und allen x86-Geräten (Intel oder AMD) verfügbar.", "files-external-storage.unsupported.description-general": "Externer Speicher ist auf dem Raspberry Pi wegen Stromproblemen nicht verfügbar. Externer Speicher ist auf dem Umbrel Home, Umbrel Pro und allen x86-Geräten (Intel oder AMD) verfügbar.", "files-external-storage.unsupported.title": "Externer Speicher wird nicht unterstützt", "files-folder": "Ordner", "files-format.confirm": "Formatieren", "files-format.description": "Beim Formatieren werden alle Daten auf {{driveName}} gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden.", "files-format.description-unreadable": "umbrelOS kann den Inhalt von {{driveName}} nicht lesen. Du kannst es formatieren, um es mit umbrelOS zu verwenden.", "files-format.drive-label": "Name", "files-format.error": "Formatieren des Laufwerks fehlgeschlagen", "files-format.exfat-description": "Maximale Kompatibilität mit Windows, macOS und Linux", "files-format.ext4-description": "Bessere Leistung mit umbrelOS und Linux", "files-format.filesystem": "Dateisystem", "files-format.filesystem-label": "Formatieren als", "files-format.formatting": "Formatieren...", "files-format.title": "Laufwerk formatieren", "files-format.title-requires-format": "Formatierung erforderlich", "files-formatting-island.formatting": "Formatieren...", "files-formatting-island.formatting-drives": "Formatieren von {{count}} Laufwerken", "files-listing.empty": "Keine Elemente", "files-listing.error": "Es ist ein Fehler aufgetreten", "files-listing.item-count-truncated": "{{formattedCount}}+ Elemente", "files-listing.item-count_one": "{{formattedCount}} Element", "files-listing.item-count_other": "{{formattedCount}} Elemente", "files-listing.loading": "Wird geladen...", "files-listing.no-such-file": "Keine solche Datei oder kein solcher Ordner", "files-listing.selected-count": "{{selectedCount}} von {{totalCount}} ausgewählt", "files-listing.selected-count-truncated": "{{selectedCount}} von {{totalCount}}+ ausgewählt", "files-name-drawer.new-folder": "Neuer Ordner", "files-name-drawer.new-folder-description": "Gib einen Namen für den neuen Ordner ein.", "files-name-drawer.new-folder-input": "Ordnername", "files-name-drawer.rename-file": "Datei umbenennen", "files-name-drawer.rename-file-description": "Gib einen neuen Namen für diese Datei ein.", "files-name-drawer.rename-file-input": "Dateiname", "files-name-drawer.rename-folder": "Ordner umbenennen", "files-name-drawer.rename-folder-description": "Gib einen neuen Namen für diesen Ordner ein.", "files-name-drawer.rename-folder-input": "Ordnername", "files-network-storage-error.add-share": "Hinzufügen der Netzwerkfreigabe fehlgeschlagen: {{message}}", "files-network-storage-error.discover-servers": "Erkennung von Netzwerkgeräten fehlgeschlagen: {{message}}", "files-network-storage-error.discover-shares": "Suche nach Netzwerkfreigaben fehlgeschlagen: {{message}}", "files-network-storage-error.remove-share": "Entfernen der Netzwerkfreigabe fehlgeschlagen: {{message}}", "files-operations-island.copying": "Kopieren von \"{{from}}\" nach \"{{to}}\"", "files-operations-island.moving": "Verschieben von \"{{from}}\" nach \"{{to}}\"", "files-operations-island.restoring": "Stelle \"{{from}}\" nach \"{{to}}\" wieder her", "files-path.input-group": "Pfadeingabe", "files-path.input-label": "Aktueller Pfad", "files-permanently-delete.confirm": "Endgültig löschen", "files-permanently-delete.description-multiple": "Bist du sicher, dass du diese {{count}} Elemente endgültig löschen möchtest? Du kannst diese Aktion nicht rückgängig machen.", "files-permanently-delete.description-single": "Bist du sicher, dass du „{{fileName}}“ endgültig löschen möchtest? Du kannst diese Aktion nicht rückgängig machen.", "files-permanently-delete.title-multiple": "{{count}} Elemente endgültig löschen?", "files-permanently-delete.title-single": "Endgültig löschen?", "files-search.default": "Nach Dateien und Ordnern suchen", "files-search.no-results": "Keine Ergebnisse gefunden für \"{{query}}\"", "files-search.placeholder": "Suchen", "files-search.searching-label": "Suche im Umbrel von {{name}}", "files-share.home-description": "Greife von anderen Geräten in deinem Netzwerk auf alle Dateien in „{{homeDirectoryName}}“ zu.", "files-share.home-title": "„{{homeDirectoryName}}“ im Netzwerk freigeben", "files-share.instructions.how-to-access": "So greifst du darauf zu", "files-share.instructions.ios.enter-password": "Gib {{password}} als Passwort ein.", "files-share.instructions.ios.enter-server": "Gib {{smbUrl}} als Serveradresse ein.", "files-share.instructions.ios.enter-username": "Gib {{username}} als Benutzernamen ein.", "files-share.instructions.ios.install-files": "Installiere die App „Files“ aus dem App Store, falls nicht vorhanden.", "files-share.instructions.ios.tap-connect": "Tippe auf „Verbinden“, um darauf zuzugreifen.", "files-share.instructions.ios.tap-dots": "Tippe oben rechts auf die drei Punkte (...) und wähle „Mit Server verbinden“.", "files-share.instructions.macos.click-connect": "Klicke auf „Verbinden“, um darauf zuzugreifen.", "files-share.instructions.macos.enter-password": "Gib {{password}} als Passwort ein.", "files-share.instructions.macos.enter-url": "Gib {{smbUrl}} ein und klicke auf „Verbinden“.", "files-share.instructions.macos.enter-username": "Gib {{username}} als Benutzernamen ein.", "files-share.instructions.macos.open-finder": "Öffne „Finder“ und drücke ⌘ + K.", "files-share.instructions.macos.select-registered": "Wähle „Registrierter Benutzer“, wenn du dazu aufgefordert wirst.", "files-share.instructions.macos.time-machine": "Wie du es als Time Machine-Backupziel verwendest", "files-share.instructions.macos.time-machine.choose-encryption": "Wähle zwischen verschlüsselten oder unverschlüsselten Backups.", "files-share.instructions.macos.time-machine.disk-limit": "Lege unter „Disk Usage Limit“ fest, wie viel Speicherplatz du auf deinem Umbrel für Time Machine-Backups reservieren möchtest, und klicke dann auf „Fertig“.", "files-share.instructions.macos.time-machine.follow-steps": "Befolge die obigen Schritte und öffne die Systemeinstellungen auf deinem Mac.", "files-share.instructions.macos.time-machine.go-settings": "Gehe zu Time Machine und klicke auf „Backup-Datenträger hinzufügen…“.", "files-share.instructions.macos.time-machine.select-disk": "Wähle den Ordner aus und klicke auf \"Laufwerk einrichten...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Folge den geführten Schritten, um dein Backup einzurichten.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Führe die oben genannten Schritte aus und gehe dann auf deinem anderen Umbrel zu \"{{settings}}\" > \"{{backups}}\".", "files-share.instructions.umbrelos.backup.select-add": "Wähle die Option \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Wähle dieses Umbrel-Gerät aus der Liste der verbundenen Geräte.", "files-share.instructions.umbrelos.backup.title": "Wie du es als Sicherungsziel für dein anderes Umbrel verwendest", "files-share.instructions.umbrelos.cant-find-note": "Findest du es nicht? Wähle \"Manuell hinzufügen\" und nutze die folgenden Zugangsdaten. Wenn es trotzdem nicht klappt, überprüfe, dass beide Geräte im selben Netzwerk sind.", "files-share.instructions.umbrelos.enter-password": "Gib {{password}} als Passwort ein.", "files-share.instructions.umbrelos.enter-username": "Gib {{username}} als Benutzernamen ein.", "files-share.instructions.umbrelos.open-and-click": "Öffne auf deinem anderen Umbrel \"Files\" und klicke in der Seitenleiste auf neben \" {{deviceLabel}}\".", "files-share.instructions.umbrelos.select-device": "Wähle dieses Umbrel-Gerät aus der Liste automatisch erkannter Geräte in deinem Netzwerk aus.", "files-share.instructions.umbrelos.select-sharename": "Wähle \"{{sharename}}\" und klicke, um die Freigabe hinzuzufügen.", "files-share.instructions.windows.enter-password": "Gib {{password}} als Passwort ein.", "files-share.instructions.windows.enter-url": "Gib {{smbUrl}} ein und drücke Enter.", "files-share.instructions.windows.enter-username": "Gib {{username}} als Benutzernamen ein.", "files-share.instructions.windows.open-run": "Drücke Windows + R, um das „Ausführen“-Dialogfeld zu öffnen.", "files-share.instructions.windows.remember-credentials": "Aktiviere „Remember my credentials“ und klicke auf OK.", "files-share.regular-description": "Gib diesen Ordner frei, um von anderen Geräten in deinem Netzwerk darauf zuzugreifen", "files-share.regular-title": "Ordner im Netzwerk freigeben", "files-share.toggle": "„{{name}}“ in deinem Netzwerk freigeben", "files-sidebar.apps": "Apps", "files-sidebar.external-storage": "Externer Speicher", "files-sidebar.favorites": "Favoriten", "files-sidebar.home": "Startseite", "files-sidebar.navigation": "Dateinavigation", "files-sidebar.network": "Netzwerk", "files-sidebar.network-pathbar": "Netzwerkgeräte", "files-sidebar.network-sidebar": "Geräte", "files-sidebar.recents": "Kürzlich", "files-sidebar.shared-folders": "Freigegebene Ordner", "files-sidebar.trash": "Papierkorb", "files-sidebar.trash.open": "Öffnen", "files-sort.created": "Hinzugefügt", "files-sort.modified": "Geändert", "files-sort.name": "Name", "files-sort.size": "Größe", "files-sort.type": "Typ", "files-state.uploading": "Wird hochgeladen...", "files-state.waiting": "Warten...", "files-type.3gp": "3GP-Video", "files-type.3gp2": "3GP2-Video", "files-type.7z": "7Z-Archiv", "files-type.aac": "AAC-Audio", "files-type.ai": "Illustrator-Datei", "files-type.aiff": "AIFF-Audio", "files-type.au": "AU-Audio", "files-type.avi": "AVI-Video", "files-type.avif": "AVIF-Bild", "files-type.bmp": "BMP-Bild", "files-type.bzip2": "BZIP2-Archiv", "files-type.caf": "CAF-Audio", "files-type.compressed": "Komprimiertes Archiv", "files-type.csv": "CSV-Datei", "files-type.directory": "Ordner", "files-type.dmg": "Festplatten-Image", "files-type.dv": "DV-Video", "files-type.epub": "EPUB-eBook", "files-type.excel": "Excel-Tabelle", "files-type.exe": "Windows-Ausführbare Datei", "files-type.executable": "Ausführbare Datei", "files-type.external-drive": "Laufwerk", "files-type.flac": "FLAC-Audio", "files-type.flv": "FLV-Video", "files-type.gif": "GIF-Bild", "files-type.gzip": "GZIP-Archiv", "files-type.heic": "HEIC-Bild", "files-type.ico": "ICO-Bild", "files-type.iso": "ISO-Image", "files-type.jpeg": "JPEG-Bild", "files-type.keynote": "Keynote-Präsentation", "files-type.lzip": "LZIP-Archiv", "files-type.lzma": "LZMA-Archiv", "files-type.lzop": "LZOP-Archiv", "files-type.m3u": "M3U-Wiedergabeliste", "files-type.m4a": "M4A-Audio", "files-type.m4v": "M4V-Video", "files-type.midi": "MIDI-Audio", "files-type.mka": "MKA-Audio", "files-type.mkv": "MKV-Video", "files-type.mng": "MNG-Video", "files-type.mobi": "MOBI-eBook", "files-type.mp3": "MP3-Audio", "files-type.mp4": "MP4-Video", "files-type.mp4-audio": "MP4-Audio", "files-type.mpeg": "MPEG-Video", "files-type.mpeg-ts": "MPEG-Transportstream", "files-type.network-drive": "Netzwerklaufwerk", "files-type.numbers": "Numbers-Tabelle", "files-type.ogg": "OGG-Audio", "files-type.ogv": "OGV-Video", "files-type.pages": "Pages-Dokument", "files-type.pdf": "PDF-Dokument", "files-type.png": "PNG-Bild", "files-type.powerpoint": "PowerPoint-Präsentation", "files-type.psd": "Photoshop-Dokument", "files-type.quicktime": "QuickTime-Video", "files-type.rar": "RAR-Archiv", "files-type.sgi": "SGI-Film", "files-type.svg": "SVG-Bild", "files-type.tar": "TAR-Archiv", "files-type.tiff": "TIFF-Bild", "files-type.ts": "TS-Video", "files-type.txt": "Textdatei", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "WAV-Audio", "files-type.webm": "WebM-Video", "files-type.webm-audio": "WebM-Audio", "files-type.webp": "WebP-Bild", "files-type.wma": "WMA-Audio", "files-type.wmv": "WMV-Video", "files-type.word": "Word-Dokument", "files-type.xz": "XZ-Archiv", "files-type.zip": "ZIP-Archiv", "files-upload-island.uploading-count": "Lade {{count}} Elemente hoch", "files-view.icons": "Symbole", "files-view.list": "Liste", "files-view.sort-by": "Sortieren nach", "files-view.view-as": "Anzeigen als", "files-widgets.favorites.no-items-text": "Füge einen Ordner zu deinen Favoriten hinzu, um ihn hier zu sehen", "files-widgets.recents.no-items-text": "Keine kürzlich verwendeten Dateien", "generic-in": "im", "hide-details": "Details ausblenden", "install-first.install-app": "Installiere {{app}}", "install-first.title": "{{app}} benötigt diese Apps", "install-your-first-app": "Installiere deine erste App", "language": "Sprache", "language-description": "Deine bevorzugte umbrelOS Sprache", "language.select-description": "Bevorzugte umbrelOS-Sprache auswählen", "live-usage": "Live-Nutzung", "loading": "Lädt", "local-ip": "Lokale IP", "login-2fa.subtitle": "Gib den 2FA-Code ein, der in deiner Authenticator-App angezeigt wird", "login-2fa.title": "Authentifizieren", "login-with-umbrel.description": "Gib dein Umbrel-Passwort ein, um {{app}} zu öffnen", "login-with-umbrel.title": "Mit Umbrel anmelden", "login.password-label": "Passwort", "login.password.submit": "Anmelden", "login.subtitle": "Gib dein Umbrel-Passwort ein, um dich anzumelden", "login.title": "Willkommen zurück", "logout": "Abmelden", "logout-error-generic": "Fehler: Abmeldung fehlgeschlagen", "logout.confirm.submit": "Abmelden", "logout.confirm.title": "Möchtest du dich wirklich abmelden?", "memory": "Arbeitsspeicher", "memory.low": "Wenig Arbeitsspeicher", "migrate": "Migrieren", "migrate.callout": "Schalte dein Umbrel nicht aus, bis die Migration abgeschlossen ist", "migrate.failed.retry": "Erneut versuchen", "migrate.failed.title": "Migration fehlgeschlagen", "migrate.success.description": "Alle deine Apps, App-Daten und Kontodetails wurden auf dein Umbrel Home migriert.", "migrate.success.title": "Migration erfolgreich", "migration-assistant": "Migrationsassistent", "migration-assistant-description": "Übertrage alle deine Apps und Daten von einem Raspberry Pi auf {{deviceName}}", "migration-assistant-unsupported-device-description": "Migration Assistant unterstützt derzeit das Übertragen aller Daten und Apps von einem Raspberry Pi mit umbrelOS auf Umbrel Home oder Umbrel Pro. Öffne Migration Assistant auf deinem Umbrel Home oder Umbrel Pro, um loszulegen.", "migration-assistant.continue-migration.ready.submit": "Migration starten", "migration-assistant.failed": "Irgendetwas stimmt nicht...", "migration-assistant.failed.retrying-message": "Wiederholen...", "migration-assistant.mobile.start-button": "Migration starten", "migration-assistant.prep.body": "Vorbereitung für die Migration", "migration-assistant.prep.button-continue": "Fortfahren", "migration-assistant.prep.callout": "Die Daten auf deinem {{deviceName}}, falls vorhanden, werden dauerhaft gelöscht.", "migration-assistant.prep.connect-disk-to-home": "Schließe das externe Laufwerk an einen beliebigen USB-Anschluss deines {{deviceName}} an.", "migration-assistant.prep.prep-done-continue-message": "Wenn du fertig bist, klicke unten auf '{{button}}'.", "migration-assistant.prep.shut-down-rpi": "Schalte dein Raspberry Pi Umbrel aus.", "migration-assistant.ready.description": "Alle deine Daten und Apps sind bereit, auf dein {{deviceName}} migriert zu werden", "migration-assistant.ready.hint-header": "Dinge, die du beachten solltest", "migration-assistant.ready.hint-keep-pi-off.description": "Dies hilft, Probleme mit Apps wie Lightning Node zu vermeiden", "migration-assistant.ready.hint-keep-pi-off.title": "Halte dein Raspberry Pi nach dem Update ausgeschaltet", "migration-assistant.ready.hint-use-same-password.description": "Denk daran, das Passwort deines Raspberry Pi Umbrel zu verwenden, um dich bei deinem {{deviceName}} anzumelden", "migration-assistant.ready.hint-use-same-password.title": "Verwende das gleiche Passwort", "migration-assistant.ready.title": "Du bist bereit für die Migration!", "mini-browser.default-title": "Ordner auswählen", "mini-browser.empty-external": "Schließe ein externes Laufwerk an, damit es hier angezeigt wird.", "mini-browser.empty-network": "Füge ein Umbrel oder ein NAS hinzu, damit es hier angezeigt wird.", "mini-browser.load-more": "Mehr laden", "mini-browser.load-more-in-folder": "Mehr in {{name}} laden", "mini-browser.loading-more": "Mehr wird geladen…", "mini-browser.select": "Auswählen", "mini-browser.select-folder": "Ordner auswählen", "name": "Name", "nas": "NAS", "no-forgot-password-message": "Wenn du dein Passwort verlierst, kannst du dich nicht bei deinem Umbrel anmelden. Stelle sicher, dass du es sicher aufbewahrst.", "no-results-found": "Keine Ergebnisse gefunden", "not-found-404": "Fehlercode: 404", "not-found-404.back": "Zurück", "not-found-404.home": "Zur Startseite", "notifications.backups-failing-location.description": "Automatische Backups zu {{location}} schlagen fehl. Überprüfe die Verbindung und deine Einstellungen für Backups.", "notifications.backups-failing.description": "Automatische Backups sind fehlgeschlagen. Schau dir deinen Backup-Standort und deine Einstellungen an.", "notifications.backups-failing.go-to-backups": "Zu Backups", "notifications.backups-failing.title": "Keine Backups in den letzten 24 Stunden", "notifications.cpu.too-hot": "Hohe CPU-Temperatur", "notifications.memory.low": "Der Arbeitsspeicher deines Geräts ist gering", "notifications.new-version-available": "{{update}} ist jetzt zur Installation verfügbar", "notifications.raid.issue.description": "Speicherproblem erkannt. Schau im Storage Manager nach Details.", "notifications.raid.issue.title": "Sofortiges Handeln erforderlich", "notifications.ssd.health.description": "Eine oder mehrere SSDs benötigen möglicherweise deine Aufmerksamkeit. Schau im Storage Manager nach Details.", "notifications.ssd.health.title": "Warnung zur SSD-Gesundheit", "notifications.storage.full": "Der Speicherplatz deines Geräts ist voll", "notifications.view": "Anzeigen", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "Mit Klick auf 'Weiter' stimmst du den umbrelOS Nutzungsbedingungen zu", "onboarding.account-created.youre-all-set-name": "Alles bereit, {{name}}.", "onboarding.contact-support": "Support", "onboarding.create-account": "Konto erstellen", "onboarding.create-account.confirm-password.input-label": "Passwort bestätigen", "onboarding.create-account.failed.name-required": "Name ist erforderlich", "onboarding.create-account.failed.passwords-dont-match": "Passwörter stimmen nicht überein", "onboarding.create-account.name.input-placeholder": "Dein Name", "onboarding.create-account.password.input-label": "Passwort", "onboarding.create-account.submit": "Erstellen", "onboarding.create-account.submitting": "Wird erstellt", "onboarding.create-account.subtitle": "Deine Kontoinformationen werden nur auf deinem Umbrel gespeichert. Stelle sicher, dass du dein Passwort sicher aufbewahrst, da es keine Möglichkeit gibt, es zurückzusetzen.", "onboarding.create-instead-long": "Neues Konto erstellen", "onboarding.create-instead-short": "Neues Konto", "onboarding.launch-umbrelos": "Starte umbrelOS", "onboarding.raid.available-storage": "Verfügbarer Speicher", "onboarding.raid.change-drives-link": "Möchtest du Laufwerke hinzufügen oder austauschen?", "onboarding.raid.configuring.subtitle": "Das kann ein paar Minuten dauern.", "onboarding.raid.configuring.title": "Wir richten deinen Speicher ein", "onboarding.raid.configuring.warning": "Bitte aktualisiere diese Seite nicht und schalte dein Umbrel nicht aus, während dein Speicher konfiguriert wird.", "onboarding.raid.continue": "Weiter", "onboarding.raid.error.detection-instructions": "Schalte Umbrel Pro aus, überprüfe, ob deine SSDs richtig sitzen, und versuche es erneut.", "onboarding.raid.error.no-ssds-detected": "Keine SSDs erkannt", "onboarding.raid.error.no-ssds-instructions": "Schalte Umbrel Pro aus und stecke mindestens eine SSD ein, um fortzufahren.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Du kannst FailSafe noch nicht aktivieren.", "onboarding.raid.failsafe.enable": "FailSafe aktivieren", "onboarding.raid.failsafe.mixed-sizes": "FailSafe wird durch deine kleinste SSD begrenzt ({{smallest}}). Extra Platz auf größeren SSDs kann nicht genutzt werden, sodass {{wasted}} unbrauchbar bleibt.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} wird zum Schutz deiner Daten verwendet. Füge eine weitere {{smallest}} SSD hinzu, um den verfügbaren Speicher auf {{futureWith3}} zu erhöhen, oder füge zwei weitere hinzu, um {{futureWith4}} zu erreichen. Du kannst jederzeit weitere SSDs hinzufügen.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} wird zum Schutz deiner Daten verwendet. Füge eine weitere {{smallest}} SSD hinzu, um den verfügbaren Speicher auf {{futureWith4}} zu erhöhen. Du kannst jederzeit weitere SSDs hinzufügen.", "onboarding.raid.failsafe.single-ssd-info": "Du hast nur eine SSD. Füge mindestens eine weitere {{size}} SSD hinzu, um den FailSafe-Schutz für deine Daten zu aktivieren. Du kannst jederzeit weitere SSDs hinzufügen.", "onboarding.raid.failsafe.subtitle": "Deine Daten bleiben sicher, falls eine einzelne SSD ausfällt", "onboarding.raid.failsafe.tip": "Verwende SSDs gleicher Größe für maximalen Speicherplatz und keinen unbrauchbaren Platz.", "onboarding.raid.failsafe.warning-now-only": "Wenn mehr als eine SSD vorhanden ist, kann FailSafe nur während der Ersteinrichtung aktiviert werden. Du kannst es später nicht mehr aktivieren.", "onboarding.raid.health-warning": "Dieses Laufwerk meldet Gesundheitsprobleme", "onboarding.raid.launching": "Wird gestartet…", "onboarding.raid.no-ssds-alt": "Keine SSDs gefunden", "onboarding.raid.recommended": "Empfohlen", "onboarding.raid.scanning": "Überprüfe deine SSD-Steckplätze", "onboarding.raid.scanning-alt": "SSDs werden gescannt", "onboarding.raid.setup-failed.description-no-retry": "Bitte fahre das Gerät herunter und versuche es erneut.", "onboarding.raid.setup-failed.description-retry": "Versuche es erneut oder fahre herunter, um deine Laufwerke zu überprüfen.", "onboarding.raid.setup-failed.title": "Speichereinrichtung fehlgeschlagen", "onboarding.raid.shutdown-dialog.description": "Um Laufwerke hinzuzufügen oder auszutauschen, schalte Umbrel Pro aus. Danach kannst du es wieder einschalten und mit der Einrichtung fortfahren.", "onboarding.raid.shutdown-dialog.title": "Laufwerke ändern?", "onboarding.raid.ssd-in-slot": "Eine {{size}} SSD in Slot {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSD-Schacht", "onboarding.raid.ssds-found": "Die folgenden SSDs wurden in deinem Umbrel Pro gefunden", "onboarding.raid.storage": "Speicher", "onboarding.raid.storage-label": "Speicher", "onboarding.raid.success.storage-info": "Speicher {{available}}", "onboarding.raid.success.storage-info-failsafe": "Speicher {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Erneut versuchen", "onboarding.raid.wasted": "Unbrauchbar", "onboarding.restore-long": "Mein Umbrel wiederherstellen", "onboarding.restore-short": "Wiederherstellen", "onboarding.start.continue": "Los geht's", "onboarding.start.subtitle": "Dein Heim-Cloud-Server ist bereit zur Einrichtung.", "onboarding.start.title": "Willkommen bei umbrelOS", "open": "Öffnen", "open-live-usage": "Live-Nutzung öffnen", "password": "Passwort", "preferences": "Einstellungen", "raid-error.description": "Dein Speichersystem konnte nicht richtig starten. Prüfe unten den Status deiner SSDs und folge den Schritten zur Fehlerbehebung. Falls das Problem weiterhin besteht, müssen eventuell betroffene SSDs ersetzt werden.", "raid-error.factory-reset-dialog.description": "Dies löscht alle Daten auf deinem Umbrel Pro und setzt ihn auf Werkseinstellungen zurück. Diese Aktion kann nicht rückgängig gemacht werden.", "raid-error.factory-reset-dialog.title": "Werkseinstellungen zurücksetzen?", "raid-error.factory-reset-failed": "Zurücksetzen auf Werkseinstellungen fehlgeschlagen", "raid-error.health-warning": "Gesundheitswarnung", "raid-error.missing-ssd-multiple": "{{count}} SSDs reagieren nicht", "raid-error.missing-ssd-one": "1 SSD reagiert nicht", "raid-error.shutdown-dialog.description": "Fahre dein Umbrel Pro herunter, stell sicher, dass alle SSDs richtig in ihren Steckplätzen sitzen, und schalte dann wieder ein.", "raid-error.shutdown-dialog.title": "Herunterfahren, um Laufwerke zu prüfen?", "raid-error.ssd-in-slot": "Eine {{size}} SSD in Steckplatz {{slot}}", "raid-error.step-check-connections.button": "Herunterfahren", "raid-error.step-check-connections.description": "Fahre herunter und überprüfe, ob alle SSDs richtig sitzen.", "raid-error.step-check-connections.title": "Verbindungen der SSDs prüfen", "raid-error.step-factory-reset.button": "Auf Werkseinstellungen zurücksetzen", "raid-error.step-factory-reset.description": "Letzter Ausweg, wenn sonst nichts hilft. Dadurch werden alle Daten gelöscht.", "raid-error.step-factory-reset.title": "Werkseinstellungen", "raid-error.step-restart.button": "Neu starten", "raid-error.step-restart.description": "Ein schneller erster Schritt, der oft hilft.", "raid-error.step-restart.title": "Versuche neu zu starten", "raid-error.title": "Speicherproblem festgestellt", "read-less": "Weniger lesen", "read-more": "Mehr lesen", "reconnect": "Erneut verbinden", "redirect.to-home": "Lädt...", "redirect.to-login": "Lädt...", "redirect.to-onboarding": "Lädt...", "redirect.to-raid-error": "Wird geladen...", "reload": "Neu laden", "remote-tor-access": "Remote Tor-Zugang", "reset": "Zurücksetzen", "restart": "Neustarten", "restart.confirm.submit": "Neustarten", "restart.confirm.title": "Möchtest du dein Umbrel wirklich neu starten?", "restart.restarting": "Neustart", "restart.restarting-message": "Bitte aktualisiere diese Seite nicht und schalte dein Umbrel nicht aus, während es neu startet.", "rewind": "Rewind", "rewind.files-as-of": "Deine Dateien vom", "rewind.loading-snapshots": "Snapshots werden geladen...", "rewind.now": "Jetzt", "rewind.preflight.description": "Finde Dateien und Ordner aus deinen vergangenen Backups und stelle sie in die Gegenwart wieder her.", "rewind.preflight.enable-backups": "Richte Backups in den Einstellungen ein, um Rewind zu verwenden", "rewind.restore-complete": "Wiederherstellung abgeschlossen", "rewind.restore-error-description": "Bitte versuche es erneut.", "rewind.restore-failed": "Wiederherstellung fehlgeschlagen", "rewind.restore-running-description": "Schließe oder aktualisiere diese Seite nicht, bis die Wiederherstellung abgeschlossen ist", "rewind.restore-selected": "Ausgewählte wiederherstellen", "rewind.restore-success-description": "Deine Dateien wurden wiederhergestellt", "rewind.restoring": "Wird wiederhergestellt", "rewind.snapshots-count_one": "{{count}} Backup seit", "rewind.snapshots-count_other": "{{count}} Backups seit", "search": "Suche", "settings": "Einstellungen", "settings.app-store-preferences.title": "App Store Einstellungen", "settings.contact-support": "Brauchst du Hilfe? Kontaktiere den Support.", "settings.file-sharing": "Dateifreigabe", "settings.file-sharing.add-folder": "Hinzufügen", "settings.file-sharing.add-folder-title": "Wähle einen Ordner zum Freigeben", "settings.file-sharing.choice-entire-description": "Teile alle Dateien auf deinem Umbrel", "settings.file-sharing.choice-entire-title": "Alles", "settings.file-sharing.choice-heading": "Was möchtest du teilen?", "settings.file-sharing.choice-specific-description": "Wähle aus, welche Ordner du teilen möchtest", "settings.file-sharing.choice-specific-title": "Bestimmte Ordner", "settings.file-sharing.choice-subtitle": "Greife auf deine Dateien und Ordner wie bei Dropbox als Netzwerkordner auf deinem Computer oder Smartphone zu", "settings.file-sharing.configure": "Konfigurieren", "settings.file-sharing.description": "Greife auf deine Dateien wie bei Dropbox als Netzwerkordner (SMB) auf anderen Geräten zu", "settings.file-sharing.home-shared-note": "Dein gesamter Ordner \"{{homeDirectoryName}}\" ist freigegeben. Einzelne Ordner müssen nicht separat freigegeben werden.", "settings.file-sharing.share-entire-home-dir": "Gesamten Home-Ordner freigeben", "settings.file-sharing.share-entire-home-dir-description": "Greife von anderen Geräten in deinem Netzwerk auf alle Dateien und Ordner in \"{{homeDirectoryName}}\" zu", "settings.file-sharing.shared-folders": "Freigegebene Ordner", "show-details": "Details anzeigen", "shut-down": "Herunterfahren", "shut-down.complete": "Herunterfahren abgeschlossen", "shut-down.complete-text": "Du kannst jetzt dein Gerät vom Strom trennen.", "shut-down.confirm.submit": "Herunterfahren", "shut-down.confirm.title": "Möchtest du dein Umbrel wirklich herunterfahren?", "shut-down.failed": "Fehler beim Herunterfahren: {{message}}", "shut-down.shutting-down": "Herunterfahren", "shut-down.shutting-down-message": "Bitte aktualisiere diese Seite nicht und schalte dein Umbrel nicht aus, während es herunterfährt.", "software-update.callout": "Bitte aktualisiere diese Seite nicht und schalte dein Umbrel nicht aus, während es aktualisiert wird.", "software-update.check": "Nach Aktualisierungen suchen", "software-update.checking": "Suche nach Aktualisierungen...", "software-update.current-running": "Du verwendest", "software-update.failed": "Aktualisierung fehlgeschlagen", "software-update.failed-to-check": "Fehler beim Suchen nach Aktualisierungen", "software-update.failed.retry": "Erneut versuchen", "software-update.install-now": "Jetzt installieren", "software-update.new-version": "Neue {{name}} ist verfügbar zur Installation", "software-update.on-latest": "Du verwendest die neueste Version von umbrelOS", "software-update.see-whats-new": "Sieh dir die Neuerungen an", "software-update.title": "Softwareaktualisierung", "software-update.updating-to": "Aktualisiere auf {{name}}", "software-update.view": "Anzeigen", "something-left": "{{left}} verbleibend", "something-went-wrong": "⚠ Es ist ein Fehler aufgetreten", "start": "Starten", "stop": "Stoppen", "storage": "Speicherplatz", "storage-manager": "Speicherverwaltung", "storage-manager.add": "Hinzufügen", "storage-manager.add-to-raid.add-ssd": "SSD hinzufügen", "storage-manager.add-to-raid.available": "Verfügbar:", "storage-manager.add-to-raid.description": "Eine neue SSD wurde erkannt und kann hinzugefügt werden.", "storage-manager.add-to-raid.enable-failsafe": "FailSafe aktivieren", "storage-manager.add-to-raid.failed-add": "Konnte die SSD nicht hinzufügen.", "storage-manager.add-to-raid.failed-enable-failsafe": "Konnte FailSafe nicht aktivieren.", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Deine neue {{size}} SSD wird dem verfügbaren Speicher hinzugefügt.", "storage-manager.add-to-raid.info-capacity-adds-available": "Deine neue {{size}} SSD fügt {{available}} verfügbaren Speicher hinzu.", "storage-manager.add-to-raid.info-capacity-adds-both": "Deine neue {{size}} SSD fügt {{available}} verfügbaren Speicher und {{protection}} zum Schutz deiner Daten hinzu.", "storage-manager.add-to-raid.info-capacity-protection-only": "Deine neue {{size}} SSD fügt {{protection}} zum Schutz deiner Daten hinzu.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Deine neue {{size}} SSD wird vollständig zum Schutz deiner Daten verwendet.", "storage-manager.add-to-raid.info-data-safe": "Deine Daten sind sicher, falls eine einzelne SSD ausfällt.", "storage-manager.add-to-raid.info-no-protection": "Wenn eine SSD ausfällt, könntest du deine Daten verlieren.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} insgesamt unbrauchbar aufgrund unterschiedlicher SSD-Größen.", "storage-manager.add-to-raid.info-wasted": "{{size}} werden aufgrund unterschiedlicher SSD-Größen unbrauchbar sein.", "storage-manager.add-to-raid.recommended": "Empfohlen", "storage-manager.add-to-raid.recommended-inline": "(empfohlen)", "storage-manager.add-to-raid.restart-active-tasks": "Aktive Aufgaben werden unterbrochen", "storage-manager.add-to-raid.restart-after": "Nach dem Neustart wird die FailSafe-Einrichtung automatisch abgeschlossen und du kannst das System wie gewohnt nutzen.", "storage-manager.add-to-raid.restart-during": "Während des Neustarts:", "storage-manager.add-to-raid.restart-intro": "Du kannst umbrelOS während dieses Vorgangs normal weiter verwenden. Bei 50% Fortschritt wird dein Umbrel automatisch neu gestartet.", "storage-manager.add-to-raid.restart-required": "Systemneustart erforderlich", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS ist vorübergehend nicht erreichbar.", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD in Steckplatz {{slot}}", "storage-manager.add-to-raid.title": "SSD zum Speicher hinzufügen", "storage-manager.add-to-raid.too-small": "SSD zu klein", "storage-manager.add-to-raid.too-small-description": "Diese SSD ({{deviceSize}}) ist kleiner als die derzeit kleinste installierte SSD ({{minSize}}). FailSafe erfordert, dass alle SSDs mindestens so groß sind wie die kleinste verwendete SSD.", "storage-manager.add-to-raid.understand-continue": "Verstanden, fortfahren", "storage-manager.add-to-raid.warning-failsafe-now-only": "Wenn du mehr als eine SSD hast, kann FailSafe jetzt nur noch sofort aktiviert werden. Später wird das nicht mehr möglich sein.", "storage-manager.add-to-raid.wasted-label": "Unbrauchbar:", "storage-manager.available-storage": "Verfügbarer Speicher", "storage-manager.description": "Speicher, Zustand und Einstellungen deiner SSDs anzeigen", "storage-manager.empty": "Leer", "storage-manager.failsafe-transition-failed": "Konnte FailSafe nicht aktivieren.", "storage-manager.for-failsafe": "Für FailSafe", "storage-manager.health.checksum-errors": "Prüfsummenfehler: {{count}}", "storage-manager.health.critical": "Kritisch", "storage-manager.health.critical-threshold": "Kritische Schwelle", "storage-manager.health.current-temperature": "Aktuelle Temperatur", "storage-manager.health.estimated-life": "Geschätzte verbleibende Lebensdauer", "storage-manager.health.general": "Allgemein", "storage-manager.health.health-status": "Zustand", "storage-manager.health.low": "Niedrig", "storage-manager.health.model-and-capacity": "Modell & Kapazität", "storage-manager.health.overheating": "Überhitzung", "storage-manager.health.raid-failed-advice": "Diese SSD hat ein Problem. Fahre dein Umbrel herunter und überprüfe die SSD-Verbindung. Wenn das Problem weiterhin besteht, muss die SSD möglicherweise ersetzt werden.", "storage-manager.health.read-errors": "Lese­fehler: {{count}}", "storage-manager.health.serial-number": "Seriennummer", "storage-manager.health.status-healthy": "Gesund", "storage-manager.health.status-unhealthy": "Ungesund", "storage-manager.health.status-unknown": "Unbekannt", "storage-manager.health.temperature": "Temperatur", "storage-manager.health.title": "SSD-Gesundheit", "storage-manager.health.warning-life-advice": "Erwäge, diese SSD bald zu ersetzen.", "storage-manager.health.warning-life-message": "Nur noch {{percent}}% Restlebensdauer.", "storage-manager.health.warning-temp-advice": "Stelle sicher, dass dein Umbrel Pro gute Luftzirkulation hat und die SSD richtig eingesetzt ist.", "storage-manager.health.warning-temp-critical": "Temperatur kritisch ({{temperature}})", "storage-manager.health.warning-temp-overheating": "Laufwerk überhitzt ({{temperature}})", "storage-manager.health.warning-threshold": "Warnschwelle", "storage-manager.health.warning-unhealthy-advice": "Diese SSD könnte bald ausfallen. Erwäge, sie zu ersetzen.", "storage-manager.health.warning-unhealthy-message": "Diese SSD könnte ein Problem haben.", "storage-manager.health.warnings": "Warnungen", "storage-manager.health.wear": "Verschleiß", "storage-manager.health.write-errors": "Schreibfehler: {{count}}", "storage-manager.install-ssd.description": "Füge weitere SSDs hinzu, um deinen Speicher zu erweitern.", "storage-manager.install-ssd.step-insert": "Setze neue SSDs in die freien Steckplätze ein", "storage-manager.install-ssd.step-power-on": "Schalte dein {{deviceName}} ein", "storage-manager.install-ssd.step-remove-bottom-cover": "Entferne die magnetische Bodenabdeckung", "storage-manager.install-ssd.step-replace-bottom-cover": "Setze die untere Abdeckung wieder auf", "storage-manager.install-ssd.step-return": "Kehre hierher zurück, um die SSDs zu deinem Speicher hinzuzufügen", "storage-manager.install-ssd.step-shut-down": "Fahre dein {{deviceName}} herunter", "storage-manager.install-ssd.title": "SSDs hinzufügen", "storage-manager.install-tips.image-alt": "SSD-Installationsanleitung", "storage-manager.install-tips.instructions": "Zum Einbauen: Entferne die Daumenschraube und schiebe die SSD schräg in den Steckplatz. Drücke die SSD nach unten, bis sie auf der Schraubensäule aufliegt, und befestige sie dann mit der Daumenschraube.", "storage-manager.install-tips.toggle": "Vergessen, wie man eine SSD einbaut?", "storage-manager.manage": "Verwalten", "storage-manager.missing-ssd-warning": "Eine SSD scheint zu fehlen. Fahre dein Umbrel herunter und überprüfe, ob alle SSDs angeschlossen sind. Wenn das Problem weiterhin besteht, muss die SSD möglicherweise ersetzt werden.", "storage-manager.mode": "Modus", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Schützt deine Daten, falls eine SSD ausfällt. Wenn deine SSDs unterschiedliche Größen haben, bleibt zusätzlicher Platz auf größeren SSDs ungenutzt.", "storage-manager.mode.failsafe.info-description": "FailSafe schützt deine Daten, indem Kopien auf mehreren SSDs gespeichert werden. Wenn eine SSD ausfällt, bleiben deine Daten sicher und können wiederhergestellt werden, sobald du eine Ersatz-SSD einsetzt.", "storage-manager.mode.failsafe.info-title": "Über FailSafe", "storage-manager.mode.full-storage": "Full Storage", "storage-manager.mode.full-storage.description": "Nutze den gesamten SSD-Speicher gemeinsam. Wenn eine SSD ausfällt, könntest du deine Daten verlieren.", "storage-manager.mode.full-storage.info-description": "Full Storage fasst alle SSDs zu einem großen Speicher zusammen und bietet maximalen Platz. Wenn jedoch eine SSD ausfällt, gehen alle Daten verloren.", "storage-manager.mode.full-storage.info-title": "Über Full Storage", "storage-manager.mode.switch-from-failsafe-unavailable": "Der Wechsel von FailSafe in den Full Storage-Modus erfordert, dass du deine Daten sicherst, das Gerät auf Werkseinstellungen zurücksetzt und ein Backup wiederherstellst.", "storage-manager.mode.switch-to-failsafe-unavailable": "Mit mehreren SSDs im Full Storage-Modus sind deine Daten über alle Laufwerke verteilt. Ein Wechsel zu FailSafe erfordert Backup, Werkseinstellungen und Wiederherstellung.", "storage-manager.mode.why-cant-switch": "Warum kann ich nicht wechseln?", "storage-manager.operation-in-progress.shutdown-description": "Du kannst das Gerät sicher herunterfahren. Der Vorgang wird pausiert und nach dem Neustart fortgesetzt, muss jedoch abgeschlossen sein, bevor du weitere Änderungen vornehmen kannst.", "storage-manager.operation-in-progress.shutdown-title": "Dein Speicher wird aktualisiert", "storage-manager.operation-in-progress.wait-description": "Bitte warte, bis der aktuelle Vorgang abgeschlossen ist, bevor du weitere Änderungen vornimmst.", "storage-manager.operation-in-progress.wait-title": "Dein Speicher wird aktualisiert", "storage-manager.operation.adding-ssd": "SSD wird hinzugefügt...", "storage-manager.operation.enabling-failsafe": "FailSafe wird aktiviert...", "storage-manager.operation.expanding": "Speicher wird erweitert...", "storage-manager.operation.rebuilding": "Daten werden wieder aufgebaut...", "storage-manager.operation.replacing": "Laufwerk wird ausgetauscht...", "storage-manager.operation.restarting": "Neustart...", "storage-manager.operation.starting": "Starte...", "storage-manager.operation.syncing-restarts": "Daten werden synchronisiert • Neustart bei 50%", "storage-manager.raid-status.degraded": "Reduziert", "storage-manager.raid-status.failed": "Ausgefallen", "storage-manager.raid-status.offline": "Offline", "storage-manager.raid-status.online": "Online", "storage-manager.raid-status.removed": "Entfernt", "storage-manager.raid-status.unavailable": "Nicht verfügbar", "storage-manager.replace": "Ersetzen", "storage-manager.replace-failed.degraded": "FailSafe-Schutz reduziert", "storage-manager.replace-failed.degraded-description": "Eine SSD fehlt in deinem FailSafe-Speicher. Ersetze sie, um den vollen Schutz wiederherzustellen.", "storage-manager.replace-failed.description": "Verwende diese SSD, um deinen FailSafe-Schutz wiederherzustellen.", "storage-manager.replace-failed.error": "Konnte den Austausch nicht starten", "storage-manager.replace-failed.replace-now": "Jetzt austauschen", "storage-manager.replace-failed.ssd-in-slot": "{{size}}-SSD in Steckplatz {{slot}}", "storage-manager.replace-failed.step-protected": "Nach Abschluss sind deine Daten wieder vollständig geschützt", "storage-manager.replace-failed.step-rebuild": "Die Daten werden auf die neue SSD wieder aufgebaut", "storage-manager.replace-failed.step-time": "Das kann je nach Datenmenge eine Weile dauern", "storage-manager.replace-failed.title": "SSD ersetzen", "storage-manager.replace-failed.too-small": "SSD zu klein", "storage-manager.replace-failed.too-small-description": "Diese SSD ({{deviceSize}}) ist kleiner als die für deinen FailSafe-Speicher erforderliche Mindestgröße ({{minSize}}).", "storage-manager.replace-failed.what-happens": "Wie es weitergeht:", "storage-manager.ssd-failing": "Fehlerhaft", "storage-manager.swap": "Tauschen", "storage-manager.swap.data-erased-description": "Im Full Storage-Modus gibt es keinen Schutz vor Datenverlust. Alle Daten auf deinem {{deviceName}} werden beim Zurücksetzen gelöscht. Sichere vorher alles.", "storage-manager.swap.data-protected": "Deine Daten sind geschützt", "storage-manager.swap.data-protected-description": "Mit aktiviertem FailSafe kannst du eine einzelne SSD austauschen, ohne Daten zu verlieren. Kein Backup nötig.", "storage-manager.swap.data-will-be-erased": "Daten werden gelöscht", "storage-manager.swap.description-failsafe": "Ersetze ein Laufwerk in deinem FailSafe-Speicher.", "storage-manager.swap.description-full-storage": "Ersetze ein Laufwerk in deiner Full Storage-Konfiguration.", "storage-manager.swap.description-no-free-slot": "Im Full Storage-Modus mit allen belegten Steckplätzen erfordert der Tausch einer SSD einen vollständigen Backup- und Wiederherstellungsprozess.", "storage-manager.swap.description-replace": "Migriere deine Daten auf eine neue SSD und entferne dann die alte.", "storage-manager.swap.failed-to-start": "Konnte den Ersatzvorgang nicht starten.", "storage-manager.swap.no-data-loss": "Kein Datenverlust", "storage-manager.swap.no-data-loss-description": "Deine Daten werden auf die neue SSD kopiert. Nach Abschluss kannst du die alte sicher entfernen.", "storage-manager.swap.safe-swap-available": "Sicherer Tausch verfügbar", "storage-manager.swap.safe-swap-description": "Da du einen freien Steckplatz hast, kannst du zuerst die neue SSD hinzufügen und dann deine Daten migrieren, bevor du die alte entfernst. Kein Backup nötig.", "storage-manager.swap.select-new-ssd": "Wähle die neue SSD:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD in Steckplatz {{slot}}", "storage-manager.swap.step-backup": "Sichere deine Daten", "storage-manager.swap.step-backup-description": "Gehe zu Einstellungen → Backups und erstelle ein Backup aller Daten.", "storage-manager.swap.step-data-copied": "Die Daten werden von der alten SSD auf die neue kopiert", "storage-manager.swap.step-factory-reset": "Werkseinstellungen", "storage-manager.swap.step-factory-reset-description": "Gehe zu Einstellungen → Erweitert → Werkseinstellungen, um dein {{deviceName}} zu löschen.", "storage-manager.swap.step-insert-new-ssd": "Setze die neue SSD in einen freien Steckplatz ein", "storage-manager.swap.step-may-take-while": "Das kann eine Weile dauern, je nachdem wie viele Daten du hast.", "storage-manager.swap.step-power-on": "Schalte dein {{deviceName}} ein", "storage-manager.swap.step-remove-bottom-cover": "Entferne die magnetische Bodenabdeckung", "storage-manager.swap.step-remove-old": "Sobald fertig, fahre herunter und entferne {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Setze die Bodenabdeckung wieder auf", "storage-manager.swap.step-restore": "Stelle deine Daten wieder her", "storage-manager.swap.step-restore-description": "Gehe zu Einstellungen → Backups und stelle dein Backup wieder her.", "storage-manager.swap.step-return-to-storage-manager": "Kehre zur Speicherverwaltung zurück, um den Tausch zu bestätigen und die neue SSD zu deinem Speicher hinzuzufügen", "storage-manager.swap.step-return-to-swap": "Kehre zur Speicherverwaltung zurück und klicke erneut auf \"Swap\", um den Austausch zu starten", "storage-manager.swap.step-setup-new-storage": "Richte deinen neuen Speicher ein", "storage-manager.swap.step-setup-new-storage-description": "Schalte dein {{deviceName}} ein und schließe die Einrichtung mit der neuen SSD ab.", "storage-manager.swap.step-shut-down": "Fahre dein {{deviceName}} herunter", "storage-manager.swap.step-shut-down-and-swap": "Herunterfahren und {{ssd}} tauschen", "storage-manager.swap.step-shut-down-and-swap-description-other": "Ausschalten, Gerät öffnen, SSD ersetzen und wieder zusammenbauen.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Ausschalten, Bodenabdeckung entfernen, SSD ersetzen und Abdeckung wieder schließen.", "storage-manager.swap.step-swap-ssd": "Tausche {{ssd}} gegen eine neue mit derselben Größe", "storage-manager.swap.too-small": "Zu klein ({{size}} benötigt)", "storage-manager.swap.what-happens-next": "Was als Nächstes passiert:", "storage-manager.total-capacity-added": "Hinzugefügte Gesamtkapazität", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Belegt", "storage-manager.wasted": "Unbrauchbar", "storage-manager.wasted-size": "{{size}} nicht verwendbar", "storage.full": "Speicherplatz voll", "storage.low": "Wenig Speicherplatz", "temperature": "Temperatur", "temperature.dangerously-hot": "Sehr heiß", "temperature.nice": "Angenehm", "temperature.normal": "Normal", "temperature.too-hot-suggestion": "Überlege, die Umgebung deines Geräts zu ändern.", "temperature.warm": "Warm", "terminal": "Terminal", "terminal-description": "Führe benutzerdefinierte Befehle in umbrelOS oder innerhalb einer App aus", "terminal.app": "App", "terminal.app-description": "Führe benutzerdefinierte Befehle innerhalb einer spezifischen App aus", "terminal.umbrelos-description": "Führe benutzerdefinierte Befehle in umbrelOS aus", "tor-description": "Greife von überall auf dein Umbrel zu mit einem Tor-Browser", "tor-enabled-description": "Greife von überall mit einem Tor-Browser über die folgende URL auf dein Umbrel zu:", "tor-error": "Fehler beim Aktualisieren der Tor-Einstellung: {{message}}", "tor.disable.description": "Dies kann einige Minuten dauern", "tor.disable.progress": "Remote-Tor-Zugriff wird deaktiviert", "tor.enable.description": "Dies kann einige Minuten dauern", "tor.enable.mobile.switch-label": "Remote Tor-Zugang aktivieren", "tor.hidden-service": "Tor Hidden Service URL", "troubleshoot": "Fehlerbehebung", "troubleshoot-description": "Fehlerbehebung für umbrelOS oder eine App", "troubleshoot-no-logs-yet": "Noch keine Protokolle", "troubleshoot-pick-title": "Fehlerbehebung", "troubleshoot.app": "App", "troubleshoot.app-description": "Protokolle einer auf deinem Umbrel installierten App anzeigen", "troubleshoot.app-download": "{{app}} Protokolle herunterladen", "troubleshoot.share-with-umbrel-support": "Mit dem Umbrel-Support teilen", "troubleshoot.system-download": "{{label}} herunterladen", "troubleshoot.umbrelos-description": "umbrelOS-Protokolle anzeigen", "troubleshoot.umbrelos-logs": "umbrelOS-Protokolle", "trpc.backend-unavailable": "Fehler: Verbindung zur System-API fehlgeschlagen", "trpc.checking-backend": "Lädt...", "try-again": "Erneut versuchen", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Unbekannt", "unknown-app": "Unbekannte App", "unknown-error": "Unbekannter Fehler", "uptime": "Betriebszeit", "url": "URL", "wallpaper": "Hintergrundbild", "wallpaper-description": "Dein Umbrel Hintergrundbild und Thema", "whats-new.continue": "Fortfahren", "whats-new.feature-1.description": "Richte automatisierte, verschlüsselte Backups deines gesamten Umbrel auf einem externen USB-Laufwerk, einem NAS oder einem anderen Umbrel ein.", "whats-new.feature-2.description": "Springe in der Zeit zurück, um bestimmte Dateien und Ordner aus früheren Backups wiederherzustellen.", "whats-new.feature-3.description": "Oder stelle dein gesamtes Umbrel wieder her, inklusive aller Apps, Dateien und Daten.", "whats-new.feature-4.description": "Verbinde ein NAS oder ein anderes Umbrel und greife über Files auf dessen Speicher zu.", "whats-new.feature-4.title": "Netzwerkgeräte", "whats-new.feature-5.description": "Schließe externe USB-Laufwerke an (auf dem Umbrel Home oder auf jedem Intel- oder AMD-Gerät) und greife über Files darauf zu.", "whats-new.feature-5.helper-text": "Auf Raspberry Pi-Geräten nicht unterstützt, da es zu Stromproblemen kommen kann.", "whats-new.feature-5.title": "Externer Speicher", "whats-new.next": "Weiter", "whats-new.title": "Neu in {{version}}", "widget.progress.in-progress": "In Bearbeitung", "widgets.edit.select-up-to-3-widgets": "Wähle bis zu 3 Widgets", "widgets.install-an-app-before-using-widgets": "Installiere eine App, um deinen Startbildschirm mit Widgets anzupassen.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Offene Netzwerke können unsicher sein", "wifi-connection-failed": "Verbindung fehlgeschlagen", "wifi-dangerous-change-confirmation-description": "Ein Wechsel des Wi-Fi-Netzwerks kann dich von deinem Umbrel trennen. Um dich erneut zu verbinden, stelle sicher, dass sowohl dein Umbrel als auch das Gerät, von dem aus du darauf zugreifst, im selben Netzwerk sind.", "wifi-dangerous-change-confirmation-title": "Bist du sicher, dass du das Wi-Fi-Netzwerk wechseln möchtest?", "wifi-dangerous-disable-confirmation-description": "Das Deaktivieren von Wi-Fi kann dich von deinem Umbrel trennen. Um dich erneut zu verbinden, stecke ein Ethernet-Kabel in dein Umbrel und stelle sicher, dass sowohl dein Umbrel als auch das Gerät, von dem aus du darauf zugreifst, im selben Netzwerk sind.", "wifi-dangerous-disable-confirmation-title": "Bist du sicher, dass du Wi-Fi deaktivieren möchtest?", "wifi-description": "Verbinde dein Gerät mit einem Wi-Fi-Netzwerk", "wifi-description-long": "Dein Gerät bleibt mit deinem gewählten Wi-Fi verbunden, auch wenn das Ethernet-Kabel entfernt wird, und verbindet sich beim Start automatisch wieder mit dem Wi-Fi.", "wifi-no-networks-message": "Keine Wi-Fi-Netzwerke gefunden", "wifi-searching": "Suche nach Wi-Fi-Netzwerken...", "wifi-unsupported-device-description": "Wi-Fi wird auf diesem Gerät nicht unterstützt. Dies kann an einem fehlenden oder inkompatiblen WLAN-Adapter liegen.", "wifi-view-networks": "Netzwerke anzeigen" } ================================================ FILE: packages/ui/public/locales/en.json ================================================ { "2fa": "2FA", "2fa-description": "A second layer of security for your Umbrel login and apps", "2fa.disable.title": "Disable two-factor authentication", "2fa.enable.or-paste": "Or paste the following code in your authenticator app", "2fa.enable.scan-this": "Scan this QR code using an authenticator app like Google Authenticator or Authy", "2fa.enable.title": "Enable two-factor authentication", "2fa.enter-code": "Enter the code displayed in your authenticator app", "account": "Account", "account-description": "Your name and password", "advanced-settings": "Advanced settings", "advanced-settings-description": "Terminal, umbrelOS Beta Program, Cloudflare DNS, and more", "app-not-found": "App not found: {{app}}", "app-only-over-tor": "{{app}} can only be used over Tor. Please access your Umbrel in a Tor browser on your remote access URL (Settings > Advanced settings > Remote Tor access) to open this app.", "app-page.section.about": "About", "app-page.section.credentials.title": "Default credentials", "app-page.section.dependencies.n-alternatives": "See {{count}} alternatives", "app-page.section.info.compatibility": "Compatibility", "app-page.section.info.compatibility-compatible": "Compatible", "app-page.section.info.compatibility-not-compatible": "Not compatible", "app-page.section.info.developer": "Developer", "app-page.section.info.source-code": "Source Code", "app-page.section.info.source-code.public": "Public", "app-page.section.info.submitted-by": "Submitted by", "app-page.section.info.support": "Get support", "app-page.section.info.title": "Info", "app-page.section.info.version": "Version", "app-page.section.recommendations.title": "You might also like", "app-page.section.release-notes.title": "What's new", "app-page.section.release-notes.version": "Version {{version}}", "app-page.section.requires": "Requires", "app-picker.search": "Search...", "app-picker.select-app": "Select app...", "app-settings.connected-to": "{{appName}} is connected to these apps", "app-settings.save-changes": "Save changes", "app-settings.title": "Settings", "app-store.browse-category-apps": "Browse {{category}} apps", "app-store.category.ai": "AI", "app-store.category.all": "All apps", "app-store.category.automation": "Home & Automation", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Crypto", "app-store.category.developer": "Developer Tools", "app-store.category.discover": "Discover", "app-store.category.files": "Files & Productivity", "app-store.category.finance": "Finance", "app-store.category.media": "Media", "app-store.category.networking": "Networking", "app-store.category.social": "Social", "app-store.description": "Your app update settings", "app-store.discover.temporarily-unavailable-description": "Browse categories above or search to find apps", "app-store.discover.temporarily-unavailable-title": "Featured content temporarily unavailable", "app-store.menu.community-app-stores": "Community App Stores", "app-store.search-apps": "Search apps", "app-store.search.no-results": "No results", "app-store.search.results-for": "Results for", "app-store.title": "App Store", "app-store.updates": "Updates", "app-updates.less": "less", "app-updates.more": "more", "app-updates.no-updates": "All apps are up-to-date!", "app-updates.update": "Update", "app-updates.update-all": "Update all", "app-updates.updates-available-count_one": "{{count}} update available", "app-updates.updates-available-count_other": "{{count}} updates available", "app-updates.updating": "Updating...", "app.install": "Install", "app.installed": "Installed", "app.installing": "Installing", "app.offline": "Not running", "app.open": "Open", "app.optimized-for-umbrel-home": "Optimized for Umbrel Home", "app.os-update-required.confirm": "Check for umbrelOS update", "app.os-update-required.description": "{{appName}} requires umbrelOS {{version}} or later", "app.os-update-required.title": "Update umbrelOS", "app.restarting": "Restarting", "app.starting": "Starting", "app.stopping": "Stopping", "app.uninstall.confirm.description": "All data associated with {{app}} will be permanently deleted. This action cannot be undone.", "app.uninstall.confirm.submit": "Uninstall", "app.uninstall.confirm.title": "Uninstall {{app}}?", "app.uninstall.deps.used-by.description_one": "Uninstall {{firstAppToUninstall}} first to uninstall {{app}}.", "app.uninstall.deps.used-by.description_other": "Uninstall these apps first to uninstall {{app}}.", "app.uninstall.deps.used-by.title": "{{app}} is used by", "app.uninstalling": "Uninstalling", "app.updating": "Updating", "app.view": "View", "app_one": "app", "app_other": "apps", "apps.uninstall.failed-to-get-required-apps": "Failed to get required apps", "apps.uninstalled-all.success": "Uninstalled all apps", "auth.checking-backend-for-user": "Loading...", "auth.failed-checking-if-user-logged-in": "Error: Auth login check failed", "auth.failed-to-check-if-user-exists": "Error: Auth existence check failes", "back": "Back", "backups": "Backups", "backups-configure": "Configure", "backups-configure.add-backup-location": "Add backup location", "backups-configure.available": "Available", "backups-configure.awaiting-next-backup": "Awaiting next automatic backup", "backups-configure.back-up-now": "Back up now", "backups-configure.backing-up-now": "Backing up now...", "backups-configure.connected": "Connected", "backups-configure.connection": "Connection", "backups-configure.in-progress": "In progress", "backups-configure.last-backup": "Last backup", "backups-configure.locations": "Locations", "backups-configure.no-backup-locations": "Add a backup location to start backing up your data", "backups-configure.not-connected": "Not connected", "backups-configure.path": "Path", "backups-configure.remove-backup-location": "Remove backup location", "backups-configure.remove-backup-location-confirmation": "Are you sure?", "backups-configure.remove-backup-location-confirmation-description": "This will remove '{{device}}' from your backup locations. Your existing backups on this device will not be deleted, but automatic backups will stop.", "backups-configure.status": "Status", "backups-configure.total-backups": "Total backups", "backups-configure.used": "Used", "backups-configure.view": "View", "backups-description": "Back up your files, apps, and data to another Umbrel, NAS, or external drive", "backups-error.backup-not-found": "The backup could not be found.", "backups-error.generic": "Something went wrong: {{details}}", "backups-error.in-progress": "A backup process is already running. Please wait for it to finish.", "backups-error.invalid-exclusion-path": "Only files and folders in your Home directory can be excluded from backups.", "backups-error.invalid-password": "The encryption password is incorrect.", "backups-error.invalid-path": "The selected location is not valid for backups.", "backups-error.mount-failed": "Could not access the backup snapshot.", "backups-error.mount-timeout": "Could not access the backup snapshot. Try again or check if the device is connected properly.", "backups-error.not-enough-space": "Not enough space available on the backup device.", "backups-error.not-found": "The backup or backup location could not be found.", "backups-error.repository-exists": "A backup location already exists at this folder.", "backups-error.repository-not-found": "The backup location could not be found.", "backups-exclusions.add": "Add", "backups-exclusions.app-paths-cannot-be-modified": "These files/folders are set by the app developer and cannot be modified:", "backups-exclusions.app-paths-explanation": "This app excludes the following data from being backed up. These paths usually contain non-essential items (like caches or logs that can be recreated) or data that could cause issues if restored (such as outdated app states that might lead to conflicts or inconsistencies).", "backups-exclusions.auto-excluded": "Auto-excluded", "backups-exclusions.exclude-entire-app": "Exclude entire app", "backups-exclusions.excluded-apps": "Excluded apps", "backups-exclusions.files-and-folders": "Excluded files and folders", "backups-exclusions.no-excluded-apps": "No excluded apps", "backups-exclusions.no-excluded-files-or-folders": "No excluded files or folders", "backups-exclusions.select-item-to-exclude": "Select item to exclude", "backups-exclusions.stop-excluding": "Stop excluding", "backups-floating-island.backing-up": "Backing up...", "backups-floating-island.backing-up-to": "Backing up your Umbrel...", "backups-restore": "Restore", "backups-restore-full": "Full Restore", "backups-restore-full-description": "Restore your entire Umbrel from a backup", "backups-restore-header": "Restore your Umbrel", "backups-restore-pro.after-restore": "After restoring, your temporary account will be replaced with your backed-up account and data.", "backups-restore-pro.step1": "Complete onboarding by clicking \"Get Started\" below. This will be your temporary account until you restore your backed-up account.", "backups-restore-pro.step2": "Once setup is complete, go to <0>Settings → Backups → Restore", "backups-restore-pro.step3": "Follow the prompts in the Restore Wizard.", "backups-restore-pro.subtitle": "Restoring from a backup on Umbrel Pro requires a few extra steps", "backups-restore.backup-date": "Backup date", "backups-restore.backup-location": "Backup location", "backups-restore.browse-cloud-subtitle": "Restore from Umbrel Private Cloud (coming soon)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Restore from an external USB drive", "backups-restore.browse-external-title": "External Drive", "backups-restore.browse-nas-or-external": "Browse another Umbrel, NAS, or an external drive to restore from a backup", "backups-restore.browse-nas-subtitle": "Restore from another Umbrel or NAS device on your network", "backups-restore.browse-nas-title": "Another Umbrel or NAS", "backups-restore.choose": "Choose", "backups-restore.choose-backup-location": "Choose a backup location", "backups-restore.connect-to-backup-location": "Connect to a backup location", "backups-restore.encryption-password": "Encryption password", "backups-restore.encryption-password-description": "Enter the encryption password that you set when you enabled backups", "backups-restore.enter-password-to-confirm": "Enter your Umbrel password to confirm", "backups-restore.final-confirmation": "Are you sure?", "backups-restore.final-confirmation-description": "Restoring from this backup will replace your current umbrelOS apps and data with the contents of the selected backup. Any files, folders, or apps excluded from this backup will be removed from your Umbrel. This action cannot be undone.", "backups-restore.invalid-password": "Invalid password", "backups-restore.last-backup": "Last backup: {{date}}", "backups-restore.latest": "Latest", "backups-restore.no-backups-found": "No backups found", "backups-restore.no-backups-yet": "No backups yet", "backups-restore.please-select-backup": "Please select a backup", "backups-restore.please-select-repository": "Please select a repository", "backups-restore.restore-from-nas-or-external": "Restore your Umbrel from a backup on another Umbrel, a NAS, or an external drive", "backups-restore.restore-from-unlisted": "Restore from another location", "backups-restore.restore-umbrel": "Restore Umbrel", "backups-restore.restore-warning": "Restoring from this backup will replace your current umbrelOS apps and data with the contents of the selected backup. Any files, folders, or apps excluded from this backup will be removed from your Umbrel. Open <0>Rewind if you wish to restore specific files or folders instead.", "backups-restore.restoring-from": "You are about to restore from the following backup:", "backups-restore.review-description": "Restoring will set up your Umbrel with the account, files, apps, and settings that were included at the time of this backup. This may take some time. Once it's complete, your login password will be set to the one you used when the backup was created.", "backups-restore.select-backup": "Select a backup", "backups-restore.select-backup-description": "Select the backup you want to restore from", "backups-restore.select-backup-file": "Select your backup file", "backups-restore.select-backup-file-only": "Only {{backupFileName}} can be selected", "backups-restore.total-size": "Total size", "backups-restore.unknown-date": "Unknown date", "backups-restore.unknown-repository": "Unknown repository", "backups-rewind": "Rewind", "backups-rewind-description": "Jump back in time to restore specific files and folders", "backups-rewind.start": "Start Rewind", "backups-setup": "Set up", "backups-setup-confirm": "Finish setup", "backups-setup-external-description": "Back up to an external USB drive", "backups-setup-nas-or-umbrel-description": "Back up to another Umbrel or a NAS device on your network", "backups-setup-umbrel-or-nas": "Another Umbrel or NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Extend your peace of mind beyond your home with end-to-end encrypted backups to Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Get early access", "backups-setup-umbrel-private-cloud-description": "End-to-end encrypted backups to Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Coming soon", "backups.add-umbrel-or-nas": "Add Umbrel or NAS", "backups.all-apps-and-data-will-be-backed-up": "All apps and data will be backed up", "backups.apps-and-data": "Apps & data", "backups.backup-location": "Backup location", "backups.browse": "Browse", "backups.choose-folder-within-device": "Choose a folder within {{device}} to save your backups", "backups.confirm-password": "Confirm password", "backups.copy": "Copy", "backups.encryption": "Encryption", "backups.encryption-password-warning": "Make sure your encryption password is stored securely, such as in a password manager. You will not be able to see it again, and you will need it to restore from your backups.", "backups.exclude-from-backups": "Exclude from Backups", "backups.exclude-from-backups-description": "Exclude specific files, folders, and apps from your backups.", "backups.hide": "Hide", "backups.i-understand": "I understand", "backups.location": "Location", "backups.modals.already-in-use.description": "This backup location is already being used for backups on this Umbrel.", "backups.modals.already-in-use.manage": "Manage in Backups", "backups.modals.already-in-use.title": "Backup location already in use", "backups.modals.connect-existing.description": "An Umbrel backup already exists at this location. Enter its encryption password to add it to this Umbrel.", "backups.modals.connect-existing.title": "Connect existing Umbrel backup", "backups.no-external-drives-detected": "No external drives detected", "backups.no-password-set": "No password set", "backups.password-is-set": "Password is set", "backups.password-minimum-length": "Password must be at least 8 characters", "backups.password-safety-warning": "Your backups will be encrypted with this password. Keep it safe, as you will not be able to see it again, and you will need it to restore from your backups.", "backups.passwords-do-not-match": "Passwords do not match", "backups.please-choose-folder": "Please choose a folder", "backups.restore-failed.message": "There was an error while restoring your Umbrel. Your current apps and data were not changed.", "backups.restore-failed.retry": "Go to Restore", "backups.restore-failed.title": "Restore failed", "backups.restoring": "Restoring your Umbrel", "backups.restoring-completing": "Finishing up. Your Umbrel will restart shortly...", "backups.restoring-progress": "Restored {{percent}}%", "backups.restoring-time-remaining": "{{time}} remaining", "backups.restoring-warning": "Do not power off your Umbrel or disconnect your backup location during restore", "backups.review": "Review and confirm", "backups.review-description": "Review the details of your backup and confirm your selection", "backups.scanning-for-external-drives": "Scanning for external drives...", "backups.schedule-description": "umbrelOS backs up your data automatically on an hourly basis. It keeps encrypted hourly backups for the past 24 hours, daily backups for the past week, weekly backups for the past month, and monthly backups for the past year. Backups older than one year are automatically removed.", "backups.select-backup-folder": "Select backup folder", "backups.select-backup-folder-description": "Choose a folder where you'd like to store your backups.", "backups.select-backup-location": "Select a backup location", "backups.set-encryption-password": "Set encryption password", "backups.set-encryption-password-description": "Protect your backups with a password. This ensures your data stays private and can only be restored with this password.", "backups.show": "Show", "backups.storage-capacity-warning": "{{device}} must have free space equal to at least twice your backup size", "backups.store-encryption-password-safely": "Store your encryption password safely", "beta-program": "umbrelOS Beta Program", "beta-program-description": "Opt in to receive umbrelOS beta updates, gain early access to new features, and help us refine them by providing your feedback. Beta updates might be unstable, and troubleshooting may require familiarity with terminal.", "cancel": "Cancel", "change": "Change", "change-name": "Change name", "change-name.failed.name-required": "Name is required", "change-name.input-placeholder": "Your name", "change-password": "Change password", "change-password.callout": "If you lose your password, you won't be able to log into your Umbrel. Make sure to safely secure it.", "change-password.current-password": "Current password", "change-password.failed.current-required": "Current password is required", "change-password.failed.min-length": "Password must be at least {{characters}} characters", "change-password.failed.must-be-unique": "New password must be different from the current password", "change-password.failed.new-required": "New password is required", "change-password.failed.no-match": "Passwords do not match", "change-password.failed.repeat-required": "Repeat password is required", "change-password.new-password": "New password", "change-password.repeat-password": "Repeat password", "check-for-latest-version": "Check for the latest umbrelOS update", "clipboard.copied": "Copied", "close": "Close", "cmdk.change-wallpaper": "Change wallpaper", "cmdk.frequent-apps": "Frequently used", "cmdk.input-placeholder": "Search for apps, settings, or actions", "cmdk.live-usage": "Live Usage", "cmdk.restart-umbrel": "Restart Umbrel", "cmdk.shutdown-umbrel": "Shut down Umbrel", "cmdk.update-all-apps": "Update all apps", "cmdk.widgets": "Widgets", "community-app-store": "Community App Store", "community-app-store.add-error": "Failed to add app store: {{message}}", "community-app-store.back-to-umbrel-app-store": "Back to Umbrel App Store", "community-app-store.open-button": "Open", "community-app-store.remove-button": "Remove", "community-app-store.remove-error": "Failed to remove app store: {{message}}", "community-app-stores.add-button": "Add", "community-app-stores.description": "Community App Stores allow you to install apps on your Umbrel that may not be available in the official Umbrel App Store. They also make it easy to test beta versions of Umbrel apps before developers release them on the official Umbrel App Store.", "community-app-stores.learn-more": "Learn more", "community-app-stores.warning": "Community App Stores can be created by anyone. The apps published in them are not verified or vetted by the official Umbrel App Store team, and can potentially be insecure or malicious. Use caution and only add app stores from developers you trust.", "confirm": "Confirm", "connect": "Connect", "connecting": "Connecting...", "connection-lost": "Connection lost", "connection-lost-description": "This can happen when your browser tab has been inactive, your network connection was interrupted, or your device is offline.", "continue": "Continue", "continue-to-log-in": "Continue to log in", "cpu": "CPU", "cpu-core-count": "{{cores}} threads", "default-credentials.close": "Got it", "default-credentials.description": "Here are the default credentials you will need to log into the app.", "default-credentials.dont-show-again": "Don't show this again", "default-credentials.dont-show-again-notice": "You can access these credentials at any time in the future by right-clicking on the app icon.", "default-credentials.open": "Open {{app}}", "default-credentials.password": "Default password", "default-credentials.title": "Credentials for {{app}}", "default-credentials.username": "Default username", "desktop.app.context.go-to-store-page": "View in App Store", "desktop.app.context.settings": "Settings", "desktop.app.context.show-default-credentials": "Show default credentials", "desktop.app.context.uninstall": "Uninstall", "desktop.context-menu.change-wallpaper": "Change wallpaper", "desktop.context-menu.edit-widgets": "Edit widgets", "desktop.context-menu.logout": "Log out", "desktop.greeting.afternoon": "Good afternoon, {{name}}", "desktop.greeting.evening": "Good evening, {{name}}", "desktop.greeting.morning": "Good morning, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "For the viber", "desktop.install-first.for-the-bitcoiner": "For the Bitcoiner", "desktop.install-first.for-the-self-hoster": "For the self-hoster", "desktop.install-first.for-the-streamer": "For the streamer", "desktop.install-first.link-to-app-store": "Explore more in App Store", "desktop.not-enough-room": "Use a larger screen to view your apps.", "device": "Device", "device-info": "Device info", "device-info-description": "Information about your device", "device-info.device": "Device", "device-info.model-number": "Model number", "device-info.serial-number": "Serial number", "device-info.view-info": "View info", "device-name.home-or-pro": "Umbrel Home or Umbrel Pro", "disable": "Disable", "done": "Done", "download-logs": "Download logs", "enabling-tor": "Enabling Remote Tor access", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS offers better network reliability. Disable to use your router's DNS settings.", "external-dns-error": "Failed to update DNS setting: {{message}}", "external-drive": "External Drive", "factory-reset": "Factory Reset", "factory-reset-description": "Erase all your data and apps, restoring umbrelOS to default settings", "factory-reset-failed": "Failed to reset your device: {{message}}", "factory-reset.confirm.body": "Confirm your password to reset", "factory-reset.confirm.ethernet-required-warning": "Ensure your device is connected to your router via Ethernet (not Wi-Fi) and you're accessing it from your local network (e.g., http://umbrel.local or your device's local IP address).", "factory-reset.confirm.submit": "Erase everything and reset", "factory-reset.confirm.submit-callout": "This action cannot be undone.", "factory-reset.rebooting.message": "Your device will restart and all data will be erased. Please don't close this page.", "factory-reset.rebooting.status": "Resetting...", "factory-reset.rebooting.title": "Factory reset in progress", "factory-reset.review.account-info": "Account info and password", "factory-reset.review.apps": "Apps", "factory-reset.review.following-will-be-removed": "The following will be removed from your device", "factory-reset.review.installed-apps_one": "{{count}} installed app", "factory-reset.review.installed-apps_other": "{{count}} installed apps", "factory-reset.review.submit": "Continue", "factory-reset.review.total-data": "Total data", "files": "Files", "files-action.add-favorite": "Add to favorites", "files-action.add-network-device": "Add device", "files-action.cancel-upload": "Cancel upload", "files-action.compress": "Compress", "files-action.copy": "Copy", "files-action.cut": "Cut", "files-action.delete": "Delete permanently", "files-action.download": "Download", "files-action.download-items": "Download {{count}} items", "files-action.drop-to-upload": "Drop to upload", "files-action.eject-disk": "Eject", "files-action.empty-trash": "Empty Trash", "files-action.format-drive": "Format", "files-action.go-to-path": "Go to...", "files-action.new-folder": "New Folder", "files-action.open": "Open", "files-action.paste": "Paste", "files-action.remove-favorite": "Remove from favorites", "files-action.remove-network-host": "Eject network drive", "files-action.remove-network-share": "Eject network share", "files-action.rename": "Rename", "files-action.restore": "Restore", "files-action.select": "Select", "files-action.share": "Share over network...", "files-action.sharing": "Sharing...", "files-action.show-in-folder": "Show in Enclosing Folder", "files-action.trash": "Trash", "files-action.uncompress": "Uncompress", "files-action.upload": "Upload", "files-add-network-share.add-manually": "Add manually", "files-add-network-share.add-share": "Add share", "files-add-network-share.back": "Back", "files-add-network-share.continue": "Continue", "files-add-network-share.description": "Connect to another Umbrel, a NAS, or a shared drive on your network to access them within Files.", "files-add-network-share.discovering": "Discovering...", "files-add-network-share.enter-details-manually": "Enter server details", "files-add-network-share.host-label": "Server address", "files-add-network-share.host-required": "Server address is required", "files-add-network-share.manual-share-help": "Enter the exact name of the share as it appears on your server", "files-add-network-share.no-shares-found": "No shares found on this server", "files-add-network-share.not-seeing-share": "Not seeing your share?", "files-add-network-share.password-label": "Password", "files-add-network-share.password-required": "Password is required", "files-add-network-share.retrieving-shares": "Retrieving shares...", "files-add-network-share.retry-discovery": "Rescan network", "files-add-network-share.select-share": "Select a share to add", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Share is required", "files-add-network-share.title": "Add a network share", "files-add-network-share.username-label": "Username", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Username is required", "files-audio-island.now-playing": "Now Playing", "files-audio-island.pause": "Pause", "files-audio-island.play": "Play", "files-backend-error.base-directory-not-found": "The base directory could not be found", "files-backend-error.cant-find-root": "Could not verify the file path", "files-backend-error.destination-already-exists": "An item with the same name already exists at the destination", "files-backend-error.destination-not-exist": "The destination folder does not exist", "files-backend-error.does-not-exist": "The file or folder does not exist", "files-backend-error.escapes-base": "The path is outside the allowed directory", "files-backend-error.invalid-base": "The path does not belong to a valid directory", "files-backend-error.invalid-filename": "The file name is not valid", "files-backend-error.invalid-path": "The file path is not valid", "files-backend-error.mkdir-failed": "Failed to create the folder", "files-backend-error.move-failed": "Failed to move the item", "files-backend-error.not-enough-space": "Not enough storage space available", "files-backend-error.operation-not-allowed": "This operation is not allowed", "files-backend-error.parent-not-directory": "The parent path is not a folder", "files-backend-error.parent-not-exist": "The parent folder does not exist", "files-backend-error.path-not-absolute": "The file path is not valid", "files-backend-error.share-already-exists": "This folder is already shared", "files-backend-error.share-name-generation-failed": "Could not generate a unique share name", "files-backend-error.source-not-exists": "The source file or folder does not exist", "files-backend-error.subdir-of-self": "A folder cannot be moved or copied into itself", "files-backend-error.trash-meta-not-exists": "Could not find the original location for this item", "files-backend-error.unique-name-index-exceeded": "Could not generate a unique name. Too many items with similar names exist", "files-backend-error.upload-failed": "Upload failed", "files-collision.action.keep-both": "Keep Both", "files-collision.action.replace": "Replace", "files-collision.action.skip": "Skip", "files-collision.destination.original-location": "its original location", "files-collision.message": "Do you want to replace the existing item or keep both?", "files-collision.title": "\"{{itemName}}\" already exists in {{destinationName}}", "files-download.confirm": "Download", "files-download.description": "Files cannot open this type of file. Would you like to download it instead?", "files-download.title": "Download {{name}}?", "files-empty-trash.confirm": "Empty", "files-empty-trash.description": "Are you sure you want to permanently delete all items in the trash? You can't undo this action.", "files-empty-trash.title": "Empty Trash?", "files-empty.directory": "No items in this folder", "files-empty.network": "No network devices", "files-empty.network-host-offline": "Network device offline", "files-error.add-favorite": "Add to favorites failed: {{message}}", "files-error.add-share": "Share folder failed: {{message}}", "files-error.compress": "Compression failed: {{message}}", "files-error.copy": "Copy failed: {{message}}", "files-error.create-folder": "Create folder failed: {{message}}", "files-error.delete": "Delete failed: {{message}}", "files-error.eject-disk": "Eject drive failed: {{message}}", "files-error.empty-trash": "Empty trash failed: {{message}}", "files-error.extract": "Extraction failed: {{message}}", "files-error.folder-already-exists": "A folder with this name already exists", "files-error.move": "Move failed: {{message}}", "files-error.remove-favorite": "Remove from favorites failed: {{message}}", "files-error.remove-share": "Remove shared folder failed: {{message}}", "files-error.rename": "Rename failed: {{message}}", "files-error.restore": "Restore failed: {{message}}", "files-error.trash": "Move to trash failed: {{message}}", "files-error.upload": "Upload failed: {{message}}", "files-error.upload-network-error": "Upload failed for {{name}}: A network error occurred", "files-extension-change.confirm": "Continue", "files-extension-change.description-add": "Are you sure you want to change the extension of '{{fileName}}' to '{{extension}}'? This may cause the file to be unreadable.", "files-extension-change.description-remove": "Are you sure you want to remove the extension of '{{fileName}}'?", "files-extension-change.title-add": "Change extension to '{{extension}}'?", "files-extension-change.title-remove": "Remove extension?", "files-external-storage.unsupported.description": "Your connected external drive can't be used on a Raspberry Pi due to power issues. External storage is available on the Umbrel Home, Umbrel Pro, and all x86 (Intel or AMD) devices.", "files-external-storage.unsupported.description-general": "External storage is not available on Raspberry Pi due to power issues. External storage is available on the Umbrel Home, Umbrel Pro, and all x86 (Intel or AMD) devices.", "files-external-storage.unsupported.title": "External Storage Not Supported", "files-folder": "Folder", "files-format.confirm": "Format", "files-format.description": "Formatting will erase all data on {{driveName}}. This action cannot be undone.", "files-format.description-unreadable": "umbrelOS cannot read the contents of {{driveName}}. You can format it to use with umbrelOS.", "files-format.drive-label": "Name", "files-format.error": "Failed to format drive", "files-format.exfat-description": "Maximum compatibility with Windows, macOS, and Linux", "files-format.ext4-description": "Better performance with umbrelOS and Linux", "files-format.filesystem": "Filesystem", "files-format.filesystem-label": "Format as", "files-format.formatting": "Formatting...", "files-format.title": "Format Drive", "files-format.title-requires-format": "Format Required", "files-formatting-island.formatting": "Formatting...", "files-formatting-island.formatting-drives": "Formatting {{count}} drives", "files-listing.empty": "No items", "files-listing.error": "An error occurred", "files-listing.item-count-truncated": "{{formattedCount}}+ items", "files-listing.item-count_one": "{{formattedCount}} item", "files-listing.item-count_other": "{{formattedCount}} items", "files-listing.loading": "Loading...", "files-listing.no-such-file": "No such file or folder", "files-listing.selected-count": "{{selectedCount}} of {{totalCount}} selected", "files-listing.selected-count-truncated": "{{selectedCount}} of {{totalCount}}+ selected", "files-name-drawer.new-folder": "New Folder", "files-name-drawer.new-folder-description": "Enter a name for the new folder.", "files-name-drawer.new-folder-input": "Folder Name", "files-name-drawer.rename-file": "Rename File", "files-name-drawer.rename-file-description": "Enter a new name for this file.", "files-name-drawer.rename-file-input": "File Name", "files-name-drawer.rename-folder": "Rename Folder", "files-name-drawer.rename-folder-description": "Enter a new name for this folder.", "files-name-drawer.rename-folder-input": "Folder Name", "files-network-storage-error.add-share": "Add network share failed: {{message}}", "files-network-storage-error.discover-servers": "Network device discovery failed: {{message}}", "files-network-storage-error.discover-shares": "Network share discovery failed: {{message}}", "files-network-storage-error.remove-share": "Remove network share failed: {{message}}", "files-operations-island.copying": "Copying \"{{from}}\" to \"{{to}}\"", "files-operations-island.moving": "Moving \"{{from}}\" to \"{{to}}\"", "files-operations-island.restoring": "Restoring \"{{from}}\" to \"{{to}}\"", "files-path.input-group": "Path input", "files-path.input-label": "Current path", "files-permanently-delete.confirm": "Delete permanently", "files-permanently-delete.description-multiple": "Are you sure you want to permanently delete these {{count}} items? You can't undo this action.", "files-permanently-delete.description-single": "Are you sure you want to permanently delete \"{{fileName}}\"? You can't undo this action.", "files-permanently-delete.title-multiple": "Delete {{count}} items permanently?", "files-permanently-delete.title-single": "Delete permanently?", "files-search.default": "Search for files and folders", "files-search.no-results": "No results found for \"{{query}}\"", "files-search.placeholder": "Search", "files-search.searching-label": "Searching {{name}}'s Umbrel", "files-share.home-description": "Access all the files in \"{{homeDirectoryName}}\" from other devices on your network", "files-share.home-title": "Share \"{{homeDirectoryName}}\" over network", "files-share.instructions.how-to-access": "How to access", "files-share.instructions.ios.enter-password": "Enter {{password}} as the password.", "files-share.instructions.ios.enter-server": "Enter {{smbUrl}} as the server address.", "files-share.instructions.ios.enter-username": "Enter {{username}} as the username.", "files-share.instructions.ios.install-files": "Install \"Files\" app from App Store if not installed.", "files-share.instructions.ios.tap-connect": "Tap \"Connect\" to access it.", "files-share.instructions.ios.tap-dots": "Tap the three dots (...) on the top right and select \"Connect to Server\".", "files-share.instructions.macos.click-connect": "Click \"Connect\" to access it.", "files-share.instructions.macos.enter-password": "Enter {{password}} as the password.", "files-share.instructions.macos.enter-url": "Enter {{smbUrl}} and click Connect.", "files-share.instructions.macos.enter-username": "Enter {{username}} as the username.", "files-share.instructions.macos.open-finder": "Open \"Finder\", and press ⌘ + K.", "files-share.instructions.macos.select-registered": "Select \"Registered User\" when prompted.", "files-share.instructions.macos.time-machine": "How to use as a Time Machine backup location", "files-share.instructions.macos.time-machine.choose-encryption": "Choose between encrypted or unencrypted backups.", "files-share.instructions.macos.time-machine.disk-limit": "For 'Disk Usage Limit', specify the maximum amount of space you want to allocate on your Umbrel for Time Machine backups, then click \"Done\".", "files-share.instructions.macos.time-machine.follow-steps": "Follow the above steps and open System Settings on your Mac.", "files-share.instructions.macos.time-machine.go-settings": "Go to Time Machine, click \"Add Backup Disk...\".", "files-share.instructions.macos.time-machine.select-disk": "Select the folder and click \"Set Up Disk...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Follow the guided steps to configure your backup.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Follow the above steps and then go to \"{{settings}}\" > \"{{backups}}\" on your other Umbrel.", "files-share.instructions.umbrelos.backup.select-add": "Select the option to \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Select this Umbrel device from the list of connected devices.", "files-share.instructions.umbrelos.backup.title": "How to use as a backup location for your other Umbrel", "files-share.instructions.umbrelos.cant-find-note": "Can't find it? Try selecting \"Add manually\" and use the following credentials. If you still can't add it, ensure that both of your devices are on the same network.", "files-share.instructions.umbrelos.enter-password": "Enter {{password}} as the password.", "files-share.instructions.umbrelos.enter-username": "Enter {{username}} as the username.", "files-share.instructions.umbrelos.open-and-click": "On your other Umbrel, open \"Files\" and click next to \" {{deviceLabel}}\" in the sidebar.", "files-share.instructions.umbrelos.select-device": "Select this Umbrel device from the list of auto-detected devices on your network.", "files-share.instructions.umbrelos.select-sharename": "Select \"{{sharename}}\" and click to add share.", "files-share.instructions.windows.enter-password": "Enter {{password}} as the password.", "files-share.instructions.windows.enter-url": "Type {{smbUrl}} and press Enter.", "files-share.instructions.windows.enter-username": "Enter {{username}} as the username.", "files-share.instructions.windows.open-run": "Press Windows + R to open Run dialog.", "files-share.instructions.windows.remember-credentials": "Check \"Remember my credentials\" and click OK.", "files-share.regular-description": "Share this folder to access it from other devices on your network", "files-share.regular-title": "Share folder over network", "files-share.toggle": "Share \"{{name}}\" over your network", "files-sidebar.apps": "Apps", "files-sidebar.external-storage": "External storage", "files-sidebar.favorites": "Favorites", "files-sidebar.home": "Home", "files-sidebar.navigation": "File navigation", "files-sidebar.network": "Network", "files-sidebar.network-pathbar": "Network Devices", "files-sidebar.network-sidebar": "Devices", "files-sidebar.recents": "Recents", "files-sidebar.shared-folders": "Shared folders", "files-sidebar.trash": "Trash", "files-sidebar.trash.open": "Open", "files-sort.created": "Added", "files-sort.modified": "Modified", "files-sort.name": "Name", "files-sort.size": "Size", "files-sort.type": "Type", "files-state.uploading": "Uploading...", "files-state.waiting": "Waiting...", "files-type.3gp": "3GP Video", "files-type.3gp2": "3GP2 Video", "files-type.7z": "7Z Archive", "files-type.aac": "AAC Audio", "files-type.ai": "Illustrator File", "files-type.aiff": "AIFF Audio", "files-type.au": "AU Audio", "files-type.avi": "AVI Video", "files-type.avif": "AVIF Image", "files-type.bmp": "BMP Image", "files-type.bzip2": "BZIP2 Archive", "files-type.caf": "CAF Audio", "files-type.compressed": "Compressed Archive", "files-type.csv": "CSV File", "files-type.directory": "Folder", "files-type.dmg": "Disk Image", "files-type.dv": "DV Video", "files-type.epub": "EPUB eBook", "files-type.excel": "Excel Spreadsheet", "files-type.exe": "Windows Executable", "files-type.executable": "Executable", "files-type.external-drive": "Drive", "files-type.flac": "FLAC Audio", "files-type.flv": "FLV Video", "files-type.gif": "GIF Image", "files-type.gzip": "GZIP Archive", "files-type.heic": "HEIC Image", "files-type.ico": "ICO Image", "files-type.iso": "ISO Image", "files-type.jpeg": "JPEG Image", "files-type.keynote": "Keynote Presentation", "files-type.lzip": "LZIP Archive", "files-type.lzma": "LZMA Archive", "files-type.lzop": "LZOP Archive", "files-type.m3u": "M3U Playlist", "files-type.m4a": "M4A Audio", "files-type.m4v": "M4V Video", "files-type.midi": "MIDI Audio", "files-type.mka": "MKA Audio", "files-type.mkv": "MKV Video", "files-type.mng": "MNG Video", "files-type.mobi": "MOBI eBook", "files-type.mp3": "MP3 Audio", "files-type.mp4": "MP4 Video", "files-type.mp4-audio": "MP4 Audio", "files-type.mpeg": "MPEG Video", "files-type.mpeg-ts": "MPEG Transport Stream", "files-type.network-drive": "Network Drive", "files-type.numbers": "Numbers Spreadsheet", "files-type.ogg": "OGG Audio", "files-type.ogv": "OGV Video", "files-type.pages": "Pages Document", "files-type.pdf": "PDF Document", "files-type.png": "PNG Image", "files-type.powerpoint": "PowerPoint Presentation", "files-type.psd": "Photoshop Document", "files-type.quicktime": "QuickTime Video", "files-type.rar": "RAR Archive", "files-type.sgi": "SGI Movie", "files-type.svg": "SVG Image", "files-type.tar": "TAR Archive", "files-type.tiff": "TIFF Image", "files-type.ts": "TS Video", "files-type.txt": "Text File", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "WAV Audio", "files-type.webm": "WebM Video", "files-type.webm-audio": "WebM Audio", "files-type.webp": "WebP Image", "files-type.wma": "WMA Audio", "files-type.wmv": "WMV Video", "files-type.word": "Word Document", "files-type.xz": "XZ Archive", "files-type.zip": "ZIP Archive", "files-upload-island.uploading-count": "Uploading {{count}} items", "files-view.icons": "Icons", "files-view.list": "List", "files-view.sort-by": "Sort by", "files-view.view-as": "View as", "files-widgets.favorites.no-items-text": "Add a folder to favorites to see it here", "files-widgets.recents.no-items-text": "No recent files", "generic-in": "in", "hide-details": "Hide details", "install-first.install-app": "Install {{app}}", "install-first.title": "{{app}} requires these apps", "install-your-first-app": "Install your first app", "language": "Language", "language-description": "Your preferred umbrelOS language", "language.select-description": "Select preferred umbrelOS language", "live-usage": "Live Usage", "loading": "Loading", "local-ip": "Local IP", "login-2fa.subtitle": "Enter the 2FA code displayed in your authenticator app", "login-2fa.title": "Authenticate", "login-with-umbrel.description": "Enter your Umbrel password to open {{app}}", "login-with-umbrel.title": "Log in with Umbrel", "login.password-label": "Password", "login.password.submit": "Log in", "login.subtitle": "Enter your Umbrel password to log in", "login.title": "Welcome back", "logout": "Log out", "logout-error-generic": "Error: Logout failed", "logout.confirm.submit": "Log out", "logout.confirm.title": "Are you sure you want to log out?", "memory": "Memory", "memory.low": "Low memory", "migrate": "Migrate", "migrate.callout": "Do not turn off your Umbrel until the migration is complete", "migrate.failed.retry": "Retry", "migrate.failed.title": "Migration failed", "migrate.success.description": "All your apps, app data, and account details have been migrated to your Umbrel Home.", "migrate.success.title": "Migration successful", "migration-assistant": "Migration Assistant", "migration-assistant-description": "Transfer all your apps and data from a Raspberry Pi to {{deviceName}}", "migration-assistant-unsupported-device-description": "Migration Assistant currently supports transferring all data and apps from a Raspberry Pi with umbrelOS to Umbrel Home or Umbrel Pro. Open Migration Assistant on your Umbrel Home or Umbrel Pro to get started.", "migration-assistant.continue-migration.ready.submit": "Start migration", "migration-assistant.failed": "Something's not right...", "migration-assistant.failed.retrying-message": "Retrying...", "migration-assistant.mobile.start-button": "Start migration", "migration-assistant.prep.body": "Prepare for migration", "migration-assistant.prep.button-continue": "Continue", "migration-assistant.prep.callout": "The data on your {{deviceName}}, if any, will be permanently deleted.", "migration-assistant.prep.connect-disk-to-home": "Connect its external drive to any USB port on your {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Once done, click '{{button}}' below.", "migration-assistant.prep.shut-down-rpi": "Shut down your Raspberry Pi Umbrel.", "migration-assistant.ready.description": "All your data and apps are ready to be migrated to your {{deviceName}}", "migration-assistant.ready.hint-header": "Things to keep in mind", "migration-assistant.ready.hint-keep-pi-off.description": "This helps prevent issues with apps such as Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Keep your Raspberry Pi off after the update", "migration-assistant.ready.hint-use-same-password.description": "Remember to use your Raspberry Pi Umbrel password to log into your {{deviceName}}", "migration-assistant.ready.hint-use-same-password.title": "Use the same password", "migration-assistant.ready.title": "You're all set to migrate!", "mini-browser.default-title": "Select folder", "mini-browser.empty-external": "Connect an external drive to have it appear here.", "mini-browser.empty-network": "Add an Umbrel or NAS to have it appear here.", "mini-browser.load-more": "Load more", "mini-browser.load-more-in-folder": "Load more in {{name}}", "mini-browser.loading-more": "Loading more…", "mini-browser.select": "Select", "mini-browser.select-folder": "Select folder", "name": "Name", "nas": "NAS", "no-forgot-password-message": "If you lose your password, you won't be able to log into your Umbrel. Make sure to safely secure it.", "no-results-found": "No results found", "not-found-404": "Error code: 404", "not-found-404.back": "Back", "not-found-404.home": "Go to Home", "notifications.backups-failing-location.description": "Automatic backups to {{location}} have been failing. Check the connection and review your backup settings.", "notifications.backups-failing.description": "Automatic backups have been failing. Check your backup location and review your settings.", "notifications.backups-failing.go-to-backups": "Go to Backups", "notifications.backups-failing.title": "No Backups in the last 24 hours", "notifications.cpu.too-hot": "High CPU temperature", "notifications.memory.low": "Your device's memory is low", "notifications.new-version-available": "{{update}} is now available to install", "notifications.raid.issue.description": "Storage issue detected. Check Storage Manager for details.", "notifications.raid.issue.title": "Urgent action required", "notifications.ssd.health.description": "One or more SSDs may need attention. Check Storage Manager for details.", "notifications.ssd.health.title": "SSD health warning", "notifications.storage.full": "Your device's storage is full", "notifications.view": "View", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "By clicking 'Launch umbrelOS', you agree to the umbrelOS Terms of Service", "onboarding.account-created.youre-all-set-name": "You're all set, {{name}}.", "onboarding.contact-support": "Support", "onboarding.create-account": "Create account", "onboarding.create-account.confirm-password.input-label": "Confirm password", "onboarding.create-account.failed.name-required": "Name is required", "onboarding.create-account.failed.passwords-dont-match": "Passwords do not match", "onboarding.create-account.name.input-placeholder": "Your name", "onboarding.create-account.password.input-label": "Password", "onboarding.create-account.submit": "Create", "onboarding.create-account.submitting": "Creating", "onboarding.create-account.subtitle": "Your account info is stored only on your Umbrel. Make sure to back up your password safely as there is no way to reset it.", "onboarding.create-instead-long": "Create new account", "onboarding.create-instead-short": "New account", "onboarding.launch-umbrelos": "Launch umbrelOS", "onboarding.raid.available-storage": "Available storage", "onboarding.raid.change-drives-link": "Need to add or change drives?", "onboarding.raid.configuring.subtitle": "This may take a few minutes.", "onboarding.raid.configuring.title": "Configuring your storage", "onboarding.raid.configuring.warning": "Please do not refresh this page or turn off your Umbrel while it is configuring your storage.", "onboarding.raid.continue": "Continue", "onboarding.raid.error.detection-instructions": "Power off Umbrel Pro, check that your SSDs are properly seated, and try again.", "onboarding.raid.error.no-ssds-detected": "No SSDs detected", "onboarding.raid.error.no-ssds-instructions": "Power off Umbrel Pro and insert at least one SSD to continue.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Can't enable FailSafe yet", "onboarding.raid.failsafe.enable": "Enable FailSafe", "onboarding.raid.failsafe.mixed-sizes": "FailSafe is limited by your smallest SSD ({{smallest}}). Extra space on larger SSDs can't be used, leaving {{wasted}} unusable.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} is used for data protection. Add another {{smallest}} SSD to increase available storage to {{futureWith3}}, or add two more for {{futureWith4}}. You can add more SSDs at any time.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} is used for data protection. Add another {{smallest}} SSD to increase available storage to {{futureWith4}}. You can add more SSDs at any time.", "onboarding.raid.failsafe.single-ssd-info": "You only have one SSD. Add at least one more {{size}} SSD to enable FailSafe protection for your data. You can add more SSDs at any time.", "onboarding.raid.failsafe.subtitle": "Your data stays safe if any single SSD fails", "onboarding.raid.failsafe.tip": "Use same-sized SSDs for maximum storage and zero unusable space.", "onboarding.raid.failsafe.warning-now-only": "With more than one SSD, FailSafe can only be enabled during initial setup. You won't be able to enable it later.", "onboarding.raid.health-warning": "This drive is reporting health issues", "onboarding.raid.launching": "Launching...", "onboarding.raid.no-ssds-alt": "No SSDs found", "onboarding.raid.recommended": "Recommended", "onboarding.raid.scanning": "Checking your SSD slots", "onboarding.raid.scanning-alt": "Scanning SSDs", "onboarding.raid.setup-failed.description-no-retry": "Please shut down and try again.", "onboarding.raid.setup-failed.description-retry": "Try again, or shut down to check your drives.", "onboarding.raid.setup-failed.title": "Storage setup failed", "onboarding.raid.shutdown-dialog.description": "To add or change drives, power off Umbrel Pro. Once done you can power back on and continue with the setup.", "onboarding.raid.shutdown-dialog.title": "Change drives?", "onboarding.raid.ssd-in-slot": "One {{size}} SSD in Slot {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSD Tray", "onboarding.raid.ssds-found": "The following SSDs were found in your Umbrel Pro", "onboarding.raid.storage": "Storage", "onboarding.raid.storage-label": "Storage", "onboarding.raid.success.storage-info": "Storage {{available}}", "onboarding.raid.success.storage-info-failsafe": "Storage {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Try again", "onboarding.raid.wasted": "Unusable", "onboarding.restore-long": "Restore my Umbrel", "onboarding.restore-short": "Restore", "onboarding.start.continue": "Get started", "onboarding.start.subtitle": "Your home cloud server is ready to set up.", "onboarding.start.title": "Welcome to umbrelOS", "open": "Open", "open-live-usage": "Open Live Usage", "password": "Password", "preferences": "Preferences", "raid-error.description": "Your storage system could not start properly. Check the status of your SSDs below and follow the troubleshooting steps. If the issue persists, any impacted SSDs may need to be replaced.", "raid-error.factory-reset-dialog.description": "This will erase all data on your Umbrel Pro and reset it to factory settings. This action cannot be undone.", "raid-error.factory-reset-dialog.title": "Factory reset?", "raid-error.factory-reset-failed": "Couldn't factory reset", "raid-error.health-warning": "Health warning", "raid-error.missing-ssd-multiple": "{{count}} SSDs are not responding", "raid-error.missing-ssd-one": "1 SSD is not responding", "raid-error.shutdown-dialog.description": "Power off your Umbrel Pro, ensure all SSDs are properly seated in their slots, then power back on.", "raid-error.shutdown-dialog.title": "Shut down to check drives?", "raid-error.ssd-in-slot": "One {{size}} SSD in Slot {{slot}}", "raid-error.step-check-connections.button": "Shut down", "raid-error.step-check-connections.description": "Shut down and check that all SSDs are properly seated.", "raid-error.step-check-connections.title": "Check SSD connections", "raid-error.step-factory-reset.button": "Factory Reset", "raid-error.step-factory-reset.description": "Last resort if nothing else works. This erases all data.", "raid-error.step-factory-reset.title": "Factory reset", "raid-error.step-restart.button": "Restart", "raid-error.step-restart.description": "A quick first step that often helps", "raid-error.step-restart.title": "Try restarting", "raid-error.title": "Storage Issue Detected", "read-less": "Read less", "read-more": "Read more", "reconnect": "Reconnect", "redirect.to-home": "Loading...", "redirect.to-login": "Loading...", "redirect.to-onboarding": "Loading...", "redirect.to-raid-error": "Loading...", "reload": "Reload", "remote-tor-access": "Remote Tor access", "reset": "Reset", "restart": "Restart", "restart.confirm.submit": "Restart", "restart.confirm.title": "Are you sure you want to restart your Umbrel?", "restart.restarting": "Restarting", "restart.restarting-message": "Please do not refresh this page or turn off your Umbrel while it is restarting.", "rewind": "Rewind", "rewind.files-as-of": "Your Files as of", "rewind.loading-snapshots": "Loading snapshots...", "rewind.now": "Now", "rewind.preflight.description": "Find files and folders from your past backups, and recover them to the present.", "rewind.preflight.enable-backups": "Set up Backups in Settings to start using Rewind", "rewind.restore-complete": "Restore complete", "rewind.restore-error-description": "Please try again.", "rewind.restore-failed": "Restore failed", "rewind.restore-running-description": "Do not close or refresh this page until restore is complete", "rewind.restore-selected": "Restore selected", "rewind.restore-success-description": "Your files have been restored", "rewind.restoring": "Restoring", "rewind.snapshots-count_one": "{{count}} backup since", "rewind.snapshots-count_other": "{{count}} backups since", "search": "Search", "settings": "Settings", "settings.app-store-preferences.title": "App Store Preferences", "settings.contact-support": "Need help? Contact support.", "settings.file-sharing": "File sharing", "settings.file-sharing.add-folder": "Add", "settings.file-sharing.add-folder-title": "Select a folder to share", "settings.file-sharing.choice-entire-description": "Share all files on your Umbrel", "settings.file-sharing.choice-entire-title": "Everything", "settings.file-sharing.choice-heading": "What would you like to share?", "settings.file-sharing.choice-specific-description": "Choose which folders to share", "settings.file-sharing.choice-specific-title": "Specific folders", "settings.file-sharing.choice-subtitle": "Access your files and folders Dropbox-style as network folders on your computer or phone", "settings.file-sharing.configure": "Configure", "settings.file-sharing.description": "Access your files Dropbox-style as a network folder (SMB) on other devices", "settings.file-sharing.home-shared-note": "Your entire \"{{homeDirectoryName}}\" folder is shared. Individual folders don't need separate sharing.", "settings.file-sharing.share-entire-home-dir": "Share your entire Home folder", "settings.file-sharing.share-entire-home-dir-description": "Access all files and folders in \"{{homeDirectoryName}}\" from other devices on your network", "settings.file-sharing.shared-folders": "Shared folders", "show-details": "Show details", "shut-down": "Shut down", "shut-down.complete": "Shutdown complete", "shut-down.complete-text": "You can now unplug your device from the power.", "shut-down.confirm.submit": "Shut down", "shut-down.confirm.title": "Are you sure you want to shut down your Umbrel?", "shut-down.failed": "Failed to shut down: {{message}}", "shut-down.shutting-down": "Shutting down", "shut-down.shutting-down-message": "Please do not refresh this page or turn off your Umbrel while it is shutting down.", "software-update.callout": "Please do not refresh this page or turn off your Umbrel while it is updating.", "software-update.check": "Check for update", "software-update.checking": "Checking for update...", "software-update.current-running": "You are on", "software-update.failed": "Failed to update", "software-update.failed-to-check": "Failed to check for updates", "software-update.failed.retry": "Retry", "software-update.install-now": "Install now", "software-update.new-version": "New {{name}} is available to install", "software-update.on-latest": "You are on the latest umbrelOS", "software-update.see-whats-new": "See what's new", "software-update.title": "Software update", "software-update.updating-to": "Updating to {{name}}", "software-update.view": "View", "something-left": "{{left}} left", "something-went-wrong": "⚠ Something went wrong", "start": "Start", "stop": "Stop", "storage": "Storage", "storage-manager": "Storage Manager", "storage-manager.add": "Add", "storage-manager.add-to-raid.add-ssd": "Add SSD", "storage-manager.add-to-raid.available": "Available:", "storage-manager.add-to-raid.description": "A new SSD has been detected and is ready to be added.", "storage-manager.add-to-raid.enable-failsafe": "Enable FailSafe", "storage-manager.add-to-raid.failed-add": "Couldn't add the SSD", "storage-manager.add-to-raid.failed-enable-failsafe": "Couldn't enable FailSafe", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Your new {{size}} SSD will be added to available storage.", "storage-manager.add-to-raid.info-capacity-adds-available": "Your new {{size}} SSD will add {{available}} of available storage.", "storage-manager.add-to-raid.info-capacity-adds-both": "Your new {{size}} SSD will add {{available}} of available storage and {{protection}} for data protection.", "storage-manager.add-to-raid.info-capacity-protection-only": "Your new {{size}} SSD will add {{protection}} for data protection.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Your new {{size}} SSD will be used entirely for data protection.", "storage-manager.add-to-raid.info-data-safe": "Your data will be safe if any single SSD fails.", "storage-manager.add-to-raid.info-no-protection": "If an SSD fails, you could lose your data.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} total unusable due to different SSD sizes.", "storage-manager.add-to-raid.info-wasted": "{{size}} will be unusable due to different SSD sizes.", "storage-manager.add-to-raid.recommended": "Recommended", "storage-manager.add-to-raid.recommended-inline": "(recommended)", "storage-manager.add-to-raid.restart-active-tasks": "Any active tasks will be interrupted", "storage-manager.add-to-raid.restart-after": "After the restart, FailSafe setup will complete automatically and you can resume normal use.", "storage-manager.add-to-raid.restart-during": "During the restart:", "storage-manager.add-to-raid.restart-intro": "You can continue using umbrelOS normally during this process. However, at 50% progress your Umbrel will restart automatically.", "storage-manager.add-to-raid.restart-required": "System restart required", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS will be temporarily inaccessible", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD in Slot {{slot}}", "storage-manager.add-to-raid.title": "Add SSD to storage", "storage-manager.add-to-raid.too-small": "SSD too small", "storage-manager.add-to-raid.too-small-description": "This SSD ({{deviceSize}}) is smaller than the smallest SSD currently installed ({{minSize}}). FailSafe requires all SSDs to be at least as large as the smallest SSD being used.", "storage-manager.add-to-raid.understand-continue": "I understand, continue", "storage-manager.add-to-raid.warning-failsafe-now-only": "Having more than one SSD means FailSafe can only be enabled now. You will not be able to enable it later.", "storage-manager.add-to-raid.wasted-label": "Unusable:", "storage-manager.available-storage": "Available storage", "storage-manager.description": "View storage, health, and settings for your SSDs", "storage-manager.empty": "Empty", "storage-manager.failsafe-transition-failed": "Couldn't enable FailSafe", "storage-manager.for-failsafe": "For FailSafe", "storage-manager.health.checksum-errors": "Checksum errors: {{count}}", "storage-manager.health.critical": "Critical", "storage-manager.health.critical-threshold": "Critical threshold", "storage-manager.health.current-temperature": "Current temperature", "storage-manager.health.estimated-life": "Estimated life remaining", "storage-manager.health.general": "General", "storage-manager.health.health-status": "Health status", "storage-manager.health.low": "Low", "storage-manager.health.model-and-capacity": "Model & size", "storage-manager.health.overheating": "Overheating", "storage-manager.health.raid-failed-advice": "This SSD has an issue. Shut down your Umbrel and check the SSD connection. If the issue persists, the SSD may need to be replaced.", "storage-manager.health.read-errors": "Read errors: {{count}}", "storage-manager.health.serial-number": "Serial number", "storage-manager.health.status-healthy": "Healthy", "storage-manager.health.status-unhealthy": "Unhealthy", "storage-manager.health.status-unknown": "Unknown", "storage-manager.health.temperature": "Temperature", "storage-manager.health.title": "SSD Health", "storage-manager.health.warning-life-advice": "Consider replacing this SSD soon.", "storage-manager.health.warning-life-message": "Only {{percent}}% life remaining", "storage-manager.health.warning-temp-advice": "Make sure your Umbrel Pro has good airflow and the SSD is properly seated.", "storage-manager.health.warning-temp-critical": "Temperature is critical ({{temperature}})", "storage-manager.health.warning-temp-overheating": "Drive is overheating ({{temperature}})", "storage-manager.health.warning-threshold": "Warning threshold", "storage-manager.health.warning-unhealthy-advice": "This SSD may fail soon. Consider replacing it.", "storage-manager.health.warning-unhealthy-message": "This SSD may have a problem", "storage-manager.health.warnings": "Warnings", "storage-manager.health.wear": "Wear", "storage-manager.health.write-errors": "Write errors: {{count}}", "storage-manager.install-ssd.description": "Add more SSDs to expand your storage", "storage-manager.install-ssd.step-insert": "Insert new SSDs into the empty slots", "storage-manager.install-ssd.step-power-on": "Power on your {{deviceName}}", "storage-manager.install-ssd.step-remove-bottom-cover": "Remove the magnetic bottom cover", "storage-manager.install-ssd.step-replace-bottom-cover": "Place the bottom cover back on", "storage-manager.install-ssd.step-return": "Return here to add the SSDs to your storage", "storage-manager.install-ssd.step-shut-down": "Shut down your {{deviceName}}", "storage-manager.install-ssd.title": "Adding SSDs", "storage-manager.install-tips.image-alt": "SSD installation instruction", "storage-manager.install-tips.instructions": "To install, remove the thumb screw and slide the SSD into the slot at an angle. Press the SSD down until it rests on the screw pillar, then secure it with the thumb screw.", "storage-manager.install-tips.toggle": "Forgot how to insert an SSD?", "storage-manager.manage": "Manage", "storage-manager.missing-ssd-warning": "An SSD appears to be missing. Shut down your Umbrel and check that all SSDs are connected. If the problem continues, the SSD may need to be replaced.", "storage-manager.mode": "Mode", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Keeps your data safe if an SSD fails. If your SSDs are different sizes, extra space on larger ones goes unused.", "storage-manager.mode.failsafe.info-description": "FailSafe protects your data by keeping copies of it across your SSDs. If any single SSD fails, your data stays safe and can be restored when you add a replacement SSD.", "storage-manager.mode.failsafe.info-title": "About FailSafe", "storage-manager.mode.full-storage": "Full Storage", "storage-manager.mode.full-storage.description": "Use all your SSD space together. If an SSD fails, you could lose your data.", "storage-manager.mode.full-storage.info-description": "Full Storage combines all your SSDs into one large space, giving you maximum storage. However, if any SSD fails, all your data will be lost.", "storage-manager.mode.full-storage.info-title": "About Full Storage", "storage-manager.mode.switch-from-failsafe-unavailable": "Switching from FailSafe to Full Storage mode requires backing up your data, factory resetting your device, and restoring from a backup.", "storage-manager.mode.switch-to-failsafe-unavailable": "With multiple SSDs in Full Storage mode, your data is spread across all drives. Switching to FailSafe requires backing up your data, factory resetting, and restoring.", "storage-manager.mode.why-cant-switch": "Why can't I switch?", "storage-manager.operation-in-progress.shutdown-description": "It's safe to shut down. The operation will pause and resume after restart, but must finish before you can make other changes.", "storage-manager.operation-in-progress.shutdown-title": "Your storage is being updated", "storage-manager.operation-in-progress.wait-description": "Please wait for the current operation to finish before making more changes.", "storage-manager.operation-in-progress.wait-title": "Your storage is being updated", "storage-manager.operation.adding-ssd": "Adding SSD...", "storage-manager.operation.enabling-failsafe": "Enabling FailSafe...", "storage-manager.operation.expanding": "Expanding storage...", "storage-manager.operation.rebuilding": "Rebuilding data...", "storage-manager.operation.replacing": "Replacing drive...", "storage-manager.operation.restarting": "Restarting...", "storage-manager.operation.starting": "Starting...", "storage-manager.operation.syncing-restarts": "Syncing data • Restarts at 50%", "storage-manager.raid-status.degraded": "Degraded", "storage-manager.raid-status.failed": "Failed", "storage-manager.raid-status.offline": "Offline", "storage-manager.raid-status.online": "Online", "storage-manager.raid-status.removed": "Removed", "storage-manager.raid-status.unavailable": "Unavailable", "storage-manager.replace": "Replace", "storage-manager.replace-failed.degraded": "FailSafe protection reduced", "storage-manager.replace-failed.degraded-description": "An SSD is missing from your FailSafe storage. Replace it to restore full protection.", "storage-manager.replace-failed.description": "Use this SSD to restore your FailSafe protection.", "storage-manager.replace-failed.error": "Couldn't start replacement", "storage-manager.replace-failed.replace-now": "Replace now", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD in Slot {{slot}}", "storage-manager.replace-failed.step-protected": "Once complete, your data will be fully protected again", "storage-manager.replace-failed.step-rebuild": "Data will be rebuilt onto the new SSD", "storage-manager.replace-failed.step-time": "This may take a while depending on how much data you have", "storage-manager.replace-failed.title": "Replace SSD", "storage-manager.replace-failed.too-small": "SSD too small", "storage-manager.replace-failed.too-small-description": "This SSD ({{deviceSize}}) is smaller than the minimum required ({{minSize}}) for your FailSafe storage.", "storage-manager.replace-failed.what-happens": "What happens next:", "storage-manager.ssd-failing": "Failing", "storage-manager.swap": "Swap", "storage-manager.swap.data-erased-description": "Full Storage mode doesn't have data protection. All data on your {{deviceName}} will be erased during factory reset. Make sure to back up everything first.", "storage-manager.swap.data-protected": "Your data is protected", "storage-manager.swap.data-protected-description": "With FailSafe enabled, you can swap out any single SSD without losing your data. No backup needed.", "storage-manager.swap.data-will-be-erased": "Data will be erased", "storage-manager.swap.description-failsafe": "Replace a drive in your FailSafe storage.", "storage-manager.swap.description-full-storage": "Replace a drive in your Full Storage setup.", "storage-manager.swap.description-no-free-slot": "In Full Storage mode with all slots in use, swapping an SSD requires a full backup and restore process.", "storage-manager.swap.description-replace": "Migrate your data to a new SSD, then remove the old one.", "storage-manager.swap.failed-to-start": "Couldn't start replacement", "storage-manager.swap.no-data-loss": "No data loss", "storage-manager.swap.no-data-loss-description": "Your data will be copied to the new SSD. Once complete, you can safely remove the old one.", "storage-manager.swap.safe-swap-available": "Safe swap available", "storage-manager.swap.safe-swap-description": "Since you have an empty slot, you can add the new SSD first and migrate your data before removing the old one. No backup required.", "storage-manager.swap.select-new-ssd": "Select the new SSD to use:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD in Slot {{slot}}", "storage-manager.swap.step-backup": "Back up your data", "storage-manager.swap.step-backup-description": "Go to Settings → Backups and create a backup of all your data.", "storage-manager.swap.step-data-copied": "Data will be copied from the old SSD to the new one", "storage-manager.swap.step-factory-reset": "Factory reset", "storage-manager.swap.step-factory-reset-description": "Go to Settings → Advanced → Factory Reset to erase your {{deviceName}}.", "storage-manager.swap.step-insert-new-ssd": "Insert the new SSD into an empty slot", "storage-manager.swap.step-may-take-while": "This may take a while depending on how much data you have", "storage-manager.swap.step-power-on": "Power on your {{deviceName}}", "storage-manager.swap.step-remove-bottom-cover": "Remove the magnetic bottom cover", "storage-manager.swap.step-remove-old": "Once complete, shut down and remove {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Replace the bottom cover", "storage-manager.swap.step-restore": "Restore your data", "storage-manager.swap.step-restore-description": "Go to Settings → Backups and restore from your backup.", "storage-manager.swap.step-return-to-storage-manager": "Return here to Storage Manager to confirm the swap and add the new SSD to your storage", "storage-manager.swap.step-return-to-swap": "Return here to Storage Manager and click \"Swap\" again to start the replacement", "storage-manager.swap.step-setup-new-storage": "Set up your new storage", "storage-manager.swap.step-setup-new-storage-description": "Power on your {{deviceName}} and complete the setup process with your new SSD.", "storage-manager.swap.step-shut-down": "Shut down your {{deviceName}}", "storage-manager.swap.step-shut-down-and-swap": "Shut down and swap {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Power off, open your device, replace the SSD, and reassemble.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Power off, remove the bottom cover, replace the SSD, and close the cover.", "storage-manager.swap.step-swap-ssd": "Swap {{ssd}} with a new one of the same size", "storage-manager.swap.too-small": "Too small ({{size}} required)", "storage-manager.swap.what-happens-next": "What happens next:", "storage-manager.total-capacity-added": "Total capacity added", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Used", "storage-manager.wasted": "Unusable", "storage-manager.wasted-size": "{{size}} Unusable", "storage.full": "Storage full", "storage.low": "Low storage", "temperature": "Temperature", "temperature.dangerously-hot": "Very hot", "temperature.nice": "Nice", "temperature.normal": "Normal", "temperature.too-hot-suggestion": "Consider changing your device's environment.", "temperature.warm": "Warm", "terminal": "Terminal", "terminal-description": "Run custom commands in umbrelOS or within an app", "terminal.app": "App", "terminal.app-description": "Run custom commands within a specific app", "terminal.umbrelos-description": "Run custom commands in umbrelOS", "tor-description": "Access your Umbrel from anywhere using a Tor browser", "tor-enabled-description": "Access your Umbrel from anywhere using a Tor browser on the following URL:", "tor-error": "Failed to update Tor setting: {{message}}", "tor.disable.description": "This may take a few minutes", "tor.disable.progress": "Disabling Remote Tor access", "tor.enable.description": "This may take a few minutes", "tor.enable.mobile.switch-label": "Enable remote Tor access", "tor.hidden-service": "Tor hidden service URL", "troubleshoot": "Troubleshoot", "troubleshoot-description": "Troubleshoot umbrelOS or an app", "troubleshoot-no-logs-yet": "No logs yet", "troubleshoot-pick-title": "Troubleshoot", "troubleshoot.app": "App", "troubleshoot.app-description": "View logs of an app installed on your Umbrel", "troubleshoot.app-download": "Download {{app}} logs", "troubleshoot.share-with-umbrel-support": "Share with Umbrel Support", "troubleshoot.system-download": "Download {{label}}", "troubleshoot.umbrelos-description": "View umbrelOS logs", "troubleshoot.umbrelos-logs": "umbrelOS logs", "trpc.backend-unavailable": "Error: Connection to the system API failed", "trpc.checking-backend": "Loading...", "try-again": "Try again", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Unknown", "unknown-app": "Unknown app", "unknown-error": "Unknown error", "uptime": "Uptime", "url": "URL", "wallpaper": "Wallpaper", "wallpaper-description": "Your Umbrel wallpaper and theme", "whats-new.continue": "Continue", "whats-new.feature-1.description": "Set up automated, encrypted backups of your entire Umbrel to an external USB drive, a NAS, or another Umbrel.", "whats-new.feature-2.description": "Jump back in time to recover specific files and folders from previous backups.", "whats-new.feature-3.description": "Or restore your entire Umbrel, including all your apps, files, and data.", "whats-new.feature-4.description": "Connect a NAS or another Umbrel, and access its storage from Files.", "whats-new.feature-4.title": "Network Devices", "whats-new.feature-5.description": "Connect external USB drives (on the Umbrel Home, or any Intel or AMD device) and access them from Files.", "whats-new.feature-5.helper-text": "Not supported on Raspberry Pi devices due to potential power issues.", "whats-new.feature-5.title": "External Storage", "whats-new.next": "Next", "whats-new.title": "What's new in {{version}}", "widget.progress.in-progress": "In progress", "widgets.edit.select-up-to-3-widgets": "Select up to 3 widgets", "widgets.install-an-app-before-using-widgets": "Install an app to start customizing your homescreen with widgets.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Open networks can be insecure", "wifi-connection-failed": "Unable to connect", "wifi-dangerous-change-confirmation-description": "Changing the Wi-Fi network may disconnect you from your Umbrel. To reconnect, ensure that both your Umbrel and the device you're accessing it from are on the same network.", "wifi-dangerous-change-confirmation-title": "Are you sure you want to change Wi-Fi network?", "wifi-dangerous-disable-confirmation-description": "Disabling Wi-Fi may disconnect you from your Umbrel. To reconnect, plug in an Ethernet cable to your Umbrel and ensure that both your Umbrel and the device you're accessing it from are on the same network.", "wifi-dangerous-disable-confirmation-title": "Are you sure you want to disable Wi-Fi?", "wifi-description": "Connect your device to a Wi-Fi network", "wifi-description-long": "Your device stays connected to your chosen Wi-Fi, even if the Ethernet cable is removed, and automatically reconnects to Wi-Fi on startup.", "wifi-no-networks-message": "No Wi-Fi networks found", "wifi-searching": "Searching for Wi-Fi networks...", "wifi-unsupported-device-description": "Wi-Fi is not supported on this device. This may be due to a missing or incompatible wireless adapter.", "wifi-view-networks": "View networks" } ================================================ FILE: packages/ui/public/locales/es.json ================================================ { "2fa": "2FA", "2fa-description": "Una segunda capa de seguridad para tu inicio de sesión en Umbrel y aplicaciones", "2fa.disable.title": "Desactivar autenticación de dos factores", "2fa.enable.or-paste": "O pega el siguiente código en tu aplicación de autenticación", "2fa.enable.scan-this": "Escanea este código QR usando una aplicación de autenticación como Google Authenticator o Authy", "2fa.enable.title": "Activar autenticación de dos factores", "2fa.enter-code": "Introduce el código mostrado en tu aplicación de autenticación", "account": "Cuenta", "account-description": "Tu nombre y contraseña", "advanced-settings": "Configuración avanzada", "advanced-settings-description": "Terminal, Programa Beta de umbrelOS, Cloudflare DNS, y más", "app-not-found": "Aplicación no encontrada: {{app}}", "app-only-over-tor": "{{app}} solo se puede usar a través de Tor. Por favor, accede a tu Umbrel desde un navegador Tor usando tu URL de acceso remoto (Settings > Advanced settings > Remote Tor access) para abrir esta aplicación.", "app-page.section.about": "Acerca de", "app-page.section.credentials.title": "Credenciales predeterminadas", "app-page.section.dependencies.n-alternatives": "Ver {{count}} alternativas", "app-page.section.info.compatibility": "Compatibilidad", "app-page.section.info.compatibility-compatible": "Compatible", "app-page.section.info.compatibility-not-compatible": "No compatible", "app-page.section.info.developer": "Desarrollador", "app-page.section.info.source-code": "Código fuente", "app-page.section.info.source-code.public": "Público", "app-page.section.info.submitted-by": "Enviado por", "app-page.section.info.support": "Obtener soporte", "app-page.section.info.title": "Información", "app-page.section.info.version": "Versión", "app-page.section.recommendations.title": "También te podría gustar", "app-page.section.release-notes.title": "Novedades", "app-page.section.release-notes.version": "Versión {{version}}", "app-page.section.requires": "Requiere", "app-picker.search": "Buscar...", "app-picker.select-app": "Seleccionar aplicación...", "app-settings.connected-to": "{{appName}} está conectado a estas aplicaciones", "app-settings.save-changes": "Guardar cambios", "app-settings.title": "Configuración", "app-store.browse-category-apps": "Explorar aplicaciones de {{category}}", "app-store.category.ai": "IA", "app-store.category.all": "Todas las aplicaciones", "app-store.category.automation": "Hogar y Automatización", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Cripto", "app-store.category.developer": "Herramientas para Desarrolladores", "app-store.category.discover": "Descubrir", "app-store.category.files": "Archivos y Productividad", "app-store.category.finance": "Finanzas", "app-store.category.media": "Medios", "app-store.category.networking": "Redes", "app-store.category.social": "Social", "app-store.description": "Tus configuraciones de actualización de aplicaciones", "app-store.discover.temporarily-unavailable-description": "Explora las categorías de arriba o usa la búsqueda para encontrar aplicaciones", "app-store.discover.temporarily-unavailable-title": "Contenido destacado temporalmente no disponible", "app-store.menu.community-app-stores": "Tiendas de Aplicaciones Comunitarias", "app-store.search-apps": "Buscar aplicaciones", "app-store.search.no-results": "Sin resultados", "app-store.search.results-for": "Resultados para", "app-store.title": "App Store", "app-store.updates": "Actualizaciones", "app-updates.less": "menos", "app-updates.more": "más", "app-updates.no-updates": "¡Todas las aplicaciones están actualizadas!", "app-updates.update": "Actualizar", "app-updates.update-all": "Actualizar todo", "app-updates.updates-available-count_one": "{{count}} actualización disponible", "app-updates.updates-available-count_other": "{{count}} actualizaciones disponibles", "app-updates.updating": "Actualizando...", "app.install": "Instalar", "app.installed": "Instalado", "app.installing": "Instalando", "app.offline": "No en ejecución", "app.open": "Abrir", "app.optimized-for-umbrel-home": "Optimizado para Umbrel Home", "app.os-update-required.confirm": "Buscar actualización de umbrelOS", "app.os-update-required.description": "{{appName}} requiere umbrelOS {{version}} o posterior", "app.os-update-required.title": "Actualizar umbrelOS", "app.restarting": "Reiniciando", "app.starting": "Iniciando", "app.stopping": "Deteniendo", "app.uninstall.confirm.description": "Todos los datos asociados con {{app}} serán eliminados permanentemente. Esta acción no se puede deshacer.", "app.uninstall.confirm.submit": "Desinstalar", "app.uninstall.confirm.title": "¿Desinstalar {{app}}?", "app.uninstall.deps.used-by.description_one": "Desinstala {{firstAppToUninstall}} primero para desinstalar {{app}}.", "app.uninstall.deps.used-by.description_other": "Desinstala estas aplicaciones primero para desinstalar {{app}}.", "app.uninstall.deps.used-by.title": "{{app}} es utilizado por", "app.uninstalling": "Desinstalando", "app.updating": "Actualizando", "app.view": "Ver", "app_one": "aplicación", "app_other": "aplicaciones", "apps.uninstall.failed-to-get-required-apps": "Error al obtener aplicaciones requeridas", "apps.uninstalled-all.success": "Todas las aplicaciones desinstaladas", "auth.checking-backend-for-user": "Cargando...", "auth.failed-checking-if-user-logged-in": "Error: Falló la verificación de inicio de sesión", "auth.failed-to-check-if-user-exists": "Error: Falló la verificación de existencia", "back": "Atrás", "backups": "Copias de seguridad", "backups-configure": "Configurar", "backups-configure.add-backup-location": "Agregar ubicación de copia de seguridad", "backups-configure.available": "Disponible", "backups-configure.awaiting-next-backup": "Esperando la próxima copia de seguridad automática", "backups-configure.back-up-now": "Hacer copia de seguridad ahora", "backups-configure.backing-up-now": "Haciendo copia de seguridad...", "backups-configure.connected": "Conectado", "backups-configure.connection": "Conexión", "backups-configure.in-progress": "En progreso", "backups-configure.last-backup": "Última copia de seguridad", "backups-configure.locations": "Ubicaciones", "backups-configure.no-backup-locations": "Agrega una ubicación de copia de seguridad para empezar a hacer copias de seguridad de tus datos", "backups-configure.not-connected": "No conectado", "backups-configure.path": "Ruta", "backups-configure.remove-backup-location": "Eliminar ubicación de copia de seguridad", "backups-configure.remove-backup-location-confirmation": "¿Estás seguro?", "backups-configure.remove-backup-location-confirmation-description": "Esto eliminará '{{device}}' de tus ubicaciones de copia de seguridad. Las copias existentes en ese dispositivo no se borrarán, pero las copias automáticas dejarán de realizarse.", "backups-configure.status": "Estado", "backups-configure.total-backups": "Total de copias de seguridad", "backups-configure.used": "Usado", "backups-configure.view": "Ver", "backups-description": "Haz copias de seguridad de tus archivos, apps y datos en otro Umbrel, un NAS o un disco externo", "backups-error.backup-not-found": "No se pudo encontrar la copia de seguridad.", "backups-error.generic": "Algo salió mal: {{details}}", "backups-error.in-progress": "Ya se está ejecutando un proceso de copia de seguridad. Por favor, espera a que termine.", "backups-error.invalid-exclusion-path": "Solo se pueden excluir de las copias de seguridad archivos y carpetas dentro de tu carpeta personal.", "backups-error.invalid-password": "La contraseña de cifrado es incorrecta.", "backups-error.invalid-path": "La ubicación seleccionada no es válida para copias de seguridad.", "backups-error.mount-failed": "No se pudo acceder a la instantánea de la copia de seguridad.", "backups-error.mount-timeout": "No se pudo acceder a la instantánea de la copia de seguridad. Intenta de nuevo o comprueba si el dispositivo está correctamente conectado.", "backups-error.not-enough-space": "No hay suficiente espacio disponible en el dispositivo de copia de seguridad.", "backups-error.not-found": "No se pudo encontrar la copia de seguridad o su ubicación.", "backups-error.repository-exists": "Ya existe una ubicación de copia de seguridad en esta carpeta.", "backups-error.repository-not-found": "No se pudo encontrar la ubicación de copia de seguridad.", "backups-exclusions.add": "Agregar", "backups-exclusions.app-paths-cannot-be-modified": "Estos archivos/carpetas están definidos por el desarrollador de la app y no se pueden modificar:", "backups-exclusions.app-paths-explanation": "Esta app excluye los siguientes datos de la copia de seguridad. Estas rutas suelen contener elementos no esenciales (como caches o registros que se pueden recrear) o datos que podrían causar problemas si se restauran (por ejemplo, estados antiguos de la app que podrían generar conflictos o inconsistencias).", "backups-exclusions.auto-excluded": "Excluido automáticamente", "backups-exclusions.exclude-entire-app": "Excluir toda la app", "backups-exclusions.excluded-apps": "Apps excluidas", "backups-exclusions.files-and-folders": "Archivos y carpetas excluidos", "backups-exclusions.no-excluded-apps": "No hay apps excluidas", "backups-exclusions.no-excluded-files-or-folders": "No hay archivos o carpetas excluidos", "backups-exclusions.select-item-to-exclude": "Selecciona el elemento a excluir", "backups-exclusions.stop-excluding": "Dejar de excluir", "backups-floating-island.backing-up": "Haciendo copia de seguridad...", "backups-floating-island.backing-up-to": "Haciendo copia de seguridad de tu Umbrel...", "backups-restore": "Restaurar", "backups-restore-full": "Restauración completa", "backups-restore-full-description": "Restaura todo tu Umbrel desde una copia de seguridad", "backups-restore-header": "Restaurar tu Umbrel", "backups-restore-pro.after-restore": "Después de restaurar, tu cuenta temporal será reemplazada por la cuenta y los datos de tu copia de seguridad.", "backups-restore-pro.step1": "Completa la configuración inicial haciendo clic en \"Comenzar\" a continuación. Esta será tu cuenta temporal hasta que restaures tu cuenta respaldada.", "backups-restore-pro.step2": "Una vez completada la configuración, ve a <0>Configuración → Backups → Restaurar", "backups-restore-pro.step3": "Sigue las indicaciones del asistente de restauración.", "backups-restore-pro.subtitle": "Restaurar una copia de seguridad en Umbrel Pro requiere algunos pasos adicionales", "backups-restore.backup-date": "Fecha de la copia de seguridad", "backups-restore.backup-location": "Ubicación de copia de seguridad", "backups-restore.browse-cloud-subtitle": "Restaurar desde Umbrel Private Cloud (próximamente)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Restaurar desde una unidad USB externa", "backups-restore.browse-external-title": "Disco externo", "backups-restore.browse-nas-or-external": "Explora otro Umbrel, NAS o un disco externo para restaurar desde una copia de seguridad", "backups-restore.browse-nas-subtitle": "Restaurar desde otro dispositivo Umbrel o NAS en tu red", "backups-restore.browse-nas-title": "Otro Umbrel o NAS", "backups-restore.choose": "Seleccionar", "backups-restore.choose-backup-location": "Selecciona una ubicación de copia de seguridad", "backups-restore.connect-to-backup-location": "Conectar a una ubicación de copia de seguridad", "backups-restore.encryption-password": "Contraseña de cifrado", "backups-restore.encryption-password-description": "Introduce la contraseña de cifrado que estableciste cuando activaste las copias de seguridad", "backups-restore.enter-password-to-confirm": "Introduce tu contraseña de Umbrel para confirmar", "backups-restore.final-confirmation": "¿Estás seguro?", "backups-restore.final-confirmation-description": "Restaurar desde esta copia de seguridad reemplazará las apps y datos actuales de umbrelOS con el contenido de la copia seleccionada. Cualquier archivo, carpeta o app excluida de esta copia se eliminará de tu Umbrel. Esta acción no se puede deshacer.", "backups-restore.invalid-password": "Contraseña inválida", "backups-restore.last-backup": "Última copia de seguridad: {{date}}", "backups-restore.latest": "Última", "backups-restore.no-backups-found": "No se encontraron copias de seguridad", "backups-restore.no-backups-yet": "Aún no hay copias de seguridad", "backups-restore.please-select-backup": "Por favor, selecciona una copia de seguridad", "backups-restore.please-select-repository": "Por favor, selecciona un repositorio", "backups-restore.restore-from-nas-or-external": "Restaura tu Umbrel desde una copia de seguridad en otro Umbrel, en un NAS o en una unidad externa", "backups-restore.restore-from-unlisted": "Restaurar desde otra ubicación", "backups-restore.restore-umbrel": "Restaurar Umbrel", "backups-restore.restore-warning": "Restaurar desde esta copia de seguridad reemplazará las apps y datos actuales de umbrelOS con el contenido de la copia seleccionada. Cualquier archivo, carpeta o app excluida de esta copia se eliminará de tu Umbrel. Abre <0>Rewind si quieres restaurar archivos o carpetas específicos en su lugar.", "backups-restore.restoring-from": "Estás a punto de restaurar desde la siguiente copia de seguridad:", "backups-restore.review-description": "La restauración configurará tu Umbrel con la cuenta, los archivos, las apps y la configuración que estaban incluidos en el momento de esta copia de seguridad. Esto puede tardar un poco. Una vez finalizado, tu contraseña de inicio de sesión se establecerá en la que usaste cuando se creó la copia de seguridad.", "backups-restore.select-backup": "Selecciona una copia de seguridad", "backups-restore.select-backup-description": "Selecciona la copia de seguridad desde la que quieres restaurar", "backups-restore.select-backup-file": "Selecciona tu archivo de copia de seguridad", "backups-restore.select-backup-file-only": "Solo se puede seleccionar {{backupFileName}}", "backups-restore.total-size": "Tamaño total", "backups-restore.unknown-date": "Fecha desconocida", "backups-restore.unknown-repository": "Repositorio desconocido", "backups-rewind": "Rewind", "backups-rewind-description": "Retrocede en el tiempo para restaurar archivos y carpetas específicos", "backups-rewind.start": "Iniciar Rewind", "backups-setup": "Configurar", "backups-setup-confirm": "Finalizar configuración", "backups-setup-external-description": "Haz una copia de seguridad en una unidad USB externa", "backups-setup-nas-or-umbrel-description": "Realiza copias de seguridad en otro Umbrel o en un dispositivo NAS de tu red", "backups-setup-umbrel-or-nas": "Otro Umbrel o NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Extiende tu tranquilidad más allá de tu hogar con copias de seguridad cifradas de extremo a extremo en Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Obtén acceso anticipado", "backups-setup-umbrel-private-cloud-description": "Copias de seguridad cifradas de extremo a extremo en Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Próximamente", "backups.add-umbrel-or-nas": "Agregar Umbrel o NAS", "backups.all-apps-and-data-will-be-backed-up": "Se harán copias de seguridad de todas las apps y datos", "backups.apps-and-data": "Apps y datos", "backups.backup-location": "Ubicación de copia de seguridad", "backups.browse": "Examinar", "backups.choose-folder-within-device": "Elige una carpeta dentro de {{device}} para guardar tus copias de seguridad", "backups.confirm-password": "Confirmar contraseña", "backups.copy": "Copiar", "backups.encryption": "Cifrado", "backups.encryption-password-warning": "Asegúrate de guardar tu contraseña de cifrado de forma segura, por ejemplo en un gestor de contraseñas. No podrás verla de nuevo y la necesitarás para restaurar tus copias de seguridad.", "backups.exclude-from-backups": "Excluir de las copias de seguridad", "backups.exclude-from-backups-description": "Excluye archivos, carpetas y apps específicos de tus copias de seguridad.", "backups.hide": "Ocultar", "backups.i-understand": "Entiendo", "backups.location": "Ubicación", "backups.modals.already-in-use.description": "Esta ubicación ya se está usando para Backups en este Umbrel.", "backups.modals.already-in-use.manage": "Administrar en Backups", "backups.modals.already-in-use.title": "Ubicación de Backups ya en uso", "backups.modals.connect-existing.description": "Ya existe una copia de seguridad de Umbrel en esta ubicación. Introduce su contraseña de cifrado para añadirla a este Umbrel.", "backups.modals.connect-existing.title": "Conectar copia de seguridad existente de Umbrel", "backups.no-external-drives-detected": "No se detectaron discos externos", "backups.no-password-set": "No hay contraseña establecida", "backups.password-is-set": "Contraseña establecida", "backups.password-minimum-length": "La contraseña debe tener al menos 8 caracteres", "backups.password-safety-warning": "Tus copias de seguridad se cifrarán con esta contraseña. Guárdala de forma segura, ya que no podrás verla de nuevo y la necesitarás para restaurarlas.", "backups.passwords-do-not-match": "Las contraseñas no coinciden", "backups.please-choose-folder": "Por favor, elige una carpeta", "backups.restore-failed.message": "Se produjo un error al restaurar tu Umbrel. Tus aplicaciones y datos actuales no se han modificado.", "backups.restore-failed.retry": "Ir a Restaurar", "backups.restore-failed.title": "Error al restaurar", "backups.restoring": "Restaurando tu Umbrel", "backups.restoring-completing": "Casi listo. Tu Umbrel se reiniciará en breve...", "backups.restoring-progress": "Restaurado {{percent}}%", "backups.restoring-time-remaining": "{{time}} restantes", "backups.restoring-warning": "No apagues tu Umbrel ni desconectes la ubicación de copia de seguridad durante la restauración", "backups.review": "Revisar y confirmar", "backups.review-description": "Revisa los detalles de tu copia de seguridad y confirma tu selección", "backups.scanning-for-external-drives": "Buscando discos externos...", "backups.schedule-description": "umbrelOS hace copias de seguridad automáticamente cada hora. Mantiene copias cifradas horarias de las últimas 24 horas, copias diarias de la última semana, copias semanales del último mes y copias mensuales del último año. Las copias de seguridad con más de un año se eliminan automáticamente.", "backups.select-backup-folder": "Seleccionar carpeta de copia de seguridad", "backups.select-backup-folder-description": "Elige una carpeta donde quieras almacenar tus copias de seguridad.", "backups.select-backup-location": "Seleccionar una ubicación de copia de seguridad", "backups.set-encryption-password": "Establecer contraseña de cifrado", "backups.set-encryption-password-description": "Protege tus copias de seguridad con una contraseña. Esto asegura que tus datos permanezcan privados y solo puedan restaurarse con esta contraseña.", "backups.show": "Mostrar", "backups.storage-capacity-warning": "{{device}} debe tener espacio libre al menos igual al doble del tamaño de tu copia de seguridad", "backups.store-encryption-password-safely": "Guarda tu contraseña de cifrado de forma segura", "beta-program": "Programa Beta de umbrelOS", "beta-program-description": "Opta por recibir actualizaciones beta de umbrelOS, accede antes a nuevas características y ayúdanos a refinarlas proporcionando tu feedback. Las actualizaciones beta pueden ser inestables y la solución de problemas puede requerir familiaridad con el terminal.", "cancel": "Cancelar", "change": "Cambiar", "change-name": "Cambiar nombre", "change-name.failed.name-required": "Se requiere nombre", "change-name.input-placeholder": "Tu nombre", "change-password": "Cambiar contraseña", "change-password.callout": "Si pierdes tu contraseña, no podrás iniciar sesión en tu Umbrel. Asegúrate de guardarla de forma segura.", "change-password.current-password": "Contraseña actual", "change-password.failed.current-required": "Se requiere contraseña actual", "change-password.failed.min-length": "La contraseña debe tener al menos {{characters}} caracteres", "change-password.failed.must-be-unique": "La nueva contraseña debe ser diferente de la contraseña actual", "change-password.failed.new-required": "Se requiere nueva contraseña", "change-password.failed.no-match": "Las contraseñas no coinciden", "change-password.failed.repeat-required": "Se requiere repetir la contraseña", "change-password.new-password": "Nueva contraseña", "change-password.repeat-password": "Repetir contraseña", "check-for-latest-version": "Buscar la última actualización de umbrelOS", "clipboard.copied": "Copiado", "close": "Cerrar", "cmdk.change-wallpaper": "Cambiar fondo de pantalla", "cmdk.frequent-apps": "Usadas frecuentemente", "cmdk.input-placeholder": "Buscar aplicaciones, configuraciones o acciones", "cmdk.live-usage": "Uso en vivo", "cmdk.restart-umbrel": "Reiniciar Umbrel", "cmdk.shutdown-umbrel": "Apagar Umbrel", "cmdk.update-all-apps": "Actualizar todas las aplicaciones", "cmdk.widgets": "Widgets", "community-app-store": "Tienda de Aplicaciones Comunitaria", "community-app-store.add-error": "No pudimos añadir la App Store: {{message}}", "community-app-store.back-to-umbrel-app-store": "Volver a la Tienda de Aplicaciones de Umbrel", "community-app-store.open-button": "Abrir", "community-app-store.remove-button": "Eliminar", "community-app-store.remove-error": "No pudimos eliminar la App Store: {{message}}", "community-app-stores.add-button": "Añadir", "community-app-stores.description": "Las Tiendas de Aplicaciones Comunitarias te permiten instalar aplicaciones en tu Umbrel que pueden no estar disponibles en la Tienda de Aplicaciones oficial de Umbrel. También facilitan probar versiones beta de aplicaciones de Umbrel antes de que los desarrolladores las lancen en la Tienda de Aplicaciones oficial de Umbrel.", "community-app-stores.learn-more": "Aprender más", "community-app-stores.warning": "Cualquiera puede crear Tiendas de Aplicaciones Comunitarias. Las aplicaciones publicadas en ellas no están verificadas ni revisadas por el equipo de la Tienda de Aplicaciones oficial de Umbrel, y pueden ser potencialmente inseguras o maliciosas. Usa precaución y solo añade tiendas de aplicaciones de desarrolladores en los que confíes.", "confirm": "Confirmar", "connect": "Conectar", "connecting": "Conectando...", "connection-lost": "Conexión perdida", "connection-lost-description": "Esto puede ocurrir si la pestaña de tu navegador ha estado inactiva, tu conexión de red se ha interrumpido o tu dispositivo está sin conexión.", "continue": "Continuar", "continue-to-log-in": "Continuar para iniciar sesión", "cpu": "CPU", "cpu-core-count": "{{cores}} hilos", "default-credentials.close": "Entendido", "default-credentials.description": "Aquí tienes las credenciales que necesitarás para iniciar sesión en la aplicación.", "default-credentials.dont-show-again": "No mostrar esto nuevamente", "default-credentials.dont-show-again-notice": "Puedes acceder a estas credenciales en cualquier momento en el futuro haciendo clic derecho en el icono de la aplicación.", "default-credentials.open": "Abrir {{app}}", "default-credentials.password": "Contraseña por defecto", "default-credentials.title": "Credenciales para {{app}}", "default-credentials.username": "Nombre de usuario por defecto", "desktop.app.context.go-to-store-page": "Ver en la Tienda de Aplicaciones", "desktop.app.context.settings": "Configuración", "desktop.app.context.show-default-credentials": "Mostrar credenciales predeterminadas", "desktop.app.context.uninstall": "Desinstalar", "desktop.context-menu.change-wallpaper": "Cambiar fondo de pantalla", "desktop.context-menu.edit-widgets": "Editar widgets", "desktop.context-menu.logout": "Cerrar sesión", "desktop.greeting.afternoon": "Buenas tardes, {{name}}", "desktop.greeting.evening": "Buenas noches, {{name}}", "desktop.greeting.morning": "Buenos días, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Para Viber", "desktop.install-first.for-the-bitcoiner": "Para el bitcoinero", "desktop.install-first.for-the-self-hoster": "Para el autoalojador", "desktop.install-first.for-the-streamer": "Para el streamer", "desktop.install-first.link-to-app-store": "Explorar más en la Tienda de Aplicaciones", "desktop.not-enough-room": "Usa una pantalla más grande para ver tus aplicaciones.", "device": "Dispositivo", "device-info": "Información del dispositivo", "device-info-description": "Información sobre tu dispositivo", "device-info.device": "Dispositivo", "device-info.model-number": "Número de modelo", "device-info.serial-number": "Número de serie", "device-info.view-info": "Ver información", "device-name.home-or-pro": "Umbrel Home or Umbrel Pro", "disable": "Desactivar", "done": "Hecho", "download-logs": "Descargar registros", "enabling-tor": "Habilitando el acceso remoto mediante Tor", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS ofrece una mejor fiabilidad de red. Desactívalo para usar las configuraciones DNS de tu router.", "external-dns-error": "No pudimos actualizar la configuración de DNS: {{message}}", "external-drive": "Unidad externa", "factory-reset": "Restablecimiento de fábrica", "factory-reset-description": "Borra todos tus datos y aplicaciones, restaurando umbrelOS a su configuración predeterminada", "factory-reset-failed": "No pudimos restablecer tu dispositivo: {{message}}", "factory-reset.confirm.body": "Confirma tu contraseña para restablecer", "factory-reset.confirm.ethernet-required-warning": "Asegúrate de que tu dispositivo esté conectado a tu router mediante Ethernet (no Wi-Fi) y que estés accediendo desde tu red local (por ejemplo, http://umbrel.local o la dirección IP local de tu dispositivo).", "factory-reset.confirm.submit": "Borrar todo y restablecer", "factory-reset.confirm.submit-callout": "Esta acción no se puede deshacer.", "factory-reset.rebooting.message": "Tu dispositivo se reiniciará y todos los datos se borrarán. Por favor, no cierres esta página.", "factory-reset.rebooting.status": "Restableciendo...", "factory-reset.rebooting.title": "Restablecimiento de fábrica en curso", "factory-reset.review.account-info": "Información de la cuenta y contraseña", "factory-reset.review.apps": "Aplicaciones", "factory-reset.review.following-will-be-removed": "Lo siguiente será eliminado de tu dispositivo", "factory-reset.review.installed-apps_one": "{{count}} aplicación instalada", "factory-reset.review.installed-apps_other": "{{count}} aplicaciones instaladas", "factory-reset.review.submit": "Continuar", "factory-reset.review.total-data": "Datos totales", "files": "Files", "files-action.add-favorite": "Agregar a favoritos", "files-action.add-network-device": "Añadir dispositivo", "files-action.cancel-upload": "Cancelar subida", "files-action.compress": "Comprimir", "files-action.copy": "Copiar", "files-action.cut": "Cortar", "files-action.delete": "Eliminar permanentemente", "files-action.download": "Descargar", "files-action.download-items": "Descargar {{count}} elementos", "files-action.drop-to-upload": "Suelta para subir", "files-action.eject-disk": "Expulsar", "files-action.empty-trash": "Vaciar papelera", "files-action.format-drive": "Formatear", "files-action.go-to-path": "Ir a...", "files-action.new-folder": "Nueva carpeta", "files-action.open": "Abrir", "files-action.paste": "Pegar", "files-action.remove-favorite": "Quitar de Favoritos", "files-action.remove-network-host": "Expulsar unidad de red", "files-action.remove-network-share": "Expulsar recurso compartido de red", "files-action.rename": "Renombrar", "files-action.restore": "Restaurar", "files-action.select": "Seleccionar", "files-action.share": "Compartir en la red...", "files-action.sharing": "Compartiendo...", "files-action.show-in-folder": "Mostrar en la carpeta que lo contiene", "files-action.trash": "Enviar a la papelera", "files-action.uncompress": "Descomprimir", "files-action.upload": "Subir", "files-add-network-share.add-manually": "Agregar manualmente", "files-add-network-share.add-share": "Agregar recurso compartido", "files-add-network-share.back": "Atrás", "files-add-network-share.continue": "Continuar", "files-add-network-share.description": "Conéctate a un NAS u otra unidad compartida en tu red para acceder a ellos desde Files.", "files-add-network-share.discovering": "Buscando...", "files-add-network-share.enter-details-manually": "Introduce los detalles del servidor", "files-add-network-share.host-label": "Dirección del servidor", "files-add-network-share.host-required": "Se requiere la dirección del servidor", "files-add-network-share.manual-share-help": "Introduce el nombre exacto de la carpeta compartida tal y como aparece en tu servidor", "files-add-network-share.no-shares-found": "No se encontraron carpetas compartidas en este servidor", "files-add-network-share.not-seeing-share": "¿No ves tu carpeta compartida?", "files-add-network-share.password-label": "Contraseña", "files-add-network-share.password-required": "Se requiere la contraseña", "files-add-network-share.retrieving-shares": "Obteniendo recursos compartidos...", "files-add-network-share.retry-discovery": "Volver a escanear la red", "files-add-network-share.select-share": "Selecciona un recurso compartido para agregar", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Se requiere el recurso compartido", "files-add-network-share.title": "Agregar un recurso compartido de red", "files-add-network-share.username-label": "Nombre de usuario", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Se requiere el nombre de usuario", "files-audio-island.now-playing": "Reproduciendo ahora", "files-audio-island.pause": "Pausar", "files-audio-island.play": "Reproducir", "files-backend-error.base-directory-not-found": "No se encontró el directorio base", "files-backend-error.cant-find-root": "No se pudo verificar la ruta del archivo", "files-backend-error.destination-already-exists": "Ya existe un elemento con el mismo nombre en el destino", "files-backend-error.destination-not-exist": "La carpeta de destino no existe", "files-backend-error.does-not-exist": "El archivo o la carpeta no existe", "files-backend-error.escapes-base": "La ruta está fuera del directorio permitido", "files-backend-error.invalid-base": "La ruta no pertenece a un directorio válido", "files-backend-error.invalid-filename": "El nombre del archivo no es válido", "files-backend-error.invalid-path": "La ruta del archivo no es válida", "files-backend-error.mkdir-failed": "No se pudo crear la carpeta", "files-backend-error.move-failed": "No se pudo mover el elemento", "files-backend-error.not-enough-space": "No hay suficiente espacio de almacenamiento disponible", "files-backend-error.operation-not-allowed": "Esta operación no está permitida", "files-backend-error.parent-not-directory": "La ruta padre no es una carpeta", "files-backend-error.parent-not-exist": "La carpeta padre no existe", "files-backend-error.path-not-absolute": "La ruta del archivo no es válida", "files-backend-error.share-already-exists": "Esta carpeta ya está compartida", "files-backend-error.share-name-generation-failed": "No se pudo generar un nombre único para la carpeta compartida", "files-backend-error.source-not-exists": "El archivo o la carpeta de origen no existe", "files-backend-error.subdir-of-self": "No se puede mover o copiar una carpeta dentro de sí misma", "files-backend-error.trash-meta-not-exists": "No se pudo encontrar la ubicación original de este elemento", "files-backend-error.unique-name-index-exceeded": "No se pudo generar un nombre único. Existen demasiados elementos con nombres similares", "files-backend-error.upload-failed": "Subida fallida", "files-collision.action.keep-both": "Conservar ambos", "files-collision.action.replace": "Reemplazar", "files-collision.action.skip": "Omitir", "files-collision.destination.original-location": "su ubicación original", "files-collision.message": "¿Quieres reemplazar el elemento existente o conservar ambos?", "files-collision.title": "\"{{itemName}}\" ya existe en {{destinationName}}", "files-download.confirm": "Descargar", "files-download.description": "Files no puede abrir este tipo de archivo. ¿Quieres descargarlo?", "files-download.title": "¿Descargar {{name}}?", "files-empty-trash.confirm": "Vaciar", "files-empty-trash.description": "¿Estás seguro de que quieres eliminar permanentemente todos los elementos de la papelera? No podrás deshacer esta acción.", "files-empty-trash.title": "¿Vaciar la papelera?", "files-empty.directory": "No hay elementos en esta carpeta", "files-empty.network": "Sin dispositivos de red", "files-empty.network-host-offline": "Dispositivo de red sin conexión", "files-error.add-favorite": "No se pudo añadir a favoritos: {{message}}", "files-error.add-share": "No se pudo compartir la carpeta: {{message}}", "files-error.compress": "Compresión fallida: {{message}}", "files-error.copy": "Copia fallida: {{message}}", "files-error.create-folder": "No se pudo crear la carpeta: {{message}}", "files-error.delete": "No se pudo eliminar: {{message}}", "files-error.eject-disk": "No se pudo expulsar la unidad: {{message}}", "files-error.empty-trash": "No se pudo vaciar la papelera: {{message}}", "files-error.extract": "Extracción fallida: {{message}}", "files-error.folder-already-exists": "Ya existe una carpeta con este nombre", "files-error.move": "No se pudo mover: {{message}}", "files-error.remove-favorite": "No se pudo quitar de favoritos: {{message}}", "files-error.remove-share": "No se pudo eliminar la carpeta compartida: {{message}}", "files-error.rename": "No se pudo renombrar: {{message}}", "files-error.restore": "No se pudo restaurar: {{message}}", "files-error.trash": "No se pudo mover a la papelera: {{message}}", "files-error.upload": "No se pudo subir: {{message}}", "files-error.upload-network-error": "La subida de {{name}} falló: ocurrió un error de red", "files-extension-change.confirm": "Continuar", "files-extension-change.description-add": "¿Estás seguro de que quieres cambiar la extensión de '{{fileName}}' a '{{extension}}'? Esto podría hacer que el archivo fuera ilegible.", "files-extension-change.description-remove": "¿Estás seguro de que quieres quitar la extensión de '{{fileName}}'?", "files-extension-change.title-add": "¿Cambiar la extensión a '{{extension}}'?", "files-extension-change.title-remove": "¿Quitar la extensión?", "files-external-storage.unsupported.description": "Tu unidad externa conectada no se puede usar en una Raspberry Pi debido a problemas de alimentación. El almacenamiento externo está disponible en Umbrel Home, Umbrel Pro y en todos los dispositivos x86 (Intel o AMD).", "files-external-storage.unsupported.description-general": "El almacenamiento externo no está disponible en Raspberry Pi debido a problemas de energía. Está disponible en Umbrel Home, Umbrel Pro y en todos los dispositivos x86 (Intel o AMD).", "files-external-storage.unsupported.title": "Almacenamiento externo no compatible", "files-folder": "Carpeta", "files-format.confirm": "Formatear", "files-format.description": "El formateo borrará todos los datos de {{driveName}}. Esta acción no se puede deshacer.", "files-format.description-unreadable": "umbrelOS no puede leer el contenido de {{driveName}}. Puedes formatearlo para usarlo con umbrelOS.", "files-format.drive-label": "Nombre", "files-format.error": "No se pudo formatear la unidad", "files-format.exfat-description": "Máxima compatibilidad con Windows, macOS y Linux", "files-format.ext4-description": "Mejor rendimiento con umbrelOS y Linux", "files-format.filesystem": "Sistema de archivos", "files-format.filesystem-label": "Formatear como", "files-format.formatting": "Formateando...", "files-format.title": "Formatear unidad", "files-format.title-requires-format": "Se requiere formateo", "files-formatting-island.formatting": "Formateando...", "files-formatting-island.formatting-drives": "Formateando {{count}} unidades", "files-listing.empty": "No hay elementos", "files-listing.error": "Ocurrió un error", "files-listing.item-count-truncated": "{{formattedCount}}+ elementos", "files-listing.item-count_one": "{{formattedCount}} elemento", "files-listing.item-count_other": "{{formattedCount}} elementos", "files-listing.loading": "Cargando...", "files-listing.no-such-file": "No existe tal archivo o carpeta", "files-listing.selected-count": "{{selectedCount}} de {{totalCount}} seleccionados", "files-listing.selected-count-truncated": "{{selectedCount}} de {{totalCount}}+ seleccionados", "files-name-drawer.new-folder": "Nueva carpeta", "files-name-drawer.new-folder-description": "Ingresa un nombre para la nueva carpeta.", "files-name-drawer.new-folder-input": "Nombre de carpeta", "files-name-drawer.rename-file": "Renombrar archivo", "files-name-drawer.rename-file-description": "Ingresa un nuevo nombre para este archivo.", "files-name-drawer.rename-file-input": "Nombre de archivo", "files-name-drawer.rename-folder": "Renombrar carpeta", "files-name-drawer.rename-folder-description": "Ingresa un nuevo nombre para esta carpeta.", "files-name-drawer.rename-folder-input": "Nombre de carpeta", "files-network-storage-error.add-share": "No se pudo añadir el recurso compartido de red: {{message}}", "files-network-storage-error.discover-servers": "Error al descubrir dispositivos de red: {{message}}", "files-network-storage-error.discover-shares": "Error al descubrir recursos compartidos de red: {{message}}", "files-network-storage-error.remove-share": "No se pudo eliminar el recurso compartido de red: {{message}}", "files-operations-island.copying": "Copiando \"{{from}}\" a \"{{to}}\"", "files-operations-island.moving": "Moviendo \"{{from}}\" a \"{{to}}\"", "files-operations-island.restoring": "Restaurando \"{{from}}\" en \"{{to}}\"", "files-path.input-group": "Entrada de ruta", "files-path.input-label": "Ruta actual", "files-permanently-delete.confirm": "Eliminar permanentemente", "files-permanently-delete.description-multiple": "¿Estás seguro de que quieres eliminar permanentemente estos {{count}} elementos? No podrás deshacer esta acción.", "files-permanently-delete.description-single": "¿Estás seguro de que quieres eliminar permanentemente \"{{fileName}}\"? No podrás deshacer esta acción.", "files-permanently-delete.title-multiple": "¿Eliminar permanentemente {{count}} elementos?", "files-permanently-delete.title-single": "¿Eliminar permanentemente?", "files-search.default": "Buscar archivos y carpetas", "files-search.no-results": "No se encontraron resultados para \"{{query}}\"", "files-search.placeholder": "Buscar", "files-search.searching-label": "Buscando el Umbrel de {{name}}", "files-share.home-description": "Accede a todos los archivos en \"{{homeDirectoryName}}\" desde otros dispositivos en tu red", "files-share.home-title": "Compartir \"{{homeDirectoryName}}\" en la red", "files-share.instructions.how-to-access": "Cómo acceder", "files-share.instructions.ios.enter-password": "Ingresa {{password}} como contraseña.", "files-share.instructions.ios.enter-server": "Ingresa {{smbUrl}} como dirección del servidor.", "files-share.instructions.ios.enter-username": "Ingresa {{username}} como nombre de usuario.", "files-share.instructions.ios.install-files": "Instala la aplicación \"Files\" desde App Store si no está instalada.", "files-share.instructions.ios.tap-connect": "Toca \"Conectar\" para acceder.", "files-share.instructions.ios.tap-dots": "Toca los tres puntos (...) en la parte superior derecha y selecciona \"Conectarse al servidor\".", "files-share.instructions.macos.click-connect": "Haz clic en \"Conectar\" para acceder.", "files-share.instructions.macos.enter-password": "Ingresa {{password}} como contraseña.", "files-share.instructions.macos.enter-url": "Ingresa {{smbUrl}} y haz clic en Conectar.", "files-share.instructions.macos.enter-username": "Ingresa {{username}} como nombre de usuario.", "files-share.instructions.macos.open-finder": "Abre \"Finder\" y presiona ⌘ + K.", "files-share.instructions.macos.select-registered": "Selecciona \"Usuario registrado\" cuando se te solicite.", "files-share.instructions.macos.time-machine": "Cómo usarlo como ubicación de copia de seguridad de Time Machine", "files-share.instructions.macos.time-machine.choose-encryption": "Elige entre respaldos cifrados o sin cifrar.", "files-share.instructions.macos.time-machine.disk-limit": "En 'Límite de uso de disco', especifica la cantidad máxima de espacio que deseas asignar en tu Umbrel para las copias de seguridad de Time Machine y luego haz clic en \"Hecho\".", "files-share.instructions.macos.time-machine.follow-steps": "Sigue los pasos anteriores y abre Configuración del Sistema en tu Mac.", "files-share.instructions.macos.time-machine.go-settings": "Ve a Time Machine y haz clic en \"Agregar disco de respaldo...\".", "files-share.instructions.macos.time-machine.select-disk": "Selecciona la carpeta y haz clic en \"Configurar disco...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Sigue los pasos guiados para configurar tus Backups.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Sigue los pasos anteriores y luego ve a \"{{settings}}\" > \"{{backups}}\" en tu otro Umbrel.", "files-share.instructions.umbrelos.backup.select-add": "Selecciona la opción para \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Selecciona este dispositivo Umbrel de la lista de dispositivos conectados.", "files-share.instructions.umbrelos.backup.title": "Cómo usarlo como ubicación de copia de seguridad para tu otro Umbrel", "files-share.instructions.umbrelos.cant-find-note": "¿No lo encuentras? Intenta seleccionar \"Agregar manualmente\" y usa las siguientes credenciales. Si aún no puedes agregarlo, asegúrate de que ambos dispositivos estén en la misma red.", "files-share.instructions.umbrelos.enter-password": "Introduce {{password}} como contraseña.", "files-share.instructions.umbrelos.enter-username": "Introduce {{username}} como nombre de usuario.", "files-share.instructions.umbrelos.open-and-click": "En tu otro Umbrel, abre \"Files\" y haz clic en junto a \" {{deviceLabel}}\" en la barra lateral.", "files-share.instructions.umbrelos.select-device": "Selecciona este dispositivo Umbrel de la lista de dispositivos detectados automáticamente en tu red.", "files-share.instructions.umbrelos.select-sharename": "Selecciona \"{{sharename}}\" y haz clic para agregar el recurso compartido.", "files-share.instructions.windows.enter-password": "Ingresa {{password}} como contraseña.", "files-share.instructions.windows.enter-url": "Escribe {{smbUrl}} y presiona Enter.", "files-share.instructions.windows.enter-username": "Ingresa {{username}} como nombre de usuario.", "files-share.instructions.windows.open-run": "Presiona Windows + R para abrir el cuadro de diálogo Ejecutar.", "files-share.instructions.windows.remember-credentials": "Marca \"Remember my credentials\" y haz clic en OK.", "files-share.regular-description": "Comparte esta carpeta para acceder a ella desde otros dispositivos en tu red", "files-share.regular-title": "Compartir carpeta en la red", "files-share.toggle": "Compartir \"{{name}}\" en tu red", "files-sidebar.apps": "Aplicaciones", "files-sidebar.external-storage": "Almacenamiento externo", "files-sidebar.favorites": "Favoritos", "files-sidebar.home": "Inicio", "files-sidebar.navigation": "Navegación de archivos", "files-sidebar.network": "Red", "files-sidebar.network-pathbar": "Dispositivos de red", "files-sidebar.network-sidebar": "Dispositivos", "files-sidebar.recents": "Recientes", "files-sidebar.shared-folders": "Carpetas compartidas", "files-sidebar.trash": "Papelera", "files-sidebar.trash.open": "Abrir", "files-sort.created": "Agregado", "files-sort.modified": "Modificado", "files-sort.name": "Nombre", "files-sort.size": "Tamaño", "files-sort.type": "Tipo", "files-state.uploading": "Subiendo...", "files-state.waiting": "Esperando...", "files-type.3gp": "Vídeo 3GP", "files-type.3gp2": "Vídeo 3GP2", "files-type.7z": "Archivo 7Z", "files-type.aac": "Audio AAC", "files-type.ai": "Archivo de Illustrator", "files-type.aiff": "Audio AIFF", "files-type.au": "Audio AU", "files-type.avi": "Vídeo AVI", "files-type.avif": "Imagen AVIF", "files-type.bmp": "Imagen BMP", "files-type.bzip2": "Archivo BZIP2", "files-type.caf": "Audio CAF", "files-type.compressed": "Archivo comprimido", "files-type.csv": "Archivo CSV", "files-type.directory": "Carpeta", "files-type.dmg": "Imagen de disco", "files-type.dv": "Vídeo DV", "files-type.epub": "eBook EPUB", "files-type.excel": "Hoja de cálculo de Excel", "files-type.exe": "Ejecutable de Windows", "files-type.executable": "Ejecutable", "files-type.external-drive": "Unidad", "files-type.flac": "Audio FLAC", "files-type.flv": "Vídeo FLV", "files-type.gif": "Imagen GIF", "files-type.gzip": "Archivo GZIP", "files-type.heic": "Imagen HEIC", "files-type.ico": "Imagen ICO", "files-type.iso": "Imagen ISO", "files-type.jpeg": "Imagen JPEG", "files-type.keynote": "Presentación de Keynote", "files-type.lzip": "Archivo LZIP", "files-type.lzma": "Archivo LZMA", "files-type.lzop": "Archivo LZOP", "files-type.m3u": "Lista de reproducción M3U", "files-type.m4a": "Audio M4A", "files-type.m4v": "Vídeo M4V", "files-type.midi": "Audio MIDI", "files-type.mka": "Audio MKA", "files-type.mkv": "Vídeo MKV", "files-type.mng": "Vídeo MNG", "files-type.mobi": "eBook MOBI", "files-type.mp3": "Audio MP3", "files-type.mp4": "Vídeo MP4", "files-type.mp4-audio": "Audio MP4", "files-type.mpeg": "Vídeo MPEG", "files-type.mpeg-ts": "Flujo de transporte MPEG", "files-type.network-drive": "Unidad de red", "files-type.numbers": "Hoja de cálculo de Numbers", "files-type.ogg": "Audio OGG", "files-type.ogv": "Vídeo OGV", "files-type.pages": "Documento de Pages", "files-type.pdf": "Documento PDF", "files-type.png": "Imagen PNG", "files-type.powerpoint": "Presentación de PowerPoint", "files-type.psd": "Documento de Photoshop", "files-type.quicktime": "Vídeo QuickTime", "files-type.rar": "Archivo RAR", "files-type.sgi": "Vídeo SGI", "files-type.svg": "Imagen SVG", "files-type.tar": "Archivo TAR", "files-type.tiff": "Imagen TIFF", "files-type.ts": "Vídeo TS", "files-type.txt": "Archivo de texto", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "Audio WAV", "files-type.webm": "Vídeo WebM", "files-type.webm-audio": "Audio WebM", "files-type.webp": "Imagen WebP", "files-type.wma": "Audio WMA", "files-type.wmv": "Vídeo WMV", "files-type.word": "Documento de Word", "files-type.xz": "Archivo XZ", "files-type.zip": "Archivo ZIP", "files-upload-island.uploading-count": "Subiendo {{count}} elementos", "files-view.icons": "Iconos", "files-view.list": "Lista", "files-view.sort-by": "Ordenar por", "files-view.view-as": "Ver como", "files-widgets.favorites.no-items-text": "Agrega una carpeta a Favoritos para verla aquí", "files-widgets.recents.no-items-text": "No hay archivos recientes", "generic-in": "en", "hide-details": "Ocultar detalles", "install-first.install-app": "Instalar {{app}}", "install-first.title": "{{app}} requiere estas aplicaciones", "install-your-first-app": "Instala tu primera aplicación", "language": "Idioma", "language-description": "Tu idioma preferido para umbrelOS", "language.select-description": "Selecciona el idioma preferido para umbrelOS", "live-usage": "Uso en vivo", "loading": "Cargando", "local-ip": "IP local", "login-2fa.subtitle": "Ingresa el código 2FA mostrado en tu aplicación de autenticación", "login-2fa.title": "Autenticar", "login-with-umbrel.description": "Ingresa tu contraseña de Umbrel para abrir {{app}}", "login-with-umbrel.title": "Iniciar sesión con Umbrel", "login.password-label": "Contraseña", "login.password.submit": "Iniciar sesión", "login.subtitle": "Ingresa tu contraseña de Umbrel para iniciar sesión", "login.title": "Bienvenido de nuevo", "logout": "Cerrar sesión", "logout-error-generic": "Error: Falló el cierre de sesión", "logout.confirm.submit": "Cerrar sesión", "logout.confirm.title": "¿Estás seguro de que quieres cerrar sesión?", "memory": "Memoria", "memory.low": "Memoria baja", "migrate": "Migrar", "migrate.callout": "No apagues tu Umbrel hasta que la migración se complete", "migrate.failed.retry": "Reintentar", "migrate.failed.title": "La migración falló", "migrate.success.description": "Todas tus aplicaciones, datos de aplicaciones y detalles de cuenta han sido migrados a tu Umbrel Home.", "migrate.success.title": "Migración exitosa", "migration-assistant": "Asistente de migración", "migration-assistant-description": "Transfiere todas tus aplicaciones y datos desde un Raspberry Pi a {{deviceName}}", "migration-assistant-unsupported-device-description": "Migration Assistant actualmente admite transferir todos los datos y aplicaciones desde un Raspberry Pi con umbrelOS a Umbrel Home o Umbrel Pro. Abre Migration Assistant en tu Umbrel Home o Umbrel Pro para empezar.", "migration-assistant.continue-migration.ready.submit": "Iniciar migración", "migration-assistant.failed": "Algo no está bien...", "migration-assistant.failed.retrying-message": "Reintentando...", "migration-assistant.mobile.start-button": "Iniciar migración", "migration-assistant.prep.body": "Prepararse para la migración", "migration-assistant.prep.button-continue": "Continuar", "migration-assistant.prep.callout": "Los datos en tu {{deviceName}}, si los hay, se eliminarán de forma permanente.", "migration-assistant.prep.connect-disk-to-home": "Conecta el disco externo a cualquier puerto USB de tu {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Una vez hecho, haz clic en '{{button}}' abajo.", "migration-assistant.prep.shut-down-rpi": "Apaga tu Umbrel Raspberry Pi.", "migration-assistant.ready.description": "Todos tus datos y aplicaciones están listos para ser migrados a tu {{deviceName}}", "migration-assistant.ready.hint-header": "Cosas a tener en cuenta", "migration-assistant.ready.hint-keep-pi-off.description": "Esto ayuda a prevenir problemas con aplicaciones como Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Mantén tu Raspberry Pi apagado después de la actualización", "migration-assistant.ready.hint-use-same-password.description": "Recuerda usar la contraseña de Umbrel de tu Raspberry Pi para iniciar sesión en tu {{deviceName}}", "migration-assistant.ready.hint-use-same-password.title": "Usa la misma contraseña", "migration-assistant.ready.title": "Todo listo para migrar!", "mini-browser.default-title": "Seleccionar carpeta", "mini-browser.empty-external": "Conecta una unidad externa para que aparezca aquí.", "mini-browser.empty-network": "Añade un Umbrel o NAS para que aparezca aquí.", "mini-browser.load-more": "Cargar más", "mini-browser.load-more-in-folder": "Cargar más en {{name}}", "mini-browser.loading-more": "Cargando más…", "mini-browser.select": "Seleccionar", "mini-browser.select-folder": "Seleccionar carpeta", "name": "Nombre", "nas": "NAS", "no-forgot-password-message": "Si pierdes tu contraseña, no podrás iniciar sesión en tu Umbrel. Asegúrate de guardarla de forma segura.", "no-results-found": "No se encontraron resultados", "not-found-404": "Código de error: 404", "not-found-404.back": "Atrás", "not-found-404.home": "Ir a inicio", "notifications.backups-failing-location.description": "Los backups automáticos en {{location}} han estado fallando. Comprueba la conexión y verifica la configuración de tus Backups.", "notifications.backups-failing.description": "Los Backups automáticos han estado fallando. Revisa la ubicación de tus Backups y verifica tu configuración.", "notifications.backups-failing.go-to-backups": "Ir a Backups", "notifications.backups-failing.title": "No se han realizado Backups en las últimas 24 horas", "notifications.cpu.too-hot": "Alta temperatura del CPU", "notifications.memory.low": "La memoria de tu dispositivo está baja", "notifications.new-version-available": "{{update}} está disponible para instalar", "notifications.raid.issue.description": "Se ha detectado un problema de almacenamiento. Revisa Storage Manager para más detalles.", "notifications.raid.issue.title": "Se necesita acción urgente", "notifications.ssd.health.description": "Uno o más SSD podrían necesitar atención. Revisa Storage Manager para más detalles.", "notifications.ssd.health.title": "Advertencia de salud del SSD", "notifications.storage.full": "El almacenamiento de tu dispositivo está lleno", "notifications.view": "Ver", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "Al hacer clic en 'Siguiente', aceptas los Términos de servicio de umbrelOS", "onboarding.account-created.youre-all-set-name": "Todo listo, {{name}}.", "onboarding.contact-support": "Soporte", "onboarding.create-account": "Crear cuenta", "onboarding.create-account.confirm-password.input-label": "Confirmar contraseña", "onboarding.create-account.failed.name-required": "Se requiere nombre", "onboarding.create-account.failed.passwords-dont-match": "Las contraseñas no coinciden", "onboarding.create-account.name.input-placeholder": "Tu nombre", "onboarding.create-account.password.input-label": "Contraseña", "onboarding.create-account.submit": "Crear", "onboarding.create-account.submitting": "Creando", "onboarding.create-account.subtitle": "La información de tu cuenta se almacena solo en tu Umbrel. Asegúrate de hacer una copia de seguridad de tu contraseña de forma segura, ya que no hay forma de restablecerla.", "onboarding.create-instead-long": "Crear cuenta nueva", "onboarding.create-instead-short": "Nueva cuenta", "onboarding.launch-umbrelos": "Iniciar umbrelOS", "onboarding.raid.available-storage": "Almacenamiento disponible", "onboarding.raid.change-drives-link": "¿Necesitas añadir o cambiar unidades?", "onboarding.raid.configuring.subtitle": "Esto puede tardar unos minutos.", "onboarding.raid.configuring.title": "Configurando tu almacenamiento", "onboarding.raid.configuring.warning": "Por favor, no actualices esta página ni apagues tu Umbrel mientras se configura el almacenamiento.", "onboarding.raid.continue": "Continuar", "onboarding.raid.error.detection-instructions": "Apaga tu Umbrel Pro, comprueba que tus SSDs estén bien colocados y vuelve a intentarlo.", "onboarding.raid.error.no-ssds-detected": "No se detectaron SSDs", "onboarding.raid.error.no-ssds-instructions": "Apaga tu Umbrel Pro e inserta al menos un SSD para continuar.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Aún no se puede activar FailSafe", "onboarding.raid.failsafe.enable": "Activar FailSafe", "onboarding.raid.failsafe.mixed-sizes": "FailSafe está limitado por tu SSD más pequeño ({{smallest}}). El espacio extra en los SSD más grandes no puede usarse, dejando {{wasted}} inutilizable.", "onboarding.raid.failsafe.protection-info-2ssds": "Se usa {{protection}} para la protección de datos. Añade otro SSD de {{smallest}} para aumentar el almacenamiento disponible a {{futureWith3}}, o añade dos más para {{futureWith4}}. Puedes añadir más SSDs en cualquier momento.", "onboarding.raid.failsafe.protection-info-3ssds": "Se usa {{protection}} para la protección de datos. Añade otro SSD de {{smallest}} para aumentar el almacenamiento disponible a {{futureWith4}}. Puedes añadir más SSDs en cualquier momento.", "onboarding.raid.failsafe.single-ssd-info": "Solo tienes un SSD. Añade al menos otro SSD de {{size}} para habilitar la protección FailSafe de tus datos. Puedes añadir más SSDs en cualquier momento.", "onboarding.raid.failsafe.subtitle": "Tus datos estarán seguros si falla algún SSD", "onboarding.raid.failsafe.tip": "Usa SSDs del mismo tamaño para obtener el máximo almacenamiento y cero espacio inutilizable.", "onboarding.raid.failsafe.warning-now-only": "Con más de un SSD, FailSafe solo puede activarse durante la configuración inicial. No podrás activarlo después.", "onboarding.raid.health-warning": "Esta unidad presenta problemas de salud", "onboarding.raid.launching": "Iniciando...", "onboarding.raid.no-ssds-alt": "No se encontraron SSDs", "onboarding.raid.recommended": "Recomendado", "onboarding.raid.scanning": "Revisando las ranuras de tus SSDs", "onboarding.raid.scanning-alt": "Buscando SSDs", "onboarding.raid.setup-failed.description-no-retry": "Apaga el dispositivo e inténtalo de nuevo.", "onboarding.raid.setup-failed.description-retry": "Inténtalo de nuevo, o apaga el dispositivo para revisar tus unidades.", "onboarding.raid.setup-failed.title": "Error en la configuración del almacenamiento", "onboarding.raid.shutdown-dialog.description": "Para añadir o cambiar unidades, apaga Umbrel Pro. Cuando termines, enciéndelo de nuevo y continúa con la configuración.", "onboarding.raid.shutdown-dialog.title": "¿Cambiar unidades?", "onboarding.raid.ssd-in-slot": "Un {{size}} SSD en la ranura {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "Bandeja SSD", "onboarding.raid.ssds-found": "Se encontraron los siguientes SSDs en tu Umbrel Pro", "onboarding.raid.storage": "Almacenamiento", "onboarding.raid.storage-label": "Almacenamiento", "onboarding.raid.success.storage-info": "Almacenamiento {{available}}", "onboarding.raid.success.storage-info-failsafe": "Almacenamiento {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Reintentar", "onboarding.raid.wasted": "Inutilizable", "onboarding.restore-long": "Restaurar mi Umbrel", "onboarding.restore-short": "Restaurar", "onboarding.start.continue": "Comenzar", "onboarding.start.subtitle": "Tu servidor en la nube está listo para configurarse.", "onboarding.start.title": "Bienvenido a umbrelOS", "open": "Abrir", "open-live-usage": "Abrir uso en vivo", "password": "Contraseña", "preferences": "Preferencias", "raid-error.description": "Tu sistema de almacenamiento no pudo iniciarse correctamente. Revisa el estado de tus SSDs a continuación y sigue los pasos de solución. Si el problema persiste, puede que sea necesario reemplazar los SSDs afectados.", "raid-error.factory-reset-dialog.description": "Esto borrará todos los datos de tu Umbrel Pro y lo restablecerá a los valores de fábrica. Esta acción no se puede deshacer.", "raid-error.factory-reset-dialog.title": "¿Restablecer de fábrica?", "raid-error.factory-reset-failed": "No se pudo restablecer de fábrica", "raid-error.health-warning": "Advertencia de salud", "raid-error.missing-ssd-multiple": "{{count}} SSDs no responden", "raid-error.missing-ssd-one": "1 SSD no responde", "raid-error.shutdown-dialog.description": "Apaga tu Umbrel Pro, asegúrate de que todos los SSDs están bien colocados en sus slots y vuelve a encenderlo.", "raid-error.shutdown-dialog.title": "¿Apagar para comprobar las unidades?", "raid-error.ssd-in-slot": "Un SSD de {{size}} en Slot {{slot}}", "raid-error.step-check-connections.button": "Apagar", "raid-error.step-check-connections.description": "Apaga el dispositivo y comprueba que todos los SSDs están correctamente colocados.", "raid-error.step-check-connections.title": "Comprueba las conexiones de los SSDs", "raid-error.step-factory-reset.button": "Restablecer de fábrica", "raid-error.step-factory-reset.description": "Último recurso si nada más funciona. Esto borrará todos los datos.", "raid-error.step-factory-reset.title": "Restablecer de fábrica", "raid-error.step-restart.button": "Reiniciar", "raid-error.step-restart.description": "Un primer paso rápido que suele ayudar", "raid-error.step-restart.title": "Intenta reiniciar", "raid-error.title": "Problema de almacenamiento detectado", "read-less": "Leer menos", "read-more": "Leer más", "reconnect": "Reconectar", "redirect.to-home": "Cargando...", "redirect.to-login": "Cargando...", "redirect.to-onboarding": "Cargando...", "redirect.to-raid-error": "Cargando...", "reload": "Recargar", "remote-tor-access": "Acceso remoto Tor", "reset": "Reiniciar", "restart": "Reiniciar", "restart.confirm.submit": "Reiniciar", "restart.confirm.title": "¿Estás seguro de que quieres reiniciar tu Umbrel?", "restart.restarting": "Reiniciando", "restart.restarting-message": "Por favor, no refresques esta página ni apagues tu Umbrel mientras se reinicia.", "rewind": "Rewind", "rewind.files-as-of": "Tus archivos a fecha de", "rewind.loading-snapshots": "Cargando instantáneas...", "rewind.now": "Ahora", "rewind.preflight.description": "Encuentra archivos y carpetas de tus copias de seguridad anteriores y recupéralos al presente.", "rewind.preflight.enable-backups": "Configura Backups en Ajustes para empezar a usar Rewind", "rewind.restore-complete": "Restauración completada", "rewind.restore-error-description": "Por favor, inténtalo de nuevo.", "rewind.restore-failed": "Restauración fallida", "rewind.restore-running-description": "No cierres ni recargues esta página hasta que la restauración haya finalizado", "rewind.restore-selected": "Restaurar seleccionados", "rewind.restore-success-description": "Tus archivos se han restaurado", "rewind.restoring": "Restaurando", "rewind.snapshots-count_one": "{{count}} copia de seguridad desde", "rewind.snapshots-count_other": "{{count}} copias de seguridad desde", "search": "Buscar", "settings": "Configuración", "settings.app-store-preferences.title": "Preferencias de App Store", "settings.contact-support": "¿Necesitas ayuda? Contacta con soporte.", "settings.file-sharing": "Compartir archivos", "settings.file-sharing.add-folder": "Añadir", "settings.file-sharing.add-folder-title": "Selecciona una carpeta para compartir", "settings.file-sharing.choice-entire-description": "Comparte todos los archivos de tu Umbrel", "settings.file-sharing.choice-entire-title": "Todo", "settings.file-sharing.choice-heading": "¿Qué quieres compartir?", "settings.file-sharing.choice-specific-description": "Elige qué carpetas compartir", "settings.file-sharing.choice-specific-title": "Carpetas específicas", "settings.file-sharing.choice-subtitle": "Accede a tus archivos y carpetas al estilo Dropbox como carpetas de red en tu ordenador o teléfono", "settings.file-sharing.configure": "Configurar", "settings.file-sharing.description": "Accede a tus archivos al estilo Dropbox como una carpeta de red (SMB) desde otros dispositivos", "settings.file-sharing.home-shared-note": "Toda tu carpeta \"{{homeDirectoryName}}\" está compartida. No es necesario compartir las carpetas individuales por separado.", "settings.file-sharing.share-entire-home-dir": "Comparte toda tu carpeta Home", "settings.file-sharing.share-entire-home-dir-description": "Accede a todos los archivos y carpetas en \"{{homeDirectoryName}}\" desde otros dispositivos en tu red", "settings.file-sharing.shared-folders": "Carpetas compartidas", "show-details": "Mostrar detalles", "shut-down": "Apagar", "shut-down.complete": "Apagado completo", "shut-down.complete-text": "Ahora puedes desconectar tu dispositivo de la energía.", "shut-down.confirm.submit": "Apagar", "shut-down.confirm.title": "¿Estás seguro de que quieres apagar tu Umbrel?", "shut-down.failed": "No pudimos apagar: {{message}}", "shut-down.shutting-down": "Apagando", "shut-down.shutting-down-message": "Por favor, no refresques esta página ni apagues tu Umbrel mientras se apaga.", "software-update.callout": "Por favor, no refresques esta página ni apagues tu Umbrel mientras se actualiza.", "software-update.check": "Buscar actualización", "software-update.checking": "Buscando actualización...", "software-update.current-running": "Estás en", "software-update.failed": "Falló la actualización", "software-update.failed-to-check": "Error al buscar actualizaciones", "software-update.failed.retry": "Reintentar", "software-update.install-now": "Instalar ahora", "software-update.new-version": "Nueva versión {{name}} disponible para instalar", "software-update.on-latest": "Estás en la última versión de umbrelOS", "software-update.see-whats-new": "Ver novedades", "software-update.title": "Actualización de software", "software-update.updating-to": "Actualizando a {{name}}", "software-update.view": "Ver", "something-left": "{{left}} restantes", "something-went-wrong": "⚠ Algo salió mal", "start": "Iniciar", "stop": "Detener", "storage": "Almacenamiento", "storage-manager": "Administrador de almacenamiento", "storage-manager.add": "Agregar", "storage-manager.add-to-raid.add-ssd": "Agregar SSD", "storage-manager.add-to-raid.available": "Disponible:", "storage-manager.add-to-raid.description": "Se ha detectado un nuevo SSD y está listo para ser agregado.", "storage-manager.add-to-raid.enable-failsafe": "Activar FailSafe", "storage-manager.add-to-raid.failed-add": "No se pudo agregar el SSD", "storage-manager.add-to-raid.failed-enable-failsafe": "No se pudo activar FailSafe", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Tu nuevo SSD de {{size}} se añadirá al almacenamiento disponible.", "storage-manager.add-to-raid.info-capacity-adds-available": "Tu nuevo SSD de {{size}} agregará {{available}} de almacenamiento disponible.", "storage-manager.add-to-raid.info-capacity-adds-both": "Tu nuevo SSD de {{size}} agregará {{available}} de almacenamiento disponible y {{protection}} para protección de datos.", "storage-manager.add-to-raid.info-capacity-protection-only": "Tu nuevo SSD de {{size}} agregará {{protection}} para protección de datos.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Tu nuevo SSD de {{size}} se usará completamente para protección de datos.", "storage-manager.add-to-raid.info-data-safe": "Tus datos estarán seguros si falla cualquier SSD individual.", "storage-manager.add-to-raid.info-no-protection": "Si un SSD falla, podrías perder tus datos.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} en total inutilizable debido a los diferentes tamaños de SSD.", "storage-manager.add-to-raid.info-wasted": "{{size}} será inutilizable debido a los diferentes tamaños de SSD.", "storage-manager.add-to-raid.recommended": "Recomendado", "storage-manager.add-to-raid.recommended-inline": "(recomendado)", "storage-manager.add-to-raid.restart-active-tasks": "Cualquier tarea activa será interrumpida", "storage-manager.add-to-raid.restart-after": "Después del reinicio, la configuración de FailSafe se completará automáticamente y podrás reanudar el uso normal.", "storage-manager.add-to-raid.restart-during": "Durante el reinicio:", "storage-manager.add-to-raid.restart-intro": "Puedes seguir usando umbrelOS con normalidad durante este proceso. Sin embargo, al llegar al 50% de progreso tu Umbrel se reiniciará automáticamente.", "storage-manager.add-to-raid.restart-required": "Se requiere reinicio del sistema", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS estará temporalmente inaccesible", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD en Slot {{slot}}", "storage-manager.add-to-raid.title": "Agregar SSD al almacenamiento", "storage-manager.add-to-raid.too-small": "SSD demasiado pequeño", "storage-manager.add-to-raid.too-small-description": "Este SSD ({{deviceSize}}) es más pequeño que el SSD más pequeño instalado actualmente ({{minSize}}). FailSafe requiere que todos los SSD sean al menos tan grandes como el SSD más pequeño en uso.", "storage-manager.add-to-raid.understand-continue": "Entiendo, continuar", "storage-manager.add-to-raid.warning-failsafe-now-only": "Tener más de un SSD significa que FailSafe solo puede activarse ahora. No podrás activarlo más tarde.", "storage-manager.add-to-raid.wasted-label": "Inutilizable:", "storage-manager.available-storage": "Almacenamiento disponible", "storage-manager.description": "Ver el almacenamiento, el estado y la configuración de tus SSDs", "storage-manager.empty": "Vacío", "storage-manager.failsafe-transition-failed": "No se pudo activar FailSafe", "storage-manager.for-failsafe": "Para FailSafe", "storage-manager.health.checksum-errors": "Errores de checksum: {{count}}", "storage-manager.health.critical": "Crítico", "storage-manager.health.critical-threshold": "Umbral crítico", "storage-manager.health.current-temperature": "Temperatura actual", "storage-manager.health.estimated-life": "Vida útil estimada restante", "storage-manager.health.general": "General", "storage-manager.health.health-status": "Estado de salud", "storage-manager.health.low": "Bajo", "storage-manager.health.model-and-capacity": "Modelo y tamaño", "storage-manager.health.overheating": "Sobrecalentamiento", "storage-manager.health.raid-failed-advice": "Este SSD tiene un problema. Apaga tu Umbrel y comprueba la conexión del SSD. Si el problema persiste, puede que sea necesario reemplazar el SSD.", "storage-manager.health.read-errors": "Errores de lectura: {{count}}", "storage-manager.health.serial-number": "Número de serie", "storage-manager.health.status-healthy": "Saludable", "storage-manager.health.status-unhealthy": "Con problemas", "storage-manager.health.status-unknown": "Desconocido", "storage-manager.health.temperature": "Temperatura", "storage-manager.health.title": "Estado de los SSD", "storage-manager.health.warning-life-advice": "Considera reemplazar este SSD pronto.", "storage-manager.health.warning-life-message": "Solo queda {{percent}}% de vida", "storage-manager.health.warning-temp-advice": "Asegúrate de que tu Umbrel Pro tenga buena ventilación y que el SSD esté correctamente insertado.", "storage-manager.health.warning-temp-critical": "La temperatura es crítica ({{temperature}})", "storage-manager.health.warning-temp-overheating": "La unidad se está sobrecalentando ({{temperature}})", "storage-manager.health.warning-threshold": "Umbral de advertencia", "storage-manager.health.warning-unhealthy-advice": "Este SSD puede fallar pronto. Considera reemplazarlo.", "storage-manager.health.warning-unhealthy-message": "Este SSD podría tener un problema", "storage-manager.health.warnings": "Advertencias", "storage-manager.health.wear": "Desgaste", "storage-manager.health.write-errors": "Errores de escritura: {{count}}", "storage-manager.install-ssd.description": "Añade más SSDs para ampliar tu almacenamiento", "storage-manager.install-ssd.step-insert": "Inserta los nuevos SSDs en los slots vacíos", "storage-manager.install-ssd.step-power-on": "Enciende tu {{deviceName}}", "storage-manager.install-ssd.step-remove-bottom-cover": "Retira la cubierta magnética inferior", "storage-manager.install-ssd.step-replace-bottom-cover": "Vuelve a colocar la tapa inferior", "storage-manager.install-ssd.step-return": "Vuelve aquí para agregar los SSDs a tu almacenamiento", "storage-manager.install-ssd.step-shut-down": "Apaga tu {{deviceName}}", "storage-manager.install-ssd.title": "Instalación de SSDs", "storage-manager.install-tips.image-alt": "Instrucciones de instalación del SSD", "storage-manager.install-tips.instructions": "Para instalarlo, quita el tornillo de pulgar y desliza el SSD en la ranura en diagonal. Presiona el SSD hacia abajo hasta que repose sobre el soporte del tornillo y luego asegúralo con el tornillo de pulgar.", "storage-manager.install-tips.toggle": "¿Olvidaste cómo insertar un SSD?", "storage-manager.manage": "Administrar", "storage-manager.missing-ssd-warning": "Parece faltar un SSD. Apaga tu Umbrel y comprueba que todos los SSD estén conectados. Si el problema continúa, puede que sea necesario reemplazar el SSD.", "storage-manager.mode": "Modo", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Mantiene tus datos seguros si un SSD falla. Si tus SSDs son de distinto tamaño, el espacio extra en los más grandes queda sin usar.", "storage-manager.mode.failsafe.info-description": "FailSafe protege tus datos manteniendo copias en tus SSDs. Si falla cualquier SSD, tus datos permanecen seguros y se pueden restaurar cuando añadas un SSD de reemplazo.", "storage-manager.mode.failsafe.info-title": "Acerca de FailSafe", "storage-manager.mode.full-storage": "Almacenamiento completo", "storage-manager.mode.full-storage.description": "Usa todo el espacio de tus SSDs conjuntamente. Si un SSD falla, podrías perder tus datos.", "storage-manager.mode.full-storage.info-description": "Full Storage combina todos tus SSDs en un único gran espacio, ofreciéndote el máximo almacenamiento. Sin embargo, si algún SSD falla, todos tus datos se perderán.", "storage-manager.mode.full-storage.info-title": "Acerca de Almacenamiento completo", "storage-manager.mode.switch-from-failsafe-unavailable": "Cambiar de FailSafe a Full Storage requiere que hagas una copia de seguridad de tus datos, restablezcas el dispositivo a valores de fábrica y restaures desde la copia.", "storage-manager.mode.switch-to-failsafe-unavailable": "Con varios SSDs en Full Storage, tus datos están repartidos entre todas las unidades. Cambiar a FailSafe requiere hacer copia de seguridad, restablecer a valores de fábrica y restaurar.", "storage-manager.mode.why-cant-switch": "¿Por qué no puedo cambiar?", "storage-manager.operation-in-progress.shutdown-description": "Es seguro apagar el dispositivo. La operación se pausará y se reanudará después del reinicio, pero debe finalizar antes de que puedas hacer otros cambios.", "storage-manager.operation-in-progress.shutdown-title": "Tu almacenamiento se está actualizando", "storage-manager.operation-in-progress.wait-description": "Por favor, espera a que la operación actual termine antes de hacer más cambios.", "storage-manager.operation-in-progress.wait-title": "Tu almacenamiento se está actualizando", "storage-manager.operation.adding-ssd": "Agregando SSD...", "storage-manager.operation.enabling-failsafe": "Activando FailSafe...", "storage-manager.operation.expanding": "Ampliando el almacenamiento...", "storage-manager.operation.rebuilding": "Reconstruyendo datos...", "storage-manager.operation.replacing": "Reemplazando la unidad...", "storage-manager.operation.restarting": "Reiniciando...", "storage-manager.operation.starting": "Iniciando...", "storage-manager.operation.syncing-restarts": "Sincronizando datos • Se reinicia al 50%", "storage-manager.raid-status.degraded": "Degradado", "storage-manager.raid-status.failed": "Fallado", "storage-manager.raid-status.offline": "Desconectado", "storage-manager.raid-status.online": "En línea", "storage-manager.raid-status.removed": "Retirado", "storage-manager.raid-status.unavailable": "No disponible", "storage-manager.replace": "Reemplazar", "storage-manager.replace-failed.degraded": "Protección de FailSafe reducida", "storage-manager.replace-failed.degraded-description": "Falta un SSD en tu almacenamiento FailSafe. Reemplázalo para restaurar la protección completa.", "storage-manager.replace-failed.description": "Usa este SSD para restaurar la protección de FailSafe.", "storage-manager.replace-failed.error": "No se pudo iniciar el reemplazo", "storage-manager.replace-failed.replace-now": "Reemplazar ahora", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD en la ranura {{slot}}", "storage-manager.replace-failed.step-protected": "Una vez completado, tus datos estarán completamente protegidos de nuevo", "storage-manager.replace-failed.step-rebuild": "Los datos se reconstruirán en el nuevo SSD", "storage-manager.replace-failed.step-time": "Esto puede tardar un tiempo, según la cantidad de datos que tengas", "storage-manager.replace-failed.title": "Reemplazar SSD", "storage-manager.replace-failed.too-small": "SSD demasiado pequeño", "storage-manager.replace-failed.too-small-description": "Este SSD ({{deviceSize}}) es más pequeño que el mínimo requerido ({{minSize}}) para tu almacenamiento FailSafe.", "storage-manager.replace-failed.what-happens": "Qué pasa a continuación:", "storage-manager.ssd-failing": "Con fallos", "storage-manager.swap": "Intercambiar", "storage-manager.swap.data-erased-description": "El modo Full Storage no tiene protección de datos. Todos los datos en tu {{deviceName}} se borrarán durante el restablecimiento de fábrica. Asegúrate de hacer una copia de seguridad de todo primero.", "storage-manager.swap.data-protected": "Tus datos están protegidos", "storage-manager.swap.data-protected-description": "Con FailSafe activado, puedes cambiar cualquier SSD individual sin perder tus datos. No necesitas copia de seguridad.", "storage-manager.swap.data-will-be-erased": "Los datos se borrarán", "storage-manager.swap.description-failsafe": "Reemplaza una unidad en tu almacenamiento FailSafe.", "storage-manager.swap.description-full-storage": "Reemplaza una unidad en tu configuración Full Storage.", "storage-manager.swap.description-no-free-slot": "En Full Storage con todos los slots ocupados, intercambiar un SSD requiere un proceso completo de copia de seguridad y restauración.", "storage-manager.swap.description-replace": "Migra tus datos a un nuevo SSD y luego retira el antiguo.", "storage-manager.swap.failed-to-start": "No se pudo iniciar el reemplazo", "storage-manager.swap.no-data-loss": "Sin pérdida de datos", "storage-manager.swap.no-data-loss-description": "Tus datos se copiarán al nuevo SSD. Una vez completado, podrás retirar el antiguo de forma segura.", "storage-manager.swap.safe-swap-available": "Intercambio seguro disponible", "storage-manager.swap.safe-swap-description": "Como tienes un slot vacío, puedes agregar primero el nuevo SSD y migrar tus datos antes de retirar el antiguo. No se requiere copia de seguridad.", "storage-manager.swap.select-new-ssd": "Selecciona el nuevo SSD a usar:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD en Slot {{slot}}", "storage-manager.swap.step-backup": "Haz una copia de seguridad de tus datos", "storage-manager.swap.step-backup-description": "Ve a Ajustes → Backups y crea una copia de seguridad de todos tus datos.", "storage-manager.swap.step-data-copied": "Los datos se copiarán del SSD antiguo al nuevo", "storage-manager.swap.step-factory-reset": "Restablecer de fábrica", "storage-manager.swap.step-factory-reset-description": "Ve a Ajustes → Avanzado → Restablecer de fábrica para borrar tu {{deviceName}}.", "storage-manager.swap.step-insert-new-ssd": "Inserta el nuevo SSD en un slot vacío", "storage-manager.swap.step-may-take-while": "Esto puede tardar un tiempo, dependiendo de la cantidad de datos que tengas", "storage-manager.swap.step-power-on": "Enciende tu {{deviceName}}", "storage-manager.swap.step-remove-bottom-cover": "Retira la cubierta magnética inferior", "storage-manager.swap.step-remove-old": "Una vez completado, apaga y retira {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Vuelve a colocar la cubierta inferior", "storage-manager.swap.step-restore": "Restaura tus datos", "storage-manager.swap.step-restore-description": "Ve a Ajustes → Backups y restaura desde tu copia de seguridad.", "storage-manager.swap.step-return-to-storage-manager": "Vuelve al Administrador de almacenamiento para confirmar el intercambio y añadir el nuevo SSD a tu almacenamiento", "storage-manager.swap.step-return-to-swap": "Vuelve al Administrador de almacenamiento y haz clic en \"Intercambiar\" nuevamente para iniciar el reemplazo", "storage-manager.swap.step-setup-new-storage": "Configura tu nuevo almacenamiento", "storage-manager.swap.step-setup-new-storage-description": "Enciende tu {{deviceName}} y completa el proceso de configuración con tu nuevo SSD.", "storage-manager.swap.step-shut-down": "Apaga tu {{deviceName}}", "storage-manager.swap.step-shut-down-and-swap": "Apaga y reemplaza {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Apaga, abre tu dispositivo, reemplaza el SSD y vuelve a montar.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Apaga, retira la cubierta inferior, reemplaza el SSD y vuelve a colocar la cubierta.", "storage-manager.swap.step-swap-ssd": "Intercambia {{ssd}} por uno nuevo del mismo tamaño", "storage-manager.swap.too-small": "Demasiado pequeño (se requiere {{size}})", "storage-manager.swap.what-happens-next": "Qué sucede a continuación:", "storage-manager.total-capacity-added": "Capacidad total añadida", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Usado", "storage-manager.wasted": "No utilizable", "storage-manager.wasted-size": "{{size}} No utilizable", "storage.full": "Almacenamiento lleno", "storage.low": "Almacenamiento bajo", "temperature": "Temperatura", "temperature.dangerously-hot": "Muy caliente", "temperature.nice": "Agradable", "temperature.normal": "Normal", "temperature.too-hot-suggestion": "Considera cambiar el entorno de tu dispositivo.", "temperature.warm": "Cálido", "terminal": "Terminal", "terminal-description": "Ejecuta comandos personalizados en umbrelOS o dentro de una aplicación", "terminal.app": "App", "terminal.app-description": "Ejecuta comandos personalizados dentro de una app específica", "terminal.umbrelos-description": "Ejecuta comandos personalizados en umbrelOS", "tor-description": "Accede a tu Umbrel desde cualquier lugar usando un navegador Tor", "tor-enabled-description": "Accede a tu Umbrel desde cualquier lugar usando un navegador Tor en la siguiente URL:", "tor-error": "No pudimos actualizar la configuración de Tor: {{message}}", "tor.disable.description": "Esto puede tardar unos minutos", "tor.disable.progress": "Deshabilitando el acceso remoto mediante Tor", "tor.enable.description": "Esto puede tardar unos minutos", "tor.enable.mobile.switch-label": "Activar acceso remoto Tor", "tor.hidden-service": "URL del servicio oculto de Tor", "troubleshoot": "Solucionar problemas", "troubleshoot-description": "Solucionar problemas de umbrelOS o una aplicación", "troubleshoot-no-logs-yet": "Aún no hay registros", "troubleshoot-pick-title": "Solucionar problemas", "troubleshoot.app": "Aplicación", "troubleshoot.app-description": "Ver registros de una aplicación instalada en tu Umbrel", "troubleshoot.app-download": "Descargar registros de {{app}}", "troubleshoot.share-with-umbrel-support": "Compartir con el soporte de Umbrel", "troubleshoot.system-download": "Descargar {{label}}", "troubleshoot.umbrelos-description": "Ver los registros de umbrelOS", "troubleshoot.umbrelos-logs": "Registros de umbrelOS", "trpc.backend-unavailable": "Error: Conexión con la API del sistema fallida", "trpc.checking-backend": "Cargando...", "try-again": "Intentar de nuevo", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Desconocido", "unknown-app": "Aplicación desconocida", "unknown-error": "Error desconocido", "uptime": "Tiempo de actividad", "url": "URL", "wallpaper": "Fondo de pantalla", "wallpaper-description": "Tu fondo de pantalla y tema de Umbrel", "whats-new.continue": "Continuar", "whats-new.feature-1.description": "Configura copias de seguridad automáticas y cifradas de todo tu Umbrel en un disco USB externo, un NAS o en otro Umbrel.", "whats-new.feature-2.description": "Vuelve atrás en el tiempo para recuperar archivos y carpetas específicos de copias de seguridad anteriores.", "whats-new.feature-3.description": "O restaura todo tu Umbrel, incluyendo todas tus aplicaciones, archivos y datos.", "whats-new.feature-4.description": "Conecta un NAS u otro Umbrel y accede a su almacenamiento desde Files.", "whats-new.feature-4.title": "Dispositivos de red", "whats-new.feature-5.description": "Conecta discos USB externos (en Umbrel Home o en cualquier dispositivo Intel o AMD) y accede a ellos desde Files.", "whats-new.feature-5.helper-text": "No es compatible con dispositivos Raspberry Pi debido a posibles problemas de energía.", "whats-new.feature-5.title": "Almacenamiento externo", "whats-new.next": "Siguiente", "whats-new.title": "Novedades en {{version}}", "widget.progress.in-progress": "En progreso", "widgets.edit.select-up-to-3-widgets": "Selecciona hasta 3 widgets", "widgets.install-an-app-before-using-widgets": "Instala una aplicación para comenzar a personalizar tu pantalla de inicio con widgets.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Las redes abiertas pueden ser inseguras", "wifi-connection-failed": "No se pudo conectar", "wifi-dangerous-change-confirmation-description": "Cambiar la red Wi-Fi puede desconectarte de tu Umbrel. Para reconectar, asegúrate de que tanto tu Umbrel como el dispositivo desde el que accedes estén en la misma red.", "wifi-dangerous-change-confirmation-title": "¿Estás seguro de que quieres cambiar la red Wi-Fi?", "wifi-dangerous-disable-confirmation-description": "Desactivar el Wi-Fi puede desconectarte de tu Umbrel. Para reconectar, enchufa un cable Ethernet a tu Umbrel y asegúrate de que tanto tu Umbrel como el dispositivo desde el que accedes estén en la misma red.", "wifi-dangerous-disable-confirmation-title": "¿Estás seguro de que quieres desactivar el Wi-Fi?", "wifi-description": "Conecta tu dispositivo a una red Wi-Fi", "wifi-description-long": "Tu dispositivo permanece conectado a tu Wi-Fi elegido, incluso si se quita el cable Ethernet, y se reconecta automáticamente al Wi-Fi al iniciar.", "wifi-no-networks-message": "No se encontraron redes Wi-Fi", "wifi-searching": "Buscando redes Wi-Fi...", "wifi-unsupported-device-description": "El Wi-Fi no es compatible con este dispositivo. Esto puede deberse a un adaptador inalámbrico faltante o incompatible.", "wifi-view-networks": "Ver redes" } ================================================ FILE: packages/ui/public/locales/fr.json ================================================ { "2fa": "2FA", "2fa-description": "Une seconde couche de sécurité pour votre connexion Umbrel et applications", "2fa.disable.title": "Désactiver l'authentification à deux facteurs", "2fa.enable.or-paste": "Ou collez le code suivant dans votre application d'authentification", "2fa.enable.scan-this": "Scannez ce code QR avec une application d'authentification comme Google Authenticator ou Authy", "2fa.enable.title": "Activer l'authentification à deux facteurs", "2fa.enter-code": "Entrez le code affiché dans votre application d'authentification", "account": "Compte", "account-description": "Votre nom et mot de passe", "advanced-settings": "Paramètres avancés", "advanced-settings-description": "Terminal, Programme Beta umbrelOS, DNS Cloudflare, et plus", "app-not-found": "Application non trouvée : {{app}}", "app-only-over-tor": "{{app}} ne peut être utilisé que via Tor. Accédez à votre Umbrel depuis un navigateur Tor en utilisant votre URL d'accès à distance (Paramètres > Paramètres avancés > Accès distant via Tor) pour ouvrir cette application.", "app-page.section.about": "À propos", "app-page.section.credentials.title": "Identifiants par défaut", "app-page.section.dependencies.n-alternatives": "Voir {{count}} alternatives", "app-page.section.info.compatibility": "Compatibilité", "app-page.section.info.compatibility-compatible": "Compatible", "app-page.section.info.compatibility-not-compatible": "Non compatible", "app-page.section.info.developer": "Développeur", "app-page.section.info.source-code": "Code source", "app-page.section.info.source-code.public": "Public", "app-page.section.info.submitted-by": "Soumis par", "app-page.section.info.support": "Obtenir de l'aide", "app-page.section.info.title": "Infos", "app-page.section.info.version": "Version", "app-page.section.recommendations.title": "Vous pourriez aussi aimer", "app-page.section.release-notes.title": "Nouveautés", "app-page.section.release-notes.version": "Version {{version}}", "app-page.section.requires": "Nécessite", "app-picker.search": "Rechercher...", "app-picker.select-app": "Sélectionner une application...", "app-settings.connected-to": "{{appName}} est connecté à ces applications", "app-settings.save-changes": "Enregistrer les modifications", "app-settings.title": "Réglages", "app-store.browse-category-apps": "Parcourir les applications {{category}}", "app-store.category.ai": "IA", "app-store.category.all": "Toutes les applications", "app-store.category.automation": "Maison & Automatisation", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Crypto", "app-store.category.developer": "Outils Développeur", "app-store.category.discover": "Découvrir", "app-store.category.files": "Fichiers & Productivité", "app-store.category.finance": "Finance", "app-store.category.media": "Médias", "app-store.category.networking": "Réseautage", "app-store.category.social": "Social", "app-store.description": "Vos paramètres de mise à jour des applications", "app-store.discover.temporarily-unavailable-description": "Parcourez les catégories ci-dessus ou utilisez la recherche pour trouver des apps", "app-store.discover.temporarily-unavailable-title": "Contenu mis en avant momentanément indisponible", "app-store.menu.community-app-stores": "App Stores Communautaires", "app-store.search-apps": "Rechercher des applications", "app-store.search.no-results": "Aucun résultat", "app-store.search.results-for": "Résultats pour", "app-store.title": "App Store", "app-store.updates": "Mises à jour", "app-updates.less": "moins", "app-updates.more": "plus", "app-updates.no-updates": "Toutes les applications sont à jour !", "app-updates.update": "Mettre à jour", "app-updates.update-all": "Mettre à jour tout", "app-updates.updates-available-count_one": "{{count}} mise à jour disponible", "app-updates.updates-available-count_other": "{{count}} mises à jour disponibles", "app-updates.updating": "Mise à jour...", "app.install": "Installer", "app.installed": "Installé", "app.installing": "Installation", "app.offline": "Non en cours d'exécution", "app.open": "Ouvrir", "app.optimized-for-umbrel-home": "Optimisé pour Umbrel Home", "app.os-update-required.confirm": "Vérifier les mises à jour d'umbrelOS", "app.os-update-required.description": "{{appName}} nécessite umbrelOS {{version}} ou une version ultérieure", "app.os-update-required.title": "Mettre à jour umbrelOS", "app.restarting": "Redémarrage", "app.starting": "Démarrage", "app.stopping": "Arrêt", "app.uninstall.confirm.description": "Toutes les données associées à {{app}} seront définitivement supprimées. Cette action est irréversible.", "app.uninstall.confirm.submit": "Désinstaller", "app.uninstall.confirm.title": "Désinstaller {{app}} ?", "app.uninstall.deps.used-by.description_one": "Désinstallez {{firstAppToUninstall}} d'abord pour désinstaller {{app}}.", "app.uninstall.deps.used-by.description_other": "Désinstallez ces applications d'abord pour désinstaller {{app}}.", "app.uninstall.deps.used-by.title": "{{app}} est utilisé par", "app.uninstalling": "Désinstallation", "app.updating": "Mise à jour", "app.view": "Voir", "app_one": "application", "app_other": "applications", "apps.uninstall.failed-to-get-required-apps": "Échec de la récupération des applications requises", "apps.uninstalled-all.success": "Toutes les applications désinstallées", "auth.checking-backend-for-user": "Chargement...", "auth.failed-checking-if-user-logged-in": "Erreur : Vérification de la connexion échouée", "auth.failed-to-check-if-user-exists": "Erreur : Vérification de l'existence échouée", "back": "Retour", "backups": "Sauvegardes", "backups-configure": "Configurer", "backups-configure.add-backup-location": "Ajouter un emplacement de sauvegarde", "backups-configure.available": "Disponible", "backups-configure.awaiting-next-backup": "En attente de la prochaine sauvegarde automatique", "backups-configure.back-up-now": "Sauvegarder maintenant", "backups-configure.backing-up-now": "Sauvegarde en cours...", "backups-configure.connected": "Connecté", "backups-configure.connection": "Connexion", "backups-configure.in-progress": "En cours", "backups-configure.last-backup": "Dernière sauvegarde", "backups-configure.locations": "Emplacements", "backups-configure.no-backup-locations": "Ajoutez un emplacement de sauvegarde pour commencer à sauvegarder vos données", "backups-configure.not-connected": "Non connecté", "backups-configure.path": "Chemin", "backups-configure.remove-backup-location": "Supprimer l'emplacement de sauvegarde", "backups-configure.remove-backup-location-confirmation": "Êtes-vous sûr ?", "backups-configure.remove-backup-location-confirmation-description": "Cela supprimera '{{device}}' de vos emplacements de sauvegarde. Vos sauvegardes existantes sur cet appareil ne seront pas supprimées, mais les sauvegardes automatiques cesseront.", "backups-configure.status": "Statut", "backups-configure.total-backups": "Total des Backups", "backups-configure.used": "Utilisé", "backups-configure.view": "Afficher", "backups-description": "Sauvegardez vos fichiers, applications et données vers un autre Umbrel, un NAS ou un disque externe", "backups-error.backup-not-found": "La sauvegarde est introuvable.", "backups-error.generic": "Une erreur est survenue : {{details}}", "backups-error.in-progress": "Une sauvegarde est déjà en cours. Patientez le temps qu'elle se termine.", "backups-error.invalid-exclusion-path": "Seuls les fichiers et dossiers de votre répertoire personnel peuvent être exclus des sauvegardes.", "backups-error.invalid-password": "Le mot de passe de chiffrement est incorrect.", "backups-error.invalid-path": "L'emplacement sélectionné n'est pas valide pour les sauvegardes.", "backups-error.mount-failed": "Impossible d'accéder à l'instantané de sauvegarde.", "backups-error.mount-timeout": "Impossible d'accéder à l'instantané de sauvegarde. Réessayez ou vérifiez que le périphérique est bien connecté.", "backups-error.not-enough-space": "Pas assez d'espace disponible sur le périphérique de sauvegarde.", "backups-error.not-found": "La sauvegarde ou l'emplacement de sauvegarde est introuvable.", "backups-error.repository-exists": "Un emplacement de sauvegarde existe déjà dans ce dossier.", "backups-error.repository-not-found": "L'emplacement de sauvegarde est introuvable.", "backups-exclusions.add": "Ajouter", "backups-exclusions.app-paths-cannot-be-modified": "Ces fichiers/dossiers sont définis par le développeur de l'application et ne peuvent pas être modifiés :", "backups-exclusions.app-paths-explanation": "Cette application exclut les données suivantes des sauvegardes. Ces chemins contiennent généralement des éléments non essentiels (comme des caches ou des logs recréables) ou des données qui pourraient poser problème si elles sont restaurées (par exemple des états d'application obsolètes pouvant entraîner des conflits ou des incohérences).", "backups-exclusions.auto-excluded": "Exclu automatiquement", "backups-exclusions.exclude-entire-app": "Exclure l'application entière", "backups-exclusions.excluded-apps": "Applications exclues", "backups-exclusions.files-and-folders": "Fichiers et dossiers exclus", "backups-exclusions.no-excluded-apps": "Aucune application exclue", "backups-exclusions.no-excluded-files-or-folders": "Aucun fichier ou dossier exclu", "backups-exclusions.select-item-to-exclude": "Sélectionnez l'élément à exclure", "backups-exclusions.stop-excluding": "Ne plus exclure", "backups-floating-island.backing-up": "Sauvegarde en cours...", "backups-floating-island.backing-up-to": "Sauvegarde de votre Umbrel...", "backups-restore": "Restaurer", "backups-restore-full": "Restauration complète", "backups-restore-full-description": "Restaurer l'intégralité de votre Umbrel depuis une sauvegarde", "backups-restore-header": "Restaurer votre Umbrel", "backups-restore-pro.after-restore": "Après la restauration, votre compte temporaire sera remplacé par votre compte sauvegardé et ses données.", "backups-restore-pro.step1": "Terminez la configuration en cliquant sur « Commencer » ci-dessous. Ce compte sera temporaire jusqu'à ce que vous restauriez votre compte sauvegardé.", "backups-restore-pro.step2": "Une fois la configuration terminée, allez dans <0>Paramètres → Sauvegardes → Restaurer", "backups-restore-pro.step3": "Suivez les instructions de l'assistant de restauration.", "backups-restore-pro.subtitle": "La restauration d'une sauvegarde sur Umbrel Pro demande quelques étapes supplémentaires", "backups-restore.backup-date": "Date de la sauvegarde", "backups-restore.backup-location": "Emplacement de sauvegarde", "backups-restore.browse-cloud-subtitle": "Restaurer depuis Umbrel Private Cloud (bientôt disponible)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Restaurer depuis un disque USB externe", "backups-restore.browse-external-title": "Disque dur externe", "backups-restore.browse-nas-or-external": "Parcourez un autre Umbrel, un NAS ou un disque externe pour restaurer une sauvegarde", "backups-restore.browse-nas-subtitle": "Restaurer depuis un autre appareil Umbrel ou NAS sur votre réseau", "backups-restore.browse-nas-title": "Un autre Umbrel ou NAS", "backups-restore.choose": "Choisir", "backups-restore.choose-backup-location": "Choisissez un emplacement de sauvegarde", "backups-restore.connect-to-backup-location": "Se connecter à un emplacement de sauvegarde", "backups-restore.encryption-password": "Mot de passe de chiffrement", "backups-restore.encryption-password-description": "Saisissez le mot de passe de chiffrement que vous avez défini lorsque vous avez activé les sauvegardes", "backups-restore.enter-password-to-confirm": "Entrez votre mot de passe Umbrel pour confirmer", "backups-restore.final-confirmation": "Êtes-vous sûr ?", "backups-restore.final-confirmation-description": "Restaurer à partir de cette sauvegarde remplacera vos applications et données umbrelOS actuelles par le contenu de la sauvegarde sélectionnée. Tous les fichiers, dossiers ou applications exclus de cette sauvegarde seront supprimés de votre Umbrel. Cette action est irréversible.", "backups-restore.invalid-password": "Mot de passe invalide", "backups-restore.last-backup": "Dernière sauvegarde : {{date}}", "backups-restore.latest": "Dernière", "backups-restore.no-backups-found": "Aucune sauvegarde trouvée", "backups-restore.no-backups-yet": "Pas encore de sauvegardes", "backups-restore.please-select-backup": "Veuillez sélectionner une sauvegarde", "backups-restore.please-select-repository": "Veuillez sélectionner un dépôt", "backups-restore.restore-from-nas-or-external": "Restaurer votre Umbrel à partir d'une sauvegarde sur un autre Umbrel, un NAS ou un disque externe", "backups-restore.restore-from-unlisted": "Restaurer depuis un autre emplacement", "backups-restore.restore-umbrel": "Restaurer Umbrel", "backups-restore.restore-warning": "Restaurer à partir de cette sauvegarde remplacera vos applications et données umbrelOS actuelles par le contenu de la sauvegarde sélectionnée. Tous les fichiers, dossiers ou applications exclus de cette sauvegarde seront supprimés de votre Umbrel. Ouvrez <0>Rewind si vous souhaitez restaurer des fichiers ou dossiers spécifiques à la place.", "backups-restore.restoring-from": "Vous êtes sur le point de restaurer la sauvegarde suivante :", "backups-restore.review-description": "La restauration configurera votre Umbrel avec le compte, les fichiers, les applications et les paramètres présents au moment de cette sauvegarde. Cela peut prendre un peu de temps. Une fois terminée, votre mot de passe de connexion sera celui que vous aviez utilisé lors de la création de la sauvegarde.", "backups-restore.select-backup": "Sélectionnez une sauvegarde", "backups-restore.select-backup-description": "Sélectionnez la sauvegarde à partir de laquelle vous souhaitez restaurer", "backups-restore.select-backup-file": "Sélectionnez votre fichier de sauvegarde", "backups-restore.select-backup-file-only": "Seul {{backupFileName}} peut être sélectionné", "backups-restore.total-size": "Taille totale", "backups-restore.unknown-date": "Date inconnue", "backups-restore.unknown-repository": "Dépôt inconnu", "backups-rewind": "Rewind", "backups-rewind-description": "Remontez dans le temps pour restaurer certains fichiers et dossiers.", "backups-rewind.start": "Démarrer Rewind", "backups-setup": "Configurer", "backups-setup-confirm": "Terminer la configuration", "backups-setup-external-description": "Sauvegarder sur un disque USB externe", "backups-setup-nas-or-umbrel-description": "Sauvegarder sur un autre Umbrel ou un périphérique NAS sur votre réseau", "backups-setup-umbrel-or-nas": "Un autre Umbrel ou NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Prolongez votre tranquillité d'esprit au-delà de votre domicile avec des sauvegardes chiffrées de bout en bout vers Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Obtenir l'accès anticipé", "backups-setup-umbrel-private-cloud-description": "Sauvegardes chiffrées de bout en bout vers Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Bientôt disponible", "backups.add-umbrel-or-nas": "Ajouter Umbrel ou NAS", "backups.all-apps-and-data-will-be-backed-up": "Toutes les applications et données seront sauvegardées", "backups.apps-and-data": "Applications & données", "backups.backup-location": "Emplacement de sauvegarde", "backups.browse": "Parcourir", "backups.choose-folder-within-device": "Choisissez un dossier dans {{device}} pour enregistrer vos sauvegardes", "backups.confirm-password": "Confirmer le mot de passe", "backups.copy": "Copier", "backups.encryption": "Chiffrement", "backups.encryption-password-warning": "Assurez-vous de conserver votre mot de passe de chiffrement en lieu sûr, par exemple dans un gestionnaire de mots de passe. Vous ne pourrez plus le voir ensuite, et vous en aurez besoin pour restaurer vos sauvegardes.", "backups.exclude-from-backups": "Exclure des sauvegardes", "backups.exclude-from-backups-description": "Exclure des fichiers, dossiers et applications spécifiques de vos sauvegardes.", "backups.hide": "Masquer", "backups.i-understand": "J'ai compris", "backups.location": "Emplacement", "backups.modals.already-in-use.description": "Cet emplacement de sauvegarde est déjà utilisé pour les sauvegardes de cet Umbrel.", "backups.modals.already-in-use.manage": "Gérer dans Backups", "backups.modals.already-in-use.title": "Emplacement de sauvegarde déjà utilisé", "backups.modals.connect-existing.description": "Une sauvegarde Umbrel existe déjà à cet emplacement. Saisissez son mot de passe de chiffrement pour l'ajouter à cet Umbrel.", "backups.modals.connect-existing.title": "Connecter une sauvegarde Umbrel existante", "backups.no-external-drives-detected": "Aucun disque externe détecté", "backups.no-password-set": "Aucun mot de passe défini", "backups.password-is-set": "Mot de passe défini", "backups.password-minimum-length": "Le mot de passe doit contenir au moins 8 caractères", "backups.password-safety-warning": "Vos sauvegardes seront chiffrées avec ce mot de passe. Gardez-le en sécurité, car vous ne pourrez plus le voir ensuite, et vous en aurez besoin pour restaurer vos sauvegardes.", "backups.passwords-do-not-match": "Les mots de passe ne correspondent pas", "backups.please-choose-folder": "Veuillez choisir un dossier", "backups.restore-failed.message": "Une erreur est survenue lors de la restauration de votre Umbrel. Vos applications et données actuelles n'ont pas été modifiées.", "backups.restore-failed.retry": "Aller à la restauration", "backups.restore-failed.title": "Échec de la restauration", "backups.restoring": "Restauration de votre Umbrel", "backups.restoring-completing": "Finalisation en cours. Votre Umbrel redémarrera sous peu...", "backups.restoring-progress": "Restauré {{percent}}%", "backups.restoring-time-remaining": "Il reste {{time}}", "backups.restoring-warning": "Ne coupez pas l'alimentation de votre Umbrel et ne déconnectez pas l'emplacement de sauvegarde pendant la restauration", "backups.review": "Vérifier et confirmer", "backups.review-description": "Vérifiez les détails de votre sauvegarde et confirmez votre sélection", "backups.scanning-for-external-drives": "Recherche de disques externes...", "backups.schedule-description": "umbrelOS sauvegarde automatiquement vos données toutes les heures. Il conserve des sauvegardes horaires chiffrées pour les dernières 24 heures, des sauvegardes quotidiennes pour la semaine passée, des sauvegardes hebdomadaires pour le mois passé et des sauvegardes mensuelles pour l'année passée. Les sauvegardes de plus d'un an sont supprimées automatiquement.", "backups.select-backup-folder": "Sélectionner le dossier de sauvegarde", "backups.select-backup-folder-description": "Choisissez un dossier où vous souhaitez stocker vos sauvegardes.", "backups.select-backup-location": "Sélectionner un emplacement de sauvegarde", "backups.set-encryption-password": "Définir le mot de passe de chiffrement", "backups.set-encryption-password-description": "Protégez vos sauvegardes par mot de passe. Cela garantit que vos données restent privées et ne peuvent être restaurées qu'avec ce mot de passe.", "backups.show": "Afficher", "backups.storage-capacity-warning": "{{device}} doit disposer d'un espace libre au moins égal au double de la taille de votre sauvegarde", "backups.store-encryption-password-safely": "Conservez votre mot de passe de chiffrement en lieu sûr", "beta-program": "Programme bêta d'umbrelOS", "beta-program-description": "Optez pour recevoir des mises à jour bêta d'umbrelOS, accédez en avant-première à de nouvelles fonctionnalités et aidez-nous à les peaufiner en fournissant vos retours. Les mises à jour bêta peuvent être instables, et le dépannage peut nécessiter une familiarité avec le terminal.", "cancel": "Annuler", "change": "Changer", "change-name": "Changer de nom", "change-name.failed.name-required": "Le nom est requis", "change-name.input-placeholder": "Votre nom", "change-password": "Changer le mot de passe", "change-password.callout": "Si vous perdez votre mot de passe, vous ne pourrez pas vous connecter à votre Umbrel. Assurez-vous de le sécuriser soigneusement.", "change-password.current-password": "Mot de passe actuel", "change-password.failed.current-required": "Le mot de passe actuel est requis", "change-password.failed.min-length": "Le mot de passe doit comporter au moins {{characters}} caractères", "change-password.failed.must-be-unique": "Le nouveau mot de passe doit être différent du mot de passe actuel", "change-password.failed.new-required": "Un nouveau mot de passe est requis", "change-password.failed.no-match": "Les mots de passe ne correspondent pas", "change-password.failed.repeat-required": "Répétition du mot de passe requise", "change-password.new-password": "Nouveau mot de passe", "change-password.repeat-password": "Répéter le mot de passe", "check-for-latest-version": "Vérifier la dernière mise à jour d'umbrelOS", "clipboard.copied": "Copié", "close": "Fermer", "cmdk.change-wallpaper": "Changer de fond d'écran", "cmdk.frequent-apps": "Fréquemment utilisé", "cmdk.input-placeholder": "Rechercher des applications, paramètres ou actions", "cmdk.live-usage": "Utilisation en direct", "cmdk.restart-umbrel": "Redémarrer Umbrel", "cmdk.shutdown-umbrel": "Éteindre Umbrel", "cmdk.update-all-apps": "Mettre à jour toutes les applications", "cmdk.widgets": "Widgets", "community-app-store": "App Store Communautaire", "community-app-store.add-error": "Impossible d'ajouter l'App Store : {{message}}", "community-app-store.back-to-umbrel-app-store": "Retour à l'App Store Umbrel", "community-app-store.open-button": "Ouvrir", "community-app-store.remove-button": "Retirer", "community-app-store.remove-error": "Impossible de supprimer l'App Store : {{message}}", "community-app-stores.add-button": "Ajouter", "community-app-stores.description": "Les App Stores Communautaires vous permettent d'installer des applications sur votre Umbrel qui peuvent ne pas être disponibles dans l'App Store officiel d'Umbrel. Ils facilitent également le test des versions bêta des applications Umbrel avant que les développeurs les publient sur l'App Store officiel d'Umbrel.", "community-app-stores.learn-more": "En savoir plus", "community-app-stores.warning": "Les App Stores Communautaires peuvent être créés par n'importe qui. Les applications publiées ne sont pas vérifiées ni approuvées par l'équipe de l'App Store officiel d'Umbrel et peuvent potentiellement être non sécurisées ou malveillantes. Soyez prudent et ajoutez uniquement des app stores de développeurs en qui vous avez confiance.", "confirm": "Confirmer", "connect": "Connecter", "connecting": "Connexion...", "connection-lost": "Connexion perdue", "connection-lost-description": "Cela peut arriver lorsque l'onglet de votre navigateur est resté inactif, que votre connexion réseau a été interrompue ou que votre appareil est hors ligne.", "continue": "Continuer", "continue-to-log-in": "Continuer pour se connecter", "cpu": "CPU", "cpu-core-count": "{{cores}} threads", "default-credentials.close": "Compris", "default-credentials.description": "Voici les identifiants dont vous aurez besoin pour vous connecter à l'application.", "default-credentials.dont-show-again": "Ne plus afficher", "default-credentials.dont-show-again-notice": "Vous pouvez accéder à ces identifiants à tout moment dans le futur en cliquant avec le bouton droit sur l'icône de l'application.", "default-credentials.open": "Ouvrir {{app}}", "default-credentials.password": "Mot de passe par défaut", "default-credentials.title": "Identifiants pour {{app}}", "default-credentials.username": "Nom d'utilisateur par défaut", "desktop.app.context.go-to-store-page": "Voir dans l'App Store", "desktop.app.context.settings": "Réglages", "desktop.app.context.show-default-credentials": "Afficher les identifiants par défaut", "desktop.app.context.uninstall": "Désinstaller", "desktop.context-menu.change-wallpaper": "Changer de fond d'écran", "desktop.context-menu.edit-widgets": "Modifier les widgets", "desktop.context-menu.logout": "Se déconnecter", "desktop.greeting.afternoon": "Bon après-midi, {{name}}", "desktop.greeting.evening": "Bonsoir, {{name}}", "desktop.greeting.morning": "Bonjour, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Pour Viber", "desktop.install-first.for-the-bitcoiner": "Pour le Bitcoiner", "desktop.install-first.for-the-self-hoster": "Pour l'auto-hébergement", "desktop.install-first.for-the-streamer": "Pour le streamer", "desktop.install-first.link-to-app-store": "Explorer plus dans l'App Store", "desktop.not-enough-room": "Utilisez un écran plus grand pour voir vos applications.", "device": "Appareil", "device-info": "Infos sur l'appareil", "device-info-description": "Informations sur votre appareil", "device-info.device": "Appareil", "device-info.model-number": "Numéro de modèle", "device-info.serial-number": "Numéro de série", "device-info.view-info": "Voir les informations", "device-name.home-or-pro": "Umbrel Home ou Umbrel Pro", "disable": "Désactiver", "done": "Terminé", "download-logs": "Télécharger les journaux", "enabling-tor": "Activation de l'accès Tor à distance", "external-dns": "DNS Cloudflare", "external-dns-description": "Le DNS Cloudflare offre une meilleure fiabilité du réseau. Désactivez pour utiliser les paramètres DNS de votre routeur.", "external-dns-error": "Impossible de mettre à jour le paramètre DNS : {{message}}", "external-drive": "Disque externe", "factory-reset": "Réinitialisation d'usine", "factory-reset-description": "Effacez toutes vos données et applications, et rétablissez umbrelOS aux paramètres par défaut", "factory-reset-failed": "Impossible de réinitialiser votre appareil : {{message}}", "factory-reset.confirm.body": "Confirmez votre mot de passe pour réinitialiser", "factory-reset.confirm.ethernet-required-warning": "Assurez-vous que votre appareil est connecté à votre routeur via un câble Ethernet (pas en Wi-Fi) et que vous y accédez depuis votre réseau local (par exemple, http://umbrel.local ou l'adresse IP locale de votre appareil).", "factory-reset.confirm.submit": "Effacer tout et réinitialiser", "factory-reset.confirm.submit-callout": "Cette action est irréversible.", "factory-reset.rebooting.message": "Votre appareil va redémarrer et toutes les données seront effacées. Ne fermez pas cette page.", "factory-reset.rebooting.status": "Réinitialisation...", "factory-reset.rebooting.title": "Réinitialisation d'usine en cours", "factory-reset.review.account-info": "Infos du compte et mot de passe", "factory-reset.review.apps": "Applications", "factory-reset.review.following-will-be-removed": "Les éléments suivants seront supprimés de votre appareil", "factory-reset.review.installed-apps_one": "{{count}} application installée", "factory-reset.review.installed-apps_other": "{{count}} applications installées", "factory-reset.review.submit": "Continuer", "factory-reset.review.total-data": "Données totales", "files": "Files", "files-action.add-favorite": "Ajouter aux favoris", "files-action.add-network-device": "Ajouter un appareil", "files-action.cancel-upload": "Annuler l’envoi", "files-action.compress": "Compresser", "files-action.copy": "Copier", "files-action.cut": "Couper", "files-action.delete": "Supprimer définitivement", "files-action.download": "Télécharger", "files-action.download-items": "Télécharger {{count}} éléments", "files-action.drop-to-upload": "Déposez pour importer", "files-action.eject-disk": "Éjecter", "files-action.empty-trash": "Vider la corbeille", "files-action.format-drive": "Formater", "files-action.go-to-path": "Aller à...", "files-action.new-folder": "Nouveau dossier", "files-action.open": "Ouvrir", "files-action.paste": "Coller", "files-action.remove-favorite": "Retirer des favoris", "files-action.remove-network-host": "Éjecter le lecteur réseau", "files-action.remove-network-share": "Éjecter le partage réseau", "files-action.rename": "Renommer", "files-action.restore": "Restaurer", "files-action.select": "Sélectionner", "files-action.share": "Partager sur le réseau…", "files-action.sharing": "Partage en cours…", "files-action.show-in-folder": "Afficher dans le dossier parent", "files-action.trash": "Corbeille", "files-action.uncompress": "Décompresser", "files-action.upload": "Importer", "files-add-network-share.add-manually": "Ajouter manuellement", "files-add-network-share.add-share": "Ajouter le partage", "files-add-network-share.back": "Retour", "files-add-network-share.continue": "Continuer", "files-add-network-share.description": "Connecte-toi à un NAS ou à un autre lecteur partagé sur ton réseau pour y accéder depuis Fichiers.", "files-add-network-share.discovering": "Recherche en cours...", "files-add-network-share.enter-details-manually": "Entrez les détails du serveur", "files-add-network-share.host-label": "Adresse du serveur", "files-add-network-share.host-required": "L'adresse du serveur est requise", "files-add-network-share.manual-share-help": "Entrez le nom exact du partage tel qu'il apparaît sur votre serveur", "files-add-network-share.no-shares-found": "Aucun partage trouvé sur ce serveur", "files-add-network-share.not-seeing-share": "Vous ne voyez pas votre partage ?", "files-add-network-share.password-label": "Mot de passe", "files-add-network-share.password-required": "Le mot de passe est requis", "files-add-network-share.retrieving-shares": "Récupération des partages…", "files-add-network-share.retry-discovery": "Analyser le réseau à nouveau", "files-add-network-share.select-share": "Sélectionne un partage à ajouter", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Le partage est requis", "files-add-network-share.title": "Ajouter un partage réseau", "files-add-network-share.username-label": "Nom d'utilisateur", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Le nom d'utilisateur est requis", "files-audio-island.now-playing": "Lecture en cours", "files-audio-island.pause": "Pause", "files-audio-island.play": "Lire", "files-backend-error.base-directory-not-found": "Impossible de trouver le répertoire de base", "files-backend-error.cant-find-root": "Impossible de vérifier le chemin du fichier", "files-backend-error.destination-already-exists": "Un élément portant le même nom existe déjà à la destination", "files-backend-error.destination-not-exist": "Le dossier de destination n'existe pas", "files-backend-error.does-not-exist": "Le fichier ou le dossier n'existe pas", "files-backend-error.escapes-base": "Le chemin est en dehors du répertoire autorisé", "files-backend-error.invalid-base": "Le chemin ne correspond pas à un répertoire valide", "files-backend-error.invalid-filename": "Le nom de fichier n'est pas valide", "files-backend-error.invalid-path": "Le chemin du fichier n'est pas valide", "files-backend-error.mkdir-failed": "Impossible de créer le dossier", "files-backend-error.move-failed": "Impossible de déplacer l'élément", "files-backend-error.not-enough-space": "Espace de stockage insuffisant", "files-backend-error.operation-not-allowed": "Cette opération n'est pas autorisée", "files-backend-error.parent-not-directory": "Le chemin parent n'est pas un dossier", "files-backend-error.parent-not-exist": "Le dossier parent n'existe pas", "files-backend-error.path-not-absolute": "Le chemin du fichier n'est pas valide", "files-backend-error.share-already-exists": "Ce dossier est déjà partagé", "files-backend-error.share-name-generation-failed": "Impossible de générer un nom de partage unique", "files-backend-error.source-not-exists": "Le fichier ou dossier source n'existe pas", "files-backend-error.subdir-of-self": "Un dossier ne peut pas être déplacé ou copié dans lui-même", "files-backend-error.trash-meta-not-exists": "Impossible de trouver l'emplacement d'origine de cet élément", "files-backend-error.unique-name-index-exceeded": "Impossible de générer un nom unique : trop d'éléments ont des noms similaires", "files-backend-error.upload-failed": "Échec du téléversement", "files-collision.action.keep-both": "Conserver les deux", "files-collision.action.replace": "Remplacer", "files-collision.action.skip": "Ignorer", "files-collision.destination.original-location": "son emplacement d’origine", "files-collision.message": "Voulez-vous remplacer l’élément existant ou conserver les deux ?", "files-collision.title": "\"{{itemName}}\" existe déjà dans {{destinationName}}", "files-download.confirm": "Télécharger", "files-download.description": "Files ne peut pas ouvrir ce type de fichier. Voulez-vous plutôt le télécharger ?", "files-download.title": "Télécharger {{name}} ?", "files-empty-trash.confirm": "Vider", "files-empty-trash.description": "Êtes-vous sûr de vouloir supprimer définitivement tous les éléments de la corbeille ? Vous ne pourrez pas annuler cette action.", "files-empty-trash.title": "Vider la corbeille ?", "files-empty.directory": "Aucun élément dans ce dossier", "files-empty.network": "Aucun périphérique réseau", "files-empty.network-host-offline": "Appareil réseau hors ligne", "files-error.add-favorite": "Impossible d'ajouter aux favoris : {{message}}", "files-error.add-share": "Impossible de partager le dossier : {{message}}", "files-error.compress": "Impossible de compresser : {{message}}", "files-error.copy": "Impossible de copier : {{message}}", "files-error.create-folder": "Impossible de créer le dossier : {{message}}", "files-error.delete": "Impossible de supprimer : {{message}}", "files-error.eject-disk": "Impossible d'éjecter le lecteur : {{message}}", "files-error.empty-trash": "Impossible de vider la corbeille : {{message}}", "files-error.extract": "Impossible d'extraire : {{message}}", "files-error.folder-already-exists": "Un dossier portant ce nom existe déjà", "files-error.move": "Impossible de déplacer : {{message}}", "files-error.remove-favorite": "Impossible de retirer des favoris : {{message}}", "files-error.remove-share": "Impossible de supprimer le dossier partagé : {{message}}", "files-error.rename": "Impossible de renommer : {{message}}", "files-error.restore": "Impossible de restaurer : {{message}}", "files-error.trash": "Impossible de déplacer vers la corbeille : {{message}}", "files-error.upload": "Échec du téléversement : {{message}}", "files-error.upload-network-error": "Échec du téléversement de {{name}} : une erreur réseau est survenue", "files-extension-change.confirm": "Continuer", "files-extension-change.description-add": "Êtes-vous sûr de vouloir changer l’extension de « {{fileName}} » en « {{extension}} » ? Cela pourrait rendre le fichier illisible.", "files-extension-change.description-remove": "Êtes-vous sûr de vouloir supprimer l’extension de « {{fileName}} » ?", "files-extension-change.title-add": "Changer l’extension en « {{extension}} » ?", "files-extension-change.title-remove": "Supprimer l’extension ?", "files-external-storage.unsupported.description": "Le disque externe branché ne peut pas être utilisé sur un Raspberry Pi à cause de problèmes d'alimentation. Le stockage externe est disponible sur Umbrel Home, Umbrel Pro et tous les appareils x86 (Intel ou AMD).", "files-external-storage.unsupported.description-general": "Le stockage externe n'est pas disponible sur Raspberry Pi à cause de problèmes d'alimentation. Le stockage externe est disponible sur Umbrel Home, Umbrel Pro et tous les appareils x86 (Intel ou AMD).", "files-external-storage.unsupported.title": "Stockage externe non pris en charge", "files-folder": "Dossier", "files-format.confirm": "Formater", "files-format.description": "Le formatage effacera toutes les données de {{driveName}}. Cette action est irréversible.", "files-format.description-unreadable": "umbrelOS ne peut pas lire le contenu de {{driveName}}. Vous pouvez le formater pour l'utiliser avec umbrelOS.", "files-format.drive-label": "Nom", "files-format.error": "Impossible de formater le disque", "files-format.exfat-description": "Compatibilité maximale avec Windows, macOS et Linux", "files-format.ext4-description": "Meilleures performances avec umbrelOS et Linux", "files-format.filesystem": "Système de fichiers", "files-format.filesystem-label": "Formater en", "files-format.formatting": "Formatage...", "files-format.title": "Formater le disque", "files-format.title-requires-format": "Format requis", "files-formatting-island.formatting": "Formatage en cours...", "files-formatting-island.formatting-drives": "Formatage de {{count}} lecteurs", "files-listing.empty": "Aucun élément", "files-listing.error": "Une erreur s'est produite", "files-listing.item-count-truncated": "{{formattedCount}}+ éléments", "files-listing.item-count_one": "{{formattedCount}} élément", "files-listing.item-count_other": "{{formattedCount}} éléments", "files-listing.loading": "Chargement...", "files-listing.no-such-file": "Aucun fichier ou dossier de ce nom", "files-listing.selected-count": "{{selectedCount}} sur {{totalCount}} sélectionnés", "files-listing.selected-count-truncated": "{{selectedCount}} sur {{totalCount}}+ sélectionnés", "files-name-drawer.new-folder": "Nouveau dossier", "files-name-drawer.new-folder-description": "Entrez un nom pour le nouveau dossier.", "files-name-drawer.new-folder-input": "Nom du dossier", "files-name-drawer.rename-file": "Renommer le fichier", "files-name-drawer.rename-file-description": "Entrez un nouveau nom pour ce fichier.", "files-name-drawer.rename-file-input": "Nom du fichier", "files-name-drawer.rename-folder": "Renommer le dossier", "files-name-drawer.rename-folder-description": "Entrez un nouveau nom pour ce dossier.", "files-name-drawer.rename-folder-input": "Nom du dossier", "files-network-storage-error.add-share": "Impossible d'ajouter un partage réseau : {{message}}", "files-network-storage-error.discover-servers": "Échec de la découverte des appareils réseau : {{message}}", "files-network-storage-error.discover-shares": "Échec de la découverte des partages réseau : {{message}}", "files-network-storage-error.remove-share": "Impossible de supprimer le partage réseau : {{message}}", "files-operations-island.copying": "Copie de \"{{from}}\" vers \"{{to}}\"", "files-operations-island.moving": "Déplacement de \"{{from}}\" vers \"{{to}}\"", "files-operations-island.restoring": "Restauration de \"{{from}}\" vers \"{{to}}\"", "files-path.input-group": "Saisie du chemin", "files-path.input-label": "Chemin actuel", "files-permanently-delete.confirm": "Supprimer définitivement", "files-permanently-delete.description-multiple": "Êtes-vous sûr de vouloir supprimer définitivement ces {{count}} éléments ? Vous ne pourrez pas annuler cette action.", "files-permanently-delete.description-single": "Êtes-vous sûr de vouloir supprimer définitivement « {{fileName}} » ? Vous ne pourrez pas annuler cette action.", "files-permanently-delete.title-multiple": "Supprimer définitivement {{count}} éléments ?", "files-permanently-delete.title-single": "Supprimer définitivement ?", "files-search.default": "Rechercher des fichiers et des dossiers", "files-search.no-results": "Aucun résultat trouvé pour \"{{query}}\"", "files-search.placeholder": "Rechercher", "files-search.searching-label": "Recherche de l'Umbrel de {{name}}", "files-share.home-description": "Accédez à tous les fichiers de « {{homeDirectoryName}} » depuis d’autres appareils sur votre réseau", "files-share.home-title": "Partager « {{homeDirectoryName}} » sur le réseau", "files-share.instructions.how-to-access": "Comment y accéder", "files-share.instructions.ios.enter-password": "Saisissez {{password}} comme mot de passe.", "files-share.instructions.ios.enter-server": "Saisissez {{smbUrl}} comme adresse du serveur.", "files-share.instructions.ios.enter-username": "Saisissez {{username}} comme nom d’utilisateur.", "files-share.instructions.ios.install-files": "Installez l’app « Files » depuis l’App Store si elle n’est pas déjà installée.", "files-share.instructions.ios.tap-connect": "Touchez « Connect » pour y accéder.", "files-share.instructions.ios.tap-dots": "Touchez les trois points (...) en haut à droite et sélectionnez « Connect to Server ».", "files-share.instructions.macos.click-connect": "Cliquez sur « Se connecter » pour y accéder.", "files-share.instructions.macos.enter-password": "Saisissez {{password}} comme mot de passe.", "files-share.instructions.macos.enter-url": "Saisissez {{smbUrl}} et cliquez sur « Connecter ».", "files-share.instructions.macos.enter-username": "Saisissez {{username}} comme nom d’utilisateur.", "files-share.instructions.macos.open-finder": "Ouvrez « Finder », puis appuyez sur ⌘ + K.", "files-share.instructions.macos.select-registered": "Sélectionnez « Utilisateur enregistré » lorsqu’on vous le demande.", "files-share.instructions.macos.time-machine": "Comment l'utiliser comme emplacement de sauvegarde pour Time Machine", "files-share.instructions.macos.time-machine.choose-encryption": "Choisissez entre des sauvegardes chiffrées ou non chiffrées.", "files-share.instructions.macos.time-machine.disk-limit": "Pour « Disk Usage Limit », définissez l’espace maximal à allouer sur votre Umbrel pour les sauvegardes Time Machine, puis cliquez sur « Done ».", "files-share.instructions.macos.time-machine.follow-steps": "Suivez les étapes ci-dessus puis ouvrez Réglages Système sur votre Mac.", "files-share.instructions.macos.time-machine.go-settings": "Accédez à Time Machine, puis cliquez sur « Add Backup Disk... ».", "files-share.instructions.macos.time-machine.select-disk": "Sélectionnez le dossier et cliquez sur \"Configurer le disque...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Suivez les étapes guidées pour configurer votre sauvegarde.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Suivez les étapes ci‑dessus, puis allez dans \"{{settings}}\" > \"{{backups}}\" sur votre autre Umbrel.", "files-share.instructions.umbrelos.backup.select-add": "Sélectionnez l'option \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Sélectionnez cet appareil Umbrel dans la liste des appareils connectés.", "files-share.instructions.umbrelos.backup.title": "Comment l'utiliser comme emplacement de sauvegarde pour votre autre Umbrel", "files-share.instructions.umbrelos.cant-find-note": "Vous ne le trouvez pas ? Essayez de sélectionner \"Ajouter manuellement\" et utilisez les identifiants suivants. Si vous n'arrivez toujours pas à l'ajouter, vérifiez que vos deux appareils sont sur le même réseau.", "files-share.instructions.umbrelos.enter-password": "Saisissez {{password}} comme mot de passe.", "files-share.instructions.umbrelos.enter-username": "Saisissez {{username}} comme nom d'utilisateur.", "files-share.instructions.umbrelos.open-and-click": "Sur votre autre Umbrel, ouvrez \"Files\" et cliquez sur à côté de \" {{deviceLabel}}\" dans la barre latérale.", "files-share.instructions.umbrelos.select-device": "Sélectionnez cet appareil Umbrel dans la liste des appareils détectés automatiquement sur votre réseau.", "files-share.instructions.umbrelos.select-sharename": "Sélectionnez \"{{sharename}}\" et cliquez pour ajouter le partage.", "files-share.instructions.windows.enter-password": "Saisissez {{password}} comme mot de passe.", "files-share.instructions.windows.enter-url": "Tapez {{smbUrl}} et appuyez sur Entrée.", "files-share.instructions.windows.enter-username": "Saisissez {{username}} comme nom d’utilisateur.", "files-share.instructions.windows.open-run": "Appuyez sur Windows + R pour ouvrir la boîte de dialogue « Exécuter ».", "files-share.instructions.windows.remember-credentials": "Cochez « Remember my credentials » puis cliquez sur OK.", "files-share.regular-description": "Partagez ce dossier pour y accéder depuis d’autres appareils sur votre réseau", "files-share.regular-title": "Partager ce dossier sur le réseau", "files-share.toggle": "Partager « {{name}} » sur votre réseau", "files-sidebar.apps": "Applications", "files-sidebar.external-storage": "Stockage externe", "files-sidebar.favorites": "Favoris", "files-sidebar.home": "Accueil", "files-sidebar.navigation": "Navigation des fichiers", "files-sidebar.network": "Réseau", "files-sidebar.network-pathbar": "Périphériques réseau", "files-sidebar.network-sidebar": "Périphériques", "files-sidebar.recents": "Récents", "files-sidebar.shared-folders": "Dossiers partagés", "files-sidebar.trash": "Corbeille", "files-sidebar.trash.open": "Ouvrir", "files-sort.created": "Ajouté", "files-sort.modified": "Modifié", "files-sort.name": "Nom", "files-sort.size": "Taille", "files-sort.type": "Type", "files-state.uploading": "Téléversement...", "files-state.waiting": "En attente...", "files-type.3gp": "Vidéo 3GP", "files-type.3gp2": "Vidéo 3GP2", "files-type.7z": "Archive 7Z", "files-type.aac": "Audio AAC", "files-type.ai": "Fichier Illustrator", "files-type.aiff": "Audio AIFF", "files-type.au": "Audio AU", "files-type.avi": "Vidéo AVI", "files-type.avif": "Image AVIF", "files-type.bmp": "Image BMP", "files-type.bzip2": "Archive BZIP2", "files-type.caf": "Audio CAF", "files-type.compressed": "Archive compressée", "files-type.csv": "Fichier CSV", "files-type.directory": "Dossier", "files-type.dmg": "Image disque", "files-type.dv": "Vidéo DV", "files-type.epub": "Livre numérique EPUB", "files-type.excel": "Feuille de calcul Excel", "files-type.exe": "Exécutable Windows", "files-type.executable": "Exécutable", "files-type.external-drive": "Disque", "files-type.flac": "Audio FLAC", "files-type.flv": "Vidéo FLV", "files-type.gif": "Image GIF", "files-type.gzip": "Archive GZIP", "files-type.heic": "Image HEIC", "files-type.ico": "Image ICO", "files-type.iso": "Image ISO", "files-type.jpeg": "Image JPEG", "files-type.keynote": "Présentation Keynote", "files-type.lzip": "Archive LZIP", "files-type.lzma": "Archive LZMA", "files-type.lzop": "Archive LZOP", "files-type.m3u": "Liste de lecture M3U", "files-type.m4a": "Audio M4A", "files-type.m4v": "Vidéo M4V", "files-type.midi": "Audio MIDI", "files-type.mka": "Audio MKA", "files-type.mkv": "Vidéo MKV", "files-type.mng": "Vidéo MNG", "files-type.mobi": "Livre numérique MOBI", "files-type.mp3": "Audio MP3", "files-type.mp4": "Vidéo MP4", "files-type.mp4-audio": "Audio MP4", "files-type.mpeg": "Vidéo MPEG", "files-type.mpeg-ts": "Flux de transport MPEG", "files-type.network-drive": "Lecteur réseau", "files-type.numbers": "Feuille de calcul Numbers", "files-type.ogg": "Audio OGG", "files-type.ogv": "Vidéo OGV", "files-type.pages": "Document Pages", "files-type.pdf": "Document PDF", "files-type.png": "Image PNG", "files-type.powerpoint": "Présentation PowerPoint", "files-type.psd": "Document Photoshop", "files-type.quicktime": "Vidéo QuickTime", "files-type.rar": "Archive RAR", "files-type.sgi": "Vidéo SGI", "files-type.svg": "Image SVG", "files-type.tar": "Archive TAR", "files-type.tiff": "Image TIFF", "files-type.ts": "Vidéo TS", "files-type.txt": "Fichier texte", "files-type.umbrel-backup": "Sauvegarde Umbrel", "files-type.wav": "Audio WAV", "files-type.webm": "Vidéo WebM", "files-type.webm-audio": "Audio WebM", "files-type.webp": "Image WebP", "files-type.wma": "Audio WMA", "files-type.wmv": "Vidéo WMV", "files-type.word": "Document Word", "files-type.xz": "Archive XZ", "files-type.zip": "Archive ZIP", "files-upload-island.uploading-count": "Importation de {{count}} éléments", "files-view.icons": "Icônes", "files-view.list": "Liste", "files-view.sort-by": "Trier par", "files-view.view-as": "Afficher sous forme de", "files-widgets.favorites.no-items-text": "Ajoutez un dossier à vos favoris pour le voir ici", "files-widgets.recents.no-items-text": "Aucun fichier récent", "generic-in": "dans l’", "hide-details": "Masquer les détails", "install-first.install-app": "Installez {{app}}", "install-first.title": "{{app}} nécessite ces applications", "install-your-first-app": "Installez votre première application", "language": "Langue", "language-description": "Votre langue préférée pour umbrelOS", "language.select-description": "Sélectionnez la langue préférée pour umbrelOS", "live-usage": "Utilisation en direct", "loading": "Chargement", "local-ip": "IP locale", "login-2fa.subtitle": "Entrez le code 2FA affiché dans votre application d'authentification", "login-2fa.title": "Authentifiez-vous", "login-with-umbrel.description": "Entrez votre mot de passe Umbrel pour ouvrir {{app}}", "login-with-umbrel.title": "Se connecter avec Umbrel", "login.password-label": "Mot de passe", "login.password.submit": "Se connecter", "login.subtitle": "Entrez votre mot de passe Umbrel pour vous connecter", "login.title": "Bon retour", "logout": "Se déconnecter", "logout-error-generic": "Erreur : Échec de la déconnexion", "logout.confirm.submit": "Se déconnecter", "logout.confirm.title": "Êtes-vous sûr de vouloir vous déconnecter ?", "memory": "Mémoire", "memory.low": "Mémoire faible", "migrate": "Migrer", "migrate.callout": "Ne pas éteindre votre Umbrel jusqu'à ce que la migration soit terminée", "migrate.failed.retry": "Réessayer", "migrate.failed.title": "Échec de la migration", "migrate.success.description": "Toutes vos applications, données d'application et détails de compte ont été migrés vers votre Umbrel Home.", "migrate.success.title": "Migration réussie", "migration-assistant": "Assistant de migration", "migration-assistant-description": "Transférez toutes vos applications et données depuis un Raspberry Pi vers {{deviceName}}", "migration-assistant-unsupported-device-description": "Migration Assistant prend actuellement en charge le transfert de toutes les données et applications d'un Raspberry Pi sous umbrelOS vers Umbrel Home ou Umbrel Pro. Ouvrez Migration Assistant sur votre Umbrel Home ou Umbrel Pro pour commencer.", "migration-assistant.continue-migration.ready.submit": "Commencer la migration", "migration-assistant.failed": "Quelque chose ne va pas...", "migration-assistant.failed.retrying-message": "Nouvelle tentative...", "migration-assistant.mobile.start-button": "Commencer la migration", "migration-assistant.prep.body": "Préparation à la migration", "migration-assistant.prep.button-continue": "Continuer", "migration-assistant.prep.callout": "Les données de votre {{deviceName}}, le cas échéant, seront définitivement supprimées.", "migration-assistant.prep.connect-disk-to-home": "Branchez son disque externe à n'importe quel port USB de votre {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Une fois terminé, cliquez sur '{{button}}' ci-dessous.", "migration-assistant.prep.shut-down-rpi": "Éteignez votre Umbrel Raspberry Pi.", "migration-assistant.ready.description": "Toutes vos données et applications sont prêtes à être migrées vers votre {{deviceName}}", "migration-assistant.ready.hint-header": "Choses à garder à l'esprit", "migration-assistant.ready.hint-keep-pi-off.description": "Cela aide à éviter les problèmes avec des applications telles que Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Gardez votre Raspberry Pi éteint après la mise à jour", "migration-assistant.ready.hint-use-same-password.description": "N'oubliez pas d'utiliser le mot de passe Umbrel de votre Raspberry Pi pour vous connecter à votre {{deviceName}}", "migration-assistant.ready.hint-use-same-password.title": "Utilisez le même mot de passe", "migration-assistant.ready.title": "Tout est prêt pour la migration !", "mini-browser.default-title": "Sélectionner un dossier", "mini-browser.empty-external": "Connectez un disque externe pour qu'il apparaisse ici.", "mini-browser.empty-network": "Ajoutez un Umbrel ou un NAS pour qu'il apparaisse ici.", "mini-browser.load-more": "Charger plus", "mini-browser.load-more-in-folder": "Charger plus dans {{name}}", "mini-browser.loading-more": "Chargement…", "mini-browser.select": "Sélectionner", "mini-browser.select-folder": "Sélectionner un dossier", "name": "Nom", "nas": "NAS", "no-forgot-password-message": "Si vous perdez votre mot de passe, vous ne pourrez pas vous connecter à votre Umbrel. Assurez-vous de le sécuriser soigneusement.", "no-results-found": "Aucun résultat trouvé", "not-found-404": "Code d'erreur : 404", "not-found-404.back": "Retour", "not-found-404.home": "Aller à l'accueil", "notifications.backups-failing-location.description": "Les Backups automatiques vers {{location}} échouent. Vérifiez la connexion et revoyez vos paramètres de Backups.", "notifications.backups-failing.description": "Les backups automatiques échouent. Vérifiez l'emplacement de vos backups et revoyez vos paramètres.", "notifications.backups-failing.go-to-backups": "Aller à Backups", "notifications.backups-failing.title": "Pas de Backups au cours des dernières 24 heures", "notifications.cpu.too-hot": "Température élevée du CPU", "notifications.memory.low": "La mémoire de votre appareil est faible", "notifications.new-version-available": "{{update}} est maintenant disponible à l'installation", "notifications.raid.issue.description": "Problème de stockage détecté. Vérifiez le Gestionnaire de stockage pour plus de détails.", "notifications.raid.issue.title": "Action urgente requise", "notifications.ssd.health.description": "Un ou plusieurs SSD peuvent nécessiter une intervention. Vérifiez le Gestionnaire de stockage pour plus de détails.", "notifications.ssd.health.title": "Alerte : état du SSD", "notifications.storage.full": "Le stockage de votre appareil est plein", "notifications.view": "Voir", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "En cliquant sur 'Suivant', vous acceptez les conditions d'utilisation d'umbrelOS", "onboarding.account-created.youre-all-set-name": "Tout est prêt, {{name}}.", "onboarding.contact-support": "Support", "onboarding.create-account": "Créer un compte", "onboarding.create-account.confirm-password.input-label": "Confirmer le mot de passe", "onboarding.create-account.failed.name-required": "Le nom est requis", "onboarding.create-account.failed.passwords-dont-match": "Les mots de passe ne correspondent pas", "onboarding.create-account.name.input-placeholder": "Votre nom", "onboarding.create-account.password.input-label": "Mot de passe", "onboarding.create-account.submit": "Créer", "onboarding.create-account.submitting": "Création", "onboarding.create-account.subtitle": "Les informations de votre compte sont stockées uniquement sur votre Umbrel. Assurez-vous de sauvegarder votre mot de passe en toute sécurité car il n'y a aucun moyen de le réinitialiser.", "onboarding.create-instead-long": "Créer un nouveau compte", "onboarding.create-instead-short": "Nouveau compte", "onboarding.launch-umbrelos": "Lancer umbrelOS", "onboarding.raid.available-storage": "Stockage disponible", "onboarding.raid.change-drives-link": "Besoin d'ajouter ou de changer des disques ?", "onboarding.raid.configuring.subtitle": "Cela peut prendre quelques minutes.", "onboarding.raid.configuring.title": "Configuration de votre stockage", "onboarding.raid.configuring.warning": "Veuillez ne pas actualiser cette page ni éteindre votre Umbrel pendant la configuration du stockage.", "onboarding.raid.continue": "Continuer", "onboarding.raid.error.detection-instructions": "Éteignez Umbrel Pro, vérifiez que vos SSD sont correctement insérés, puis réessayez.", "onboarding.raid.error.no-ssds-detected": "Aucun SSD détecté", "onboarding.raid.error.no-ssds-instructions": "Éteignez Umbrel Pro et insérez au moins un SSD pour continuer.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Impossible d'activer FailSafe pour le moment", "onboarding.raid.failsafe.enable": "Activer FailSafe", "onboarding.raid.failsafe.mixed-sizes": "FailSafe est limité par votre plus petit SSD ({{smallest}}). L'espace supplémentaire sur les SSD plus grands ne pourra pas être utilisé, laissant {{wasted}} d'espace inutilisable.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} sert à protéger vos données. Ajoutez un autre SSD de {{smallest}} pour augmenter le stockage disponible à {{futureWith3}}, ou ajoutez-en deux de plus pour atteindre {{futureWith4}}. Vous pouvez ajouter d'autres SSD à tout moment.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} sert à protéger vos données. Ajoutez un autre SSD de {{smallest}} pour augmenter le stockage disponible à {{futureWith4}}. Vous pouvez ajouter d'autres SSD à tout moment.", "onboarding.raid.failsafe.single-ssd-info": "Vous n'avez qu'un seul SSD. Ajoutez au moins un autre SSD de {{size}} pour activer la protection FailSafe de vos données. Vous pouvez ajouter d'autres SSD à tout moment.", "onboarding.raid.failsafe.subtitle": "Vos données restent protégées si un seul SSD tombe en panne", "onboarding.raid.failsafe.tip": "Utilisez des SSD de même taille pour un stockage maximal et zéro espace inutilisable.", "onboarding.raid.failsafe.warning-now-only": "Avec plus d'un SSD, FailSafe ne peut être activé que lors de la configuration initiale. Vous ne pourrez pas l'activer plus tard.", "onboarding.raid.health-warning": "Ce disque signale des problèmes de santé", "onboarding.raid.launching": "Lancement...", "onboarding.raid.no-ssds-alt": "Aucun SSD trouvé", "onboarding.raid.recommended": "Recommandé", "onboarding.raid.scanning": "Vérification des emplacements SSD", "onboarding.raid.scanning-alt": "Analyse des SSD", "onboarding.raid.setup-failed.description-no-retry": "Veuillez éteindre l'appareil et réessayer.", "onboarding.raid.setup-failed.description-retry": "Réessayez, ou éteignez l'appareil pour vérifier vos disques.", "onboarding.raid.setup-failed.title": "Échec de la configuration du stockage", "onboarding.raid.shutdown-dialog.description": "Pour ajouter ou remplacer des disques, éteignez Umbrel Pro. Une fois terminé, vous pourrez rallumer et poursuivre la configuration.", "onboarding.raid.shutdown-dialog.title": "Changer les disques ?", "onboarding.raid.ssd-in-slot": "Un SSD {{size}} dans l'emplacement {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "Tiroir SSD", "onboarding.raid.ssds-found": "Les SSD suivants ont été trouvés dans votre Umbrel Pro", "onboarding.raid.storage": "Stockage", "onboarding.raid.storage-label": "Stockage", "onboarding.raid.success.storage-info": "Stockage {{available}}", "onboarding.raid.success.storage-info-failsafe": "Stockage {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Réessayer", "onboarding.raid.wasted": "Inutilisable", "onboarding.restore-long": "Restaurer mon Umbrel", "onboarding.restore-short": "Restaurer", "onboarding.start.continue": "C'est parti", "onboarding.start.subtitle": "Votre serveur cloud domestique est prêt à être configuré.", "onboarding.start.title": "Bienvenue sur umbrelOS", "open": "Ouvrir", "open-live-usage": "Ouvrir l'utilisation en direct", "password": "Mot de passe", "preferences": "Préférences", "raid-error.description": "Votre système de stockage n'a pas pu démarrer correctement. Vérifiez ci‑dessous l'état de vos SSD et suivez les étapes de dépannage. Si le problème persiste, les SSD concernés devront peut‑être être remplacés.", "raid-error.factory-reset-dialog.description": "Cela effacera toutes les données de votre Umbrel Pro et le rétablira aux paramètres d'usine. Cette opération est irréversible.", "raid-error.factory-reset-dialog.title": "Réinitialisation d'usine ?", "raid-error.factory-reset-failed": "Impossible de réinitialiser aux paramètres d'usine", "raid-error.health-warning": "Avertissement de santé", "raid-error.missing-ssd-multiple": "{{count}} SSD ne répondent pas", "raid-error.missing-ssd-one": "1 SSD ne répond pas", "raid-error.shutdown-dialog.description": "Éteignez votre Umbrel Pro, assurez-vous que tous les SSD sont correctement insérés dans leurs emplacements, puis rallumez-le.", "raid-error.shutdown-dialog.title": "Éteindre pour vérifier les disques ?", "raid-error.ssd-in-slot": "Un SSD {{size}} dans l'emplacement {{slot}}", "raid-error.step-check-connections.button": "Éteindre", "raid-error.step-check-connections.description": "Éteignez l'appareil et vérifiez que tous les SSD sont correctement en place.", "raid-error.step-check-connections.title": "Vérifier les connexions des SSD", "raid-error.step-factory-reset.button": "Réinitialiser", "raid-error.step-factory-reset.description": "Dernier recours si rien d'autre ne fonctionne. Cela efface toutes les données.", "raid-error.step-factory-reset.title": "Réinitialisation d'usine", "raid-error.step-restart.button": "Redémarrer", "raid-error.step-restart.description": "Une première étape rapide qui aide souvent", "raid-error.step-restart.title": "Essayez de redémarrer", "raid-error.title": "Problème de stockage détecté", "read-less": "Lire moins", "read-more": "Lire plus", "reconnect": "Se reconnecter", "redirect.to-home": "Chargement...", "redirect.to-login": "Chargement...", "redirect.to-onboarding": "Chargement...", "redirect.to-raid-error": "Chargement...", "reload": "Recharger", "remote-tor-access": "Accès Tor à distance", "reset": "Réinitialiser", "restart": "Redémarrer", "restart.confirm.submit": "Redémarrer", "restart.confirm.title": "Êtes-vous sûr de vouloir redémarrer votre Umbrel ?", "restart.restarting": "Redémarrage", "restart.restarting-message": "Veuillez ne pas actualiser cette page ou éteindre votre Umbrel pendant le redémarrage.", "rewind": "Rewind", "rewind.files-as-of": "Vos fichiers au", "rewind.loading-snapshots": "Chargement des instantanés...", "rewind.now": "Maintenant", "rewind.preflight.description": "Trouvez des fichiers et dossiers dans vos anciennes sauvegardes, et restaurez-les dans le présent.", "rewind.preflight.enable-backups": "Configurez les Sauvegardes dans les Réglages pour commencer à utiliser Rewind", "rewind.restore-complete": "Restauration terminée", "rewind.restore-error-description": "Veuillez réessayer.", "rewind.restore-failed": "Restaure échouée", "rewind.restore-running-description": "Ne fermez pas et ne rafraîchissez pas cette page tant que la restauration n'est pas terminée", "rewind.restore-selected": "Restaurer la sélection", "rewind.restore-success-description": "Vos fichiers ont été restaurés", "rewind.restoring": "Restauration en cours", "rewind.snapshots-count_one": "{{count}} sauvegarde depuis", "rewind.snapshots-count_other": "{{count}} sauvegardes depuis", "search": "Recherche", "settings": "Paramètres", "settings.app-store-preferences.title": "Préférences de l'App Store", "settings.contact-support": "Besoin d'aide ? Contactez le support.", "settings.file-sharing": "Partage de fichiers", "settings.file-sharing.add-folder": "Ajouter", "settings.file-sharing.add-folder-title": "Sélectionnez un dossier à partager", "settings.file-sharing.choice-entire-description": "Partager tous les fichiers sur votre Umbrel", "settings.file-sharing.choice-entire-title": "Tout", "settings.file-sharing.choice-heading": "Que voulez-vous partager ?", "settings.file-sharing.choice-specific-description": "Choisissez les dossiers à partager", "settings.file-sharing.choice-specific-title": "Dossiers spécifiques", "settings.file-sharing.choice-subtitle": "Accédez à vos fichiers et dossiers à la manière de Dropbox, comme des dossiers réseau sur votre ordinateur ou votre téléphone", "settings.file-sharing.configure": "Configurer", "settings.file-sharing.description": "Accédez à vos fichiers à la manière de Dropbox, via un dossier réseau (SMB) depuis d'autres appareils", "settings.file-sharing.home-shared-note": "Votre dossier \"{{homeDirectoryName}}\" est entièrement partagé. Les dossiers individuels n'ont pas besoin d'être partagés séparément.", "settings.file-sharing.share-entire-home-dir": "Partager l'intégralité de votre dossier personnel", "settings.file-sharing.share-entire-home-dir-description": "Accédez à tous les fichiers et dossiers de \"{{homeDirectoryName}}\" depuis d'autres appareils sur votre réseau", "settings.file-sharing.shared-folders": "Dossiers partagés", "show-details": "Afficher les détails", "shut-down": "Éteindre", "shut-down.complete": "Arrêt complet", "shut-down.complete-text": "Vous pouvez maintenant débrancher votre appareil.", "shut-down.confirm.submit": "Éteindre", "shut-down.confirm.title": "Êtes-vous sûr de vouloir éteindre votre Umbrel ?", "shut-down.failed": "Impossible d'arrêter : {{message}}", "shut-down.shutting-down": "Arrêt en cours", "shut-down.shutting-down-message": "Veuillez ne pas actualiser cette page ou éteindre votre Umbrel pendant l'arrêt.", "software-update.callout": "Veuillez ne pas actualiser cette page ou éteindre votre Umbrel pendant la mise à jour.", "software-update.check": "Vérifier la mise à jour", "software-update.checking": "Recherche de mise à jour...", "software-update.current-running": "Vous utilisez", "software-update.failed": "Échec de la mise à jour", "software-update.failed-to-check": "Échec de la vérification des mises à jour", "software-update.failed.retry": "Réessayer", "software-update.install-now": "Installer maintenant", "software-update.new-version": "Nouvelle version d'{{name}} disponible à l'installation", "software-update.on-latest": "Vous utilisez la dernière version d'umbrelOS", "software-update.see-whats-new": "Voir les nouveautés", "software-update.title": "Mise à jour logicielle", "software-update.updating-to": "Mise à jour vers {{name}}", "software-update.view": "Voir", "something-left": "{{left}} restant", "something-went-wrong": "⚠ Un problème est survenu", "start": "Démarrer", "stop": "Arrêter", "storage": "Stockage", "storage-manager": "Gestionnaire de stockage", "storage-manager.add": "Ajouter", "storage-manager.add-to-raid.add-ssd": "Ajouter un SSD", "storage-manager.add-to-raid.available": "Disponible :", "storage-manager.add-to-raid.description": "Un nouveau SSD a été détecté et est prêt à être ajouté.", "storage-manager.add-to-raid.enable-failsafe": "Activer FailSafe", "storage-manager.add-to-raid.failed-add": "Impossible d'ajouter le SSD", "storage-manager.add-to-raid.failed-enable-failsafe": "Impossible d'activer FailSafe", "storage-manager.add-to-raid.failsafe-label": "FailSafe :", "storage-manager.add-to-raid.info-capacity-added": "Votre nouveau {{size}} SSD sera ajouté à l'espace disponible.", "storage-manager.add-to-raid.info-capacity-adds-available": "Votre nouveau {{size}} SSD ajoutera {{available}} d'espace disponible.", "storage-manager.add-to-raid.info-capacity-adds-both": "Votre nouveau {{size}} SSD ajoutera {{available}} d'espace disponible et {{protection}} pour la protection des données.", "storage-manager.add-to-raid.info-capacity-protection-only": "Votre nouveau {{size}} SSD ajoutera {{protection}} pour la protection des données.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Votre nouveau {{size}} SSD sera entièrement utilisé pour la protection des données.", "storage-manager.add-to-raid.info-data-safe": "Vos données seront en sécurité si un seul SSD tombe en panne.", "storage-manager.add-to-raid.info-no-protection": "Si un SSD tombe en panne, vous pourriez perdre vos données.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} au total inutilisables en raison de différences de taille entre les SSD.", "storage-manager.add-to-raid.info-wasted": "{{size}} seront inutilisables en raison de tailles de SSD différentes.", "storage-manager.add-to-raid.recommended": "Recommandé", "storage-manager.add-to-raid.recommended-inline": "(recommandé)", "storage-manager.add-to-raid.restart-active-tasks": "Toutes les tâches actives seront interrompues", "storage-manager.add-to-raid.restart-after": "Après le redémarrage, la configuration de FailSafe se terminera automatiquement et vous pourrez reprendre une utilisation normale.", "storage-manager.add-to-raid.restart-during": "Pendant le redémarrage :", "storage-manager.add-to-raid.restart-intro": "Vous pouvez continuer à utiliser umbrelOS normalement pendant ce processus. Toutefois, à 50 % d'avancement, votre Umbrel redémarrera automatiquement.", "storage-manager.add-to-raid.restart-required": "Redémarrage du système requis", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS sera temporairement inaccessible", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD dans l'emplacement {{slot}}", "storage-manager.add-to-raid.title": "Ajouter un SSD au stockage", "storage-manager.add-to-raid.too-small": "SSD trop petit", "storage-manager.add-to-raid.too-small-description": "Ce SSD ({{deviceSize}}) est plus petit que le plus petit SSD actuellement installé ({{minSize}}). FailSafe exige que tous les SSD soient au moins aussi grands que le plus petit SSD utilisé.", "storage-manager.add-to-raid.understand-continue": "J'ai compris, continuer", "storage-manager.add-to-raid.warning-failsafe-now-only": "Avoir plus d'un SSD signifie que FailSafe ne peut être activé que maintenant. Vous ne pourrez pas l'activer plus tard.", "storage-manager.add-to-raid.wasted-label": "Inutilisable :", "storage-manager.available-storage": "Stockage disponible", "storage-manager.description": "Consultez le stockage, l'état et les paramètres de vos SSD", "storage-manager.empty": "Vide", "storage-manager.failsafe-transition-failed": "Impossible d'activer FailSafe", "storage-manager.for-failsafe": "Pour FailSafe", "storage-manager.health.checksum-errors": "Erreurs de checksum : {{count}}", "storage-manager.health.critical": "Critique", "storage-manager.health.critical-threshold": "Seuil critique", "storage-manager.health.current-temperature": "Température actuelle", "storage-manager.health.estimated-life": "Durée de vie estimée restante", "storage-manager.health.general": "Général", "storage-manager.health.health-status": "État de santé", "storage-manager.health.low": "Faible", "storage-manager.health.model-and-capacity": "Modèle et capacité", "storage-manager.health.overheating": "Surchauffe", "storage-manager.health.raid-failed-advice": "Ce SSD présente un problème. Éteignez votre Umbrel et vérifiez la connexion du SSD. Si le problème persiste, le SSD devra peut‑être être remplacé.", "storage-manager.health.read-errors": "Erreurs de lecture : {{count}}", "storage-manager.health.serial-number": "Numéro de série", "storage-manager.health.status-healthy": "En bon état", "storage-manager.health.status-unhealthy": "En mauvais état", "storage-manager.health.status-unknown": "Inconnu", "storage-manager.health.temperature": "Température", "storage-manager.health.title": "Santé des SSD", "storage-manager.health.warning-life-advice": "Pensez à remplacer ce SSD bientôt.", "storage-manager.health.warning-life-message": "Seulement {{percent}}% de durée de vie restante", "storage-manager.health.warning-temp-advice": "Assurez-vous que votre Umbrel Pro bénéficie d'un bon flux d'air et que le SSD est correctement installé.", "storage-manager.health.warning-temp-critical": "Température critique ({{temperature}})", "storage-manager.health.warning-temp-overheating": "Le disque est en surchauffe ({{temperature}})", "storage-manager.health.warning-threshold": "Seuil d'avertissement", "storage-manager.health.warning-unhealthy-advice": "Ce SSD pourrait bientôt tomber en panne. Envisagez de le remplacer.", "storage-manager.health.warning-unhealthy-message": "Ce SSD pourrait présenter un problème", "storage-manager.health.warnings": "Avertissements", "storage-manager.health.wear": "Usure", "storage-manager.health.write-errors": "Erreurs d'écriture : {{count}}", "storage-manager.install-ssd.description": "Ajoutez des SSD supplémentaires pour étendre votre stockage", "storage-manager.install-ssd.step-insert": "Insérez les nouveaux SSD dans les emplacements vides", "storage-manager.install-ssd.step-power-on": "Allumez votre {{deviceName}}", "storage-manager.install-ssd.step-remove-bottom-cover": "Retirez le couvercle magnétique inférieur", "storage-manager.install-ssd.step-replace-bottom-cover": "Remettez le capot inférieur en place", "storage-manager.install-ssd.step-return": "Revenez ici pour ajouter les SSD à votre stockage", "storage-manager.install-ssd.step-shut-down": "Éteignez votre {{deviceName}}", "storage-manager.install-ssd.title": "Ajout de SSD", "storage-manager.install-tips.image-alt": "Instructions d'installation du SSD", "storage-manager.install-tips.instructions": "Pour l'installer, retirez la vis moletée et glissez le SSD dans l'emplacement en l'inclinant. Appuyez sur le SSD jusqu'à ce qu'il repose sur le pilier de la vis, puis fixez-le avec la vis moletée.", "storage-manager.install-tips.toggle": "Vous avez oublié comment insérer un SSD ?", "storage-manager.manage": "Gérer", "storage-manager.missing-ssd-warning": "Un SSD semble manquer. Éteignez votre Umbrel et vérifiez que tous les SSD sont bien connectés. Si le problème persiste, le SSD devra peut‑être être remplacé.", "storage-manager.mode": "Mode", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Protège vos données si un SSD tombe en panne. Si vos SSD ont des tailles différentes, l'espace supplémentaire des plus grands restera inutilisé.", "storage-manager.mode.failsafe.info-description": "FailSafe protège vos données en en conservant des copies réparties sur vos SSD. Si un SSD tombe en panne, vos données restent sécurisées et peuvent être restaurées lorsque vous ajoutez un SSD de remplacement.", "storage-manager.mode.failsafe.info-title": "À propos de FailSafe", "storage-manager.mode.full-storage": "Stockage complet", "storage-manager.mode.full-storage.description": "Use all your SSD space together. If an SSD fails, you could lose your data.", "storage-manager.mode.full-storage.info-description": "Full Storage combine tous vos SSD en un seul grand espace, vous offrant un stockage maximal. Cependant, si un SSD tombe en panne, toutes vos données seront perdues.", "storage-manager.mode.full-storage.info-title": "À propos du Stockage complet", "storage-manager.mode.switch-from-failsafe-unavailable": "Passer de FailSafe au mode Full Storage nécessite de sauvegarder vos données, de réinitialiser l'appareil aux paramètres d'usine et de restaurer depuis une sauvegarde.", "storage-manager.mode.switch-to-failsafe-unavailable": "Avec plusieurs SSD en mode Full Storage, vos données sont réparties sur tous les disques. Passer à FailSafe nécessite de sauvegarder vos données, de réinitialiser l'appareil aux paramètres d'usine et de restaurer.", "storage-manager.mode.why-cant-switch": "Pourquoi ne puis-je pas basculer ?", "storage-manager.operation-in-progress.shutdown-description": "Vous pouvez éteindre en toute sécurité. L'opération sera mise en pause et reprendra après le redémarrage, mais elle doit se terminer avant que vous puissiez effectuer d'autres modifications.", "storage-manager.operation-in-progress.shutdown-title": "Votre stockage est en cours de mise à jour", "storage-manager.operation-in-progress.wait-description": "Patientez jusqu'à la fin de l'opération en cours avant de faire d'autres modifications.", "storage-manager.operation-in-progress.wait-title": "Votre stockage est en cours de mise à jour", "storage-manager.operation.adding-ssd": "Ajout du SSD...", "storage-manager.operation.enabling-failsafe": "Activation de FailSafe...", "storage-manager.operation.expanding": "Extension du stockage...", "storage-manager.operation.rebuilding": "Reconstruction des données...", "storage-manager.operation.replacing": "Remplacement du disque...", "storage-manager.operation.restarting": "Redémarrage...", "storage-manager.operation.starting": "Démarrage...", "storage-manager.operation.syncing-restarts": "Synchronisation des données • Redémarrage à 50 %", "storage-manager.raid-status.degraded": "Dégradé", "storage-manager.raid-status.failed": "Défaillant", "storage-manager.raid-status.offline": "Hors ligne", "storage-manager.raid-status.online": "En ligne", "storage-manager.raid-status.removed": "Retiré", "storage-manager.raid-status.unavailable": "Indisponible", "storage-manager.replace": "Remplacer", "storage-manager.replace-failed.degraded": "Protection FailSafe réduite", "storage-manager.replace-failed.degraded-description": "Un SSD manque dans votre stockage FailSafe. Remplacez-le pour retrouver une protection complète.", "storage-manager.replace-failed.description": "Utilisez ce SSD pour restaurer la protection FailSafe.", "storage-manager.replace-failed.error": "Impossible de démarrer le remplacement", "storage-manager.replace-failed.replace-now": "Remplacer maintenant", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD dans l'emplacement {{slot}}", "storage-manager.replace-failed.step-protected": "Une fois terminé, vos données seront à nouveau entièrement protégées.", "storage-manager.replace-failed.step-rebuild": "Les données seront reconstruites sur le nouveau SSD", "storage-manager.replace-failed.step-time": "Cela peut prendre un certain temps en fonction de la quantité de données.", "storage-manager.replace-failed.title": "Remplacer le SSD", "storage-manager.replace-failed.too-small": "SSD trop petit", "storage-manager.replace-failed.too-small-description": "Ce SSD ({{deviceSize}}) est plus petit que la taille minimale requise ({{minSize}}) pour votre stockage FailSafe.", "storage-manager.replace-failed.what-happens": "Que se passe-t-il ensuite :", "storage-manager.ssd-failing": "Défaillant", "storage-manager.swap": "Échanger", "storage-manager.swap.data-erased-description": "Le mode Full Storage n'offre pas de protection des données. Toutes les données sur votre {{deviceName}} seront effacées lors de la réinitialisation d'usine. Veillez à tout sauvegarder au préalable.", "storage-manager.swap.data-protected": "Vos données sont protégées", "storage-manager.swap.data-protected-description": "Avec FailSafe activé, vous pouvez remplacer n'importe quel SSD sans perdre vos données. Aucune sauvegarde nécessaire.", "storage-manager.swap.data-will-be-erased": "Les données seront effacées", "storage-manager.swap.description-failsafe": "Remplacez un disque dans votre stockage FailSafe.", "storage-manager.swap.description-full-storage": "Remplacez un disque dans votre configuration Full Storage.", "storage-manager.swap.description-no-free-slot": "En mode Full Storage avec tous les emplacements occupés, remplacer un SSD nécessite un processus complet de sauvegarde et de restauration.", "storage-manager.swap.description-replace": "Migrez vos données vers un nouveau SSD, puis retirez l'ancien.", "storage-manager.swap.failed-to-start": "Impossible de démarrer le remplacement", "storage-manager.swap.no-data-loss": "Aucune perte de données", "storage-manager.swap.no-data-loss-description": "Vos données seront copiées sur le nouveau SSD. Une fois l'opération terminée, vous pourrez retirer l'ancien en toute sécurité.", "storage-manager.swap.safe-swap-available": "Échange sécurisé disponible", "storage-manager.swap.safe-swap-description": "Comme vous disposez d'un emplacement vide, vous pouvez ajouter d'abord le nouveau SSD et migrer vos données avant de retirer l'ancien. Aucune sauvegarde requise.", "storage-manager.swap.select-new-ssd": "Sélectionnez le nouveau SSD à utiliser :", "storage-manager.swap.ssd-in-slot": "{{size}} SSD dans l'emplacement {{slot}}", "storage-manager.swap.step-backup": "Sauvegardez vos données", "storage-manager.swap.step-backup-description": "Allez dans Paramètres → Backups et créez une sauvegarde de toutes vos données.", "storage-manager.swap.step-data-copied": "Les données seront copiées de l'ancien SSD vers le nouveau", "storage-manager.swap.step-factory-reset": "Réinitialisation d'usine", "storage-manager.swap.step-factory-reset-description": "Allez dans Paramètres → Avancé → Réinitialisation d'usine pour effacer votre {{deviceName}}.", "storage-manager.swap.step-insert-new-ssd": "Insérez le nouveau SSD dans un emplacement vide", "storage-manager.swap.step-may-take-while": "Cela peut prendre un certain temps selon la quantité de données que vous avez", "storage-manager.swap.step-power-on": "Allumez votre {{deviceName}}", "storage-manager.swap.step-remove-bottom-cover": "Retirez le couvercle magnétique inférieur", "storage-manager.swap.step-remove-old": "Une fois terminé, éteignez et retirez {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Replacez le couvercle inférieur", "storage-manager.swap.step-restore": "Restaurez vos données", "storage-manager.swap.step-restore-description": "Allez dans Paramètres → Backups et restaurez depuis votre sauvegarde.", "storage-manager.swap.step-return-to-storage-manager": "Revenez ici dans le Gestionnaire de stockage pour confirmer l'échange et ajouter le nouveau SSD à votre stockage", "storage-manager.swap.step-return-to-swap": "Revenez ici dans le Gestionnaire de stockage et cliquez de nouveau sur \"Échanger\" pour démarrer le remplacement", "storage-manager.swap.step-setup-new-storage": "Configurez votre nouveau stockage", "storage-manager.swap.step-setup-new-storage-description": "Allumez votre {{deviceName}} et terminez le processus de configuration avec votre nouveau SSD.", "storage-manager.swap.step-shut-down": "Éteignez votre {{deviceName}}", "storage-manager.swap.step-shut-down-and-swap": "Éteignez et remplacez {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Éteignez, ouvrez votre appareil, remplacez le SSD, puis remontez-le.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Éteignez, retirez le couvercle inférieur, remplacez le SSD, puis refermez le couvercle.", "storage-manager.swap.step-swap-ssd": "Remplacez {{ssd}} par un nouveau de la même taille", "storage-manager.swap.too-small": "Trop petit ({{size}} requis)", "storage-manager.swap.what-happens-next": "Ce qui se passe ensuite :", "storage-manager.total-capacity-added": "Capacité totale ajoutée", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Utilisé", "storage-manager.wasted": "Inutilisable", "storage-manager.wasted-size": "{{size}} Inutilisable", "storage.full": "Stockage plein", "storage.low": "Stockage faible", "temperature": "Température", "temperature.dangerously-hot": "Très chaud", "temperature.nice": "Agréable", "temperature.normal": "Normal", "temperature.too-hot-suggestion": "Envisagez de changer l'environnement de votre appareil.", "temperature.warm": "Tiède", "terminal": "Terminal", "terminal-description": "Exécutez des commandes personnalisées dans umbrelOS ou au sein d'une application", "terminal.app": "App", "terminal.app-description": "Exécutez des commandes personnalisées dans une application spécifique", "terminal.umbrelos-description": "Exécutez des commandes personnalisées dans umbrelOS", "tor-description": "Accédez à votre Umbrel de n'importe où en utilisant un navigateur Tor", "tor-enabled-description": "Accédez à votre Umbrel de n'importe où en utilisant un navigateur Tor à l'URL suivante :", "tor-error": "Impossible de mettre à jour le paramètre Tor : {{message}}", "tor.disable.description": "Cela peut prendre quelques minutes", "tor.disable.progress": "Désactivation de l'accès Tor à distance", "tor.enable.description": "Cela peut prendre quelques minutes", "tor.enable.mobile.switch-label": "Activer l'accès Tor à distance", "tor.hidden-service": "URL du service caché Tor", "troubleshoot": "Dépannage", "troubleshoot-description": "Dépanner umbrelOS ou une application", "troubleshoot-no-logs-yet": "Aucun journal pour le moment", "troubleshoot-pick-title": "Dépannage", "troubleshoot.app": "Application", "troubleshoot.app-description": "Voir les journaux d'une application installée sur votre Umbrel", "troubleshoot.app-download": "Télécharger les journaux de {{app}}", "troubleshoot.share-with-umbrel-support": "Partager avec le support Umbrel", "troubleshoot.system-download": "Télécharger {{label}}", "troubleshoot.umbrelos-description": "Afficher les journaux umbrelOS", "troubleshoot.umbrelos-logs": "Journaux umbrelOS", "trpc.backend-unavailable": "Erreur : Connexion à l'API système échouée", "trpc.checking-backend": "Chargement...", "try-again": "Réessayer", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Inconnu", "unknown-app": "Application inconnue", "unknown-error": "Erreur inconnue", "uptime": "Temps de fonctionnement", "url": "URL", "wallpaper": "Fond d'écran", "wallpaper-description": "Votre fond d'écran et thème Umbrel", "whats-new.continue": "Continuer", "whats-new.feature-1.description": "Configurez des sauvegardes automatisées et chiffrées de l'intégralité de votre Umbrel vers un disque USB externe, un NAS ou un autre Umbrel.", "whats-new.feature-2.description": "Revenez en arrière pour récupérer des fichiers et dossiers précis à partir de sauvegardes précédentes.", "whats-new.feature-3.description": "Ou restaurez l'intégralité de votre Umbrel, y compris toutes vos applications, fichiers et données.", "whats-new.feature-4.description": "Connectez un NAS ou un autre Umbrel et accédez à son stockage depuis Files.", "whats-new.feature-4.title": "Périphériques réseau", "whats-new.feature-5.description": "Connectez des disques USB externes (sur Umbrel Home ou sur n'importe quel appareil Intel ou AMD) et accédez-y depuis Files.", "whats-new.feature-5.helper-text": "Non pris en charge sur les appareils Raspberry Pi en raison de possibles problèmes d'alimentation.", "whats-new.feature-5.title": "Stockage externe", "whats-new.next": "Suivant", "whats-new.title": "Nouveautés de {{version}}", "widget.progress.in-progress": "En cours", "widgets.edit.select-up-to-3-widgets": "Sélectionnez jusqu'à 3 widgets", "widgets.install-an-app-before-using-widgets": "Installez une application pour commencer à personnaliser votre écran d'accueil avec des widgets.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Les réseaux ouverts peuvent être peu sécurisés", "wifi-connection-failed": "Impossible de se connecter", "wifi-dangerous-change-confirmation-description": "Changer de réseau Wi-Fi peut vous déconnecter de votre Umbrel. Pour vous reconnecter, assurez-vous que votre Umbrel et l'appareil à partir duquel vous y accédez sont sur le même réseau.", "wifi-dangerous-change-confirmation-title": "Êtes-vous sûr de vouloir changer de réseau Wi-Fi ?", "wifi-dangerous-disable-confirmation-description": "Désactiver le Wi-Fi peut vous déconnecter de votre Umbrel. Pour vous reconnecter, branchez un câble Ethernet à votre Umbrel et assurez-vous que votre Umbrel et l'appareil à partir duquel vous y accédez sont sur le même réseau.", "wifi-dangerous-disable-confirmation-title": "Êtes-vous sûr de vouloir désactiver le Wi-Fi ?", "wifi-description": "Connectez votre appareil à un réseau Wi-Fi", "wifi-description-long": "Votre appareil reste connecté à votre Wi-Fi choisi, même si le câble Ethernet est retiré, et se reconnecte automatiquement au Wi-Fi au démarrage.", "wifi-no-networks-message": "Aucun réseau Wi-Fi trouvé", "wifi-searching": "Recherche de réseaux Wi-Fi...", "wifi-unsupported-device-description": "Le Wi-Fi n'est pas pris en charge sur cet appareil. Cela peut être dû à un adaptateur sans fil manquant ou incompatible.", "wifi-view-networks": "Voir les réseaux" } ================================================ FILE: packages/ui/public/locales/hu.json ================================================ { "2fa": "2FA", "2fa-description": "Egy második biztonsági réteg az Umbrel bejelentkezésedhez és az alkalmazásaidhoz", "2fa.disable.title": "Kétlépcsős azonosítás letiltása", "2fa.enable.or-paste": "Vagy illeszd be a következő kódot az hitelesítő alkalmazásodba", "2fa.enable.scan-this": "Olvasd be ezt a QR-kódot egy hitelesítő alkalmazással, például a Google Authenticator vagy az Authy segítségével", "2fa.enable.title": "Kétlépcsős azonosítás engedélyezése", "2fa.enter-code": "Add meg a hitelesítő alkalmazásod által megjelenített kódot", "account": "Fiók", "account-description": "A neved és jelszavad", "advanced-settings": "Haladó beállítások", "advanced-settings-description": "Terminál, umbrelOS Béta Program, Cloudflare DNS, és még sok más", "app-not-found": "Alkalmazás nem található: {{app}}", "app-only-over-tor": "{{app}} csak Toron keresztül használható. Kérlek, nyisd meg az Umbrel-t egy Tor böngészőben a távoli hozzáférési URL-eden (Beállítások > Speciális beállítások > Távoli Tor-hozzáférés), hogy megnyisd ezt az alkalmazást.", "app-page.section.about": "Rólunk", "app-page.section.credentials.title": "Alapértelmezett hitelesítési adatok", "app-page.section.dependencies.n-alternatives": "Lásd a {{count}} alternatívát", "app-page.section.info.compatibility": "Kompatibilitás", "app-page.section.info.compatibility-compatible": "Kompatibilis", "app-page.section.info.compatibility-not-compatible": "Nem kompatibilis", "app-page.section.info.developer": "Fejlesztő", "app-page.section.info.source-code": "Forráskód", "app-page.section.info.source-code.public": "Nyilvános", "app-page.section.info.submitted-by": "Beküldte", "app-page.section.info.support": "Támogatás kérése", "app-page.section.info.title": "Információ", "app-page.section.info.version": "Verzió", "app-page.section.recommendations.title": "Neked is tetszhet", "app-page.section.release-notes.title": "Újdonságok", "app-page.section.release-notes.version": "{{version}} verzió", "app-page.section.requires": "Követelmények", "app-picker.search": "Keresés...", "app-picker.select-app": "Válassz alkalmazást...", "app-settings.connected-to": "{{appName}} ezekhez az alkalmazásokhoz csatlakozik", "app-settings.save-changes": "Változtatások mentése", "app-settings.title": "Beállítások", "app-store.browse-category-apps": "Böngészd a(z) {{category}} alkalmazásokat", "app-store.category.ai": "AI", "app-store.category.all": "Összes alkalmazás", "app-store.category.automation": "Otthon és automatizáció", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Kripto", "app-store.category.developer": "Fejlesztői eszközök", "app-store.category.discover": "Felfedezés", "app-store.category.files": "Fájlok és termelékenység", "app-store.category.finance": "Pénzügy", "app-store.category.media": "Média", "app-store.category.networking": "Hálózat", "app-store.category.social": "Közösségi", "app-store.description": "Az alkalmazásfrissítési beállításaid", "app-store.discover.temporarily-unavailable-description": "Böngészd a fenti kategóriákat, vagy keress, hogy alkalmazásokat találj", "app-store.discover.temporarily-unavailable-title": "A kiemelt tartalom jelenleg nem érhető el", "app-store.menu.community-app-stores": "Közösségi alkalmazásboltok", "app-store.search-apps": "Alkalmazások keresése", "app-store.search.no-results": "Nincs találat", "app-store.search.results-for": "Eredmények erre", "app-store.title": "Alkalmazásbolt", "app-store.updates": "Frissítések", "app-updates.less": "kevesebb", "app-updates.more": "több", "app-updates.no-updates": "Minden alkalmazás naprakész!", "app-updates.update": "Frissítés", "app-updates.update-all": "Összes frissítése", "app-updates.updates-available-count_one": "{{count}} frissítés elérhető", "app-updates.updates-available-count_other": "{{count}} frissítés elérhető", "app-updates.updating": "Frissítés...", "app.install": "Telepítés", "app.installed": "Telepítve", "app.installing": "Telepítés folyamatban", "app.offline": "Nem fut", "app.open": "Megnyitás", "app.optimized-for-umbrel-home": "Optimalizált az Umbrel Home-hoz", "app.os-update-required.confirm": "Ellenőrizd az umbrelOS frissítését", "app.os-update-required.description": "A(z) {{appName}} alkalmazásnak umbrelOS {{version}} vagy újabb verzióra van szüksége", "app.os-update-required.title": "Frissítsd az umbrelOS-t", "app.restarting": "Újraindítás", "app.starting": "Indítás", "app.stopping": "Leállítás", "app.uninstall.confirm.description": "Az {{app}}-hez tartozó összes adat véglegesen törlésre kerül. Ez a művelet nem vonható vissza.", "app.uninstall.confirm.submit": "Eltávolítás", "app.uninstall.confirm.title": "{{app}} eltávolítása?", "app.uninstall.deps.used-by.description_one": "Először távolítsd el a(z) {{firstAppToUninstall}} alkalmazást az {{app}} eltávolításához.", "app.uninstall.deps.used-by.description_other": "Először távolítsd el ezeket az alkalmazásokat az {{app}} eltávolításához.", "app.uninstall.deps.used-by.title": "{{app}} használja", "app.uninstalling": "Eltávolítás", "app.updating": "Frissítés", "app.view": "Megtekintés", "app_one": "alkalmazás", "app_other": "alkalmazások", "apps.uninstall.failed-to-get-required-apps": "Nem sikerült megszerezni a szükséges alkalmazásokat", "apps.uninstalled-all.success": "Minden alkalmazás eltávolítva", "auth.checking-backend-for-user": "Betöltés...", "auth.failed-checking-if-user-logged-in": "Hiba: Nem sikerült ellenőrizni a bejelentkezést", "auth.failed-to-check-if-user-exists": "Hiba: Nem sikerült ellenőrizni a felhasználó létezését", "back": "Vissza", "backups": "Backups", "backups-configure": "Konfigurálás", "backups-configure.add-backup-location": "Backup-hely hozzáadása", "backups-configure.available": "Elérhető", "backups-configure.awaiting-next-backup": "Várakozás a következő automatikus backupra", "backups-configure.back-up-now": "Most backup készítése", "backups-configure.backing-up-now": "Backup készítése...", "backups-configure.connected": "Csatlakoztatva", "backups-configure.connection": "Kapcsolat", "backups-configure.in-progress": "Folyamatban", "backups-configure.last-backup": "Utolsó backup", "backups-configure.locations": "Helyek", "backups-configure.no-backup-locations": "Adj hozzá egy backup helyet az adataid backupolásának megkezdéséhez", "backups-configure.not-connected": "Nincs csatlakoztatva", "backups-configure.path": "Elérési út", "backups-configure.remove-backup-location": "Backup-hely eltávolítása", "backups-configure.remove-backup-location-confirmation": "Biztos vagy benne?", "backups-configure.remove-backup-location-confirmation-description": "Ez eltávolítja a '{{device}}' eszközt a backup helyek közül. A meglévő backupjaid ezen az eszközön nem törlődnek, de az automatikus backupok leállnak.", "backups-configure.status": "Állapot", "backups-configure.total-backups": "Backups összesen", "backups-configure.used": "Használt", "backups-configure.view": "Megtekintés", "backups-description": "Készíts backupot a fájljaidról, alkalmazásaidról és adataidról egy másik Umbrelre, NAS-ra vagy külső meghajtóra", "backups-error.backup-not-found": "A biztonsági mentés nem található.", "backups-error.generic": "Hiba történt: {{details}}", "backups-error.in-progress": "Egy biztonsági mentés már folyamatban van. Kérlek, várj, amíg befejeződik.", "backups-error.invalid-exclusion-path": "Csak a Home könyvtáradban található fájlok és mappák zárhatók ki a mentésekből.", "backups-error.invalid-password": "A titkosítási jelszó helytelen.", "backups-error.invalid-path": "A kiválasztott hely nem alkalmas biztonsági mentésre.", "backups-error.mount-failed": "Nem sikerült elérni a mentési pillanatképet.", "backups-error.mount-timeout": "Nem sikerült elérni a mentési pillanatképet. Próbáld újra, vagy ellenőrizd, hogy az eszköz megfelelően csatlakozik-e.", "backups-error.not-enough-space": "Nincs elegendő hely a mentéshez használt eszközön.", "backups-error.not-found": "A biztonsági mentés vagy a mentési hely nem található.", "backups-error.repository-exists": "Ebben a mappában már létezik mentési hely.", "backups-error.repository-not-found": "A mentési hely nem található.", "backups-exclusions.add": "Hozzáadás", "backups-exclusions.app-paths-cannot-be-modified": "Ezeket a fájlokat/mappákat az alkalmazás fejlesztője határozta meg, és nem módosíthatók:", "backups-exclusions.app-paths-explanation": "Ez az alkalmazás a következő adatokat zárja ki a backupból. Ezek az útvonalak általában nem létfontosságú elemeket tartalmaznak (például gyorsítótárakat vagy naplókat, amelyek újra létrehozhatók), vagy olyan adatokat, amelyek visszaállítás esetén problémát okozhatnak (például elavult alkalmazásállapotok, amelyek ütközésekhez vagy inkonzisztenciához vezethetnek).", "backups-exclusions.auto-excluded": "Automatikusan kizárt", "backups-exclusions.exclude-entire-app": "Az egész alkalmazás kizárása", "backups-exclusions.excluded-apps": "Kizárt alkalmazások", "backups-exclusions.files-and-folders": "Kizárt fájlok és mappák", "backups-exclusions.no-excluded-apps": "Nincsenek kizárt alkalmazások", "backups-exclusions.no-excluded-files-or-folders": "Nincsenek kizárt fájlok vagy mappák", "backups-exclusions.select-item-to-exclude": "Válassz egy elemet a kizáráshoz", "backups-exclusions.stop-excluding": "Kizárás megszüntetése", "backups-floating-island.backing-up": "Backup készítése...", "backups-floating-island.backing-up-to": "Umbrel backupolása...", "backups-restore": "Visszaállítás", "backups-restore-full": "Teljes visszaállítás", "backups-restore-full-description": "Állítsd vissza az egész Umbrel rendszeredet egy biztonsági mentésből", "backups-restore-header": "Umbrel visszaállítása", "backups-restore-pro.after-restore": "A visszaállítás után az ideiglenes fiókod helyére a mentett fiókod és annak adatai kerülnek.", "backups-restore-pro.step1": "Fejezd be a beállítást az alábbi \"Get Started\" gombra kattintva. Ez lesz az ideiglenes fiókod, amíg vissza nem állítod a mentett fiókodat.", "backups-restore-pro.step2": "Ha a beállítás elkészült, menj a <0>Beállítások → Backups → Visszaállítás", "backups-restore-pro.step3": "Kövesd a Restore Wizard utasításait.", "backups-restore-pro.subtitle": "Umbrel Pro-n egy biztonsági mentés visszaállítása néhány további lépést igényel", "backups-restore.backup-date": "Backup dátuma", "backups-restore.backup-location": "Backup hely", "backups-restore.browse-cloud-subtitle": "Visszaállítás az Umbrel Private Cloud-ból (hamarosan)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Visszaállítás külső USB-meghajtóról", "backups-restore.browse-external-title": "Külső meghajtó", "backups-restore.browse-nas-or-external": "Böngéssz egy másik Umbrelt, NAS-t vagy külső meghajtót, ahonnan backupból visszaállíthatsz", "backups-restore.browse-nas-subtitle": "Visszaállítás a hálózatodon található másik Umbrelről vagy NAS eszközről", "backups-restore.browse-nas-title": "Egy másik Umbrel vagy NAS", "backups-restore.choose": "Válassz", "backups-restore.choose-backup-location": "Válassz egy backup helyet", "backups-restore.connect-to-backup-location": "Csatlakozás egy backup helyhez", "backups-restore.encryption-password": "Titkosítási jelszó", "backups-restore.encryption-password-description": "Add meg azt a titkosítási jelszót, amit a biztonsági mentések engedélyezésekor állítottál be", "backups-restore.enter-password-to-confirm": "Add meg az Umbrel jelszavadat a megerősítéshez", "backups-restore.final-confirmation": "Biztos vagy benne?", "backups-restore.final-confirmation-description": "Ennek a backupnak a visszaállítása felülírja a jelenlegi umbrelOS alkalmazásaidat és adataidat a kiválasztott backup tartalmával. A backupból kizárt fájlok, mappák vagy alkalmazások eltávolításra kerülnek az Umbrelről. Ezt a műveletet nem lehet visszavonni.", "backups-restore.invalid-password": "Érvénytelen jelszó", "backups-restore.last-backup": "Utolsó backup: {{date}}", "backups-restore.latest": "Legfrissebb", "backups-restore.no-backups-found": "Nem találhatók backupok", "backups-restore.no-backups-yet": "Még nincsenek backupok", "backups-restore.please-select-backup": "Kérlek, válassz egy backupot", "backups-restore.please-select-repository": "Kérlek, válassz egy tárolót", "backups-restore.restore-from-nas-or-external": "Állítsd vissza az Umbrel-edet egy másik Umbrel-ről, egy NAS-ról vagy egy külső meghajtóról készült biztonsági mentésből", "backups-restore.restore-from-unlisted": "Visszaállítás másik helyről", "backups-restore.restore-umbrel": "Umbrel visszaállítása", "backups-restore.restore-warning": "Ennek a backupnak a visszaállítása felülírja a jelenlegi umbrelOS alkalmazásaidat és adataidat a kiválasztott backup tartalmával. A backupból kizárt fájlok, mappák vagy alkalmazások eltávolításra kerülnek az Umbrelről. Ha csak bizonyos fájlokat vagy mappákat szeretnél visszaállítani, nyisd meg a <0>Rewind-et.", "backups-restore.restoring-from": "Most a következő biztonsági mentésről fogsz visszaállítani:", "backups-restore.review-description": "A visszaállítás azzal a fiókkal, fájlokkal, alkalmazásokkal és beállításokkal állítja be az Umbrel-edet, amelyek a mentés készítésekor szerepeltek. Ez eltarthat egy ideig. Ha kész, a bejelentkezési jelszavad arra a jelszóra lesz visszaállítva, amelyet a mentés készítésekor használtál.", "backups-restore.select-backup": "Válassz egy backupot", "backups-restore.select-backup-description": "Válaszd ki azt a backupot, amelyből vissza szeretnél állítani", "backups-restore.select-backup-file": "Válaszd ki a biztonsági mentés fájlodat", "backups-restore.select-backup-file-only": "Csak a {{backupFileName}} választható", "backups-restore.total-size": "Teljes méret", "backups-restore.unknown-date": "Ismeretlen dátum", "backups-restore.unknown-repository": "Ismeretlen tároló", "backups-rewind": "Rewind", "backups-rewind-description": "Ugorj vissza az időben, és állítsd vissza a kiválasztott fájlokat és mappákat", "backups-rewind.start": "Rewind indítása", "backups-setup": "Beállítás", "backups-setup-confirm": "Beállítás befejezése", "backups-setup-external-description": "Biztonsági mentés külső USB-meghajtóra", "backups-setup-nas-or-umbrel-description": "Készíts backupot egy másik Umbrelre vagy a hálózatodon lévő NAS eszközre", "backups-setup-umbrel-or-nas": "Másik Umbrel vagy NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Nyugi otthonon kívülre is: küldj végpontok közötti titkosítással védett backupokat az Umbrel Private Cloud-ba.", "backups-setup-umbrel-private-cloud-cta-link": "Szerezz korai hozzáférést", "backups-setup-umbrel-private-cloud-description": "Végpontok közötti titkosítással védett backupok az Umbrel Private Cloud-ba", "backups-setup-umbrel-private-cloud-subtitle": "Hamarosan", "backups.add-umbrel-or-nas": "Umbrel vagy NAS hozzáadása", "backups.all-apps-and-data-will-be-backed-up": "Minden alkalmazás és adat backupolva lesz", "backups.apps-and-data": "Alkalmazások és adatok", "backups.backup-location": "Backup hely", "backups.browse": "Böngészés", "backups.choose-folder-within-device": "Válassz egy mappát a {{device}} eszközön, ahová elmented a backupjaidat", "backups.confirm-password": "Jelszó megerősítése", "backups.copy": "Másolás", "backups.encryption": "Titkosítás", "backups.encryption-password-warning": "Győződj meg róla, hogy a titkosítási jelszó biztonságban van tárolva (például jelszókezelőben). Ezt a jelszót később nem fogod tudni újra megnézni, és szükséged lesz rá a backupok visszaállításához.", "backups.exclude-from-backups": "Kizárás a Backups-ból", "backups.exclude-from-backups-description": "Zárj ki konkrét fájlokat, mappákat és alkalmazásokat a backupjaidból.", "backups.hide": "Elrejtés", "backups.i-understand": "Értem", "backups.location": "Hely", "backups.modals.already-in-use.description": "Ezt a helyet már használják biztonsági mentésekhez ezen az Umbrel-en.", "backups.modals.already-in-use.manage": "Kezelés a Backups-ban", "backups.modals.already-in-use.title": "A biztonsági mentés helye már használatban van", "backups.modals.connect-existing.description": "Ezen a helyen már létezik egy Umbrel biztonsági mentés. Add meg a titkosítási jelszót, hogy hozzáadd ehhez az Umbrel-hez.", "backups.modals.connect-existing.title": "Meglévő Umbrel biztonsági mentés csatlakoztatása", "backups.no-external-drives-detected": "Nem található külső meghajtó", "backups.no-password-set": "Nincs beállítva jelszó", "backups.password-is-set": "Jelszó beállítva", "backups.password-minimum-length": "A jelszónak legalább 8 karakter hosszúnak kell lennie", "backups.password-safety-warning": "A backupjaidat ezzel a jelszóval fogjuk titkosítani. Tartsd biztonságban, mert később nem fogod tudni megtekinteni, és szükséged lesz rá a backupok visszaállításához.", "backups.passwords-do-not-match": "A jelszavak nem egyeznek", "backups.please-choose-folder": "Kérlek, válassz egy mappát", "backups.restore-failed.message": "Hiba történt az Umbrel visszaállítása közben. A jelenlegi alkalmazásaid és adataid nem módosultak.", "backups.restore-failed.retry": "Visszaállítás", "backups.restore-failed.title": "Visszaállítás sikertelen", "backups.restoring": "Umbrel visszaállítása", "backups.restoring-completing": "Épp befejezzük. Az Umbrel rövidesen újraindul...", "backups.restoring-progress": "{{percent}}% visszaállítva", "backups.restoring-time-remaining": "{{time}} hátra", "backups.restoring-warning": "Ne kapcsold ki az Umbrel-t, és ne válaszd le a backup helyet visszaállítás közben", "backups.review": "Ellenőrizd és erősítsd meg", "backups.review-description": "Ellenőrizd a backup részleteit, majd erősítsd meg a választásodat", "backups.scanning-for-external-drives": "Külső meghajtók keresése...", "backups.schedule-description": "Az umbrelOS óránként automatikusan backupot készít az adataidról. Az elmúlt 24 órából óránként titkosított backupokat tart meg, az elmúlt hétre naponta backupokat, az elmúlt hónapra hetente backupokat, és az elmúlt évre havi backupokat. Az egy évnél régebbi backupok automatikusan törlődnek.", "backups.select-backup-folder": "Válassz backup mappát", "backups.select-backup-folder-description": "Válassz egy mappát, ahová a backupjaidat szeretnéd tárolni.", "backups.select-backup-location": "Válassz egy backup helyet", "backups.set-encryption-password": "Titkosítási jelszó beállítása", "backups.set-encryption-password-description": "Védd a backupjaidat egy jelszóval. Ez biztosítja, hogy az adataid privátok maradjanak, és csak ezzel a jelszóval állíthatók vissza.", "backups.show": "Megjelenítés", "backups.storage-capacity-warning": "{{device}}-nek legalább a backup méretének kétszeresével megegyező szabad hellyel kell rendelkeznie", "backups.store-encryption-password-safely": "Tárold a titkosítási jelszavad biztonságosan", "beta-program": "umbrelOS Beta Program", "beta-program-description": "Iratkozz fel az umbrelOS béta frissítésekre, szerezd meg az új funkciók korai hozzáférését, és segíts fejleszteni azokat a visszajelzéseiddel. A béta frissítések instabilak lehetnek, és a hibaelhárítás terminál ismereteket igényelhet.", "cancel": "Mégse", "change": "Változtatás", "change-name": "Név változtatása", "change-name.failed.name-required": "A név megadása kötelező", "change-name.input-placeholder": "A te neved", "change-password": "Jelszó változtatása", "change-password.callout": "Ha elveszted a jelszavad, nem tudsz majd bejelentkezni az Umbrel-be. Biztosítsd, hogy biztonságosan tárolod.", "change-password.current-password": "Jelenlegi jelszó", "change-password.failed.current-required": "A jelenlegi jelszó megadása kötelező", "change-password.failed.min-length": "A jelszónak legalább {{characters}} karakter hosszúnak kell lennie", "change-password.failed.must-be-unique": "Az új jelszónak különböznie kell a jelenlegitől", "change-password.failed.new-required": "Az új jelszó megadása kötelező", "change-password.failed.no-match": "A jelszavak nem egyeznek", "change-password.failed.repeat-required": "A jelszó ismétlése kötelező", "change-password.new-password": "Új jelszó", "change-password.repeat-password": "Jelszó ismétlése", "check-for-latest-version": "Legfrissebb umbrelOS frissítés ellenőrzése", "clipboard.copied": "Másolva", "close": "Bezárás", "cmdk.change-wallpaper": "Háttérkép megváltoztatása", "cmdk.frequent-apps": "Gyakran használt", "cmdk.input-placeholder": "Keresés alkalmazások, beállítások vagy műveletek között", "cmdk.live-usage": "Élő használat", "cmdk.restart-umbrel": "Umbrel újraindítása", "cmdk.shutdown-umbrel": "Umbrel leállítása", "cmdk.update-all-apps": "Összes alkalmazás frissítése", "cmdk.widgets": "Widgetek", "community-app-store": "Közösségi Alkalmazásbolt", "community-app-store.add-error": "App Store hozzáadása sikertelen: {{message}}", "community-app-store.back-to-umbrel-app-store": "Vissza az Umbrel Alkalmazásboltba", "community-app-store.open-button": "Megnyitás", "community-app-store.remove-button": "Eltávolítás", "community-app-store.remove-error": "App Store eltávolítása sikertelen: {{message}}", "community-app-stores.add-button": "Hozzáadás", "community-app-stores.description": "A Közösségi Alkalmazásboltok lehetővé teszik, hogy olyan alkalmazásokat telepíts az Umbrel-re, amelyek nem elérhetőek az hivatalos Umbrel Alkalmazásboltban. Ezen kívül egyszerűvé teszik az Umbrel alkalmazások béta verzióinak tesztelését, mielőtt a fejlesztők kiadják őket az hivatalos Umbrel Alkalmazásboltban.", "community-app-stores.learn-more": "Tudj meg többet", "community-app-stores.warning": "A Közösségi Alkalmazásboltokat bárki létrehozhatja. Az ezekben közzétett alkalmazásokat nem ellenőrzi vagy vizsgálja az hivatalos Umbrel Alkalmazásbolt csapata, és potenciálisan nem biztonságosak vagy rosszindulatúak lehetnek. Legyél óvatos, és csak olyan alkalmazásboltokat adj hozzá, amelyeket megbízható fejlesztők készítettek.", "confirm": "Megerősítés", "connect": "Csatlakozás", "connecting": "Csatlakozás...", "connection-lost": "Kapcsolat megszakadt", "connection-lost-description": "Ez akkor fordulhat elő, ha a böngészőfül inaktív volt, a hálózati kapcsolat megszakadt, vagy az eszköz offline.", "continue": "Folytatás", "continue-to-log-in": "Folytatás a bejelentkezéshez", "cpu": "CPU", "cpu-core-count": "{{cores}} szál", "default-credentials.close": "Rendben", "default-credentials.description": "Itt találod a bejelentkezéshez szükséges hitelesítési adatokat.", "default-credentials.dont-show-again": "Ne mutasd újra ezt", "default-credentials.dont-show-again-notice": "A jövőben bármikor hozzáférhetsz ezekhez a hitelesítő adatokhoz az alkalmazás ikonra jobb egérgombbal kattintva.", "default-credentials.open": "Nyisd meg a(z) {{app}} alkalmazást", "default-credentials.password": "Alapértelmezett jelszó", "default-credentials.title": "{{app}} hitelesítési adatai", "default-credentials.username": "Alapértelmezett felhasználónév", "desktop.app.context.go-to-store-page": "Megtekintés az Alkalmazásboltban", "desktop.app.context.settings": "Beállítások", "desktop.app.context.show-default-credentials": "Alapértelmezett hitelesítési adatok megjelenítése", "desktop.app.context.uninstall": "Eltávolítás", "desktop.context-menu.change-wallpaper": "Háttérkép megváltoztatása", "desktop.context-menu.edit-widgets": "Widgetek szerkesztése", "desktop.context-menu.logout": "Kijelentkezés", "desktop.greeting.afternoon": "Jó délutánt, {{name}}", "desktop.greeting.evening": "Jó estét, {{name}}", "desktop.greeting.morning": "Jó reggelt, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Viber-felhasználóknak", "desktop.install-first.for-the-bitcoiner": "A Bitcoin felhasználóknak", "desktop.install-first.for-the-self-hoster": "Az önálló hosztok számára", "desktop.install-first.for-the-streamer": "A streamerek számára", "desktop.install-first.link-to-app-store": "Fedezz fel többet az App Store-ban", "desktop.not-enough-room": "Használj nagyobb képernyőt az alkalmazások megtekintéséhez.", "device": "Eszköz", "device-info": "Eszközinformációk", "device-info-description": "Információk az eszközödről", "device-info.device": "Eszköz", "device-info.model-number": "Modellszám", "device-info.serial-number": "Sorozatszám", "device-info.view-info": "Információ megtekintése", "device-name.home-or-pro": "Umbrel Home vagy Umbrel Pro", "disable": "Letiltás", "done": "Kész", "download-logs": "Naplók letöltése", "enabling-tor": "Távoli Tor-hozzáférés engedélyezése", "external-dns": "Cloudflare DNS", "external-dns-description": "A Cloudflare DNS jobb hálózati megbízhatóságot kínál. Kapcsold ki, ha a routered DNS beállításait szeretnéd használni.", "external-dns-error": "DNS-beállítás frissítése sikertelen: {{message}}", "external-drive": "Külső meghajtó", "factory-reset": "Gyári beállítások visszaállítása", "factory-reset-description": "Minden adatod és alkalmazásod törlése és az umbrelOS visszaállítása alapértelmezett beállításokra", "factory-reset-failed": "A készülék visszaállítása sikertelen: {{message}}", "factory-reset.confirm.body": "Erősítsd meg a jelszavad a visszaállításhoz", "factory-reset.confirm.ethernet-required-warning": "Bizonyosodj meg róla, hogy az eszközöd Ethernet-kábellel csatlakozik az útválasztódhoz (nem Wi-Fi-n keresztül), és a helyi hálózatodról éred el (pl. http://umbrel.local vagy az eszközöd helyi IP címe).", "factory-reset.confirm.submit": "Mindent törölni és visszaállítani", "factory-reset.confirm.submit-callout": "Ez a művelet nem vonható vissza.", "factory-reset.rebooting.message": "Az eszközöd újraindul, és minden adat törlődik. Kérjük, ne zárd be ezt az oldalt.", "factory-reset.rebooting.status": "Visszaállítás...", "factory-reset.rebooting.title": "Gyári visszaállítás folyamatban", "factory-reset.review.account-info": "Fiókinformációk és jelszó", "factory-reset.review.apps": "Alkalmazások", "factory-reset.review.following-will-be-removed": "A következő elemek kerülnek eltávolításra az eszközödről", "factory-reset.review.installed-apps_one": "{{count}} telepített alkalmazás", "factory-reset.review.installed-apps_other": "{{count}} telepített alkalmazás", "factory-reset.review.submit": "Folytatás", "factory-reset.review.total-data": "Összes adat", "files": "Files", "files-action.add-favorite": "Hozzáadás a kedvencekhez", "files-action.add-network-device": "Eszköz hozzáadása", "files-action.cancel-upload": "Feltöltés visszonása", "files-action.compress": "Tömörítés", "files-action.copy": "Másolás", "files-action.cut": "Kivágás", "files-action.delete": "Végleges törlés", "files-action.download": "Letöltés", "files-action.download-items": "{{count}} elem letöltése", "files-action.drop-to-upload": "Húzd ide a feltöltéshez", "files-action.eject-disk": "Kiadás", "files-action.empty-trash": "Kuka ürítése", "files-action.format-drive": "Formázás", "files-action.go-to-path": "Ugrás ide...", "files-action.new-folder": "Új mappa", "files-action.open": "Megnyitás", "files-action.paste": "Beillesztés", "files-action.remove-favorite": "Eltávolítás a kedvencek közül", "files-action.remove-network-host": "Hálózati meghajtó leválasztása", "files-action.remove-network-share": "Hálózati megosztás leválasztása", "files-action.rename": "Átnevezés", "files-action.restore": "Visszaállítás", "files-action.select": "Kiválasztás", "files-action.share": "Megosztás a hálózaton...", "files-action.sharing": "Megosztás...", "files-action.show-in-folder": "Megjelenítés a tartalmazó mappában", "files-action.trash": "Kuka", "files-action.uncompress": "Kicsomagolás", "files-action.upload": "Feltöltés", "files-add-network-share.add-manually": "Kézi hozzáadás", "files-add-network-share.add-share": "Megosztás hozzáadása", "files-add-network-share.back": "Vissza", "files-add-network-share.continue": "Folytatás", "files-add-network-share.description": "Csatlakozz egy NAS-hoz vagy más, a hálózatodon megosztott meghajtóhoz, hogy a Fájlokban elérhesd őket.", "files-add-network-share.discovering": "Keresés...", "files-add-network-share.enter-details-manually": "Add meg a szerver adatait", "files-add-network-share.host-label": "Szerver címe", "files-add-network-share.host-required": "Kötelező megadni a szerver címét", "files-add-network-share.manual-share-help": "Írd be a megosztás pontos nevét, ahogy az a szervereden szerepel", "files-add-network-share.no-shares-found": "Ezen a szerveren nem található megosztás", "files-add-network-share.not-seeing-share": "Nem látod a megosztásodat?", "files-add-network-share.password-label": "Jelszó", "files-add-network-share.password-required": "Kötelező megadni a jelszót", "files-add-network-share.retrieving-shares": "Megosztások lekérése...", "files-add-network-share.retry-discovery": "Hálózat újrakeresése", "files-add-network-share.select-share": "Válassz egy hozzáadandó megosztást", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Kötelező megadni a megosztást", "files-add-network-share.title": "Hálózati megosztás hozzáadása", "files-add-network-share.username-label": "Felhasználónév", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Kötelező megadni a felhasználónevet", "files-audio-island.now-playing": "Most szól", "files-audio-island.pause": "Szünet", "files-audio-island.play": "Lejátszás", "files-backend-error.base-directory-not-found": "Az alapkönyvtár nem található.", "files-backend-error.cant-find-root": "Nem sikerült ellenőrizni a fájl elérési útját.", "files-backend-error.destination-already-exists": "A célhelyen már létezik ugyanolyan nevű elem.", "files-backend-error.destination-not-exist": "A célmappa nem létezik.", "files-backend-error.does-not-exist": "A fájl vagy mappa nem létezik.", "files-backend-error.escapes-base": "Az elérési út az engedélyezett könyvtáron kívül esik.", "files-backend-error.invalid-base": "Az elérési út nem egy érvényes könyvtárhoz tartozik.", "files-backend-error.invalid-filename": "A fájlnév érvénytelen.", "files-backend-error.invalid-path": "Az elérési út érvénytelen.", "files-backend-error.mkdir-failed": "Nem sikerült létrehozni a mappát.", "files-backend-error.move-failed": "Nem sikerült áthelyezni az elemet.", "files-backend-error.not-enough-space": "Nincs elegendő tárhely.", "files-backend-error.operation-not-allowed": "Ez a művelet nem engedélyezett.", "files-backend-error.parent-not-directory": "A szülő útvonal nem mappa.", "files-backend-error.parent-not-exist": "A szülőmappa nem létezik.", "files-backend-error.path-not-absolute": "Az elérési út érvénytelen.", "files-backend-error.share-already-exists": "Ez a mappa már meg van osztva.", "files-backend-error.share-name-generation-failed": "Nem sikerült egyedi megosztási nevet generálni.", "files-backend-error.source-not-exists": "A forrásfájl vagy mappa nem létezik.", "files-backend-error.subdir-of-self": "Egy mappa nem másolható vagy mozgatható önmagába.", "files-backend-error.trash-meta-not-exists": "Nem található az elem eredeti helye.", "files-backend-error.unique-name-index-exceeded": "Nem sikerült egy egyedi nevet generálni. Túl sok hasonló nevű elem létezik.", "files-backend-error.upload-failed": "Feltöltés sikertelen.", "files-collision.action.keep-both": "Mindkettő megtartása", "files-collision.action.replace": "Felülírás", "files-collision.action.skip": "Kihagyás", "files-collision.destination.original-location": "az eredeti helyén", "files-collision.message": "Szeretnéd felülírni a meglévő elemet, vagy megtartani mindkettőt?", "files-collision.title": "\"{{itemName}}\" már létezik a(z) {{destinationName}} helyen", "files-download.confirm": "Letöltés", "files-download.description": "A Files nem tudja megnyitni ezt a fájltípust. Inkább letöltöd?", "files-download.title": "Letöltés: {{name}}?", "files-empty-trash.confirm": "Üres", "files-empty-trash.description": "Biztosan törölni szeretnéd véglegesen a kukában lévő összes elemet? Ezt a műveletet nem lehet visszavonni.", "files-empty-trash.title": "Kuka ürítése?", "files-empty.directory": "Nincsenek elemek ebben a mappában", "files-empty.network": "Nincsenek hálózati eszközök", "files-empty.network-host-offline": "Hálózati eszköz offline", "files-error.add-favorite": "Nem sikerült hozzáadni a kedvencekhez: {{message}}.", "files-error.add-share": "Nem sikerült megosztani a mappát: {{message}}.", "files-error.compress": "Nem sikerült tömöríteni: {{message}}.", "files-error.copy": "Nem sikerült másolni: {{message}}.", "files-error.create-folder": "Nem sikerült létrehozni a mappát: {{message}}.", "files-error.delete": "Nem sikerült törölni: {{message}}.", "files-error.eject-disk": "Nem sikerült a meghajtó kiadása: {{message}}.", "files-error.empty-trash": "Nem sikerült üríteni a kukát: {{message}}.", "files-error.extract": "Nem sikerült kicsomagolni: {{message}}.", "files-error.folder-already-exists": "Már létezik ilyen nevű mappa.", "files-error.move": "Nem sikerült áthelyezni: {{message}}.", "files-error.remove-favorite": "Nem sikerült eltávolítani a kedvencekből: {{message}}.", "files-error.remove-share": "Nem sikerült eltávolítani a megosztott mappát: {{message}}.", "files-error.rename": "Nem sikerült átnevezni: {{message}}.", "files-error.restore": "Nem sikerült visszaállítani: {{message}}.", "files-error.trash": "Nem sikerült áthelyezni a kukába: {{message}}.", "files-error.upload": "Nem sikerült feltölteni: {{message}}.", "files-error.upload-network-error": "A {{name}} feltöltése sikertelen: hálózati hiba történt.", "files-extension-change.confirm": "Folytatás", "files-extension-change.description-add": "Biztosan meg szeretnéd változtatni a(z) „{{fileName}}” fájlkiterjesztését „{{extension}}”-re? Ez a fájl olvashatatlanságát okozhatja.", "files-extension-change.description-remove": "Biztosan szeretnéd eltávolítani a(z) „{{fileName}}” fájlkiterjesztését?", "files-extension-change.title-add": "Kiterjesztés módosítása „{{extension}}”-re?", "files-extension-change.title-remove": "Kiterjesztés eltávolítása?", "files-external-storage.unsupported.description": "A csatlakoztatott külső meghajtó áramellátási problémák miatt nem használható Raspberry Pi-n. Külső tárhely elérhető az Umbrel Home-on, az Umbrel Pro-n és minden x86 (Intel vagy AMD) eszközön.", "files-external-storage.unsupported.description-general": "A Raspberry Pi-n a külső tárhely nem elérhető tápellátási problémák miatt. Külső tárhely elérhető az Umbrel Home-on, az Umbrel Pro-n és minden x86 (Intel vagy AMD) eszközön.", "files-external-storage.unsupported.title": "Külső tárhely nem támogatott", "files-folder": "Mappa", "files-format.confirm": "Formázás", "files-format.description": "A formázás törli a {{driveName}} összes adatát. Ez a művelet nem vonható vissza.", "files-format.description-unreadable": "Az umbrelOS nem tudja olvasni a {{driveName}} tartalmát. Formázhatod, így umbrelOS-sel használhatod.", "files-format.drive-label": "Név", "files-format.error": "Nem sikerült formázni a meghajtót", "files-format.exfat-description": "Legnagyobb kompatibilitás Windows, macOS és Linux rendszerekkel", "files-format.ext4-description": "Jobb teljesítmény umbrelOS és Linux rendszereken", "files-format.filesystem": "Fájlrendszer", "files-format.filesystem-label": "Formázás típusa", "files-format.formatting": "Formázás...", "files-format.title": "Meghajtó formázása", "files-format.title-requires-format": "Formázás szükséges", "files-formatting-island.formatting": "Formázás...", "files-formatting-island.formatting-drives": "Formázok {{count}} meghajtót", "files-listing.empty": "Nincsenek elemek", "files-listing.error": "Hiba történt", "files-listing.item-count-truncated": "{{formattedCount}}+ elem", "files-listing.item-count_one": "{{formattedCount}} elem", "files-listing.item-count_other": "{{formattedCount}} elem", "files-listing.loading": "Betöltés...", "files-listing.no-such-file": "Nincs ilyen fájl vagy mappa", "files-listing.selected-count": "{{selectedCount}} / {{totalCount}} kiválasztva", "files-listing.selected-count-truncated": "{{selectedCount}} a(z) {{totalCount}}+ elemből kiválasztva", "files-name-drawer.new-folder": "Új mappa", "files-name-drawer.new-folder-description": "Adj meg egy nevet az új mappának.", "files-name-drawer.new-folder-input": "Mappa neve", "files-name-drawer.rename-file": "Fájl átnevezése", "files-name-drawer.rename-file-description": "Adj meg egy új nevet ehhez a fájlhoz.", "files-name-drawer.rename-file-input": "Fájl neve", "files-name-drawer.rename-folder": "Mappa átnevezése", "files-name-drawer.rename-folder-description": "Adj meg egy új nevet ehhez a mappához.", "files-name-drawer.rename-folder-input": "Mappa neve", "files-network-storage-error.add-share": "Nem sikerült hozzáadni a hálózati megosztást: {{message}}.", "files-network-storage-error.discover-servers": "Hálózati eszközök felderítése sikertelen: {{message}}.", "files-network-storage-error.discover-shares": "Hálózati megosztások felderítése sikertelen: {{message}}.", "files-network-storage-error.remove-share": "Nem sikerült eltávolítani a hálózati megosztást: {{message}}.", "files-operations-island.copying": "Másolás \"{{from}}\" ide: \"{{to}}\"", "files-operations-island.moving": "Áthelyezés \"{{from}}\" ide: \"{{to}}\"", "files-operations-island.restoring": "\"{{from}}\" visszaállítása a(z) \"{{to}}\" helyre", "files-path.input-group": "Elérési út mező", "files-path.input-label": "Aktuális elérés", "files-permanently-delete.confirm": "Végleges törlés", "files-permanently-delete.description-multiple": "Biztosan véglegesen törölni szeretnéd ezt a(z) {{count}} elemet? Ez a művelet nem vonható vissza.", "files-permanently-delete.description-single": "Biztosan véglegesen törölni szeretnéd ezt: „{{fileName}}”? Ezt a műveletet nem lehet visszavonni.", "files-permanently-delete.title-multiple": "Végleges törlés a(z) {{count}} elemhez?", "files-permanently-delete.title-single": "Véglegesen törlöd?", "files-search.default": "Fájlok és mappák keresése", "files-search.no-results": "Nincsenek találatok a(z) \"{{query}}\" keresésre", "files-search.placeholder": "Keresés", "files-search.searching-label": "Keresés {{name}} Umbreljében", "files-share.home-description": "Érd el a(z) „{{homeDirectoryName}}” összes fájlját a hálózatodon található más eszközökről.", "files-share.home-title": "„{{homeDirectoryName}}” megosztása a hálózaton", "files-share.instructions.how-to-access": "Hogyan férj hozzá", "files-share.instructions.ios.enter-password": "Jelszóként add meg: {{password}}.", "files-share.instructions.ios.enter-server": "Írd be szervercímként: {{smbUrl}}.", "files-share.instructions.ios.enter-username": "Felhasználónévként add meg: {{username}}.", "files-share.instructions.ios.install-files": "Telepítsd a „Files” alkalmazást az App Store-ból, ha még nincs telepítve.", "files-share.instructions.ios.tap-connect": "Érintsd meg a „Csatlakozás” gombot a hozzáféréshez.", "files-share.instructions.ios.tap-dots": "Érintsd meg a jobb felső sarokban lévő három pontot (...), majd válaszd a „Csatlakozás szerverhez” lehetőséget.", "files-share.instructions.macos.click-connect": "Kattints a „Csatlakozás” gombra a hozzáféréshez.", "files-share.instructions.macos.enter-password": "Jelszóként add meg: {{password}}.", "files-share.instructions.macos.enter-url": "Írd be: {{smbUrl}}, majd kattints a „Csatlakozás” gombra.", "files-share.instructions.macos.enter-username": "Felhasználónévként add meg: {{username}}.", "files-share.instructions.macos.open-finder": "Nyisd meg a „Finder”-t, majd nyomd meg a ⌘ + K billentyűket.", "files-share.instructions.macos.select-registered": "Amikor a rendszer kéri, válaszd a „Regisztrált felhasználó” lehetőséget.", "files-share.instructions.macos.time-machine": "Hogyan használd Time Machine mentési helyként", "files-share.instructions.macos.time-machine.choose-encryption": "Döntsd el, hogy titkosított vagy titkosítatlan mentést szeretnél.", "files-share.instructions.macos.time-machine.disk-limit": "A „Lemezhasználati korlát” beállításnál add meg, mekkora helyet szeretnél kiosztani az Umbrel-en a Time Machine biztonsági mentésekhez, majd kattints a „Kész” gombra.", "files-share.instructions.macos.time-machine.follow-steps": "Kövesd a fenti lépéseket, majd nyisd meg a Rendszerbeállításokat a Maceden.", "files-share.instructions.macos.time-machine.go-settings": "Lépj be a Time Machine-be, majd kattints a „Biztonsági mentési lemez hozzáadása...” gombra.", "files-share.instructions.macos.time-machine.select-disk": "Válaszd ki a mappát, majd kattints a \"Set Up Disk...\"-re.", "files-share.instructions.umbrelos.backup.follow-onscreen": "Kövesd a lépésről lépésre vezetett utasításokat a biztonsági mentés beállításához.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Kövesd a fent leírt lépéseket, majd a másik Umbrelen nyisd meg a \"{{settings}}\" > \"{{backups}}\" menüpontot.", "files-share.instructions.umbrelos.backup.select-add": "Válaszd a \"{{addUmbrelOrNas}}\" opciót.", "files-share.instructions.umbrelos.backup.select-connected": "Válaszd ki ezt az Umbrel eszközt a csatlakoztatott eszközök listájából.", "files-share.instructions.umbrelos.backup.title": "Hogyan használd mentési helyként a másik Umbrel számára.", "files-share.instructions.umbrelos.cant-find-note": "Nem találod? Próbáld meg kiválasztani a \"Kézi hozzáadás\" opciót, és használd a következő hitelesítő adatokat. Ha még így sem tudod hozzáadni, győződj meg róla, hogy mindkét eszközöd ugyanazon a hálózaton van.", "files-share.instructions.umbrelos.enter-password": "Add meg {{password}} jelszóként.", "files-share.instructions.umbrelos.enter-username": "Add meg {{username}} felhasználónévként.", "files-share.instructions.umbrelos.open-and-click": "A másik Umbreleden nyisd meg \"Files\"-t, és kattints a -ra a \" {{deviceLabel}}\" mellett az oldalsávban.", "files-share.instructions.umbrelos.select-device": "Válaszd ki ezt az Umbrel eszközt a hálózatodon automatikusan észlelt eszközök listájából.", "files-share.instructions.umbrelos.select-sharename": "Válaszd ki a \"{{sharename}}\"-t, majd kattints a megosztás hozzáadásához.", "files-share.instructions.windows.enter-password": "Jelszóként add meg: {{password}}.", "files-share.instructions.windows.enter-url": "Írd be: {{smbUrl}}, majd nyomj Entert.", "files-share.instructions.windows.enter-username": "Felhasználónévként add meg: {{username}}.", "files-share.instructions.windows.open-run": "Nyomd meg a Windows + R billentyűket a Futtatás ablak megnyitásához.", "files-share.instructions.windows.remember-credentials": "Pipáld be a „Remember my credentials” lehetőséget, majd kattints az OK gombra.", "files-share.regular-description": "Oszd meg ezt a mappát, hogy más eszközökről is elérhesd a hálózatodon keresztül.", "files-share.regular-title": "Mappa megosztása a hálózaton", "files-share.toggle": "„{{name}}” megosztása a hálózatodon", "files-sidebar.apps": "Alkalmazások", "files-sidebar.external-storage": "Külső tárhely", "files-sidebar.favorites": "Kedvencek", "files-sidebar.home": "Saját mappa", "files-sidebar.navigation": "Fájlböngészés", "files-sidebar.network": "Hálózat", "files-sidebar.network-pathbar": "Hálózati eszközök", "files-sidebar.network-sidebar": "Eszközök", "files-sidebar.recents": "Legutóbbiak", "files-sidebar.shared-folders": "Megosztott mappák", "files-sidebar.trash": "Kuka", "files-sidebar.trash.open": "Megnyitás", "files-sort.created": "Hozzáadva", "files-sort.modified": "Módosítva", "files-sort.name": "Név", "files-sort.size": "Méret", "files-sort.type": "Típus", "files-state.uploading": "Feltöltés...", "files-state.waiting": "Várakozás...", "files-type.3gp": "3GP videó", "files-type.3gp2": "3GP2 videó", "files-type.7z": "7Z archívum", "files-type.aac": "AAC hang", "files-type.ai": "Illustrator fájl", "files-type.aiff": "AIFF hang", "files-type.au": "AU hang", "files-type.avi": "AVI videó", "files-type.avif": "AVIF kép", "files-type.bmp": "BMP kép", "files-type.bzip2": "BZIP2 archívum", "files-type.caf": "CAF hang", "files-type.compressed": "Tömörített archívum", "files-type.csv": "CSV fájl", "files-type.directory": "Mappa", "files-type.dmg": "Lemezkép", "files-type.dv": "DV videó", "files-type.epub": "EPUB e-könyv", "files-type.excel": "Excel táblázat", "files-type.exe": "Windows futtatható fájl", "files-type.executable": "Futtatható fájl", "files-type.external-drive": "Meghajtó", "files-type.flac": "FLAC hang", "files-type.flv": "FLV videó", "files-type.gif": "GIF kép", "files-type.gzip": "GZIP archívum", "files-type.heic": "HEIC kép", "files-type.ico": "ICO kép", "files-type.iso": "ISO lemezkép", "files-type.jpeg": "JPEG kép", "files-type.keynote": "Keynote bemutató", "files-type.lzip": "LZIP archívum", "files-type.lzma": "LZMA archívum", "files-type.lzop": "LZOP archívum", "files-type.m3u": "M3U lejátszási lista", "files-type.m4a": "M4A hang", "files-type.m4v": "M4V videó", "files-type.midi": "MIDI hang", "files-type.mka": "MKA hang", "files-type.mkv": "MKV videó", "files-type.mng": "MNG videó", "files-type.mobi": "MOBI e-könyv", "files-type.mp3": "MP3 hang", "files-type.mp4": "MP4 videó", "files-type.mp4-audio": "MP4 hang", "files-type.mpeg": "MPEG videó", "files-type.mpeg-ts": "MPEG transport stream", "files-type.network-drive": "Hálózati meghajtó", "files-type.numbers": "Numbers táblázat", "files-type.ogg": "OGG hang", "files-type.ogv": "OGV videó", "files-type.pages": "Pages dokumentum", "files-type.pdf": "PDF dokumentum", "files-type.png": "PNG kép", "files-type.powerpoint": "PowerPoint bemutató", "files-type.psd": "Photoshop dokumentum", "files-type.quicktime": "QuickTime videó", "files-type.rar": "RAR archívum", "files-type.sgi": "SGI videó", "files-type.svg": "SVG kép", "files-type.tar": "TAR archívum", "files-type.tiff": "TIFF kép", "files-type.ts": "TS videó", "files-type.txt": "Szöveges fájl", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "WAV hang", "files-type.webm": "WebM videó", "files-type.webm-audio": "WebM hang", "files-type.webp": "WebP kép", "files-type.wma": "WMA hang", "files-type.wmv": "WMV videó", "files-type.word": "Word dokumentum", "files-type.xz": "XZ archívum", "files-type.zip": "ZIP archívum", "files-upload-island.uploading-count": "{{count}} elem feltöltése folyamatban", "files-view.icons": "Ikonok", "files-view.list": "Lista", "files-view.sort-by": "Rendezés", "files-view.view-as": "Megjelenítés", "files-widgets.favorites.no-items-text": "Adj hozzá egy mappát a Kedvencekhez, hogy itt megjelenjen", "files-widgets.recents.no-items-text": "Nincsenek legutóbbi fájlok", "generic-in": "in", "hide-details": "Részletek elrejtése", "install-first.install-app": "Telepítsd a(z) {{app}} alkalmazást", "install-first.title": "{{app}} a következő alkalmazásokat igényli", "install-your-first-app": "Telepítsd az első alkalmazásod", "language": "Nyelv", "language-description": "Az általad preferált umbrelOS nyelv", "language.select-description": "Válaszd ki az umbrelOS preferált nyelvét", "live-usage": "Élő használat", "loading": "Betöltés", "local-ip": "Helyi IP", "login-2fa.subtitle": "Add meg a hitelesítő alkalmazásod által megjelenített 2FA kódot", "login-2fa.title": "Hitelesítés", "login-with-umbrel.description": "Add meg az Umbrel jelszavad a(z) {{app}} megnyitásához", "login-with-umbrel.title": "Bejelentkezés Umbrel-lel", "login.password-label": "Jelszó", "login.password.submit": "Bejelentkezés", "login.subtitle": "Add meg az Umbrel jelszavad a bejelentkezéshez", "login.title": "Üdv újra", "logout": "Kijelentkezés", "logout-error-generic": "Hiba: Kijelentkezés sikertelen", "logout.confirm.submit": "Kijelentkezés", "logout.confirm.title": "Biztosan kijelentkezel?", "memory": "Memória", "memory.low": "Kevés memória", "migrate": "Átvitel", "migrate.callout": "Ne kapcsold ki az Umbrel-t, amíg az átvitel be nem fejeződik", "migrate.failed.retry": "Újrapróbálás", "migrate.failed.title": "Átvitel sikertelen", "migrate.success.description": "Az összes alkalmazásod, alkalmazásadataid és fiókadataid át lettek helyezve az Umbrel Home-ba.", "migrate.success.title": "Sikeres átvitel", "migration-assistant": "Átvitel Segéd", "migration-assistant-description": "Az összes alkalmazásod és adataid átvitele egy Raspberry Pi-ről a {{deviceName}}-re.", "migration-assistant-unsupported-device-description": "A Migration Assistant jelenleg támogatja az összes adat és alkalmazás átvitelét egy umbrelOS-sel futó Raspberry Pi-ről Umbrel Home-ra vagy Umbrel Pro-ra. A folytatáshoz nyisd meg a Migration Assistantet az Umbrel Home vagy Umbrel Pro eszközödön.", "migration-assistant.continue-migration.ready.submit": "Átvitel indítása", "migration-assistant.failed": "Valami nem stimmel...", "migration-assistant.failed.retrying-message": "Újrapróbálkozás...", "migration-assistant.mobile.start-button": "Átvitel indítása", "migration-assistant.prep.body": "Készülj fel az átvitelre", "migration-assistant.prep.button-continue": "Folytatás", "migration-assistant.prep.callout": "A {{deviceName}}-en található adatok, ha vannak, véglegesen törlődnek.", "migration-assistant.prep.connect-disk-to-home": "Csatlakoztasd a külső meghajtót a {{deviceName}} bármelyik USB-portjához.", "migration-assistant.prep.prep-done-continue-message": "Miután végeztél, kattints az alábbi '{{button}}' gombra.", "migration-assistant.prep.shut-down-rpi": "Kapcsold ki a Raspberry Pi Umbrel-t.", "migration-assistant.ready.description": "Az összes adatod és alkalmazásod készen áll az átvitelre a {{deviceName}}-re.", "migration-assistant.ready.hint-header": "Fontos megjegyezni", "migration-assistant.ready.hint-keep-pi-off.description": "Ez segít megelőzni a problémákat az olyan alkalmazásokkal, mint a Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Tartsd kikapcsolva a Raspberry Pi-t a frissítés után", "migration-assistant.ready.hint-use-same-password.description": "Ne feledd: a {{deviceName}}-be való bejelentkezéshez használd a Raspberry Pi Umbrel jelszavadat.", "migration-assistant.ready.hint-use-same-password.title": "Használd ugyanazt a jelszót", "migration-assistant.ready.title": "Készen állsz az átvitelre!", "mini-browser.default-title": "Mappa kiválasztása", "mini-browser.empty-external": "Csatlakoztass egy külső meghajtót, hogy itt megjelenjen.", "mini-browser.empty-network": "Adj hozzá egy Umbrel-t vagy NAS-t, hogy itt megjelenjen.", "mini-browser.load-more": "Tovább", "mini-browser.load-more-in-folder": "Tovább betöltése itt: {{name}}", "mini-browser.loading-more": "Továbbiak betöltése…", "mini-browser.select": "Válassz", "mini-browser.select-folder": "Mappa kiválasztása", "name": "Név", "nas": "NAS", "no-forgot-password-message": "Ha elveszted a jelszavad, nem fogsz tudni bejelentkezni az Umbrel-be. Biztosítsd, hogy biztonságosan tárolod.", "no-results-found": "Nincs találat", "not-found-404": "Hibakód: 404", "not-found-404.back": "Vissza", "not-found-404.home": "Vissza a Főoldalra", "notifications.backups-failing-location.description": "Az automatikus Backups a(z) {{location}}-ra nem sikerültek. Ellenőrizd a csatlakozást, és nézd át a Backups beállításait.", "notifications.backups-failing.description": "Az automatikus Backups sikertelenek. Ellenőrizd a backup helyét, és nézd át a beállításaidat.", "notifications.backups-failing.go-to-backups": "Nyisd meg a Backups-ot", "notifications.backups-failing.title": "Az elmúlt 24 órában nem voltak Backups.", "notifications.cpu.too-hot": "Magas CPU hőmérséklet", "notifications.memory.low": "Az eszközöd memóriája alacsony", "notifications.new-version-available": "{{update}} most elérhető a telepítéshez", "notifications.raid.issue.description": "Tárolási probléma észlelve. Részletekért ellenőrizd a Storage Managert.", "notifications.raid.issue.title": "Sürgős intézkedés szükséges", "notifications.ssd.health.description": "Előfordulhat, hogy egy vagy több SSD figyelmet igényel. Részletekért ellenőrizd a Storage Managert.", "notifications.ssd.health.title": "SSD állapotfigyelmeztetés", "notifications.storage.full": "Az eszközöd tárhelye megtelt", "notifications.view": "Megtekintés", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "A 'Tovább' gombra kattintva elfogadod az umbrelOS Felhasználási feltételeit", "onboarding.account-created.youre-all-set-name": "Minden készen áll, {{name}}.", "onboarding.contact-support": "Támogatás", "onboarding.create-account": "Fiók létrehozása", "onboarding.create-account.confirm-password.input-label": "Jelszó megerősítése", "onboarding.create-account.failed.name-required": "A név megadása kötelező", "onboarding.create-account.failed.passwords-dont-match": "A jelszavak nem egyeznek", "onboarding.create-account.name.input-placeholder": "A te neved", "onboarding.create-account.password.input-label": "Jelszó", "onboarding.create-account.submit": "Létrehozás", "onboarding.create-account.submitting": "Létrehozás folyamatban", "onboarding.create-account.subtitle": "Az fiók információk csak az Umbrel-eden tárolódnak. Biztosítsd, hogy biztonságosan tárolod a jelszavad, mivel nincs mód annak visszaállítására.", "onboarding.create-instead-long": "Új fiók létrehozása", "onboarding.create-instead-short": "Új fiók", "onboarding.launch-umbrelos": "Indítsd el az umbrelOS-t", "onboarding.raid.available-storage": "Elérhető tárhely", "onboarding.raid.change-drives-link": "Szeretnél meghajtót hozzáadni vagy cserélni?", "onboarding.raid.configuring.subtitle": "Ez néhány percet igénybe vehet.", "onboarding.raid.configuring.title": "A tárhelyed konfigurálása", "onboarding.raid.configuring.warning": "Kérlek, ne frissítsd az oldalt és ne kapcsold ki az Umbrelt, amíg a tárhelyed konfigurálódik.", "onboarding.raid.continue": "Tovább", "onboarding.raid.error.detection-instructions": "Kapcsold ki az Umbrel Pro-t, ellenőrizd, hogy az SSD-k rendesen a helyükön vannak-e, majd próbáld újra.", "onboarding.raid.error.no-ssds-detected": "Nem találhatók SSD-k", "onboarding.raid.error.no-ssds-instructions": "Kapcsold ki az Umbrel Pro-t, és helyezz be legalább egy SSD-t a folytatáshoz.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "A FailSafe még nem kapcsolható be", "onboarding.raid.failsafe.enable": "FailSafe engedélyezése", "onboarding.raid.failsafe.mixed-sizes": "A FailSafe a legkisebb SSD-d mérete ({{smallest}}) alapján lesz korlátozva. A nagyobb SSD-ken lévő extra hely nem használható, így {{wasted}} lesz használhatatlan.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} az adatok védelmét szolgálja. Adj hozzá még egy {{smallest}} SSD-t, hogy az elérhető tárhely {{futureWith3}}-re növekedjen, vagy adj kettőt a {{futureWith4}}-hez. Bármikor hozzáadhatsz további SSD-ket.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} az adatok védelmét szolgálja. Adj még egy {{smallest}} SSD-t az elérhető tárhely {{futureWith4}}-re növeléséhez. Bármikor hozzáadhatsz további SSD-ket.", "onboarding.raid.failsafe.single-ssd-info": "Csak egy SSD-d van. Adj hozzá legalább még egy {{size}} SSD-t, hogy bekapcsolhasd a FailSafe védelmet az adataid számára. Bármikor hozzáadhatsz további SSD-ket.", "onboarding.raid.failsafe.subtitle": "Az adataid biztonságban maradnak, ha egy SSD meghibásodik", "onboarding.raid.failsafe.tip": "A legtöbb tárhely és nulla használhatatlan hely érdekében használj egyforma méretű SSD-ket.", "onboarding.raid.failsafe.warning-now-only": "Ha több SSD van, a FailSafe csak az első beállítás során kapcsolható be. Később nem lesz lehetőséged bekapcsolni.", "onboarding.raid.health-warning": "Ez a meghajtó állapotproblémákat jelez", "onboarding.raid.launching": "Indítás...", "onboarding.raid.no-ssds-alt": "Nem találhatók SSD-k", "onboarding.raid.recommended": "Ajánlott", "onboarding.raid.scanning": "Az SSD foglalatok ellenőrzése", "onboarding.raid.scanning-alt": "SSD-k beolvasása", "onboarding.raid.setup-failed.description-no-retry": "Kapcsold ki az eszközt, majd próbáld újra.", "onboarding.raid.setup-failed.description-retry": "Próbáld újra, vagy kapcsold ki az eszközt és ellenőrizd a meghajtókat.", "onboarding.raid.setup-failed.title": "A tárhely beállítása sikertelen", "onboarding.raid.shutdown-dialog.description": "A meghajtók hozzáadásához vagy cseréjéhez kapcsold ki az Umbrel Pro-t. Ha végeztél, kapcsold vissza és folytathatod a beállítást.", "onboarding.raid.shutdown-dialog.title": "Meghajtókat cserélsz?", "onboarding.raid.ssd-in-slot": "Egy {{size}} SSD a Foglalat {{slot}}-ban", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSD-tálca", "onboarding.raid.ssds-found": "Az alábbi SSD-ket találtuk az Umbrel Pro-ban", "onboarding.raid.storage": "Tárhely", "onboarding.raid.storage-label": "Tárhely", "onboarding.raid.success.storage-info": "Tárhely {{available}}", "onboarding.raid.success.storage-info-failsafe": "Tárhely {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Próbáld újra", "onboarding.raid.wasted": "Használhatatlan", "onboarding.restore-long": "Umbrel visszaállítása", "onboarding.restore-short": "Visszaállítás", "onboarding.start.continue": "Vágj bele", "onboarding.start.subtitle": "Az otthoni felhő szervered készen áll a beállításra.", "onboarding.start.title": "Üdvözöl az umbrelOS", "open": "Megnyitás", "open-live-usage": "Élő használat megnyitása", "password": "Jelszó", "preferences": "Beállítások", "raid-error.description": "A tárolórendszered nem indult el rendesen. Ellenőrizd az alábbi SSD-k állapotát, és kövesd a hibaelhárítási lépéseket. Ha a probléma továbbra is fennáll, az érintett SSD-ket cserélni kell.", "raid-error.factory-reset-dialog.description": "Ez töröl minden adatot az Umbrel Pro-ról és visszaállítja a gyári beállításokat. Ezt a műveletet nem lehet visszavonni.", "raid-error.factory-reset-dialog.title": "Gyári visszaállítás?", "raid-error.factory-reset-failed": "Nem sikerült a gyári visszaállítás", "raid-error.health-warning": "Állapotfigyelmeztetés", "raid-error.missing-ssd-multiple": "{{count}} SSD nem válaszolnak", "raid-error.missing-ssd-one": "1 SSD nem válaszol", "raid-error.shutdown-dialog.description": "Kapcsold ki az Umbrel Pro-t, ellenőrizd, hogy minden SSD rendesen a foglalataiban van, majd kapcsold vissza.", "raid-error.shutdown-dialog.title": "Leállítsuk a készüléket az SSD-k ellenőrzéséhez?", "raid-error.ssd-in-slot": "Egy {{size}} SSD a {{slot}}. foglalatban", "raid-error.step-check-connections.button": "Leállítás", "raid-error.step-check-connections.description": "Kapcsold ki a készüléket, és ellenőrizd, hogy minden SSD megfelelően a helyén van.", "raid-error.step-check-connections.title": "Ellenőrizd az SSD-k csatlakozását", "raid-error.step-factory-reset.button": "Gyári visszaállítás", "raid-error.step-factory-reset.description": "Végső megoldás, ha semmi más nem segít. Ez minden adatot töröl.", "raid-error.step-factory-reset.title": "Gyári visszaállítás", "raid-error.step-restart.button": "Újraindítás", "raid-error.step-restart.description": "Gyors első lépés, ami gyakran segít.", "raid-error.step-restart.title": "Próbáld meg újraindítani", "raid-error.title": "Tárolási probléma észlelve", "read-less": "Kevesebb olvasása", "read-more": "Több olvasása", "reconnect": "Újracsatlakozás", "redirect.to-home": "Betöltés...", "redirect.to-login": "Betöltés...", "redirect.to-onboarding": "Betöltés...", "redirect.to-raid-error": "Betöltés...", "reload": "Újratöltés", "remote-tor-access": "Távoli Tor hozzáférés", "reset": "Visszaállítás", "restart": "Újraindítás", "restart.confirm.submit": "Újraindítás", "restart.confirm.title": "Biztosan újra akarod indítani az Umbrel-t?", "restart.restarting": "Újraindítás", "restart.restarting-message": "Ne frissítsd ezt az oldalt vagy kapcsold ki az Umbrel-t, amíg újraindul.", "rewind": "Rewind", "rewind.files-as-of": "Fájljaid állapota erre a dátumra:", "rewind.loading-snapshots": "Pillanatképek betöltése...", "rewind.now": "Most", "rewind.preflight.description": "Találd meg a fájlokat és mappákat a korábbi backupjaidból, és állítsd vissza őket a jelenbe.", "rewind.preflight.enable-backups": "Állítsd be a Backups-t a Beállításokban, hogy elkezdhessed a Rewind használatát", "rewind.restore-complete": "Visszaállítás befejezve", "rewind.restore-error-description": "Kérlek, próbáld újra.", "rewind.restore-failed": "Visszaállítás sikertelen", "rewind.restore-running-description": "Ne zárd be és ne frissítsd az oldalt, amíg a visszaállítás be nem fejeződik.", "rewind.restore-selected": "Kijelöltek visszaállítása", "rewind.restore-success-description": "A fájljaid visszaállítva.", "rewind.restoring": "Visszaállítás folyamatban", "rewind.snapshots-count_one": "{{count}} backup óta", "rewind.snapshots-count_other": "{{count}} backup óta", "search": "Keresés", "settings": "Beállítások", "settings.app-store-preferences.title": "Alkalmazásbolt beállításai", "settings.contact-support": "Segítségre van szükséged? Lépj kapcsolatba a támogatással.", "settings.file-sharing": "Fájlmegosztás", "settings.file-sharing.add-folder": "Hozzáadás", "settings.file-sharing.add-folder-title": "Válassz egy mappát megosztáshoz", "settings.file-sharing.choice-entire-description": "Oszd meg az Umbreleden lévő összes fájlt", "settings.file-sharing.choice-entire-title": "Minden", "settings.file-sharing.choice-heading": "Mit szeretnél megosztani?", "settings.file-sharing.choice-specific-description": "Válaszd ki, mely mappákat szeretnéd megosztani.", "settings.file-sharing.choice-specific-title": "Kiválasztott mappák", "settings.file-sharing.choice-subtitle": "Elérheted a fájljaidat és mappáidat Dropbox-szerűen, hálózati mappaként a számítógépeden vagy a telefonodon.", "settings.file-sharing.configure": "Beállítás", "settings.file-sharing.description": "Elérheted a fájljaidat Dropbox-szerűen, hálózati mappaként (SMB) más eszközökről.", "settings.file-sharing.home-shared-note": "Az egész \"{{homeDirectoryName}}\" mappád meg van osztva. Az egyes mappákat külön nem kell megosztanod.", "settings.file-sharing.share-entire-home-dir": "Oszd meg az egész Home mappádat", "settings.file-sharing.share-entire-home-dir-description": "A hálózatodon lévő más eszközökről elérheted a \"{{homeDirectoryName}}\" összes fájlját és mappáját.", "settings.file-sharing.shared-folders": "Megosztott mappák", "show-details": "Részletek megjelenítése", "shut-down": "Leállítás", "shut-down.complete": "Leállítás kész", "shut-down.complete-text": "Most már kihúzhatod az eszközt az áramforrásból.", "shut-down.confirm.submit": "Leállítás", "shut-down.confirm.title": "Biztosan le akarod állítani az Umbrel-t?", "shut-down.failed": "Leállítás sikertelen: {{message}}", "shut-down.shutting-down": "Leállítás", "shut-down.shutting-down-message": "Ne frissítsd ezt az oldalt vagy kapcsold ki az Umbrel-t, amíg leáll.", "software-update.callout": "Ne frissítsd ezt az oldalt vagy kapcsold ki az Umbrel-t, amíg frissít.", "software-update.check": "Frissítés ellenőrzése", "software-update.checking": "Frissítés ellenőrzése...", "software-update.current-running": "Az aktuális verzió", "software-update.failed": "Frissítés sikertelen", "software-update.failed-to-check": "Nem sikerült ellenőrizni a frissítéseket", "software-update.failed.retry": "Újrapróbálás", "software-update.install-now": "Telepítés most", "software-update.new-version": "Új {{name}} elérhető a telepítéshez", "software-update.on-latest": "A legfrissebb umbrelOS verziót használod", "software-update.see-whats-new": "Nézd meg a újdonságokat", "software-update.title": "Szoftverfrissítés", "software-update.updating-to": "{{name}} frissítése", "software-update.view": "Megtekintés", "something-left": "{{left}} maradt", "something-went-wrong": "⚠ Valami hiba történt", "start": "Indítás", "stop": "Leállítás", "storage": "Tárhely", "storage-manager": "Tárolókezelő", "storage-manager.add": "Hozzáadás", "storage-manager.add-to-raid.add-ssd": "SSD hozzáadása", "storage-manager.add-to-raid.available": "Elérhető:", "storage-manager.add-to-raid.description": "Új SSD lett észlelve, és készen áll a hozzáadásra.", "storage-manager.add-to-raid.enable-failsafe": "FailSafe engedélyezése", "storage-manager.add-to-raid.failed-add": "Nem sikerült hozzáadni az SSD-t.", "storage-manager.add-to-raid.failed-enable-failsafe": "Nem sikerült bekapcsolni a FailSafe-t.", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Az új {{size}} SSD hozzáadódik az elérhető tárhelyhez.", "storage-manager.add-to-raid.info-capacity-adds-available": "Az új {{size}} SSD {{available}} elérhető tárhelyet ad hozzá.", "storage-manager.add-to-raid.info-capacity-adds-both": "Az új {{size}} SSD {{available}} elérhető tárhelyet és {{protection}} adatvédelmet ad hozzá.", "storage-manager.add-to-raid.info-capacity-protection-only": "Az új {{size}} SSD {{protection}} adatvédelmet ad hozzá.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Az új {{size}} SSD teljes egészében az adatok védelmére lesz használva.", "storage-manager.add-to-raid.info-data-safe": "Ha egy SSD meghibásodik, az adataid biztonságban lesznek.", "storage-manager.add-to-raid.info-no-protection": "Ha egy SSD meghibásodik, elveszítheted az adataidat.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} összesen használhatatlan a különböző SSD-méretek miatt.", "storage-manager.add-to-raid.info-wasted": "{{size}} használhatatlan lesz a különböző SSD-méretek miatt.", "storage-manager.add-to-raid.recommended": "Ajánlott", "storage-manager.add-to-raid.recommended-inline": "(ajánlott)", "storage-manager.add-to-raid.restart-active-tasks": "Az aktív feladatok megszakadnak", "storage-manager.add-to-raid.restart-after": "Az újraindítás után a FailSafe beállítása automatikusan befejeződik, és folytathatod a normál használatot.", "storage-manager.add-to-raid.restart-during": "Az újraindítás közben:", "storage-manager.add-to-raid.restart-intro": "A folyamat alatt továbbra is normálisan használhatod az umbrelOS-t. Azonban 50% elérésénél az Umbrel automatikusan újraindul.", "storage-manager.add-to-raid.restart-required": "Rendszer újraindítás szükséges", "storage-manager.add-to-raid.restart-ui-inaccessible": "Az umbrelOS ideiglenesen nem lesz elérhető", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD a {{slot}}. foglalatban", "storage-manager.add-to-raid.title": "SSD hozzáadása a tárhelyhez", "storage-manager.add-to-raid.too-small": "Az SSD túl kicsi", "storage-manager.add-to-raid.too-small-description": "Ez az SSD ({{deviceSize}}) kisebb, mint a jelenleg telepített legkisebb SSD ({{minSize}}). A FailSafe megköveteli, hogy minden SSD legalább akkora legyen, mint a legkisebb használt SSD.", "storage-manager.add-to-raid.understand-continue": "Értem, folytatom", "storage-manager.add-to-raid.warning-failsafe-now-only": "Ha több SSD-d van, a FailSafe-et most kell engedélyezni. Később már nem lesz lehetőség bekapcsolni.", "storage-manager.add-to-raid.wasted-label": "Használhatatlan:", "storage-manager.available-storage": "Elérhető tárhely", "storage-manager.description": "Az SSD-k tárhelyének, állapotának és beállításainak megtekintése", "storage-manager.empty": "Üres", "storage-manager.failsafe-transition-failed": "Nem sikerült bekapcsolni a FailSafe-t.", "storage-manager.for-failsafe": "FailSafe-hez", "storage-manager.health.checksum-errors": "Ellenőrzőösszeg-hibák: {{count}}", "storage-manager.health.critical": "Kritikus", "storage-manager.health.critical-threshold": "Kritikus szint", "storage-manager.health.current-temperature": "Aktuális hőmérséklet", "storage-manager.health.estimated-life": "Becsült hátralévő élettartam", "storage-manager.health.general": "Általános", "storage-manager.health.health-status": "Állapot", "storage-manager.health.low": "Alacsony", "storage-manager.health.model-and-capacity": "Modell és méret", "storage-manager.health.overheating": "Túlmelegedés", "storage-manager.health.raid-failed-advice": "Ennek az SSD-nek problémája van. Kapcsold ki az Umbrelt, és ellenőrizd az SSD csatlakozását. Ha a hiba továbbra is fennáll, lehet, hogy ki kell cserélni az SSD-t.", "storage-manager.health.read-errors": "Olvasási hibák: {{count}}", "storage-manager.health.serial-number": "Sorozatszám", "storage-manager.health.status-healthy": "Egészséges", "storage-manager.health.status-unhealthy": "Rossz állapot", "storage-manager.health.status-unknown": "Ismeretlen", "storage-manager.health.temperature": "Hőmérséklet", "storage-manager.health.title": "SSD állapota", "storage-manager.health.warning-life-advice": "Érdemes lehet hamarosan kicserélni ezt az SSD-t.", "storage-manager.health.warning-life-message": "Csak {{percent}}% élettartam maradt", "storage-manager.health.warning-temp-advice": "Győződj meg róla, hogy az Umbrel Pro megfelelő légáramlással rendelkezik, és az SSD rendesen be van helyezve.", "storage-manager.health.warning-temp-critical": "A hőmérséklet kritikus ({{temperature}})", "storage-manager.health.warning-temp-overheating": "A meghajtó túlmelegszik ({{temperature}})", "storage-manager.health.warning-threshold": "Figyelmeztetési küszöb", "storage-manager.health.warning-unhealthy-advice": "Ez az SSD hamarosan meghibásodhat. Fontold meg a cseréjét.", "storage-manager.health.warning-unhealthy-message": "Lehet, hogy az SSD-vel probléma van.", "storage-manager.health.warnings": "Figyelmeztetések", "storage-manager.health.wear": "Elhasználódás", "storage-manager.health.write-errors": "Írási hibák: {{count}}", "storage-manager.install-ssd.description": "Adj hozzá több SSD-t a tárhely bővítéséhez", "storage-manager.install-ssd.step-insert": "Helyezd be az új SSD-ket az üres foglalatokba", "storage-manager.install-ssd.step-power-on": "Kapcsold be a {{deviceName}}-t", "storage-manager.install-ssd.step-remove-bottom-cover": "Távolítsd el a mágneses alsó fedőlapot", "storage-manager.install-ssd.step-replace-bottom-cover": "Tedd vissza az alsó fedelet", "storage-manager.install-ssd.step-return": "Térj vissza ide, hogy hozzáadd az SSD-ket a tárhelyhez", "storage-manager.install-ssd.step-shut-down": "Kapcsold ki a {{deviceName}}-t", "storage-manager.install-ssd.title": "SSD-k hozzáadása", "storage-manager.install-tips.image-alt": "SSD beszerelési útmutató", "storage-manager.install-tips.instructions": "A telepítéshez csavard ki a kézi csavart, majd ferdén csúsztasd be az SSD-t a foglalatba. Nyomd le az SSD-t, amíg rá nem ül a csavartartóra, majd rögzítsd a kézi csavarral.", "storage-manager.install-tips.toggle": "Elfelejtetted, hogyan kell egy SSD-t behelyezni?", "storage-manager.manage": "Kezelés", "storage-manager.missing-ssd-warning": "Úgy tűnik, egy SSD hiányzik. Kapcsold ki az Umbrelt, és ellenőrizd, hogy minden SSD csatlakoztatva van-e. Ha a probléma továbbra is fennáll, lehet, hogy ki kell cserélni az SSD-t.", "storage-manager.mode": "Mód", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Megvédi az adataidat, ha egy SSD meghibásodik. Ha az SSD-k különböző méretűek, a nagyobbakon lévő extra hely nem használható.", "storage-manager.mode.failsafe.info-description": "A FailSafe megvédi az adataidat azzal, hogy másolatokat tart az SSD-ken. Ha bármelyik SSD meghibásodik, az adataid biztonságban maradnak, és visszaállíthatók, amikor behelyezel egy csere SSD-t.", "storage-manager.mode.failsafe.info-title": "A FailSafe-ről", "storage-manager.mode.full-storage": "Full Storage", "storage-manager.mode.full-storage.description": "Használd az összes SSD helyét egyben. Ha egy SSD meghibásodik, elveszítheted az adataidat.", "storage-manager.mode.full-storage.info-description": "A Full Storage az összes SSD-t egy nagy közös tárhellyé egyesíti, így maximális tárhelyet kapsz. Azonban ha bármelyik SSD meghibásodik, az összes adatod elveszik.", "storage-manager.mode.full-storage.info-title": "A Full Storage-ról", "storage-manager.mode.switch-from-failsafe-unavailable": "A FailSafe-ről Full Storage módra váltáshoz biztonsági mentést kell készítened, gyári visszaállítást kell végrehajtani a készüléken, majd visszaállítani a mentésből.", "storage-manager.mode.switch-to-failsafe-unavailable": "Több SSD esetén Full Storage módban az adataid az összes meghajtón szétoszlanak. FailSafe módra váltáshoz biztonsági mentést kell készítened, gyári visszaállítást végrehajtani és visszaállítani.", "storage-manager.mode.why-cant-switch": "Miért nem tudok váltani?", "storage-manager.operation-in-progress.shutdown-description": "Biztonságos kikapcsolni. A művelet szünetel, és folytatódik az újraindítást követően, de be kell fejeződnie, mielőtt más módosításokat végezhetsz.", "storage-manager.operation-in-progress.shutdown-title": "A tárhelyed frissítése folyamatban van", "storage-manager.operation-in-progress.wait-description": "Várj, amíg az aktuális művelet befejeződik, mielőtt további módosításokat végeznél.", "storage-manager.operation-in-progress.wait-title": "A tárhelyed frissítése folyamatban van", "storage-manager.operation.adding-ssd": "SSD hozzáadása...", "storage-manager.operation.enabling-failsafe": "FailSafe engedélyezése...", "storage-manager.operation.expanding": "Tárhely bővítése...", "storage-manager.operation.rebuilding": "Adatok újjáépítése...", "storage-manager.operation.replacing": "Meghajtó cseréje...", "storage-manager.operation.restarting": "Újraindítás...", "storage-manager.operation.starting": "Indítás...", "storage-manager.operation.syncing-restarts": "Adatok szinkronizálása • 50%-nál újraindul", "storage-manager.raid-status.degraded": "Csökkentett", "storage-manager.raid-status.failed": "Meghibásodott", "storage-manager.raid-status.offline": "Offline", "storage-manager.raid-status.online": "Online", "storage-manager.raid-status.removed": "Eltávolítva", "storage-manager.raid-status.unavailable": "Nem elérhető", "storage-manager.replace": "Cserélés", "storage-manager.replace-failed.degraded": "A FailSafe védelem csökkent", "storage-manager.replace-failed.degraded-description": "Egy SSD hiányzik a FailSafe tárolódból. Cseréld ki, hogy visszaálljon a teljes védelem.", "storage-manager.replace-failed.description": "Használd ezt az SSD-t a FailSafe védelem visszaállításához.", "storage-manager.replace-failed.error": "Nem sikerült elindítani a cserét", "storage-manager.replace-failed.replace-now": "Cseréld most", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD a {{slot}}. slotban", "storage-manager.replace-failed.step-protected": "A befejezés után az adataid ismét teljesen védettek lesznek", "storage-manager.replace-failed.step-rebuild": "Az adatok visszaépülnek az új SSD-re", "storage-manager.replace-failed.step-time": "Ez eltarthat egy ideig, attól függően, mennyi adatod van", "storage-manager.replace-failed.title": "SSD cseréje", "storage-manager.replace-failed.too-small": "Az SSD túl kicsi", "storage-manager.replace-failed.too-small-description": "Ez az SSD ({{deviceSize}}) kisebb, mint a FailSafe tárolódhoz szükséges minimum ({{minSize}}).", "storage-manager.replace-failed.what-happens": "Mi történik ezután:", "storage-manager.ssd-failing": "Hibásodik", "storage-manager.swap": "Csere", "storage-manager.swap.data-erased-description": "A Full Storage módban nincs adatvédelem. A gyári visszaállítás során a {{deviceName}} összes adata törlődni fog. Ments le mindent előtte.", "storage-manager.swap.data-protected": "Az adataid védettek", "storage-manager.swap.data-protected-description": "Ha a FailSafe engedélyezve van, bármelyik egyetlen SSD kicserélhető anélkül, hogy adatot veszítenél. Mentés nem szükséges.", "storage-manager.swap.data-will-be-erased": "Az adatok törlődnek", "storage-manager.swap.description-failsafe": "Cserélj ki egy meghajtót a FailSafe tárolódban.", "storage-manager.swap.description-full-storage": "Cserélj ki egy meghajtót a Full Storage beállításodban.", "storage-manager.swap.description-no-free-slot": "Full Storage módban, ha az összes foglalat foglalt, az SSD cseréje teljes mentést és visszaállítást igényel.", "storage-manager.swap.description-replace": "Migráld át az adataidat az új SSD-re, majd távolítsd el a régit.", "storage-manager.swap.failed-to-start": "Nem sikerült elindítani a cserefolyamatot.", "storage-manager.swap.no-data-loss": "Nincs adatvesztés", "storage-manager.swap.no-data-loss-description": "Az adataid át lesznek másolva az új SSD-re. Ha kész, biztonságosan eltávolíthatod a régit.", "storage-manager.swap.safe-swap-available": "Biztonságos csere elérhető", "storage-manager.swap.safe-swap-description": "Mivel van egy üres foglalatod, először hozzáadhatod az új SSD-t és átmigrálhatod az adatokat a régit eltávolítása előtt. Mentés nem szükséges.", "storage-manager.swap.select-new-ssd": "Válaszd ki a használni kívánt új SSD-t:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD a {{slot}}. foglalatban", "storage-manager.swap.step-backup": "Készíts biztonsági mentést az adataidról", "storage-manager.swap.step-backup-description": "Lépj a Beállítások → Backups menübe, és készíts mentést az összes adatodról.", "storage-manager.swap.step-data-copied": "Az adatok át lesznek másolva a régi SSD-ről az újra", "storage-manager.swap.step-factory-reset": "Gyári visszaállítás", "storage-manager.swap.step-factory-reset-description": "Nyisd meg a Beállítások → Speciális → Gyári visszaállítás menüpontot, és töröld a {{deviceName}}-t.", "storage-manager.swap.step-insert-new-ssd": "Helyezd be az új SSD-t egy üres foglalatba", "storage-manager.swap.step-may-take-while": "Ez az adatmennyiségtől függően eltarthat egy ideig.", "storage-manager.swap.step-power-on": "Kapcsold be a {{deviceName}}-t", "storage-manager.swap.step-remove-bottom-cover": "Távolítsd el a mágneses alsó fedőlapot", "storage-manager.swap.step-remove-old": "Ha kész, kapcsold ki, és távolítsd el a {{ssd}}-t.", "storage-manager.swap.step-replace-bottom-cover": "Helyezd vissza az alsó fedőlapot", "storage-manager.swap.step-restore": "Állítsd vissza az adataidat", "storage-manager.swap.step-restore-description": "Lépj a Beállítások → Backups menübe, és állítsd vissza a mentésedet.", "storage-manager.swap.step-return-to-storage-manager": "Térj vissza ide a Storage Managerbe, hogy megerősítsd a cserét és hozzáadd az új SSD-t a tárhelyedhez.", "storage-manager.swap.step-return-to-swap": "Térj vissza ide a Storage Managerbe, és kattints ismét a Cserélés gombra a csere elindításához.", "storage-manager.swap.step-setup-new-storage": "Állítsd be az új tárhelyet", "storage-manager.swap.step-setup-new-storage-description": "Kapcsold be a {{deviceName}}-t, és fejezd be a beállítást az új SSD-vel.", "storage-manager.swap.step-shut-down": "Kapcsold ki a {{deviceName}}-t", "storage-manager.swap.step-shut-down-and-swap": "Kapcsold ki, majd cseréld ki a {{ssd}}-t", "storage-manager.swap.step-shut-down-and-swap-description-other": "Kapcsold ki, nyisd fel a készüléket, cseréld ki az SSD-t, majd szereld vissza.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Kapcsold ki, távolítsd el az alsó fedőlapot, cseréld ki az SSD-t, majd zárd vissza a fedőlapot.", "storage-manager.swap.step-swap-ssd": "Cseréld ki a {{ssd}}-t egy azonos méretű új SSD-re.", "storage-manager.swap.too-small": "Túl kicsi ({{size}} szükséges)", "storage-manager.swap.what-happens-next": "Mi történik ezután:", "storage-manager.total-capacity-added": "Hozzáadott teljes kapacitás", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Használt", "storage-manager.wasted": "Használhatatlan", "storage-manager.wasted-size": "{{size}} használhatatlan", "storage.full": "Tárhely megtelt", "storage.low": "Kevés tárhely", "temperature": "Hőmérséklet", "temperature.dangerously-hot": "Nagyon forró", "temperature.nice": "Kellemes", "temperature.normal": "Normál", "temperature.too-hot-suggestion": "Fontold meg az eszköz környezetének megváltoztatását.", "temperature.warm": "Meleg", "terminal": "Terminál", "terminal-description": "Egyedi parancsok futtatása az umbrelOS-ben vagy egy alkalmazáson belül", "terminal.app": "Alkalmazás", "terminal.app-description": "Egyedi parancsok futtatása egy adott alkalmazáson belül", "terminal.umbrelos-description": "Egyedi parancsok futtatása az umbrelOS-ben", "tor-description": "Hozzáférés az Umbrel-hez bárhonnan egy Tor böngésző segítségével", "tor-enabled-description": "Az Umbrel-hez bárhonnan hozzáférhetsz a következő URL-en keresztül Tor böngészővel:", "tor-error": "Tor-beállítás frissítése sikertelen: {{message}}", "tor.disable.description": "Ez néhány percet igénybe vehet", "tor.disable.progress": "Távoli Tor-hozzáférés letiltása", "tor.enable.description": "Ez néhány percet igénybe vehet", "tor.enable.mobile.switch-label": "Távoli Tor hozzáférés engedélyezése", "tor.hidden-service": "Tor rejtett szolgáltatás URL", "troubleshoot": "Hibaelhárítás", "troubleshoot-description": "umbrelOS vagy egy alkalmazás hibaelhárítása", "troubleshoot-no-logs-yet": "Nincs napló", "troubleshoot-pick-title": "Hibaelhárítás", "troubleshoot.app": "Alkalmazás", "troubleshoot.app-description": "Egy alkalmazás naplóinak megtekintése az Umbrel-en", "troubleshoot.app-download": "{{app}} naplók letöltése", "troubleshoot.share-with-umbrel-support": "Megosztás az Umbrel támogatással", "troubleshoot.system-download": "{{label}} letöltése", "troubleshoot.umbrelos-description": "umbrelOS naplók megtekintése", "troubleshoot.umbrelos-logs": "umbrelOS naplók", "trpc.backend-unavailable": "Hiba: Nem sikerült kapcsolódni a rendszer API-hoz", "trpc.checking-backend": "Betöltés...", "try-again": "Újrapróbálás", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Ismeretlen", "unknown-app": "Ismeretlen alkalmazás", "unknown-error": "Ismeretlen hiba", "uptime": "Üzemidő", "url": "URL", "wallpaper": "Háttérkép", "wallpaper-description": "Az Umbrel háttérképed és témád", "whats-new.continue": "Folytatás", "whats-new.feature-1.description": "Állíts be automatikus, titkosított biztonsági mentéseket az egész Umbrelről egy külső USB-meghajtóra, egy NAS-ra vagy egy másik Umbrelre.", "whats-new.feature-2.description": "Lépj vissza az időben, és állíts vissza konkrét fájlokat és mappákat korábbi mentésekből.", "whats-new.feature-3.description": "Vagy állítsd vissza az egész Umbreledet, beleértve az összes alkalmazást, fájlt és adatot.", "whats-new.feature-4.description": "Csatlakoztass egy NAS-t vagy egy másik Umbrelt, majd a Files alkalmazásból elérheted a tárolóját.", "whats-new.feature-4.title": "Hálózati eszközök", "whats-new.feature-5.description": "Csatlakoztass külső USB-meghajtókat (Umbrel Home-on vagy bármely Intel vagy AMD eszközön), és érd el őket a Files alkalmazásból.", "whats-new.feature-5.helper-text": "Raspberry Pi eszközökön nem támogatott a lehetséges áramellátási problémák miatt.", "whats-new.feature-5.title": "Külső tároló", "whats-new.next": "Következő", "whats-new.title": "{{version}} újdonságai", "widget.progress.in-progress": "Folyamatban", "widgets.edit.select-up-to-3-widgets": "Válassz ki legfeljebb 3 widgetet", "widgets.install-an-app-before-using-widgets": "Telepíts egy alkalmazást, hogy elkezdhesd testre szabni a kezdőképernyőt widgetekkel.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "A nyílt hálózatok nem biztonságosak lehetnek", "wifi-connection-failed": "Nem sikerült csatlakozni", "wifi-dangerous-change-confirmation-description": "A Wi-Fi hálózat megváltoztatása megszakíthatja az Umbrel-hez való csatlakozásodat. A csatlakozás helyreállításához győződj meg arról, hogy mind az Umbrel, mind az eszköz, amelyről hozzáférsz, ugyanazon a hálózaton van.", "wifi-dangerous-change-confirmation-title": "Biztosan meg akarod változtatni a Wi-Fi hálózatot?", "wifi-dangerous-disable-confirmation-description": "A Wi-Fi letiltása megszakíthatja az Umbrel-hez való csatlakozásodat. A csatlakozás helyreállításához csatlakoztass egy Ethernet kábelt az Umbrel-hez, és győződj meg arról, hogy mind az Umbrel, mind az eszköz, amelyről hozzáférsz, ugyanazon a hálózaton van.", "wifi-dangerous-disable-confirmation-title": "Biztosan le akarod tiltani a Wi-Fi-t?", "wifi-description": "Csatlakoztasd az eszközödet egy Wi-Fi hálózathoz", "wifi-description-long": "Az eszközöd a választott Wi-Fi-hez marad csatlakozva, még akkor is, ha az Ethernet kábel eltávolításra kerül, és automatikusan újracsatlakozik a Wi-Fi-hez indításkor.", "wifi-no-networks-message": "Nem található Wi-Fi hálózat", "wifi-searching": "Wi-Fi hálózatok keresése...", "wifi-unsupported-device-description": "Ez az eszköz nem támogatja a Wi-Fi-t. Ez hiányzó vagy inkompatibilis vezeték nélküli adapter miatt lehet.", "wifi-view-networks": "Hálózatok megtekintése" } ================================================ FILE: packages/ui/public/locales/it.json ================================================ { "2fa": "2FA", "2fa-description": "Un secondo livello di sicurezza per il tuo login e app Umbrel", "2fa.disable.title": "Disabilita l'autenticazione a due fattori", "2fa.enable.or-paste": "Oppure incolla il seguente codice nella tua app di autenticazione", "2fa.enable.scan-this": "Scansiona questo codice QR utilizzando un'app di autenticazione come Google Authenticator o Authy", "2fa.enable.title": "Abilita l'autenticazione a due fattori", "2fa.enter-code": "Inserisci il codice visualizzato nella tua app di autenticazione", "account": "Account", "account-description": "Il tuo nome e password", "advanced-settings": "Impostazioni avanzate", "advanced-settings-description": "Terminale, Programma Beta di umbrelOS, Cloudflare DNS e altro ancora", "app-not-found": "App non trovata: {{app}}", "app-only-over-tor": "L'app {{app}} è utilizzabile solo tramite Tor. Per aprirla, accedi al tuo Umbrel con un browser Tor usando l'URL di accesso remoto (Impostazioni > Impostazioni avanzate > Accesso Tor remoto).", "app-page.section.about": "Informazioni", "app-page.section.credentials.title": "Credenziali predefinite", "app-page.section.dependencies.n-alternatives": "Vedi {{count}} alternative", "app-page.section.info.compatibility": "Compatibilità", "app-page.section.info.compatibility-compatible": "Compatibile", "app-page.section.info.compatibility-not-compatible": "Non compatibile", "app-page.section.info.developer": "Sviluppatore", "app-page.section.info.source-code": "Codice Sorgente", "app-page.section.info.source-code.public": "Pubblico", "app-page.section.info.submitted-by": "Inviato da", "app-page.section.info.support": "Ottieni supporto", "app-page.section.info.title": "Info", "app-page.section.info.version": "Versione", "app-page.section.recommendations.title": "Potrebbero interessarti anche", "app-page.section.release-notes.title": "Novità", "app-page.section.release-notes.version": "Versione {{version}}", "app-page.section.requires": "Richiede", "app-picker.search": "Cerca...", "app-picker.select-app": "Seleziona app...", "app-settings.connected-to": "{{appName}} è connesso a queste app", "app-settings.save-changes": "Salva modifiche", "app-settings.title": "Impostazioni", "app-store.browse-category-apps": "Esplora le app {{category}}", "app-store.category.ai": "AI", "app-store.category.all": "Tutte le app", "app-store.category.automation": "Casa & Automazione", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Cripto", "app-store.category.developer": "Strumenti per Sviluppatori", "app-store.category.discover": "Scopri", "app-store.category.files": "File & Produttività", "app-store.category.finance": "Finanza", "app-store.category.media": "Media", "app-store.category.networking": "Networking", "app-store.category.social": "Social", "app-store.description": "Le tue impostazioni di aggiornamento app", "app-store.discover.temporarily-unavailable-description": "Sfoglia le categorie qui sopra o usa la ricerca per trovare app", "app-store.discover.temporarily-unavailable-title": "Contenuti in evidenza temporaneamente non disponibili", "app-store.menu.community-app-stores": "Community App Store", "app-store.search-apps": "Cerca app", "app-store.search.no-results": "Nessun risultato", "app-store.search.results-for": "Risultati per", "app-store.title": "App Store", "app-store.updates": "Aggiornamenti", "app-updates.less": "meno", "app-updates.more": "più", "app-updates.no-updates": "Tutte le app sono aggiornate!", "app-updates.update": "Aggiorna", "app-updates.update-all": "Aggiorna tutto", "app-updates.updates-available-count_one": "{{count}} aggiornamento disponibile", "app-updates.updates-available-count_other": "{{count}} aggiornamenti disponibili", "app-updates.updating": "Aggiornamento in corso...", "app.install": "Installa", "app.installed": "Installata", "app.installing": "Installazione", "app.offline": "Non in esecuzione", "app.open": "Apri", "app.optimized-for-umbrel-home": "Ottimizzato per Umbrel Home", "app.os-update-required.confirm": "Controlla aggiornamento di umbrelOS", "app.os-update-required.description": "{{appName}} richiede umbrelOS {{version}} o successivo", "app.os-update-required.title": "Aggiorna umbrelOS", "app.restarting": "Riavvio in corso", "app.starting": "Avvio in corso", "app.stopping": "Fermata in corso", "app.uninstall.confirm.description": "Tutti i dati associati a {{app}} verranno eliminati permanentemente. Questa azione non può essere annullata.", "app.uninstall.confirm.submit": "Disinstalla", "app.uninstall.confirm.title": "Disinstallare {{app}}?", "app.uninstall.deps.used-by.description_one": "Disinstalla prima {{firstAppToUninstall}} per disinstallare {{app}}.", "app.uninstall.deps.used-by.description_other": "Disinstalla prima queste app per disinstallare {{app}}.", "app.uninstall.deps.used-by.title": "{{app}} è utilizzata da", "app.uninstalling": "Disinstallazione", "app.updating": "Aggiornamento", "app.view": "Visualizza", "app_one": "app", "app_other": "app", "apps.uninstall.failed-to-get-required-apps": "Impossibile ottenere le app richieste", "apps.uninstalled-all.success": "Tutte le app disinstallate", "auth.checking-backend-for-user": "Caricamento...", "auth.failed-checking-if-user-logged-in": "Errore: Controllo di accesso fallito", "auth.failed-to-check-if-user-exists": "Errore: Controllo di esistenza fallito", "back": "Indietro", "backups": "Backups", "backups-configure": "Configura", "backups-configure.add-backup-location": "Aggiungi posizione di backup", "backups-configure.available": "Disponibile", "backups-configure.awaiting-next-backup": "In attesa del prossimo backup automatico", "backups-configure.back-up-now": "Esegui il backup ora", "backups-configure.backing-up-now": "Backup in corso...", "backups-configure.connected": "Connesso", "backups-configure.connection": "Connessione", "backups-configure.in-progress": "In corso", "backups-configure.last-backup": "Ultimo backup", "backups-configure.locations": "Posizioni", "backups-configure.no-backup-locations": "Aggiungi una posizione di backup per iniziare a eseguire il backup dei tuoi dati", "backups-configure.not-connected": "Non connesso", "backups-configure.path": "Percorso", "backups-configure.remove-backup-location": "Rimuovi posizione di backup", "backups-configure.remove-backup-location-confirmation": "Sei sicuro?", "backups-configure.remove-backup-location-confirmation-description": "Questo rimuoverà '{{device}}' dalle tue posizioni di backup. I backup esistenti su questo dispositivo non verranno eliminati, ma i backup automatici si interromperanno.", "backups-configure.status": "Stato", "backups-configure.total-backups": "Backups totali", "backups-configure.used": "Utilizzato", "backups-configure.view": "Visualizza", "backups-description": "Esegui il backup di file, app e dati su un altro Umbrel, un NAS o un'unità esterna", "backups-error.backup-not-found": "Il backup non è stato trovato.", "backups-error.generic": "Qualcosa è andato storto: {{details}}.", "backups-error.in-progress": "È già in esecuzione un backup. Attendi che termini.", "backups-error.invalid-exclusion-path": "Possono essere esclusi dai backup solo i file e le cartelle nella tua cartella Home.", "backups-error.invalid-password": "La password di crittografia non è corretta.", "backups-error.invalid-path": "La posizione selezionata non è valida per i backup.", "backups-error.mount-failed": "Impossibile accedere allo snapshot del backup.", "backups-error.mount-timeout": "Impossibile accedere allo snapshot del backup. Riprova o verifica che il dispositivo sia collegato correttamente.", "backups-error.not-enough-space": "Spazio insufficiente sul dispositivo di backup.", "backups-error.not-found": "Il backup o la posizione di backup non sono stati trovati.", "backups-error.repository-exists": "Esiste già una posizione di backup in questa cartella.", "backups-error.repository-not-found": "La posizione di backup non è stata trovata.", "backups-exclusions.add": "Aggiungi", "backups-exclusions.app-paths-cannot-be-modified": "Questi file/cartelle sono impostati dallo sviluppatore dell'app e non possono essere modificati:", "backups-exclusions.app-paths-explanation": "Questa app esclude i seguenti dati dal backup. Questi percorsi di solito contengono elementi non essenziali (come cache o log che possono essere ricreati) o dati che potrebbero causare problemi se ripristinati (ad esempio stati dell'app obsoleti che potrebbero portare a conflitti o incoerenze).", "backups-exclusions.auto-excluded": "Esclusi automaticamente", "backups-exclusions.exclude-entire-app": "Escludi l'app completa", "backups-exclusions.excluded-apps": "App escluse", "backups-exclusions.files-and-folders": "File e cartelle escluse", "backups-exclusions.no-excluded-apps": "Nessuna app esclusa", "backups-exclusions.no-excluded-files-or-folders": "Nessun file o cartella esclusi", "backups-exclusions.select-item-to-exclude": "Seleziona l'elemento da escludere", "backups-exclusions.stop-excluding": "Annulla esclusione", "backups-floating-island.backing-up": "Backup in corso...", "backups-floating-island.backing-up-to": "Eseguendo il backup del tuo Umbrel...", "backups-restore": "Ripristina", "backups-restore-full": "Ripristino completo", "backups-restore-full-description": "Ripristina completamente il tuo Umbrel da un backup", "backups-restore-header": "Ripristina il tuo Umbrel", "backups-restore-pro.after-restore": "Dopo il ripristino, il tuo account temporaneo verrà sostituito dal tuo account di backup e dai relativi dati.", "backups-restore-pro.step1": "Completa la configurazione iniziale facendo clic su \"Get Started\" qui sotto. Questo sarà il tuo account temporaneo fino a quando non ripristinerai il tuo account di backup.", "backups-restore-pro.step2": "Una volta completata la configurazione, vai su <0>Impostazioni → Backups → Ripristina", "backups-restore-pro.step3": "Segui le istruzioni della procedura guidata di ripristino.", "backups-restore-pro.subtitle": "Il ripristino da un backup su Umbrel Pro richiede qualche passaggio in più", "backups-restore.backup-date": "Data del backup", "backups-restore.backup-location": "Posizione di backup", "backups-restore.browse-cloud-subtitle": "Ripristina da Umbrel Private Cloud (in arrivo)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Ripristina da un'unità USB esterna", "backups-restore.browse-external-title": "Disco esterno", "backups-restore.browse-nas-or-external": "Sfoglia un altro Umbrel, un NAS o un'unità esterna da cui ripristinare un backup", "backups-restore.browse-nas-subtitle": "Ripristina da un altro dispositivo Umbrel o NAS sulla tua rete", "backups-restore.browse-nas-title": "Un altro Umbrel o NAS", "backups-restore.choose": "Scegli", "backups-restore.choose-backup-location": "Scegli una posizione di backup", "backups-restore.connect-to-backup-location": "Connetti a una posizione di backup", "backups-restore.encryption-password": "Password di crittografia", "backups-restore.encryption-password-description": "Inserisci la password di crittografia che hai impostato quando hai abilitato i backup", "backups-restore.enter-password-to-confirm": "Inserisci la password di Umbrel per confermare", "backups-restore.final-confirmation": "Sei sicuro?", "backups-restore.final-confirmation-description": "Il ripristino da questo backup sostituirà le app e i dati attuali di umbrelOS con il contenuto del backup selezionato. Eventuali file, cartelle o app esclusi da questo backup verranno rimossi dal tuo Umbrel. Questa azione non può essere annullata.", "backups-restore.invalid-password": "Password non valida", "backups-restore.last-backup": "Ultimo backup: {{date}}", "backups-restore.latest": "Più recente", "backups-restore.no-backups-found": "Nessun backup trovato", "backups-restore.no-backups-yet": "Ancora nessun backup", "backups-restore.please-select-backup": "Seleziona un backup", "backups-restore.please-select-repository": "Seleziona un repository", "backups-restore.restore-from-nas-or-external": "Ripristina il tuo Umbrel da un backup presente su un altro Umbrel, su un NAS o su un'unità esterna", "backups-restore.restore-from-unlisted": "Ripristina da un'altra posizione", "backups-restore.restore-umbrel": "Ripristina Umbrel", "backups-restore.restore-warning": "Il ripristino da questo backup sostituirà le app e i dati attuali di umbrelOS con il contenuto del backup selezionato. Eventuali file, cartelle o app esclusi da questo backup verranno rimossi dal tuo Umbrel. Apri <0>Rewind se vuoi ripristinare invece file o cartelle specifici.", "backups-restore.restoring-from": "Stai per ripristinare dal seguente backup:", "backups-restore.review-description": "Il ripristino configurerà il tuo Umbrel con l'account, i file, le app e le impostazioni presenti al momento della creazione di questo backup. Potrebbe richiedere un po' di tempo. Al termine, la password di accesso sarà quella che hai usato quando il backup è stato creato.", "backups-restore.select-backup": "Seleziona un backup", "backups-restore.select-backup-description": "Seleziona il backup da cui vuoi ripristinare", "backups-restore.select-backup-file": "Seleziona il file di backup", "backups-restore.select-backup-file-only": "Puoi selezionare solo {{backupFileName}}.", "backups-restore.total-size": "Dimensione totale", "backups-restore.unknown-date": "Data sconosciuta", "backups-restore.unknown-repository": "Repository sconosciuto", "backups-rewind": "Rewind", "backups-rewind-description": "Torna indietro nel tempo per ripristinare file e cartelle specifici", "backups-rewind.start": "Avvia Rewind", "backups-setup": "Configura", "backups-setup-confirm": "Completa configurazione", "backups-setup-external-description": "Esegui il backup su un'unità USB esterna", "backups-setup-nas-or-umbrel-description": "Esegui il backup su un altro Umbrel o su un dispositivo NAS nella tua rete", "backups-setup-umbrel-or-nas": "Un altro Umbrel o NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Estendi la tua tranquillità oltre la casa con backup end-to-end crittografati su Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Richiedi accesso anticipato", "backups-setup-umbrel-private-cloud-description": "Backup end-to-end crittografati su Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Prossimamente", "backups.add-umbrel-or-nas": "Aggiungi Umbrel o NAS", "backups.all-apps-and-data-will-be-backed-up": "Tutte le app e i dati verranno sottoposti a backup", "backups.apps-and-data": "App e dati", "backups.backup-location": "Posizione di backup", "backups.browse": "Sfoglia", "backups.choose-folder-within-device": "Scegli una cartella all'interno di {{device}} dove salvare i tuoi backup", "backups.confirm-password": "Conferma password", "backups.copy": "Copia", "backups.encryption": "Crittografia", "backups.encryption-password-warning": "Assicurati di conservare la password di crittografia in modo sicuro, ad esempio in un gestore di password. Non potrai vederla di nuovo e ti servirà per ripristinare i backup.", "backups.exclude-from-backups": "Escludi dai Backup", "backups.exclude-from-backups-description": "Escludi file, cartelle e app specifici dai tuoi backup.", "backups.hide": "Nascondi", "backups.i-understand": "Ho capito", "backups.location": "Posizione", "backups.modals.already-in-use.description": "Questa posizione di backup è già utilizzata per i Backups di questo Umbrel.", "backups.modals.already-in-use.manage": "Gestisci in Backups", "backups.modals.already-in-use.title": "Posizione di backup già in uso", "backups.modals.connect-existing.description": "Un backup di Umbrel esiste già in questa posizione. Inserisci la sua password di crittografia per aggiungerlo a questo Umbrel.", "backups.modals.connect-existing.title": "Collega un backup esistente di Umbrel", "backups.no-external-drives-detected": "Nessuna unità esterna rilevata", "backups.no-password-set": "Nessuna password impostata", "backups.password-is-set": "Password impostata", "backups.password-minimum-length": "La password deve contenere almeno 8 caratteri", "backups.password-safety-warning": "I tuoi backup verranno crittografati con questa password. Conservala in modo sicuro, perché non potrai rivederla e ti servirà per ripristinare i backup.", "backups.passwords-do-not-match": "Le password non corrispondono", "backups.please-choose-folder": "Scegli una cartella", "backups.restore-failed.message": "Si è verificato un errore durante il ripristino del tuo Umbrel. Le tue app e i tuoi dati attuali non sono stati modificati.", "backups.restore-failed.retry": "Vai al ripristino", "backups.restore-failed.title": "Ripristino non riuscito", "backups.restoring": "Ripristinando il tuo Umbrel", "backups.restoring-completing": "Quasi fatto. Il tuo Umbrel si riavvierà a breve...", "backups.restoring-progress": "Ripristinato {{percent}}%", "backups.restoring-time-remaining": "{{time}} rimanenti", "backups.restoring-warning": "Non spegnere il tuo Umbrel né scollegare la posizione di backup durante il ripristino", "backups.review": "Controlla e conferma", "backups.review-description": "Controlla i dettagli del backup e conferma la tua scelta", "backups.scanning-for-external-drives": "Ricerca unità esterne...", "backups.schedule-description": "umbrelOS esegue automaticamente il backup dei tuoi dati ogni ora. Conserve backup orari crittografati per le ultime 24 ore, backup giornalieri per l'ultima settimana, backup settimanali per l'ultimo mese e backup mensili per l'ultimo anno. I backup più vecchi di un anno vengono rimossi automaticamente.", "backups.select-backup-folder": "Seleziona cartella di backup", "backups.select-backup-folder-description": "Scegli una cartella dove vuoi memorizzare i tuoi backup.", "backups.select-backup-location": "Seleziona una posizione di backup", "backups.set-encryption-password": "Imposta password di crittografia", "backups.set-encryption-password-description": "Proteggi i tuoi backup con una password. Questo garantisce che i tuoi dati rimangano privati e possano essere ripristinati soltanto con questa password.", "backups.show": "Mostra", "backups.storage-capacity-warning": "{{device}} deve avere spazio libero pari ad almeno il doppio della dimensione del tuo backup", "backups.store-encryption-password-safely": "Conserva la password di crittografia in modo sicuro", "beta-program": "Programma Beta di umbrelOS", "beta-program-description": "Opta per ricevere aggiornamenti beta di umbrelOS, accedi in anteprima a nuove funzionalità e aiutaci a perfezionarle fornendo il tuo feedback. Gli aggiornamenti beta possono essere instabili e la risoluzione dei problemi può richiedere familiarità con il terminal.", "cancel": "Annulla", "change": "Modifica", "change-name": "Cambia nome", "change-name.failed.name-required": "Nome richiesto", "change-name.input-placeholder": "Il tuo nome", "change-password": "Cambia password", "change-password.callout": "Se perdi la tua password, non sarai in grado di accedere al tuo Umbrel. Assicurati di conservarla in modo sicuro.", "change-password.current-password": "Password attuale", "change-password.failed.current-required": "Password attuale richiesta", "change-password.failed.min-length": "La password deve essere di almeno {{characters}} caratteri", "change-password.failed.must-be-unique": "La nuova password deve essere diversa dalla password attuale", "change-password.failed.new-required": "Nuova password richiesta", "change-password.failed.no-match": "Le password non corrispondono", "change-password.failed.repeat-required": "Ripeti la password richiesta", "change-password.new-password": "Nuova password", "change-password.repeat-password": "Ripeti password", "check-for-latest-version": "Controlla gli aggiornamenti di umbrelOS", "clipboard.copied": "Copiato", "close": "Chiudi", "cmdk.change-wallpaper": "Cambia sfondo", "cmdk.frequent-apps": "Usati frequentemente", "cmdk.input-placeholder": "Cerca app, impostazioni o azioni", "cmdk.live-usage": "Utilizzo in Tempo Reale", "cmdk.restart-umbrel": "Riavvia Umbrel", "cmdk.shutdown-umbrel": "Spegni Umbrel", "cmdk.update-all-apps": "Aggiorna tutte le app", "cmdk.widgets": "Widget", "community-app-store": "Community App Store", "community-app-store.add-error": "Impossibile aggiungere l'App Store: {{message}}", "community-app-store.back-to-umbrel-app-store": "Torna a Umbrel App Store", "community-app-store.open-button": "Apri", "community-app-store.remove-button": "Rimuovi", "community-app-store.remove-error": "Impossibile rimuovere l'App Store: {{message}}", "community-app-stores.add-button": "Aggiungi", "community-app-stores.description": "I Community App Store ti permettono di installare app sul tuo Umbrel che potrebbero non essere disponibili nell'Umbrel App Store ufficiale. Ti permettono anche di testare le versioni beta delle app Umbrel prima che gli sviluppatori le rilascino sull'Umbrel App Store ufficiale.", "community-app-stores.learn-more": "Scopri di più", "community-app-stores.warning": "I Community App Store possono essere creati da chiunque. Le app pubblicate non sono verificate o esaminate dal team dell'Umbrel App Store ufficiale e possono potenzialmente essere insicure o dannose. Usa cautela e aggiungi solo app store di sviluppatori di cui ti fidi.", "confirm": "Conferma", "connect": "Collega", "connecting": "Connessione in corso...", "connection-lost": "Connessione persa", "connection-lost-description": "Questo può succedere quando la scheda del browser è rimasta inattiva, la connessione di rete è stata interrotta o il tuo dispositivo è offline.", "continue": "Continua", "continue-to-log-in": "Continua per accedere", "cpu": "CPU", "cpu-core-count": "{{cores}} thread", "default-credentials.close": "Capito", "default-credentials.description": "Ecco le credenziali che ti serviranno per accedere all'app.", "default-credentials.dont-show-again": "Non mostrare di nuovo", "default-credentials.dont-show-again-notice": "Puoi accedere a queste credenziali in qualsiasi momento in futuro facendo clic con il tasto destro sull'icona dell'app.", "default-credentials.open": "Apri {{app}}", "default-credentials.password": "Password predefinita", "default-credentials.title": "Credenziali per {{app}}", "default-credentials.username": "Nome utente predefinito", "desktop.app.context.go-to-store-page": "Visualizza in App Store", "desktop.app.context.settings": "Impostazioni", "desktop.app.context.show-default-credentials": "Mostra credenziali predefinite", "desktop.app.context.uninstall": "Disinstalla", "desktop.context-menu.change-wallpaper": "Cambia sfondo", "desktop.context-menu.edit-widgets": "Modifica widget", "desktop.context-menu.logout": "Esci", "desktop.greeting.afternoon": "Buon pomeriggio, {{name}}", "desktop.greeting.evening": "Buona sera, {{name}}", "desktop.greeting.morning": "Buongiorno, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Per Viber", "desktop.install-first.for-the-bitcoiner": "Per il bitcoiner", "desktop.install-first.for-the-self-hoster": "Per l'auto-ospitante", "desktop.install-first.for-the-streamer": "Per lo streamer", "desktop.install-first.link-to-app-store": "Esplora di più in App Store", "desktop.not-enough-room": "Usa uno schermo più grande per visualizzare le tue app.", "device": "Dispositivo", "device-info": "Info dispositivo", "device-info-description": "Informazioni sul tuo dispositivo", "device-info.device": "Dispositivo", "device-info.model-number": "Numero modello", "device-info.serial-number": "Numero di serie", "device-info.view-info": "Visualizza info", "device-name.home-or-pro": "Umbrel Home o Umbrel Pro", "disable": "Disabilita", "done": "Fine", "download-logs": "Scarica log", "enabling-tor": "Attivazione dell'accesso remoto tramite Tor", "external-dns": "DNS di Cloudflare", "external-dns-description": "Cloudflare DNS offre una maggiore affidabilità della rete. Disabilita per usare le impostazioni DNS del tuo router.", "external-dns-error": "Impossibile aggiornare l'impostazione DNS: {{message}}", "external-drive": "Unità esterna", "factory-reset": "Ripristino Impostazioni di Fabbrica", "factory-reset-description": "Cancella tutti i tuoi dati e app, ripristinando umbrelOS alle impostazioni predefinite", "factory-reset-failed": "Impossibile ripristinare il dispositivo: {{message}}", "factory-reset.confirm.body": "Conferma la tua password per il ripristino", "factory-reset.confirm.ethernet-required-warning": "Assicurati che il tuo dispositivo sia collegato al router tramite Ethernet (non Wi-Fi) e che tu stia accedendo ad esso dalla tua rete locale (ad es., http://umbrel.local o l'indirizzo IP locale del tuo dispositivo).", "factory-reset.confirm.submit": "Cancella tutto e resetta", "factory-reset.confirm.submit-callout": "Questa azione non può essere annullata.", "factory-reset.rebooting.message": "Il dispositivo si riavvierà e tutti i dati verranno cancellati. Non chiudere questa pagina.", "factory-reset.rebooting.status": "Ripristino alle impostazioni di fabbrica in corso...", "factory-reset.rebooting.title": "Ripristino alle impostazioni di fabbrica in corso", "factory-reset.review.account-info": "Informazioni account e password", "factory-reset.review.apps": "App", "factory-reset.review.following-will-be-removed": "I seguenti verranno rimossi dal tuo dispositivo", "factory-reset.review.installed-apps_one": "{{count}} app installata", "factory-reset.review.installed-apps_other": "{{count}} app installate", "factory-reset.review.submit": "Continua", "factory-reset.review.total-data": "Dati totali", "files": "Files", "files-action.add-favorite": "Aggiungi ai preferiti", "files-action.add-network-device": "Aggiungi dispositivo", "files-action.cancel-upload": "Annulla caricamento", "files-action.compress": "Comprimi", "files-action.copy": "Copia", "files-action.cut": "Taglia", "files-action.delete": "Elimina definitivamente", "files-action.download": "Scarica", "files-action.download-items": "Scarica {{count}} elementi", "files-action.drop-to-upload": "Rilascia per caricare", "files-action.eject-disk": "Espelli", "files-action.empty-trash": "Svuota il Cestino", "files-action.format-drive": "Formatta", "files-action.go-to-path": "Vai a...", "files-action.new-folder": "Nuova cartella", "files-action.open": "Apri", "files-action.paste": "Incolla", "files-action.remove-favorite": "Rimuovi dai preferiti", "files-action.remove-network-host": "Espelli unità di rete", "files-action.remove-network-share": "Espelli condivisione di rete", "files-action.rename": "Rinomina", "files-action.restore": "Ripristina", "files-action.select": "Seleziona", "files-action.share": "Condividi sulla rete...", "files-action.sharing": "Condivisione in corso...", "files-action.show-in-folder": "Mostra nella cartella di origine", "files-action.trash": "Sposta nel Cestino", "files-action.uncompress": "Decomprimi", "files-action.upload": "Carica", "files-add-network-share.add-manually": "Aggiungi manualmente", "files-add-network-share.add-share": "Aggiungi condivisione", "files-add-network-share.back": "Indietro", "files-add-network-share.continue": "Continua", "files-add-network-share.description": "Connettiti a un NAS o a un'altra unità condivisa sulla tua rete per accedervi da File.", "files-add-network-share.discovering": "Ricerca in corso...", "files-add-network-share.enter-details-manually": "Inserisci i dettagli del server", "files-add-network-share.host-label": "Indirizzo server", "files-add-network-share.host-required": "L'indirizzo del server è obbligatorio", "files-add-network-share.manual-share-help": "Inserisci il nome esatto della condivisione così come appare sul tuo server", "files-add-network-share.no-shares-found": "Nessuna condivisione trovata su questo server", "files-add-network-share.not-seeing-share": "Non vedi la tua condivisione?", "files-add-network-share.password-label": "Password", "files-add-network-share.password-required": "La password è obbligatoria", "files-add-network-share.retrieving-shares": "Recupero delle condivisioni...", "files-add-network-share.retry-discovery": "Ripeti scansione rete", "files-add-network-share.select-share": "Seleziona una condivisione da aggiungere", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "La condivisione è obbligatoria", "files-add-network-share.title": "Aggiungi una condivisione di rete", "files-add-network-share.username-label": "Nome utente", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Il nome utente è obbligatorio", "files-audio-island.now-playing": "In riproduzione", "files-audio-island.pause": "Pausa", "files-audio-island.play": "Riproduci", "files-backend-error.base-directory-not-found": "Impossibile trovare la directory di base", "files-backend-error.cant-find-root": "Impossibile verificare il percorso del file", "files-backend-error.destination-already-exists": "Nella destinazione esiste già un elemento con lo stesso nome", "files-backend-error.destination-not-exist": "La cartella di destinazione non esiste", "files-backend-error.does-not-exist": "Il file o la cartella non esiste", "files-backend-error.escapes-base": "Il percorso è fuori dalla directory consentita", "files-backend-error.invalid-base": "Il percorso non appartiene a una directory valida", "files-backend-error.invalid-filename": "Il nome del file non è valido", "files-backend-error.invalid-path": "Il percorso del file non è valido", "files-backend-error.mkdir-failed": "Impossibile creare la cartella", "files-backend-error.move-failed": "Impossibile spostare l'elemento", "files-backend-error.not-enough-space": "Spazio di archiviazione insufficiente", "files-backend-error.operation-not-allowed": "Operazione non consentita", "files-backend-error.parent-not-directory": "Il percorso padre non è una cartella", "files-backend-error.parent-not-exist": "La cartella padre non esiste", "files-backend-error.path-not-absolute": "Il percorso del file non è valido", "files-backend-error.share-already-exists": "Questa cartella è già condivisa", "files-backend-error.share-name-generation-failed": "Impossibile generare un nome di condivisione univoco", "files-backend-error.source-not-exists": "Il file o la cartella di origine non esiste", "files-backend-error.subdir-of-self": "Una cartella non può essere spostata o copiata dentro se stessa", "files-backend-error.trash-meta-not-exists": "Impossibile trovare la posizione originale di questo elemento", "files-backend-error.unique-name-index-exceeded": "Impossibile generare un nome univoco. Esistono troppi elementi con nomi simili", "files-backend-error.upload-failed": "Caricamento non riuscito", "files-collision.action.keep-both": "Mantieni entrambi", "files-collision.action.replace": "Sostituisci", "files-collision.action.skip": "Ignora", "files-collision.destination.original-location": "la sua posizione originale", "files-collision.message": "Vuoi sostituire l'elemento esistente o mantenerli entrambi?", "files-collision.title": "\"{{itemName}}\" esiste già in {{destinationName}}", "files-download.confirm": "Scarica", "files-download.description": "Files non può aprire questo tipo di file. Vuoi scaricarlo invece?", "files-download.title": "Scaricare {{name}}?", "files-empty-trash.confirm": "Svuota", "files-empty-trash.description": "Sei sicuro di voler eliminare definitivamente tutti gli elementi nel Cestino? Non potrai annullare questa azione.", "files-empty-trash.title": "Svuotare il Cestino?", "files-empty.directory": "Nessun elemento in questa cartella", "files-empty.network": "Nessun dispositivo di rete", "files-empty.network-host-offline": "Dispositivo di rete offline", "files-error.add-favorite": "Impossibile aggiungere ai preferiti: {{message}}", "files-error.add-share": "Impossibile condividere la cartella: {{message}}", "files-error.compress": "Impossibile comprimere: {{message}}", "files-error.copy": "Impossibile copiare: {{message}}", "files-error.create-folder": "Impossibile creare la cartella: {{message}}", "files-error.delete": "Impossibile eliminare: {{message}}", "files-error.eject-disk": "Impossibile espellere l'unità: {{message}}", "files-error.empty-trash": "Impossibile svuotare il cestino: {{message}}", "files-error.extract": "Impossibile estrarre: {{message}}", "files-error.folder-already-exists": "Esiste già una cartella con questo nome", "files-error.move": "Impossibile spostare: {{message}}", "files-error.remove-favorite": "Impossibile rimuovere dai preferiti: {{message}}", "files-error.remove-share": "Impossibile rimuovere la cartella condivisa: {{message}}", "files-error.rename": "Impossibile rinominare: {{message}}", "files-error.restore": "Impossibile ripristinare: {{message}}", "files-error.trash": "Impossibile spostare nel cestino: {{message}}", "files-error.upload": "Impossibile caricare: {{message}}", "files-error.upload-network-error": "Caricamento di {{name}} non riuscito: si è verificato un errore di rete", "files-extension-change.confirm": "Continua", "files-extension-change.description-add": "Sei sicuro di voler cambiare l'estensione di '{{fileName}}' in '{{extension}}'? Questo potrebbe rendere il file illeggibile.", "files-extension-change.description-remove": "Sei sicuro di voler rimuovere l'estensione di '{{fileName}}'?", "files-extension-change.title-add": "Cambiare l'estensione in '{{extension}}'?", "files-extension-change.title-remove": "Rimuovere l'estensione?", "files-external-storage.unsupported.description": "L'unità esterna collegata non può essere utilizzata su un Raspberry Pi a causa di problemi di alimentazione. L'archiviazione esterna è disponibile su Umbrel Home, Umbrel Pro e su tutti i dispositivi x86 (Intel o AMD).", "files-external-storage.unsupported.description-general": "L'archiviazione esterna non è disponibile sui Raspberry Pi a causa di problemi di alimentazione. L'archiviazione esterna è disponibile su Umbrel Home, Umbrel Pro e su tutti i dispositivi x86 (Intel o AMD).", "files-external-storage.unsupported.title": "Archiviazione esterna non supportata", "files-folder": "Cartella", "files-format.confirm": "Formatta", "files-format.description": "La formattazione cancellerà tutti i dati su {{driveName}}. Questa operazione non può essere annullata.", "files-format.description-unreadable": "umbrelOS non riesce a leggere il contenuto di {{driveName}}. Puoi formattare questa unità per usarla con umbrelOS.", "files-format.drive-label": "Nome", "files-format.error": "Impossibile formattare l'unità", "files-format.exfat-description": "Massima compatibilità con Windows, macOS e Linux", "files-format.ext4-description": "Migliori prestazioni con umbrelOS e Linux", "files-format.filesystem": "File system", "files-format.filesystem-label": "Formato", "files-format.formatting": "Formattazione in corso...", "files-format.title": "Formatta unità", "files-format.title-requires-format": "Formattazione richiesta", "files-formatting-island.formatting": "Formattazione...", "files-formatting-island.formatting-drives": "Formattazione di {{count}} unità", "files-listing.empty": "Nessun elemento", "files-listing.error": "Si è verificato un errore", "files-listing.item-count-truncated": "{{formattedCount}}+ elementi", "files-listing.item-count_one": "{{formattedCount}} elemento", "files-listing.item-count_other": "{{formattedCount}} elementi", "files-listing.loading": "Caricamento in corso...", "files-listing.no-such-file": "Nessun file o cartella corrispondente", "files-listing.selected-count": "{{selectedCount}} di {{totalCount}} selezionati", "files-listing.selected-count-truncated": "{{selectedCount}} di {{totalCount}}+ selezionati", "files-name-drawer.new-folder": "Nuova cartella", "files-name-drawer.new-folder-description": "Inserisci un nome per la nuova cartella.", "files-name-drawer.new-folder-input": "Nome cartella", "files-name-drawer.rename-file": "Rinomina file", "files-name-drawer.rename-file-description": "Inserisci un nuovo nome per questo file.", "files-name-drawer.rename-file-input": "Nome file", "files-name-drawer.rename-folder": "Rinomina cartella", "files-name-drawer.rename-folder-description": "Inserisci un nuovo nome per questa cartella.", "files-name-drawer.rename-folder-input": "Nome cartella", "files-network-storage-error.add-share": "Impossibile aggiungere la condivisione di rete: {{message}}", "files-network-storage-error.discover-servers": "Impossibile rilevare i dispositivi di rete: {{message}}", "files-network-storage-error.discover-shares": "Impossibile rilevare le condivisioni di rete: {{message}}", "files-network-storage-error.remove-share": "Impossibile rimuovere la condivisione di rete: {{message}}", "files-operations-island.copying": "Copiando \"{{from}}\" in \"{{to}}\"", "files-operations-island.moving": "Spostando \"{{from}}\" in \"{{to}}\"", "files-operations-island.restoring": "Ripristino di \"{{from}}\" in \"{{to}}\"", "files-path.input-group": "Campo percorso", "files-path.input-label": "Percorso attuale", "files-permanently-delete.confirm": "Elimina definitivamente", "files-permanently-delete.description-multiple": "Sei sicuro di voler eliminare definitivamente questi {{count}} elementi? Non potrai annullare questa azione.", "files-permanently-delete.description-single": "Sei sicuro di voler eliminare definitivamente \"{{fileName}}\"? Non potrai annullare questa azione.", "files-permanently-delete.title-multiple": "Eliminare definitivamente {{count}} elementi?", "files-permanently-delete.title-single": "Eliminare definitivamente?", "files-search.default": "Cerca file e cartelle", "files-search.no-results": "Nessun risultato trovato per \"{{query}}\"", "files-search.placeholder": "Cerca", "files-search.searching-label": "Cercando l'Umbrel di {{name}}", "files-share.home-description": "Accedi a tutti i file in \"{{homeDirectoryName}}\" da altri dispositivi sulla tua rete", "files-share.home-title": "Condividi \"{{homeDirectoryName}}\" sulla rete", "files-share.instructions.how-to-access": "Come accedere", "files-share.instructions.ios.enter-password": "Inserisci {{password}} come password.", "files-share.instructions.ios.enter-server": "Inserisci {{smbUrl}} come indirizzo server.", "files-share.instructions.ios.enter-username": "Inserisci {{username}} come nome utente.", "files-share.instructions.ios.install-files": "Installa l'app \"Files\" da App Store se non è già installata.", "files-share.instructions.ios.tap-connect": "Tocca \"Connetti\" per accedere.", "files-share.instructions.ios.tap-dots": "Tocca i tre puntini (...) in alto a destra e seleziona \"Collegati al server\".", "files-share.instructions.macos.click-connect": "Fai clic su \"Connetti\" per accedere.", "files-share.instructions.macos.enter-password": "Inserisci {{password}} come password.", "files-share.instructions.macos.enter-url": "Inserisci {{smbUrl}} e fai clic su Connetti.", "files-share.instructions.macos.enter-username": "Inserisci {{username}} come nome utente.", "files-share.instructions.macos.open-finder": "Apri \"Finder\" e premi ⌘ + K.", "files-share.instructions.macos.select-registered": "Seleziona \"Utente registrato\" quando richiesto.", "files-share.instructions.macos.time-machine": "Come usarla come destinazione di backup per Time Machine", "files-share.instructions.macos.time-machine.choose-encryption": "Scegli tra backup crittografati o non crittografati.", "files-share.instructions.macos.time-machine.disk-limit": "Per \"Limite utilizzo disco\", specifica la quantità massima di spazio che vuoi allocare su Umbrel per i backup di Time Machine, quindi fai clic su \"Fine\".", "files-share.instructions.macos.time-machine.follow-steps": "Segui i passaggi precedenti e apri Impostazioni di sistema sul tuo Mac.", "files-share.instructions.macos.time-machine.go-settings": "Vai su Time Machine, fai clic su \"Aggiungi disco di backup...\".", "files-share.instructions.macos.time-machine.select-disk": "Seleziona la cartella e fai clic su \"Imposta disco...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Segui i passaggi guidati per configurare il tuo backup.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Segui i passaggi sopra e poi vai su \"{{settings}}\" > \"{{backups}}\" sul tuo altro Umbrel.", "files-share.instructions.umbrelos.backup.select-add": "Seleziona l'opzione \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Seleziona questo Umbrel dall'elenco dei dispositivi connessi.", "files-share.instructions.umbrelos.backup.title": "Come usarlo come destinazione di backup per il tuo altro Umbrel", "files-share.instructions.umbrelos.cant-find-note": "Non riesci a trovarlo? Prova a selezionare \"Aggiungi manualmente\" e usa le seguenti credenziali. Se ancora non riesci ad aggiungerlo, assicurati che entrambi i dispositivi siano sulla stessa rete.", "files-share.instructions.umbrelos.enter-password": "Inserisci {{password}} come password.", "files-share.instructions.umbrelos.enter-username": "Inserisci {{username}} come nome utente.", "files-share.instructions.umbrelos.open-and-click": "Sul tuo altro Umbrel, apri \"Files\" e clicca accanto a \" {{deviceLabel}}\" nella barra laterale.", "files-share.instructions.umbrelos.select-device": "Seleziona questo dispositivo Umbrel dall'elenco dei dispositivi rilevati automaticamente sulla tua rete.", "files-share.instructions.umbrelos.select-sharename": "Seleziona \"{{sharename}}\" e clicca per aggiungere la condivisione.", "files-share.instructions.windows.enter-password": "Inserisci {{password}} come password.", "files-share.instructions.windows.enter-url": "Digita {{smbUrl}} e premi Invio.", "files-share.instructions.windows.enter-username": "Inserisci {{username}} come nome utente.", "files-share.instructions.windows.open-run": "Premi Windows + R per aprire la finestra Esegui.", "files-share.instructions.windows.remember-credentials": "Spunta \"Remember my credentials\" e fai clic su OK.", "files-share.regular-description": "Condividi questa cartella per accedervi da altri dispositivi sulla tua rete", "files-share.regular-title": "Condividi cartella sulla rete", "files-share.toggle": "Condividi \"{{name}}\" sulla tua rete", "files-sidebar.apps": "App", "files-sidebar.external-storage": "Archiviazione esterna", "files-sidebar.favorites": "Preferiti", "files-sidebar.home": "Home", "files-sidebar.navigation": "Navigazione file", "files-sidebar.network": "Rete", "files-sidebar.network-pathbar": "Dispositivi di rete", "files-sidebar.network-sidebar": "Dispositivi", "files-sidebar.recents": "Recenti", "files-sidebar.shared-folders": "Cartelle condivise", "files-sidebar.trash": "Cestino", "files-sidebar.trash.open": "Apri", "files-sort.created": "Aggiunto", "files-sort.modified": "Modificato", "files-sort.name": "Nome", "files-sort.size": "Dimensione", "files-sort.type": "Tipo", "files-state.uploading": "Caricamento in corso...", "files-state.waiting": "In attesa...", "files-type.3gp": "Video 3GP", "files-type.3gp2": "Video 3GP2", "files-type.7z": "Archivio 7Z", "files-type.aac": "Audio AAC", "files-type.ai": "File Illustrator", "files-type.aiff": "Audio AIFF", "files-type.au": "Audio AU", "files-type.avi": "Video AVI", "files-type.avif": "Immagine AVIF", "files-type.bmp": "Immagine BMP", "files-type.bzip2": "Archivio BZIP2", "files-type.caf": "Audio CAF", "files-type.compressed": "Archivio compresso", "files-type.csv": "File CSV", "files-type.directory": "Cartella", "files-type.dmg": "Immagine disco", "files-type.dv": "Video DV", "files-type.epub": "eBook EPUB", "files-type.excel": "Foglio di calcolo Excel", "files-type.exe": "Eseguibile Windows", "files-type.executable": "Eseguibile", "files-type.external-drive": "Disco", "files-type.flac": "Audio FLAC", "files-type.flv": "Video FLV", "files-type.gif": "Immagine GIF", "files-type.gzip": "Archivio GZIP", "files-type.heic": "Immagine HEIC", "files-type.ico": "Immagine ICO", "files-type.iso": "Immagine ISO", "files-type.jpeg": "Immagine JPEG", "files-type.keynote": "Presentazione Keynote", "files-type.lzip": "Archivio LZIP", "files-type.lzma": "Archivio LZMA", "files-type.lzop": "Archivio LZOP", "files-type.m3u": "Playlist M3U", "files-type.m4a": "Audio M4A", "files-type.m4v": "Video M4V", "files-type.midi": "Audio MIDI", "files-type.mka": "Audio MKA", "files-type.mkv": "Video MKV", "files-type.mng": "Video MNG", "files-type.mobi": "eBook MOBI", "files-type.mp3": "Audio MP3", "files-type.mp4": "Video MP4", "files-type.mp4-audio": "Audio MP4", "files-type.mpeg": "Video MPEG", "files-type.mpeg-ts": "Flusso di trasporto MPEG", "files-type.network-drive": "Unità di rete", "files-type.numbers": "Foglio di calcolo Numbers", "files-type.ogg": "Audio OGG", "files-type.ogv": "Video OGV", "files-type.pages": "Documento Pages", "files-type.pdf": "Documento PDF", "files-type.png": "Immagine PNG", "files-type.powerpoint": "Presentazione PowerPoint", "files-type.psd": "Documento Photoshop", "files-type.quicktime": "Video QuickTime", "files-type.rar": "Archivio RAR", "files-type.sgi": "Filmato SGI", "files-type.svg": "Immagine SVG", "files-type.tar": "Archivio TAR", "files-type.tiff": "Immagine TIFF", "files-type.ts": "Video TS", "files-type.txt": "File di testo", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "Audio WAV", "files-type.webm": "Video WebM", "files-type.webm-audio": "Audio WebM", "files-type.webp": "Immagine WebP", "files-type.wma": "Audio WMA", "files-type.wmv": "Video WMV", "files-type.word": "Documento Word", "files-type.xz": "Archivio XZ", "files-type.zip": "Archivio ZIP", "files-upload-island.uploading-count": "Caricamento di {{count}} elementi...", "files-view.icons": "Icone", "files-view.list": "Elenco", "files-view.sort-by": "Ordina per", "files-view.view-as": "Visualizza come", "files-widgets.favorites.no-items-text": "Aggiungi una cartella ai preferiti per visualizzarla qui", "files-widgets.recents.no-items-text": "Nessun file recente", "generic-in": "nell’", "hide-details": "Nascondi dettagli", "install-first.install-app": "Installa {{app}}", "install-first.title": "{{app}} richiede queste app", "install-your-first-app": "Installa la tua prima app", "language": "Lingua", "language-description": "La tua lingua preferita per umbrelOS", "language.select-description": "Seleziona la lingua preferita per umbrelOS", "live-usage": "Utilizzo in Tempo Reale", "loading": "Caricamento", "local-ip": "IP locale", "login-2fa.subtitle": "Inserisci il codice 2FA visualizzato nella tua app di autenticazione", "login-2fa.title": "Autentica", "login-with-umbrel.description": "Inserisci la tua password Umbrel per aprire {{app}}", "login-with-umbrel.title": "Accedi con Umbrel", "login.password-label": "Password", "login.password.submit": "Accedi", "login.subtitle": "Inserisci la tua password Umbrel per accedere", "login.title": "Bentornato", "logout": "Esci", "logout-error-generic": "Errore: Logout fallito", "logout.confirm.submit": "Esci", "logout.confirm.title": "Sei sicuro di voler uscire?", "memory": "Memoria", "memory.low": "Memoria bassa", "migrate": "Migra", "migrate.callout": "Non spegnere il tuo Umbrel fino al completamento della migrazione", "migrate.failed.retry": "Riprova", "migrate.failed.title": "Migrazione fallita", "migrate.success.description": "Tutte le tue app, i dati delle app e i dettagli dell'account sono stati migrati sul tuo Umbrel Home.", "migrate.success.title": "Migrazione riuscita", "migration-assistant": "Assistente di Migrazione", "migration-assistant-description": "Trasferisci tutte le tue app e i tuoi dati da un Raspberry Pi a {{deviceName}}", "migration-assistant-unsupported-device-description": "Attualmente Migration Assistant supporta il trasferimento di tutti i dati e delle app da un Raspberry Pi con umbrelOS a Umbrel Home o Umbrel Pro. Apri Migration Assistant sul tuo Umbrel Home o Umbrel Pro per iniziare.", "migration-assistant.continue-migration.ready.submit": "Inizia la migrazione", "migration-assistant.failed": "Qualcosa non va...", "migration-assistant.failed.retrying-message": "Riprova in corso...", "migration-assistant.mobile.start-button": "Inizia la migrazione", "migration-assistant.prep.body": "Preparazione alla migrazione", "migration-assistant.prep.button-continue": "Continua", "migration-assistant.prep.callout": "I dati sul tuo {{deviceName}}, se presenti, saranno eliminati definitivamente.", "migration-assistant.prep.connect-disk-to-home": "Collega il suo disco esterno a una qualsiasi porta USB del tuo {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Una volta fatto, clicca su '{{button}}' qui sotto.", "migration-assistant.prep.shut-down-rpi": "Spegni il tuo Umbrel su Raspberry Pi.", "migration-assistant.ready.description": "Tutti i tuoi dati e le tue app sono pronti per essere migrati su {{deviceName}}", "migration-assistant.ready.hint-header": "Cose da tenere a mente", "migration-assistant.ready.hint-keep-pi-off.description": "Questo aiuta a prevenire problemi con app come Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Tieni spento il tuo Raspberry Pi dopo l'aggiornamento", "migration-assistant.ready.hint-use-same-password.description": "Ricordati di usare la password di Umbrel sul tuo Raspberry Pi per accedere a {{deviceName}}", "migration-assistant.ready.hint-use-same-password.title": "Usa la stessa password", "migration-assistant.ready.title": "Tutto pronto per la migrazione!", "mini-browser.default-title": "Seleziona cartella", "mini-browser.empty-external": "Collega un'unità esterna per visualizzarla qui.", "mini-browser.empty-network": "Aggiungi un dispositivo Umbrel o un NAS per visualizzarlo qui.", "mini-browser.load-more": "Carica altri", "mini-browser.load-more-in-folder": "Carica altri in {{name}}", "mini-browser.loading-more": "Caricamento in corso…", "mini-browser.select": "Seleziona", "mini-browser.select-folder": "Seleziona cartella", "name": "Nome", "nas": "NAS", "no-forgot-password-message": "Se perdi la tua password, non sarai in grado di accedere al tuo Umbrel. Assicurati di conservarla in modo sicuro.", "no-results-found": "Nessun risultato trovato", "not-found-404": "Codice errore: 404", "not-found-404.back": "Indietro", "not-found-404.home": "Vai alla Home", "notifications.backups-failing-location.description": "I Backups automatici su {{location}} non funzionano. Controlla la connessione e rivedi le impostazioni dei Backups.", "notifications.backups-failing.description": "I backup automatici continuano a non riuscire. Controlla la posizione dei backup e verifica le impostazioni.", "notifications.backups-failing.go-to-backups": "Vai a Backups", "notifications.backups-failing.title": "Nessun backup nelle ultime 24 ore", "notifications.cpu.too-hot": "Temperatura della CPU alta", "notifications.memory.low": "La memoria del tuo dispositivo è bassa", "notifications.new-version-available": "{{update}} ora disponibile per l'installazione", "notifications.raid.issue.description": "Problema di archiviazione rilevato. Controlla Storage Manager per i dettagli.", "notifications.raid.issue.title": "Azione urgente richiesta", "notifications.ssd.health.description": "Uno o più SSD potrebbero richiedere attenzione. Controlla Storage Manager per i dettagli.", "notifications.ssd.health.title": "Avviso integrità SSD", "notifications.storage.full": "La memoria del tuo dispositivo è piena", "notifications.view": "Visualizza", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "Cliccando su 'Avanti', accetti i Termini di Servizio di umbrelOS", "onboarding.account-created.youre-all-set-name": "Tutto pronto, {{name}}.", "onboarding.contact-support": "Supporto", "onboarding.create-account": "Crea account", "onboarding.create-account.confirm-password.input-label": "Conferma password", "onboarding.create-account.failed.name-required": "Nome richiesto", "onboarding.create-account.failed.passwords-dont-match": "Le password non corrispondono", "onboarding.create-account.name.input-placeholder": "Il tuo nome", "onboarding.create-account.password.input-label": "Password", "onboarding.create-account.submit": "Crea", "onboarding.create-account.submitting": "Creazione", "onboarding.create-account.subtitle": "Le informazioni del tuo account sono memorizzate solo sul tuo Umbrel. Assicurati di fare un backup della tua password in modo sicuro poiché non c'è modo di reimpostarla.", "onboarding.create-instead-long": "Crea un nuovo account", "onboarding.create-instead-short": "Nuovo account", "onboarding.launch-umbrelos": "Avvia umbrelOS", "onboarding.raid.available-storage": "Spazio disponibile", "onboarding.raid.change-drives-link": "Vuoi aggiungere o sostituire le unità?", "onboarding.raid.configuring.subtitle": "Potrebbe richiedere alcuni minuti.", "onboarding.raid.configuring.title": "Configurazione dell'archiviazione", "onboarding.raid.configuring.warning": "Per favore non aggiornare questa pagina né spegnere il tuo Umbrel mentre sta configurando l'archiviazione.", "onboarding.raid.continue": "Continua", "onboarding.raid.error.detection-instructions": "Spegni Umbrel Pro, verifica che gli SSD siano inseriti correttamente e riprova.", "onboarding.raid.error.no-ssds-detected": "Nessun SSD rilevato", "onboarding.raid.error.no-ssds-instructions": "Spegni Umbrel Pro e inserisci almeno un SSD per continuare.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Non puoi ancora abilitare FailSafe", "onboarding.raid.failsafe.enable": "Abilita FailSafe", "onboarding.raid.failsafe.mixed-sizes": "FailSafe è limitato dal tuo SSD più piccolo ({{smallest}}). Lo spazio extra sugli SSD più grandi non può essere utilizzato, lasciando {{wasted}} inutilizzabile.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} viene usato per la protezione dei dati. Aggiungi un altro SSD da {{smallest}} per aumentare lo spazio disponibile a {{futureWith3}}, oppure aggiungi due SSD in più per arrivare a {{futureWith4}}. Puoi aggiungere altri SSD in qualsiasi momento.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} viene usato per la protezione dei dati. Aggiungi un altro SSD da {{smallest}} per aumentare lo spazio disponibile a {{futureWith4}}. Puoi aggiungere altri SSD in qualsiasi momento.", "onboarding.raid.failsafe.single-ssd-info": "Hai solo un SSD. Aggiungi almeno un altro SSD da {{size}} per abilitare la protezione FailSafe dei tuoi dati. Puoi aggiungere altri SSD in qualsiasi momento.", "onboarding.raid.failsafe.subtitle": "I tuoi dati restano al sicuro se un singolo SSD si guasta", "onboarding.raid.failsafe.tip": "Usa SSD di dimensioni identiche per ottenere la massima capacità e nessuno spazio inutilizzabile.", "onboarding.raid.failsafe.warning-now-only": "Con più di uno SSD, FailSafe può essere abilitato solo durante la configurazione iniziale. Non potrai abilitarlo in seguito.", "onboarding.raid.health-warning": "Questa unità segnala problemi di integrità", "onboarding.raid.launching": "Avvio...", "onboarding.raid.no-ssds-alt": "Nessun SSD trovato", "onboarding.raid.recommended": "Consigliato", "onboarding.raid.scanning": "Verifica degli slot SSD", "onboarding.raid.scanning-alt": "Scansione degli SSD", "onboarding.raid.setup-failed.description-no-retry": "Spegni e riprova.", "onboarding.raid.setup-failed.description-retry": "Riprova oppure spegni per controllare le unità.", "onboarding.raid.setup-failed.title": "Configurazione dell'archiviazione non riuscita", "onboarding.raid.shutdown-dialog.description": "Per aggiungere o sostituire le unità, spegni Umbrel Pro. Quando hai finito, riaccendilo e continua la configurazione.", "onboarding.raid.shutdown-dialog.title": "Cambiare unità?", "onboarding.raid.ssd-in-slot": "Un {{size}} SSD in Slot {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "Vassoio SSD", "onboarding.raid.ssds-found": "Sono stati trovati i seguenti SSD nel tuo Umbrel Pro", "onboarding.raid.storage": "Archiviazione", "onboarding.raid.storage-label": "Archiviazione", "onboarding.raid.success.storage-info": "Archiviazione {{available}}", "onboarding.raid.success.storage-info-failsafe": "Archiviazione {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Riprova", "onboarding.raid.wasted": "Inutilizzabile", "onboarding.restore-long": "Ripristina il tuo Umbrel", "onboarding.restore-short": "Ripristina", "onboarding.start.continue": "Inizia", "onboarding.start.subtitle": "Il tuo server cloud domestico è pronto per essere configurato.", "onboarding.start.title": "Benvenuto in umbrelOS", "open": "Apri", "open-live-usage": "Apri Utilizzo in Tempo Reale", "password": "Password", "preferences": "Preferenze", "raid-error.description": "Il sistema di archiviazione non è riuscito ad avviarsi correttamente. Controlla lo stato degli SSD qui sotto e segui i passaggi per la risoluzione. Se il problema persiste, gli SSD coinvolti potrebbero dover essere sostituiti.", "raid-error.factory-reset-dialog.description": "Questo cancellerà tutti i dati sul tuo Umbrel Pro e lo riporterà alle impostazioni di fabbrica. Questa azione non può essere annullata.", "raid-error.factory-reset-dialog.title": "Ripristino di fabbrica?", "raid-error.factory-reset-failed": "Impossibile eseguire il ripristino alle impostazioni di fabbrica", "raid-error.health-warning": "Avviso di integrità", "raid-error.missing-ssd-multiple": "{{count}} SSD non rispondono", "raid-error.missing-ssd-one": "1 SSD non risponde", "raid-error.shutdown-dialog.description": "Spegni il tuo Umbrel Pro, assicurati che tutti gli SSD siano inseriti correttamente negli slot, poi riaccendilo.", "raid-error.shutdown-dialog.title": "Spegni per controllare le unità?", "raid-error.ssd-in-slot": "Un SSD da {{size}} in Slot {{slot}}", "raid-error.step-check-connections.button": "Spegni", "raid-error.step-check-connections.description": "Spegni e verifica che tutti gli SSD siano inseriti correttamente.", "raid-error.step-check-connections.title": "Controlla le connessioni degli SSD", "raid-error.step-factory-reset.button": "Ripristino di fabbrica", "raid-error.step-factory-reset.description": "Ultima risorsa se niente altro funziona. Questo cancella tutti i dati.", "raid-error.step-factory-reset.title": "Ripristino alle impostazioni di fabbrica", "raid-error.step-restart.button": "Riavvia", "raid-error.step-restart.description": "Un primo passo rapido che spesso aiuta", "raid-error.step-restart.title": "Prova a riavviare", "raid-error.title": "Problema di archiviazione rilevato", "read-less": "Leggi meno", "read-more": "Leggi di più", "reconnect": "Riconnetti", "redirect.to-home": "Caricamento...", "redirect.to-login": "Caricamento...", "redirect.to-onboarding": "Caricamento...", "redirect.to-raid-error": "Caricamento...", "reload": "Ricarica", "remote-tor-access": "Accesso remoto Tor", "reset": "Ripristina", "restart": "Riavvia", "restart.confirm.submit": "Riavvia", "restart.confirm.title": "Sei sicuro di voler riavviare il tuo Umbrel?", "restart.restarting": "Riavvio in corso", "restart.restarting-message": "Non aggiornare questa pagina o spegnere il tuo Umbrel durante il riavvio.", "rewind": "Rewind", "rewind.files-as-of": "I tuoi file al", "rewind.loading-snapshots": "Caricamento delle istantanee...", "rewind.now": "Ora", "rewind.preflight.description": "Trova file e cartelle dai tuoi backup precedenti e ripristinali nel presente.", "rewind.preflight.enable-backups": "Configura Backups nelle Impostazioni per iniziare a usare Rewind", "rewind.restore-complete": "Ripristino completato", "rewind.restore-error-description": "Riprova.", "rewind.restore-failed": "Ripristino fallito", "rewind.restore-running-description": "Non chiudere o aggiornare questa pagina finché il ripristino non è completato", "rewind.restore-selected": "Ripristina selezionati", "rewind.restore-success-description": "I tuoi file sono stati ripristinati", "rewind.restoring": "Ripristino in corso", "rewind.snapshots-count_one": "{{count}} backup da", "rewind.snapshots-count_other": "{{count}} backup da", "search": "Cerca", "settings": "Impostazioni", "settings.app-store-preferences.title": "Preferenze App Store", "settings.contact-support": "Hai bisogno di aiuto? Contatta il supporto.", "settings.file-sharing": "Condivisione file", "settings.file-sharing.add-folder": "Aggiungi", "settings.file-sharing.add-folder-title": "Seleziona una cartella da condividere", "settings.file-sharing.choice-entire-description": "Condividi tutti i file sul tuo Umbrel", "settings.file-sharing.choice-entire-title": "Tutto", "settings.file-sharing.choice-heading": "Cosa vuoi condividere?", "settings.file-sharing.choice-specific-description": "Scegli quali cartelle condividere", "settings.file-sharing.choice-specific-title": "Cartelle specifiche", "settings.file-sharing.choice-subtitle": "Accedi ai tuoi file e alle tue cartelle in stile Dropbox come cartelle di rete sul computer o sul telefono", "settings.file-sharing.configure": "Configura", "settings.file-sharing.description": "Accedi ai tuoi file in stile Dropbox come cartella di rete (SMB) su altri dispositivi", "settings.file-sharing.home-shared-note": "L'intera cartella \"{{homeDirectoryName}}\" è condivisa. Le singole cartelle non devono essere condivise separatamente.", "settings.file-sharing.share-entire-home-dir": "Condividi l'intera cartella Home", "settings.file-sharing.share-entire-home-dir-description": "Accedi a tutti i file e le cartelle in \"{{homeDirectoryName}}\" da altri dispositivi sulla tua rete", "settings.file-sharing.shared-folders": "Cartelle condivise", "show-details": "Mostra dettagli", "shut-down": "Spegni", "shut-down.complete": "Spegnimento completato", "shut-down.complete-text": "Ora puoi scollegare il tuo dispositivo dalla corrente.", "shut-down.confirm.submit": "Spegni", "shut-down.confirm.title": "Sei sicuro di voler spegnere il tuo Umbrel?", "shut-down.failed": "Impossibile spegnere: {{message}}", "shut-down.shutting-down": "Spegnimento in corso", "shut-down.shutting-down-message": "Non aggiornare questa pagina o spegnere il tuo Umbrel durante lo spegnimento.", "software-update.callout": "Non aggiornare questa pagina o spegnere il tuo Umbrel durante l'aggiornamento.", "software-update.check": "Verifica aggiornamenti", "software-update.checking": "Verifica degli aggiornamenti in corso...", "software-update.current-running": "Sei su", "software-update.failed": "Aggiornamento non riuscito", "software-update.failed-to-check": "Impossibile verificare gli aggiornamenti", "software-update.failed.retry": "Riprova", "software-update.install-now": "Installa ora", "software-update.new-version": "Nuova versione {{name}} disponibile per l'installazione", "software-update.on-latest": "Hai l'ultima versione di umbrelOS", "software-update.see-whats-new": "Scopri le novità", "software-update.title": "Aggiornamento software", "software-update.updating-to": "Aggiornamento a {{name}}", "software-update.view": "Visualizza", "something-left": "{{left}} rimanenti", "something-went-wrong": "⚠ Qualcosa è andato storto", "start": "Avvia", "stop": "Ferma", "storage": "Archiviazione", "storage-manager": "Gestione archiviazione", "storage-manager.add": "Aggiungi", "storage-manager.add-to-raid.add-ssd": "Aggiungi SSD", "storage-manager.add-to-raid.available": "Disponibile:", "storage-manager.add-to-raid.description": "È stato rilevato un nuovo SSD ed è pronto per essere aggiunto.", "storage-manager.add-to-raid.enable-failsafe": "Abilita FailSafe", "storage-manager.add-to-raid.failed-add": "Impossibile aggiungere l'SSD", "storage-manager.add-to-raid.failed-enable-failsafe": "Impossibile abilitare FailSafe", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Il nuovo SSD {{size}} verrà aggiunto allo spazio disponibile.", "storage-manager.add-to-raid.info-capacity-adds-available": "Il tuo nuovo SSD {{size}} aggiungerà {{available}} di spazio disponibile.", "storage-manager.add-to-raid.info-capacity-adds-both": "Il tuo nuovo SSD {{size}} aggiungerà {{available}} di spazio disponibile e {{protection}} per la protezione dei dati.", "storage-manager.add-to-raid.info-capacity-protection-only": "Il tuo nuovo SSD {{size}} aggiungerà {{protection}} per la protezione dei dati.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Il tuo nuovo SSD {{size}} sarà usato interamente per la protezione dei dati.", "storage-manager.add-to-raid.info-data-safe": "I tuoi dati saranno al sicuro in caso di guasto di un singolo SSD.", "storage-manager.add-to-raid.info-no-protection": "Se un SSD dovesse guastarsi, potresti perdere i tuoi dati.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} inutilizzabile in totale a causa di SSD di dimensioni diverse.", "storage-manager.add-to-raid.info-wasted": "{{size}} saranno inutilizzabili a causa di SSD di dimensioni diverse.", "storage-manager.add-to-raid.recommended": "Consigliato", "storage-manager.add-to-raid.recommended-inline": "(consigliato)", "storage-manager.add-to-raid.restart-active-tasks": "Eventuali attività in corso verranno interrotte", "storage-manager.add-to-raid.restart-after": "Dopo il riavvio, la configurazione di FailSafe verrà completata automaticamente e potrai riprendere l'uso normale.", "storage-manager.add-to-raid.restart-during": "Durante il riavvio:", "storage-manager.add-to-raid.restart-intro": "Puoi continuare a usare umbrelOS normalmente durante il processo. Tuttavia, al 50% di avanzamento il tuo Umbrel si riavvierà automaticamente.", "storage-manager.add-to-raid.restart-required": "Riavvio del sistema richiesto", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS sarà temporaneamente inaccessibile", "storage-manager.add-to-raid.ssd-in-slot": "SSD da {{size}} in Slot {{slot}}", "storage-manager.add-to-raid.title": "Aggiungi SSD all'archiviazione", "storage-manager.add-to-raid.too-small": "SSD troppo piccolo", "storage-manager.add-to-raid.too-small-description": "Questo SSD ({{deviceSize}}) è più piccolo dell'SSD più piccolo attualmente installato ({{minSize}}). FailSafe richiede che tutti gli SSD siano almeno grandi quanto lo SSD più piccolo in uso.", "storage-manager.add-to-raid.understand-continue": "Ho capito, continua", "storage-manager.add-to-raid.warning-failsafe-now-only": "Avere più di un SSD significa che FailSafe può essere abilitato solo ora. Non potrai abilitarlo in seguito.", "storage-manager.add-to-raid.wasted-label": "Inutilizzabile:", "storage-manager.available-storage": "Spazio disponibile", "storage-manager.description": "Visualizza spazio, stato di salute e impostazioni dei tuoi SSD", "storage-manager.empty": "Vuoto", "storage-manager.failsafe-transition-failed": "Impossibile abilitare FailSafe", "storage-manager.for-failsafe": "Per FailSafe", "storage-manager.health.checksum-errors": "Errori di checksum: {{count}}", "storage-manager.health.critical": "Critico", "storage-manager.health.critical-threshold": "Soglia critica", "storage-manager.health.current-temperature": "Temperatura attuale", "storage-manager.health.estimated-life": "Vita residua stimata", "storage-manager.health.general": "Generale", "storage-manager.health.health-status": "Stato di salute", "storage-manager.health.low": "Basso", "storage-manager.health.model-and-capacity": "Modello e dimensione", "storage-manager.health.overheating": "Surriscaldamento", "storage-manager.health.raid-failed-advice": "Questo SSD ha un problema. Spegni il tuo Umbrel e verifica la connessione dell'SSD. Se il problema persiste, l'SSD potrebbe dover essere sostituito.", "storage-manager.health.read-errors": "Errori di lettura: {{count}}", "storage-manager.health.serial-number": "Numero di serie", "storage-manager.health.status-healthy": "Sano", "storage-manager.health.status-unhealthy": "Non integro", "storage-manager.health.status-unknown": "Sconosciuto", "storage-manager.health.temperature": "Temperatura", "storage-manager.health.title": "Integrità SSD", "storage-manager.health.warning-life-advice": "Valuta di sostituire presto questo SSD.", "storage-manager.health.warning-life-message": "Solo il {{percent}}% di vita rimanente", "storage-manager.health.warning-temp-advice": "Assicurati che il tuo Umbrel Pro abbia un buon flusso d'aria e che l'SSD sia correttamente inserito.", "storage-manager.health.warning-temp-critical": "La temperatura è critica ({{temperature}})", "storage-manager.health.warning-temp-overheating": "L'unità si sta surriscaldando ({{temperature}})", "storage-manager.health.warning-threshold": "Soglia di avviso", "storage-manager.health.warning-unhealthy-advice": "Questo SSD potrebbe guastarsi a breve. Valuta di sostituirlo.", "storage-manager.health.warning-unhealthy-message": "Questo SSD potrebbe avere un problema", "storage-manager.health.warnings": "Avvisi", "storage-manager.health.wear": "Usura", "storage-manager.health.write-errors": "Errori di scrittura: {{count}}", "storage-manager.install-ssd.description": "Aggiungi altri SSD per espandere lo spazio di archiviazione", "storage-manager.install-ssd.step-insert": "Inserisci i nuovi SSD negli slot vuoti", "storage-manager.install-ssd.step-power-on": "Accendi il tuo {{deviceName}}", "storage-manager.install-ssd.step-remove-bottom-cover": "Rimuovi la copertura magnetica inferiore", "storage-manager.install-ssd.step-replace-bottom-cover": "Rimetti il coperchio inferiore.", "storage-manager.install-ssd.step-return": "Torna qui per aggiungere gli SSD alla tua archiviazione", "storage-manager.install-ssd.step-shut-down": "Spegni il tuo {{deviceName}}", "storage-manager.install-ssd.title": "Aggiunta di SSD", "storage-manager.install-tips.image-alt": "Istruzioni per l'installazione SSD", "storage-manager.install-tips.instructions": "Per installare, rimuovi la vite a pollice e inserisci l'SSD nello slot con un angolo. Premi l'SSD verso il basso finché non poggia sul pilastro della vite, quindi fissalo con la vite a pollice.", "storage-manager.install-tips.toggle": "Hai dimenticato come inserire un SSD?", "storage-manager.manage": "Gestisci", "storage-manager.missing-ssd-warning": "Sembra mancare un SSD. Spegni il tuo Umbrel e verifica che tutti gli SSD siano collegati. Se il problema continua, potrebbe essere necessario sostituire l'SSD.", "storage-manager.mode": "Modalità", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Protegge i tuoi dati in caso di guasto di un SSD. Se gli SSD hanno dimensioni diverse, lo spazio extra sui più grandi rimane inutilizzato.", "storage-manager.mode.failsafe.info-description": "FailSafe protegge i tuoi dati mantenendo copie su più SSD. Se un singolo SSD si guasta, i dati restano al sicuro e possono essere ripristinati quando aggiungi un SSD di ricambio.", "storage-manager.mode.failsafe.info-title": "Informazioni su FailSafe", "storage-manager.mode.full-storage": "Archiviazione completa", "storage-manager.mode.full-storage.description": "Usa tutto lo spazio dei tuoi SSD insieme. Se un SSD si guasta, potresti perdere i dati.", "storage-manager.mode.full-storage.info-description": "Full Storage combina tutti i tuoi SSD in un unico grande spazio, offrendoti la massima capacità. Tuttavia, se un SSD si guasta, tutti i tuoi dati andranno persi.", "storage-manager.mode.full-storage.info-title": "Informazioni su Archiviazione completa", "storage-manager.mode.switch-from-failsafe-unavailable": "Passare da FailSafe alla modalità Full Storage richiede di fare il backup dei dati, ripristinare il dispositivo alle impostazioni di fabbrica e ripristinare dal backup.", "storage-manager.mode.switch-to-failsafe-unavailable": "Con più SSD in modalità Full Storage, i tuoi dati sono distribuiti su tutte le unità. Passare a FailSafe richiede il backup dei dati, un ripristino alle impostazioni di fabbrica e il ripristino dal backup.", "storage-manager.mode.why-cant-switch": "Perché non posso cambiare modalità?", "storage-manager.operation-in-progress.shutdown-description": "È sicuro spegnere il dispositivo. L'operazione verrà messa in pausa e riprenderà dopo il riavvio, ma deve essere completata prima che tu possa apportare altre modifiche.", "storage-manager.operation-in-progress.shutdown-title": "Il tuo spazio di archiviazione viene aggiornato", "storage-manager.operation-in-progress.wait-description": "Attendi il completamento dell'operazione in corso prima di apportare altre modifiche.", "storage-manager.operation-in-progress.wait-title": "Il tuo spazio di archiviazione viene aggiornato", "storage-manager.operation.adding-ssd": "Aggiunta SSD...", "storage-manager.operation.enabling-failsafe": "Attivazione di FailSafe...", "storage-manager.operation.expanding": "Espansione dell'archiviazione...", "storage-manager.operation.rebuilding": "Ricostruzione dei dati...", "storage-manager.operation.replacing": "Sostituzione dell'unità...", "storage-manager.operation.restarting": "Riavvio...", "storage-manager.operation.starting": "Avvio...", "storage-manager.operation.syncing-restarts": "Sincronizzazione dati • Riavvio al 50%", "storage-manager.raid-status.degraded": "Degradato", "storage-manager.raid-status.failed": "Guasto", "storage-manager.raid-status.offline": "Offline", "storage-manager.raid-status.online": "Online", "storage-manager.raid-status.removed": "Rimosso", "storage-manager.raid-status.unavailable": "Non disponibile", "storage-manager.replace": "Sostituisci", "storage-manager.replace-failed.degraded": "Protezione FailSafe ridotta", "storage-manager.replace-failed.degraded-description": "Manca un SSD nell'archiviazione FailSafe. Sostituiscilo per ripristinare la protezione completa.", "storage-manager.replace-failed.description": "Usa questo SSD per ripristinare la protezione FailSafe.", "storage-manager.replace-failed.error": "Impossibile avviare la sostituzione", "storage-manager.replace-failed.replace-now": "Sostituisci ora", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD nello slot {{slot}}", "storage-manager.replace-failed.step-protected": "Al termine, i tuoi dati saranno di nuovo completamente protetti", "storage-manager.replace-failed.step-rebuild": "I dati verranno ricostruiti sul nuovo SSD", "storage-manager.replace-failed.step-time": "Potrebbe richiedere un po' di tempo, a seconda della quantità di dati.", "storage-manager.replace-failed.title": "Sostituisci SSD", "storage-manager.replace-failed.too-small": "SSD troppo piccolo", "storage-manager.replace-failed.too-small-description": "Questo SSD ({{deviceSize}}) è più piccolo della dimensione minima richiesta ({{minSize}}) per la tua archiviazione FailSafe.", "storage-manager.replace-failed.what-happens": "Cosa succede dopo:", "storage-manager.ssd-failing": "A rischio guasto", "storage-manager.swap": "Sostituisci", "storage-manager.swap.data-erased-description": "La modalità Full Storage non offre protezione dei dati. Tutti i dati sul tuo {{deviceName}} saranno cancellati durante il ripristino di fabbrica. Assicurati di eseguire un backup prima.", "storage-manager.swap.data-protected": "I tuoi dati sono protetti", "storage-manager.swap.data-protected-description": "Con FailSafe abilitato, puoi sostituire un singolo SSD senza perdere dati. Nessun backup richiesto.", "storage-manager.swap.data-will-be-erased": "I dati verranno cancellati", "storage-manager.swap.description-failsafe": "Sostituisci un'unità nello storage FailSafe.", "storage-manager.swap.description-full-storage": "Sostituisci un'unità nella tua configurazione Full Storage.", "storage-manager.swap.description-no-free-slot": "In modalità Full Storage, con tutti gli slot occupati, la sostituzione di un SSD richiede un processo completo di backup e ripristino.", "storage-manager.swap.description-replace": "Migra i tuoi dati su un nuovo SSD, poi rimuovi quello vecchio.", "storage-manager.swap.failed-to-start": "Impossibile avviare la sostituzione", "storage-manager.swap.no-data-loss": "Nessuna perdita di dati", "storage-manager.swap.no-data-loss-description": "I tuoi dati saranno copiati sul nuovo SSD. Una volta completato, potrai rimuovere il vecchio in sicurezza.", "storage-manager.swap.safe-swap-available": "Sostituzione sicura disponibile", "storage-manager.swap.safe-swap-description": "Poiché hai uno slot vuoto, puoi aggiungere prima il nuovo SSD e migrare i dati prima di rimuovere quello vecchio. Nessun backup richiesto.", "storage-manager.swap.select-new-ssd": "Seleziona il nuovo SSD da utilizzare:", "storage-manager.swap.ssd-in-slot": "SSD da {{size}} in Slot {{slot}}", "storage-manager.swap.step-backup": "Esegui il backup dei dati", "storage-manager.swap.step-backup-description": "Vai su Impostazioni → Backups e crea un backup di tutti i tuoi dati.", "storage-manager.swap.step-data-copied": "I dati saranno copiati dal vecchio SSD a quello nuovo", "storage-manager.swap.step-factory-reset": "Ripristino di fabbrica", "storage-manager.swap.step-factory-reset-description": "Vai su Impostazioni → Avanzate → Ripristino di fabbrica per cancellare il tuo {{deviceName}}.", "storage-manager.swap.step-insert-new-ssd": "Inserisci il nuovo SSD in uno slot vuoto", "storage-manager.swap.step-may-take-while": "Potrebbe richiedere un po' di tempo a seconda della quantità di dati", "storage-manager.swap.step-power-on": "Accendi il tuo {{deviceName}}", "storage-manager.swap.step-remove-bottom-cover": "Rimuovi la copertura magnetica inferiore", "storage-manager.swap.step-remove-old": "Una volta completato, spegni e rimuovi {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Rimetti la copertura inferiore", "storage-manager.swap.step-restore": "Ripristina i tuoi dati", "storage-manager.swap.step-restore-description": "Vai su Impostazioni → Backups e ripristina dal tuo backup.", "storage-manager.swap.step-return-to-storage-manager": "Torna qui su Storage Manager per confermare la sostituzione e aggiungere il nuovo SSD alla tua archiviazione", "storage-manager.swap.step-return-to-swap": "Torna qui su Storage Manager e clicca di nuovo su \"Swap\" per avviare la sostituzione", "storage-manager.swap.step-setup-new-storage": "Configura la tua nuova archiviazione", "storage-manager.swap.step-setup-new-storage-description": "Accendi il tuo {{deviceName}} e completa il processo di configurazione con il nuovo SSD.", "storage-manager.swap.step-shut-down": "Spegni il tuo {{deviceName}}", "storage-manager.swap.step-shut-down-and-swap": "Spegni e sostituisci {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Spegni, apri il dispositivo, sostituisci l'SSD e rimonta il dispositivo.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Spegni, rimuovi la copertura inferiore, sostituisci l'SSD e richiudi la copertura.", "storage-manager.swap.step-swap-ssd": "Sostituisci {{ssd}} con uno nuovo delle stesse dimensioni", "storage-manager.swap.too-small": "Troppo piccolo (richiesto {{size}})", "storage-manager.swap.what-happens-next": "Cosa succede dopo:", "storage-manager.total-capacity-added": "Capacità totale aggiunta", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Utilizzato", "storage-manager.wasted": "Non utilizzabile", "storage-manager.wasted-size": "Spazio non utilizzabile: {{size}}", "storage.full": "Archiviazione piena", "storage.low": "Spazio di archiviazione basso", "temperature": "Temperatura", "temperature.dangerously-hot": "Molto caldo", "temperature.nice": "Piacevole", "temperature.normal": "Normale", "temperature.too-hot-suggestion": "Considera di cambiare l'ambiente del tuo dispositivo.", "temperature.warm": "Tiepido", "terminal": "Terminal", "terminal-description": "Esegui comandi personalizzati in umbrelOS o all'interno di un'app", "terminal.app": "App", "terminal.app-description": "Esegui comandi personalizzati all'interno di un'app specifica", "terminal.umbrelos-description": "Esegui comandi personalizzati in umbrelOS", "tor-description": "Accedi al tuo Umbrel da ovunque usando un browser Tor", "tor-enabled-description": "Accedi al tuo Umbrel da ovunque usando un browser Tor all'indirizzo seguente:", "tor-error": "Impossibile aggiornare l'impostazione Tor: {{message}}", "tor.disable.description": "Questo potrebbe richiedere alcuni minuti", "tor.disable.progress": "Disattivazione dell'accesso remoto tramite Tor", "tor.enable.description": "Questo potrebbe richiedere alcuni minuti", "tor.enable.mobile.switch-label": "Abilita l'accesso remoto Tor", "tor.hidden-service": "URL del servizio nascosto Tor", "troubleshoot": "Risoluzione problemi", "troubleshoot-description": "Risolvi problemi di umbrelOS o di un'app", "troubleshoot-no-logs-yet": "Nessun log ancora", "troubleshoot-pick-title": "Risoluzione problemi", "troubleshoot.app": "App", "troubleshoot.app-description": "Visualizza i log di un'app installata sul tuo Umbrel", "troubleshoot.app-download": "Scarica i log di {{app}}", "troubleshoot.share-with-umbrel-support": "Condividi con il supporto Umbrel", "troubleshoot.system-download": "Scarica {{label}}", "troubleshoot.umbrelos-description": "Visualizza i log di umbrelOS", "troubleshoot.umbrelos-logs": "Log di umbrelOS", "trpc.backend-unavailable": "Errore: Connessione all'API di sistema fallita", "trpc.checking-backend": "Caricamento...", "try-again": "Riprova", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Sconosciuto", "unknown-app": "App sconosciuta", "unknown-error": "Errore sconosciuto", "uptime": "Tempo di attività", "url": "URL", "wallpaper": "Sfondo", "wallpaper-description": "Il tuo sfondo e tema Umbrel", "whats-new.continue": "Continua", "whats-new.feature-1.description": "Configura backup automatici e crittografati del tuo intero Umbrel su un'unità USB esterna, su un NAS o su un altro Umbrel.", "whats-new.feature-2.description": "Torna indietro nel tempo per recuperare file e cartelle specifici da backup precedenti.", "whats-new.feature-3.description": "Oppure ripristina l'intero Umbrel, comprese tutte le tue app, i file e i dati.", "whats-new.feature-4.description": "Collega un NAS o un altro Umbrel e accedi al suo spazio di archiviazione da Files.", "whats-new.feature-4.title": "Dispositivi di rete", "whats-new.feature-5.description": "Collega unità USB esterne (su Umbrel Home o su qualsiasi dispositivo Intel o AMD) e accedervi da Files.", "whats-new.feature-5.helper-text": "Non è supportato sui dispositivi Raspberry Pi a causa di possibili problemi di alimentazione.", "whats-new.feature-5.title": "Archiviazione esterna", "whats-new.next": "Avanti", "whats-new.title": "Novità in {{version}}", "widget.progress.in-progress": "In corso", "widgets.edit.select-up-to-3-widgets": "Seleziona fino a 3 widget", "widgets.install-an-app-before-using-widgets": "Installa un'app per iniziare a personalizzare la tua schermata iniziale con i widget.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Le reti aperte possono essere insicure", "wifi-connection-failed": "Impossibile connettersi", "wifi-dangerous-change-confirmation-description": "Cambiare la rete Wi-Fi può disconnetterti dal tuo Umbrel. Per riconnetterti, assicurati che sia il tuo Umbrel che il dispositivo da cui accedi siano sulla stessa rete.", "wifi-dangerous-change-confirmation-title": "Sei sicuro di voler cambiare la rete Wi-Fi?", "wifi-dangerous-disable-confirmation-description": "Disabilitare il Wi-Fi può disconnetterti dal tuo Umbrel. Per riconnetterti, collega un cavo Ethernet al tuo Umbrel e assicurati che sia il tuo Umbrel che il dispositivo da cui accedi siano sulla stessa rete.", "wifi-dangerous-disable-confirmation-title": "Sei sicuro di voler disabilitare il Wi-Fi?", "wifi-description": "Connetti il tuo dispositivo a una rete Wi-Fi", "wifi-description-long": "Il tuo dispositivo rimane connesso al Wi-Fi scelto, anche se il cavo Ethernet viene rimosso, e si riconnette automaticamente al Wi-Fi all'avvio.", "wifi-no-networks-message": "Nessuna rete Wi-Fi trovata", "wifi-searching": "Ricerca di reti Wi-Fi...", "wifi-unsupported-device-description": "Il Wi-Fi non è supportato su questo dispositivo. Questo potrebbe essere dovuto a un adattatore wireless mancante o incompatibile.", "wifi-view-networks": "Visualizza reti" } ================================================ FILE: packages/ui/public/locales/ja.json ================================================ { "2fa": "2FA", "2fa-description": "Umbrelのログインとアプリのための二段階認証", "2fa.disable.title": "二段階認証を無効にする", "2fa.enable.or-paste": "または、以下のコードを認証アプリに貼り付けてください", "2fa.enable.scan-this": "Google AuthenticatorやAuthyのような認証アプリでこのQRコードをスキャンしてください", "2fa.enable.title": "二段階認証を有効にする", "2fa.enter-code": "認証アプリに表示されるコードを入力してください", "account": "アカウント", "account-description": "あなたの名前とパスワード", "advanced-settings": "詳細設定", "advanced-settings-description": "ターミナル、umbrelOSベータプログラム、Cloudflare DNSなど", "app-not-found": "アプリが見つかりません: {{app}}", "app-only-over-tor": "{{app}}はTor経由でのみ利用できます。このアプリを開くには、リモートアクセス用のURL(設定 > 詳細設定 > リモート Tor アクセス)にあるUmbrelへTorブラウザでアクセスしてください。", "app-page.section.about": "約", "app-page.section.credentials.title": "デフォルト資格情報", "app-page.section.dependencies.n-alternatives": "{{count}} つの代替案を表示", "app-page.section.info.compatibility": "互換性", "app-page.section.info.compatibility-compatible": "互換あり", "app-page.section.info.compatibility-not-compatible": "互換性がありません", "app-page.section.info.developer": "開発者", "app-page.section.info.source-code": "ソースコード", "app-page.section.info.source-code.public": "公開", "app-page.section.info.submitted-by": "提出者", "app-page.section.info.support": "サポートを受ける", "app-page.section.info.title": "情報", "app-page.section.info.version": "バージョン", "app-page.section.recommendations.title": "おすすめ", "app-page.section.release-notes.title": "新機能", "app-page.section.release-notes.version": "バージョン {{version}}", "app-page.section.requires": "必要条件", "app-picker.search": "検索...", "app-picker.select-app": "アプリを選択...", "app-settings.connected-to": "{{appName}}はこれらのアプリと接続されています", "app-settings.save-changes": "変更を保存", "app-settings.title": "設定", "app-store.browse-category-apps": "{{category}}アプリを閲覧", "app-store.category.ai": "AI", "app-store.category.all": "すべてのアプリ", "app-store.category.automation": "家庭&自動化", "app-store.category.bitcoin": "ビットコイン", "app-store.category.crypto": "暗号資産", "app-store.category.developer": "開発者ツール", "app-store.category.discover": "発見", "app-store.category.files": "ファイル&生産性", "app-store.category.finance": "金融", "app-store.category.media": "メディア", "app-store.category.networking": "ネットワーキング", "app-store.category.social": "ソーシャル", "app-store.description": "あなたのアプリ更新設定", "app-store.discover.temporarily-unavailable-description": "上のカテゴリをブラウズするか、検索してアプリを見つけてください", "app-store.discover.temporarily-unavailable-title": "特集コンテンツは一時的に利用できません", "app-store.menu.community-app-stores": "コミュニティApp Stores", "app-store.search-apps": "アプリを検索", "app-store.search.no-results": "結果なし", "app-store.search.results-for": "の結果", "app-store.title": "App Store", "app-store.updates": "アップデート", "app-updates.less": "少なく", "app-updates.more": "もっと", "app-updates.no-updates": "すべてのアプリが最新です!", "app-updates.update": "更新", "app-updates.update-all": "すべて更新", "app-updates.updates-available-count_one": "{{count}}個のアップデートが利用可能", "app-updates.updates-available-count_other": "{{count}}個のアップデートが利用可能", "app-updates.updating": "更新中...", "app.install": "インストール", "app.installed": "インストール済み", "app.installing": "インストール中", "app.offline": "実行されていません", "app.open": "開く", "app.optimized-for-umbrel-home": "Umbrel Homeに最適化", "app.os-update-required.confirm": "umbrelOSのアップデートを確認", "app.os-update-required.description": "{{appName}}はumbrelOS {{version}}以降が必要です", "app.os-update-required.title": "umbrelOSをアップデート", "app.restarting": "再起動中", "app.starting": "起動中", "app.stopping": "停止中", "app.uninstall.confirm.description": "{{app}}に関連するすべてのデータが永久に削除されます。この操作は元に戻せません。", "app.uninstall.confirm.submit": "アンインストール", "app.uninstall.confirm.title": "{{app}}をアンインストールしますか?", "app.uninstall.deps.used-by.description_one": "{{app}}をアンインストールする前に、最初に{{firstAppToUninstall}}をアンインストールしてください。", "app.uninstall.deps.used-by.description_other": "これらのアプリを最初にアンインストールして、{{app}}をアンインストールしてください。", "app.uninstall.deps.used-by.title": "{{app}}は以下のアプリで使用されています", "app.uninstalling": "アンインストール中", "app.updating": "更新中", "app.view": "表示", "app_one": "アプリ", "app_other": "アプリ", "apps.uninstall.failed-to-get-required-apps": "必要なアプリの取得に失敗しました", "apps.uninstalled-all.success": "すべてのアプリがアンインストールされました", "auth.checking-backend-for-user": "読み込み中...", "auth.failed-checking-if-user-logged-in": "エラー: Authログインチェックに失敗しました", "auth.failed-to-check-if-user-exists": "エラー: Auth存在チェックに失敗しました", "back": "戻る", "backups": "バックアップ", "backups-configure": "バックアップを設定", "backups-configure.add-backup-location": "バックアップ先を追加", "backups-configure.available": "利用可能", "backups-configure.awaiting-next-backup": "次の自動バックアップを待機中", "backups-configure.back-up-now": "今すぐバックアップ", "backups-configure.backing-up-now": "バックアップ中…", "backups-configure.connected": "接続済み", "backups-configure.connection": "接続", "backups-configure.in-progress": "進行中", "backups-configure.last-backup": "最終バックアップ", "backups-configure.locations": "保存先", "backups-configure.no-backup-locations": "データのバックアップを開始するには、バックアップ先を追加してください", "backups-configure.not-connected": "未接続", "backups-configure.path": "パス", "backups-configure.remove-backup-location": "バックアップ先を削除", "backups-configure.remove-backup-location-confirmation": "本当に削除しますか?", "backups-configure.remove-backup-location-confirmation-description": "これにより '{{device}}' がバックアップ先から削除されます。このデバイス上の既存のバックアップは削除されませんが、自動バックアップは停止します。", "backups-configure.status": "状態", "backups-configure.total-backups": "Backupsの合計", "backups-configure.used": "使用済み", "backups-configure.view": "表示", "backups-description": "ファイル、アプリ、データを別の Umbrel、NAS、または外付けドライブにバックアップします", "backups-error.backup-not-found": "バックアップが見つかりませんでした。", "backups-error.generic": "問題が発生しました: {{details}}", "backups-error.in-progress": "バックアップ処理は既に実行中です。終了するまでしばらくお待ちください。", "backups-error.invalid-exclusion-path": "バックアップから除外できるのは、ホームディレクトリ内のファイルとフォルダのみです。", "backups-error.invalid-password": "暗号化パスワードが正しくありません。", "backups-error.invalid-path": "選択した場所はバックアップ先として無効です。", "backups-error.mount-failed": "バックアップスナップショットにアクセスできませんでした。", "backups-error.mount-timeout": "バックアップスナップショットにアクセスできませんでした。再試行するか、デバイスが正しく接続されているか確認してください。", "backups-error.not-enough-space": "バックアップ先のデバイスに十分な空き容量がありません。", "backups-error.not-found": "バックアップまたはバックアップ先が見つかりませんでした。", "backups-error.repository-exists": "このフォルダには既にバックアップ先が存在します。", "backups-error.repository-not-found": "バックアップ先が見つかりませんでした。", "backups-exclusions.add": "追加", "backups-exclusions.app-paths-cannot-be-modified": "これらのファイル/フォルダはアプリ開発者によって設定されており、変更できません:", "backups-exclusions.app-paths-explanation": "このアプリは以下のデータをバックアップ対象から除外しています。これらのパスには通常、再生成可能なキャッシュやログなどの重要でない項目、または復元時に競合や不整合を引き起こす可能性のある古いアプリ状態などが含まれます。", "backups-exclusions.auto-excluded": "自動で除外", "backups-exclusions.exclude-entire-app": "アプリ全体を除外", "backups-exclusions.excluded-apps": "除外されたアプリ", "backups-exclusions.files-and-folders": "除外されたファイルとフォルダ", "backups-exclusions.no-excluded-apps": "除外されたアプリはありません", "backups-exclusions.no-excluded-files-or-folders": "除外されたファイルやフォルダはありません", "backups-exclusions.select-item-to-exclude": "除外する項目を選択", "backups-exclusions.stop-excluding": "除外を解除", "backups-floating-island.backing-up": "バックアップ中…", "backups-floating-island.backing-up-to": "Umbrelをバックアップしています…", "backups-restore": "復元", "backups-restore-full": "完全復元", "backups-restore-full-description": "バックアップからUmbrel全体を復元する", "backups-restore-header": "Umbrel を復元", "backups-restore-pro.after-restore": "復元後、一時的なアカウントはバックアップ済みのアカウントとデータに置き換わります。", "backups-restore-pro.step1": "下の\"Get Started\"をクリックして初期設定を完了してください。バックアップを復元するまで、このアカウントは一時的なアカウントになります。", "backups-restore-pro.step2": "セットアップが完了したら、<0>設定 → Backups → 復元へ進んでください。", "backups-restore-pro.step3": "復元ウィザードの案内に従ってください。", "backups-restore-pro.subtitle": "Umbrel Proでバックアップから復元するには、いくつか追加の手順が必要です。", "backups-restore.backup-date": "バックアップ日時", "backups-restore.backup-location": "バックアップ先", "backups-restore.browse-cloud-subtitle": "Umbrel Private Cloud から復元(近日対応予定)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "外付けUSBドライブから復元", "backups-restore.browse-external-title": "外付けドライブ", "backups-restore.browse-nas-or-external": "別の Umbrel、NAS、または外付けドライブを参照してバックアップから復元します", "backups-restore.browse-nas-subtitle": "ネットワーク上の別の Umbrel または NAS デバイスから復元", "backups-restore.browse-nas-title": "別の Umbrel または NAS", "backups-restore.choose": "選択", "backups-restore.choose-backup-location": "バックアップ先を選択", "backups-restore.connect-to-backup-location": "バックアップ先に接続", "backups-restore.encryption-password": "暗号化パスワード", "backups-restore.encryption-password-description": "バックアップを有効にしたときに設定した暗号化パスワードを入力してください", "backups-restore.enter-password-to-confirm": "確認のためUmbrelのパスワードを入力してください", "backups-restore.final-confirmation": "本当に実行しますか?", "backups-restore.final-confirmation-description": "このバックアップから復元すると、現在の umbrelOS のアプリとデータは選択したバックアップの内容で上書きされます。このバックアップで除外されているファイル、フォルダ、またはアプリは Umbrel から削除されます。この操作は元に戻せません。", "backups-restore.invalid-password": "無効なパスワード", "backups-restore.last-backup": "最終バックアップ:{{date}}", "backups-restore.latest": "最新", "backups-restore.no-backups-found": "バックアップが見つかりません", "backups-restore.no-backups-yet": "まだバックアップがありません", "backups-restore.please-select-backup": "バックアップを選択してください", "backups-restore.please-select-repository": "リポジトリを選択してください", "backups-restore.restore-from-nas-or-external": "別のUmbrel、NAS、または外付けドライブにあるバックアップからUmbrelを復元", "backups-restore.restore-from-unlisted": "別の場所から復元", "backups-restore.restore-umbrel": "Umbrelを復元", "backups-restore.restore-warning": "このバックアップから復元すると、現在の umbrelOS のアプリとデータは選択したバックアップの内容で置き換えられます。このバックアップで除外されているファイル、フォルダ、またはアプリは Umbrel から削除されます。特定のファイルやフォルダだけを復元したい場合は、<0>Rewind を開いてください。", "backups-restore.restoring-from": "以下のバックアップから復元します:", "backups-restore.review-description": "復元を行うと、バックアップ作成時に含まれていたアカウント、ファイル、アプリ、設定がUmbrelに復元されます。処理には時間がかかる場合があります。完了すると、ログインパスワードはバックアップ作成時に使用していたものに設定されます。", "backups-restore.select-backup": "バックアップを選択", "backups-restore.select-backup-description": "復元元のバックアップを選択してください", "backups-restore.select-backup-file": "バックアップファイルを選択", "backups-restore.select-backup-file-only": "選択できるのは{{backupFileName}}だけです", "backups-restore.total-size": "合計サイズ", "backups-restore.unknown-date": "不明な日付", "backups-restore.unknown-repository": "不明なリポジトリ", "backups-rewind": "Rewind", "backups-rewind-description": "特定のファイルやフォルダを復元するために過去の状態に戻す", "backups-rewind.start": "Rewindを開始", "backups-setup": "セットアップ", "backups-setup-confirm": "セットアップを完了", "backups-setup-external-description": "外付けUSBドライブにバックアップする", "backups-setup-nas-or-umbrel-description": "ネットワーク上の別の Umbrel または NAS デバイスにバックアップする", "backups-setup-umbrel-or-nas": "別の Umbrel または NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Umbrel Private Cloud に エンドツーエンドで暗号化されたバックアップ を保存して、自宅の外でも安心を広げましょう。", "backups-setup-umbrel-private-cloud-cta-link": "先行アクセスを申し込む", "backups-setup-umbrel-private-cloud-description": "Umbrel Private Cloud へのエンドツーエンド暗号化バックアップ", "backups-setup-umbrel-private-cloud-subtitle": "近日公開", "backups.add-umbrel-or-nas": "Umbrel または NAS を追加", "backups.all-apps-and-data-will-be-backed-up": "すべてのアプリとデータがバックアップされます", "backups.apps-and-data": "アプリとデータ", "backups.backup-location": "バックアップ先", "backups.browse": "参照", "backups.choose-folder-within-device": "バックアップを保存するフォルダを{{device}}内から選択してください", "backups.confirm-password": "パスワードを確認", "backups.copy": "コピー", "backups.encryption": "暗号化", "backups.encryption-password-warning": "暗号化パスワードはパスワードマネージャーなどで安全に保管してください。表示は一度きりで、バックアップから復元する際に必要になります。", "backups.exclude-from-backups": "バックアップから除外", "backups.exclude-from-backups-description": "バックアップから特定のファイル、フォルダ、アプリを除外します。", "backups.hide": "非表示", "backups.i-understand": "理解しました", "backups.location": "保存先", "backups.modals.already-in-use.description": "この場所はすでにこのUmbrelのバックアップ用に使われています。", "backups.modals.already-in-use.manage": "Backupsで管理", "backups.modals.already-in-use.title": "バックアップ先はすでに使用中です", "backups.modals.connect-existing.description": "この場所にはすでにUmbrelのバックアップがあります。暗号化パスワードを入力して、このUmbrelに追加してください。", "backups.modals.connect-existing.title": "既存のUmbrelバックアップを接続", "backups.no-external-drives-detected": "外付けドライブが検出されませんでした", "backups.no-password-set": "パスワードが設定されていません", "backups.password-is-set": "パスワードが設定されています", "backups.password-minimum-length": "パスワードは最低8文字である必要があります", "backups.password-safety-warning": "このパスワードでバックアップは暗号化されます。再表示できないため、安全に保管してください。復元時に必要になります。", "backups.passwords-do-not-match": "パスワードが一致しません", "backups.please-choose-folder": "フォルダを選択してください", "backups.restore-failed.message": "Umbrelを復元中にエラーが発生しました。現在のアプリやデータに変更はありません。", "backups.restore-failed.retry": "復元画面に移動", "backups.restore-failed.title": "復元に失敗しました", "backups.restoring": "Umbrelを復元しています", "backups.restoring-completing": "最終処理中です。Umbrelはまもなく再起動します…", "backups.restoring-progress": "復元済み {{percent}}%", "backups.restoring-time-remaining": "残り {{time}}", "backups.restoring-warning": "復元中は Umbrel の電源を切ったり、バックアップ先の接続を切断したりしないでください", "backups.review": "確認して承認", "backups.review-description": "バックアップの詳細を確認して選択を確定してください", "backups.scanning-for-external-drives": "外付けドライブをスキャン中…", "backups.schedule-description": "umbrelOS はデータを毎時自動的にバックアップします。過去24時間分の暗号化された時間ごとのバックアップ、過去1週間分の毎日のバックアップ、過去1か月分の毎週のバックアップ、過去1年分の毎月のバックアップを保持します。1年以上前のバックアップは自動的に削除されます。", "backups.select-backup-folder": "バックアップフォルダを選択", "backups.select-backup-folder-description": "バックアップを保存するフォルダを選択してください。", "backups.select-backup-location": "バックアップ先を選択", "backups.set-encryption-password": "暗号化パスワードを設定", "backups.set-encryption-password-description": "パスワードでバックアップを保護します。これによりデータがプライベートに保たれ、このパスワードでのみ復元できます。", "backups.show": "表示", "backups.storage-capacity-warning": "{{device}} にはバックアップサイズの少なくとも2倍の空き容量が必要です", "backups.store-encryption-password-safely": "暗号化パスワードを安全に保管してください", "beta-program": "umbrelOSベータプログラム", "beta-program-description": "umbrelOSのベータアップデートを受け取ることに同意し、新機能への早期アクセスを得て、フィードバックを提供することでそれらの改善に協力してください。ベータアップデートは不安定な場合があり、トラブルシューティングにはTerminalの知識が必要になることがあります。", "cancel": "キャンセル", "change": "変更", "change-name": "名前を変更", "change-name.failed.name-required": "名前が必要です", "change-name.input-placeholder": "あなたの名前", "change-password": "パスワードを変更", "change-password.callout": "パスワードを失った場合、Umbrelにログインできなくなります。安全に保管してください。", "change-password.current-password": "現在のパスワード", "change-password.failed.current-required": "現在のパスワードが必要です", "change-password.failed.min-length": "パスワードは少なくとも{{characters}}文字である必要があります", "change-password.failed.must-be-unique": "新しいパスワードは現在のパスワードと異なる必要があります", "change-password.failed.new-required": "新しいパスワードが必要です", "change-password.failed.no-match": "パスワードが一致しません", "change-password.failed.repeat-required": "パスワードの再入力が必要です", "change-password.new-password": "新しいパスワード", "change-password.repeat-password": "パスワードを再入力", "check-for-latest-version": "最新のumbrelOSアップデートを確認", "clipboard.copied": "コピーしました", "close": "閉じる", "cmdk.change-wallpaper": "壁紙を変更", "cmdk.frequent-apps": "よく使用されるアプリ", "cmdk.input-placeholder": "アプリ、設定、またはアクションを検索", "cmdk.live-usage": "ライブ使用状況", "cmdk.restart-umbrel": "Umbrelを再起動", "cmdk.shutdown-umbrel": "Umbrelをシャットダウン", "cmdk.update-all-apps": "すべてのアプリをアップデート", "cmdk.widgets": "ウィジェット", "community-app-store": "コミュニティApp Store", "community-app-store.add-error": "App Store の追加に失敗しました: {{message}}", "community-app-store.back-to-umbrel-app-store": "Umbrel App Storeに戻る", "community-app-store.open-button": "開く", "community-app-store.remove-button": "削除", "community-app-store.remove-error": "App Store の削除に失敗しました: {{message}}", "community-app-stores.add-button": "追加", "community-app-stores.description": "コミュニティApp Storesを使用すると、公式Umbrel App Storeでは入手できないアプリをUmbrelにインストールできます。これにより、開発者が公式Umbrel App Storeでリリースする前にUmbrelアプリのベータ版をテストするのも簡単になります。", "community-app-stores.learn-more": "もっと学ぶ", "community-app-stores.warning": "コミュニティApp Storesは誰でも作成できます。そこに公開されているアプリは、公式Umbrel App Storeチームによって検証されたり、審査されたりすることはありません。不安定または悪意のある可能性があります。注意して使用し、信頼できる開発者からのアプリストアのみを追加してください。", "confirm": "確認", "connect": "接続", "connecting": "接続中...", "connection-lost": "接続が切断されました", "connection-lost-description": "ブラウザのタブが非アクティブになっている、ネットワーク接続が中断された、またはデバイスがオフラインになっている場合に発生することがあります。", "continue": "続行", "continue-to-log-in": "ログインを続ける", "cpu": "CPU", "cpu-core-count": "{{cores}}スレッド", "default-credentials.close": "了解", "default-credentials.description": "アプリにログインするために必要な資格情報です。", "default-credentials.dont-show-again": "これを再度表示しない", "default-credentials.dont-show-again-notice": "将来いつでもアプリアイコンを右クリックすることで、これらの資格情報にアクセスできます。", "default-credentials.open": "{{app}}を開く", "default-credentials.password": "デフォルトパスワード", "default-credentials.title": "{{app}}の資格情報", "default-credentials.username": "デフォルトユーザー名", "desktop.app.context.go-to-store-page": "App Storeで表示", "desktop.app.context.settings": "設定", "desktop.app.context.show-default-credentials": "デフォルトの資格情報を表示", "desktop.app.context.uninstall": "アンインストール", "desktop.context-menu.change-wallpaper": "壁紙を変更", "desktop.context-menu.edit-widgets": "ウィジェットを編集", "desktop.context-menu.logout": "ログアウト", "desktop.greeting.afternoon": "こんにちは、{{name}}", "desktop.greeting.evening": "こんばんは、{{name}}", "desktop.greeting.morning": "おはようございます、{{name}}", "desktop.install-first.for-the-ai-enthusiast": "バイブを楽しむ人向け", "desktop.install-first.for-the-bitcoiner": "ビットコイナー用", "desktop.install-first.for-the-self-hoster": "セルフホスティング用", "desktop.install-first.for-the-streamer": "ストリーマー用", "desktop.install-first.link-to-app-store": "App Storeでさらに探索", "desktop.not-enough-room": "アプリを表示するにはもっと大きな画面を使用してください。", "device": "デバイス", "device-info": "デバイス情報", "device-info-description": "あなたのデバイスに関する情報", "device-info.device": "デバイス", "device-info.model-number": "モデル番号", "device-info.serial-number": "シリアル番号", "device-info.view-info": "情報を見る", "device-name.home-or-pro": "Umbrel Home または Umbrel Pro", "disable": "無効にする", "done": "完了", "download-logs": "ログをダウンロード", "enabling-tor": "リモートTorアクセスを有効にしています", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNSは、より良いネットワークの信頼性を提供します。無効にすると、ルーターのDNS設定を使用します。", "external-dns-error": "DNS 設定の更新に失敗しました: {{message}}", "external-drive": "外付けドライブ", "factory-reset": "工場出荷時リセット", "factory-reset-description": "すべてのデータとアプリを消去し、umbrelOSを初期設定に戻します", "factory-reset-failed": "デバイスのリセットに失敗しました: {{message}}", "factory-reset.confirm.body": "リセットするにはパスワードを確認してください", "factory-reset.confirm.ethernet-required-warning": "デバイスがルーターにイーサネットで接続されていることを確認し(Wi-Fiではなく)、ローカルネットワークからアクセスしていることを確認してください(例:http://umbrel.local またはデバイスのローカルIPアドレス)。", "factory-reset.confirm.submit": "すべてを消去してリセット", "factory-reset.confirm.submit-callout": "この操作は元に戻せません。", "factory-reset.rebooting.message": "デバイスが再起動し、すべてのデータが消去されます。このページを閉じないでください。", "factory-reset.rebooting.status": "リセット中…", "factory-reset.rebooting.title": "工場出荷時リセットを実行中", "factory-reset.review.account-info": "アカウント情報とパスワード", "factory-reset.review.apps": "アプリ", "factory-reset.review.following-will-be-removed": "以下のデータがあなたのデバイスから削除されます", "factory-reset.review.installed-apps_one": "{{count}}個のインストール済みアプリ", "factory-reset.review.installed-apps_other": "{{count}}個のインストール済みアプリ", "factory-reset.review.submit": "続行", "factory-reset.review.total-data": "総データ", "files": "Files", "files-action.add-favorite": "お気に入りに追加", "files-action.add-network-device": "デバイスを追加", "files-action.cancel-upload": "アップロードをキャンセル", "files-action.compress": "圧縮", "files-action.copy": "コピー", "files-action.cut": "切り取り", "files-action.delete": "完全に削除", "files-action.download": "ダウンロード", "files-action.download-items": "アイテム{{count}}件をダウンロード", "files-action.drop-to-upload": "ここにドロップしてアップロード", "files-action.eject-disk": "取り出す", "files-action.empty-trash": "ゴミ箱を空にする", "files-action.format-drive": "フォーマット", "files-action.go-to-path": "移動...", "files-action.new-folder": "新規フォルダ", "files-action.open": "開く", "files-action.paste": "貼り付け", "files-action.remove-favorite": "お気に入りから削除", "files-action.remove-network-host": "ネットワークドライブを取り出す", "files-action.remove-network-share": "ネットワーク共有を取り出す", "files-action.rename": "名前の変更", "files-action.restore": "復元", "files-action.select": "選択", "files-action.share": "ネットワークで共有...", "files-action.sharing": "共有処理中...", "files-action.show-in-folder": "所在フォルダを表示", "files-action.trash": "ゴミ箱に移動", "files-action.uncompress": "展開", "files-action.upload": "アップロード", "files-add-network-share.add-manually": "手動で追加", "files-add-network-share.add-share": "共有を追加", "files-add-network-share.back": "戻る", "files-add-network-share.continue": "続ける", "files-add-network-share.description": "NASやネットワーク上の他の共有ドライブに接続して、Files内でアクセスできます。", "files-add-network-share.discovering": "検出中...", "files-add-network-share.enter-details-manually": "サーバーの詳細を手動で入力", "files-add-network-share.host-label": "サーバアドレス", "files-add-network-share.host-required": "サーバアドレスは必須です", "files-add-network-share.manual-share-help": "サーバーに表示されている共有名を正確に入力してください", "files-add-network-share.no-shares-found": "このサーバーでは共有が見つかりませんでした", "files-add-network-share.not-seeing-share": "共有が見つかりませんか?", "files-add-network-share.password-label": "パスワード", "files-add-network-share.password-required": "パスワードは必須です", "files-add-network-share.retrieving-shares": "共有を取得中...", "files-add-network-share.retry-discovery": "ネットワークを再検索", "files-add-network-share.select-share": "追加する共有を選択", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "共有名は必須です", "files-add-network-share.title": "ネットワーク共有を追加", "files-add-network-share.username-label": "ユーザ名", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "ユーザ名は必須です", "files-audio-island.now-playing": "再生中", "files-audio-island.pause": "一時停止", "files-audio-island.play": "再生", "files-backend-error.base-directory-not-found": "ベースディレクトリが見つかりませんでした", "files-backend-error.cant-find-root": "ファイルパスを確認できませんでした", "files-backend-error.destination-already-exists": "移動先に同じ名前の項目が既に存在します", "files-backend-error.destination-not-exist": "移動先のフォルダが存在しません", "files-backend-error.does-not-exist": "ファイルまたはフォルダが存在しません", "files-backend-error.escapes-base": "パスが許可されたディレクトリの範囲外です", "files-backend-error.invalid-base": "パスが有効なディレクトリに属していません", "files-backend-error.invalid-filename": "ファイル名が無効です", "files-backend-error.invalid-path": "ファイルパスが無効です", "files-backend-error.mkdir-failed": "フォルダの作成に失敗しました", "files-backend-error.move-failed": "項目の移動に失敗しました", "files-backend-error.not-enough-space": "ストレージの空き容量が足りません", "files-backend-error.operation-not-allowed": "この操作は許可されていません", "files-backend-error.parent-not-directory": "親パスがフォルダではありません", "files-backend-error.parent-not-exist": "親フォルダが存在しません", "files-backend-error.path-not-absolute": "ファイルパスが無効です", "files-backend-error.share-already-exists": "このフォルダは既に共有されています", "files-backend-error.share-name-generation-failed": "一意の共有名を生成できませんでした", "files-backend-error.source-not-exists": "元のファイルまたはフォルダが存在しません", "files-backend-error.subdir-of-self": "フォルダを自身の中に移動またはコピーすることはできません", "files-backend-error.trash-meta-not-exists": "この項目の元の場所が見つかりませんでした", "files-backend-error.unique-name-index-exceeded": "一意の名前を生成できませんでした。類似の名前の項目が多すぎます", "files-backend-error.upload-failed": "アップロードに失敗しました", "files-collision.action.keep-both": "両方とも残す", "files-collision.action.replace": "置き換える", "files-collision.action.skip": "スキップ", "files-collision.destination.original-location": "元の場所", "files-collision.message": "既存のアイテムを置き換えるか、両方とも残しますか?", "files-collision.title": "「{{itemName}}」はすでに{{destinationName}}に存在します", "files-download.confirm": "ダウンロード", "files-download.description": "「Files」ではこの種類のファイルを開けません。代わりにダウンロードしますか?", "files-download.title": "「{{name}}」をダウンロードしますか?", "files-empty-trash.confirm": "空にする", "files-empty-trash.description": "本当にゴミ箱内のすべてのアイテムを完全に削除しますか? この操作は元に戻せません。", "files-empty-trash.title": "ゴミ箱を空にしますか?", "files-empty.directory": "このフォルダにはアイテムがありません", "files-empty.network": "ネットワークデバイスがありません", "files-empty.network-host-offline": "ネットワークデバイスがオフラインです", "files-error.add-favorite": "お気に入りに追加できませんでした: {{message}}", "files-error.add-share": "フォルダの共有に失敗しました: {{message}}", "files-error.compress": "圧縮に失敗しました: {{message}}", "files-error.copy": "コピーに失敗しました: {{message}}", "files-error.create-folder": "フォルダの作成に失敗しました: {{message}}", "files-error.delete": "削除に失敗しました: {{message}}", "files-error.eject-disk": "ドライブの取り出しに失敗しました: {{message}}", "files-error.empty-trash": "ゴミ箱を空にできませんでした: {{message}}", "files-error.extract": "展開に失敗しました: {{message}}", "files-error.folder-already-exists": "同名のフォルダが既に存在します", "files-error.move": "移動に失敗しました: {{message}}", "files-error.remove-favorite": "お気に入りから削除できませんでした: {{message}}", "files-error.remove-share": "共有フォルダの削除に失敗しました: {{message}}", "files-error.rename": "名前の変更に失敗しました: {{message}}", "files-error.restore": "復元に失敗しました: {{message}}", "files-error.trash": "ゴミ箱へ移動できませんでした: {{message}}", "files-error.upload": "アップロードに失敗しました: {{message}}", "files-error.upload-network-error": "{{name}} のアップロードに失敗しました: ネットワークエラーが発生しました", "files-extension-change.confirm": "続行", "files-extension-change.description-add": "「{{fileName}}」の拡張子を「{{extension}}」に変更してもよろしいですか? ファイルが読み込めなくなる可能性があります。", "files-extension-change.description-remove": "「{{fileName}}」の拡張子を削除してもよろしいですか?", "files-extension-change.title-add": "拡張子を「{{extension}}」に変更しますか?", "files-extension-change.title-remove": "拡張子を削除しますか?", "files-external-storage.unsupported.description": "接続した外付けドライブは電力の問題によりRaspberry Piでは使用できません。外付けストレージはUmbrel Home、Umbrel Pro、およびすべてのx86(IntelまたはAMD)デバイスで利用できます。", "files-external-storage.unsupported.description-general": "電力の問題によりRaspberry Piでは外付けストレージは利用できません。外付けストレージはUmbrel Home、Umbrel Pro、およびすべての x86 (Intel または AMD) デバイスで利用できます。", "files-external-storage.unsupported.title": "外部ストレージには対応していません", "files-folder": "フォルダ", "files-format.confirm": "フォーマット", "files-format.description": "{{driveName}}のすべてのデータが消去されます。この操作は元に戻せません。", "files-format.description-unreadable": "umbrelOSは{{driveName}}の内容を読み取れません。umbrelOSで使用するにはフォーマットしてください。", "files-format.drive-label": "名前", "files-format.error": "ドライブのフォーマットに失敗しました", "files-format.exfat-description": "Windows、macOS、Linuxとの互換性が最も高い", "files-format.ext4-description": "umbrelOSおよびLinuxでのパフォーマンスに優れる", "files-format.filesystem": "ファイルシステム", "files-format.filesystem-label": "フォーマット形式", "files-format.formatting": "フォーマット中...", "files-format.title": "ドライブをフォーマット", "files-format.title-requires-format": "フォーマットが必要です", "files-formatting-island.formatting": "フォーマット中…", "files-formatting-island.formatting-drives": "{{count}}個のドライブをフォーマットしています", "files-listing.empty": "アイテムがありません", "files-listing.error": "エラーが発生しました", "files-listing.item-count-truncated": "{{formattedCount}}+ 項目", "files-listing.item-count_one": "{{formattedCount}} 件の項目", "files-listing.item-count_other": "{{formattedCount}} 件の項目", "files-listing.loading": "読み込み中...", "files-listing.no-such-file": "そのようなファイルまたはフォルダはありません", "files-listing.selected-count": "全{{totalCount}}件のうち{{selectedCount}}件を選択", "files-listing.selected-count-truncated": "{{totalCount}}+ 項目中 {{selectedCount}} 項目を選択", "files-name-drawer.new-folder": "新規フォルダ", "files-name-drawer.new-folder-description": "新しいフォルダの名前を入力してください。", "files-name-drawer.new-folder-input": "フォルダ名", "files-name-drawer.rename-file": "ファイル名の変更", "files-name-drawer.rename-file-description": "このファイルの新しい名前を入力してください。", "files-name-drawer.rename-file-input": "ファイル名", "files-name-drawer.rename-folder": "フォルダ名の変更", "files-name-drawer.rename-folder-description": "このフォルダの新しい名前を入力してください。", "files-name-drawer.rename-folder-input": "フォルダ名", "files-network-storage-error.add-share": "ネットワーク共有の追加に失敗しました: {{message}}", "files-network-storage-error.discover-servers": "ネットワーク機器の検出に失敗しました: {{message}}", "files-network-storage-error.discover-shares": "ネットワーク共有の検出に失敗しました: {{message}}", "files-network-storage-error.remove-share": "ネットワーク共有の削除に失敗しました: {{message}}", "files-operations-island.copying": "「{{from}}」を「{{to}}」にコピーしています", "files-operations-island.moving": "「{{from}}」を「{{to}}」に移動しています", "files-operations-island.restoring": "「{{from}}」を「{{to}}」に復元しています", "files-path.input-group": "パス入力", "files-path.input-label": "現在のパス", "files-permanently-delete.confirm": "完全に削除", "files-permanently-delete.description-multiple": "これら{{count}}個のアイテムを完全に削除してよろしいですか? この操作は元に戻せません。", "files-permanently-delete.description-single": "「{{fileName}}」を完全に削除してよろしいですか? この操作は元に戻せません。", "files-permanently-delete.title-multiple": "{{count}}個のアイテムを完全に削除しますか?", "files-permanently-delete.title-single": "完全に削除しますか?", "files-search.default": "ファイルとフォルダを検索", "files-search.no-results": "「{{query}}」の検索結果は見つかりませんでした", "files-search.placeholder": "検索", "files-search.searching-label": "{{name}}のUmbrelを検索中", "files-share.home-description": "ネットワーク上の他のデバイスから「{{homeDirectoryName}}」内のすべてのファイルにアクセスできるようにします。", "files-share.home-title": "ネットワーク経由で「{{homeDirectoryName}}」を共有", "files-share.instructions.how-to-access": "アクセス方法", "files-share.instructions.ios.enter-password": "パスワードとして {{password}} を入力します。", "files-share.instructions.ios.enter-server": "サーバアドレスとして {{smbUrl}} を入力します。", "files-share.instructions.ios.enter-username": "ユーザ名として {{username}} を入力します。", "files-share.instructions.ios.install-files": "「Files」アプリがインストールされていない場合は、App Store からインストールしてください。", "files-share.instructions.ios.tap-connect": "「接続」をタップしてアクセスします。", "files-share.instructions.ios.tap-dots": "画面右上の三点ボタン(...)をタップし、「サーバに接続」を選択します。", "files-share.instructions.macos.click-connect": "「接続」をクリックしてアクセスします。", "files-share.instructions.macos.enter-password": "パスワードとして {{password}} を入力します。", "files-share.instructions.macos.enter-url": "{{smbUrl}} を入力して「接続」をクリックします。", "files-share.instructions.macos.enter-username": "ユーザ名として {{username}} を入力します。", "files-share.instructions.macos.open-finder": "「Finder」を開き、⌘ + K を押します。", "files-share.instructions.macos.select-registered": "表示されたら「登録ユーザ」を選択します。", "files-share.instructions.macos.time-machine": "Time Machine のバックアップ先としての使い方", "files-share.instructions.macos.time-machine.choose-encryption": "暗号化するか、暗号化しないかを選択します。", "files-share.instructions.macos.time-machine.disk-limit": "「ディスク使用制限」には、Time Machine バックアップに Umbrel 上で割り当てたい最大容量を入力し、「完了」をクリックします。", "files-share.instructions.macos.time-machine.follow-steps": "上記の手順に従った後、Mac のシステム設定を開きます。", "files-share.instructions.macos.time-machine.go-settings": "Time Machine に移動し、「バックアップディスクを追加...」をクリックします。", "files-share.instructions.macos.time-machine.select-disk": "フォルダを選択して「ディスクを設定...」をクリックしてください。", "files-share.instructions.umbrelos.backup.follow-onscreen": "画面の案内に従ってバックアップを設定してください。", "files-share.instructions.umbrelos.backup.follow-then-go-to": "上の手順に従った後、別のUmbrelで\"{{settings}}\" > \"{{backups}}\"に移動してください。", "files-share.instructions.umbrelos.backup.select-add": "\"{{addUmbrelOrNas}}\"のオプションを選択してください。", "files-share.instructions.umbrelos.backup.select-connected": "接続されているデバイスの一覧からこのUmbrelデバイスを選択してください。", "files-share.instructions.umbrelos.backup.title": "他の Umbrel のバックアップ先としての使い方", "files-share.instructions.umbrelos.cant-find-note": "見つかりませんか? \"手動で追加\" を選択し、以下の認証情報を使用してみてください。それでも追加できない場合は、両方のデバイスが同じネットワークに接続されていることを確認してください。", "files-share.instructions.umbrelos.enter-password": "パスワードとして {{password}} を入力してください。", "files-share.instructions.umbrelos.enter-username": "ユーザー名として {{username}} を入力してください。", "files-share.instructions.umbrelos.open-and-click": "別のUmbrelで、\"Files\"を開き、サイドバーの\" {{deviceLabel}}\"の横にあるをクリックしてください。", "files-share.instructions.umbrelos.select-device": "ネットワーク上で自動検出されたデバイス一覧からこのUmbrelデバイスを選択してください。", "files-share.instructions.umbrelos.select-sharename": "「{{sharename}}」を選択して共有を追加してください。", "files-share.instructions.windows.enter-password": "パスワードとして {{password}} を入力します。", "files-share.instructions.windows.enter-url": "{{smbUrl}} と入力して Enter キーを押します。", "files-share.instructions.windows.enter-username": "ユーザー名として {{username}} を入力します。", "files-share.instructions.windows.open-run": "Windows + R を押して「ファイル名を指定して実行」ダイアログを開きます。", "files-share.instructions.windows.remember-credentials": "「Remember my credentials」にチェックを入れて「OK」をクリックします。", "files-share.regular-description": "ネットワーク上の他のデバイスからこのフォルダにアクセスできるようにします。", "files-share.regular-title": "ネットワーク経由でフォルダを共有", "files-share.toggle": "「{{name}}」をネットワーク共有する", "files-sidebar.apps": "アプリ", "files-sidebar.external-storage": "外部ストレージ", "files-sidebar.favorites": "お気に入り", "files-sidebar.home": "ホーム", "files-sidebar.navigation": "ファイルナビゲーション", "files-sidebar.network": "ネットワーク", "files-sidebar.network-pathbar": "ネットワークデバイス", "files-sidebar.network-sidebar": "デバイス", "files-sidebar.recents": "最近", "files-sidebar.shared-folders": "共有フォルダ", "files-sidebar.trash": "ゴミ箱", "files-sidebar.trash.open": "開く", "files-sort.created": "追加日", "files-sort.modified": "更新日時", "files-sort.name": "名前", "files-sort.size": "サイズ", "files-sort.type": "種類", "files-state.uploading": "アップロード中...", "files-state.waiting": "待機中...", "files-type.3gp": "3GPビデオ", "files-type.3gp2": "3GP2ビデオ", "files-type.7z": "7Zアーカイブ", "files-type.aac": "AACオーディオ", "files-type.ai": "Illustratorファイル", "files-type.aiff": "AIFFオーディオ", "files-type.au": "AUオーディオ", "files-type.avi": "AVIビデオ", "files-type.avif": "AVIF画像", "files-type.bmp": "BMP画像", "files-type.bzip2": "BZIP2アーカイブ", "files-type.caf": "CAFオーディオ", "files-type.compressed": "圧縮アーカイブ", "files-type.csv": "CSVファイル", "files-type.directory": "フォルダ", "files-type.dmg": "ディスクイメージ", "files-type.dv": "DVビデオ", "files-type.epub": "EPUB電子書籍", "files-type.excel": "Excelスプレッドシート", "files-type.exe": "Windows実行ファイル", "files-type.executable": "実行ファイル", "files-type.external-drive": "ドライブ", "files-type.flac": "FLACオーディオ", "files-type.flv": "FLVビデオ", "files-type.gif": "GIF画像", "files-type.gzip": "GZIPアーカイブ", "files-type.heic": "HEIC画像", "files-type.ico": "ICO画像", "files-type.iso": "ISOイメージ", "files-type.jpeg": "JPEG画像", "files-type.keynote": "Keynoteプレゼンテーション", "files-type.lzip": "LZIPアーカイブ", "files-type.lzma": "LZMAアーカイブ", "files-type.lzop": "LZOPアーカイブ", "files-type.m3u": "M3Uプレイリスト", "files-type.m4a": "M4Aオーディオ", "files-type.m4v": "M4Vビデオ", "files-type.midi": "MIDIオーディオ", "files-type.mka": "MKAオーディオ", "files-type.mkv": "MKVビデオ", "files-type.mng": "MNGビデオ", "files-type.mobi": "MOBI電子書籍", "files-type.mp3": "MP3オーディオ", "files-type.mp4": "MP4ビデオ", "files-type.mp4-audio": "MP4オーディオ", "files-type.mpeg": "MPEGビデオ", "files-type.mpeg-ts": "MPEGトランスポートストリーム", "files-type.network-drive": "ネットワークドライブ", "files-type.numbers": "Numbersスプレッドシート", "files-type.ogg": "OGGオーディオ", "files-type.ogv": "OGVビデオ", "files-type.pages": "Pagesドキュメント", "files-type.pdf": "PDFドキュメント", "files-type.png": "PNG画像", "files-type.powerpoint": "PowerPointプレゼンテーション", "files-type.psd": "Photoshopドキュメント", "files-type.quicktime": "QuickTimeビデオ", "files-type.rar": "RARアーカイブ", "files-type.sgi": "SGIムービー", "files-type.svg": "SVG画像", "files-type.tar": "TARアーカイブ", "files-type.tiff": "TIFF画像", "files-type.ts": "TSビデオ", "files-type.txt": "テキストファイル", "files-type.umbrel-backup": "Umbrel バックアップ", "files-type.wav": "WAVオーディオ", "files-type.webm": "WebMビデオ", "files-type.webm-audio": "WebMオーディオ", "files-type.webp": "WebP画像", "files-type.wma": "WMAオーディオ", "files-type.wmv": "WMVビデオ", "files-type.word": "Wordドキュメント", "files-type.xz": "XZアーカイブ", "files-type.zip": "ZIPアーカイブ", "files-upload-island.uploading-count": "{{count}} 個のアイテムをアップロード中", "files-view.icons": "アイコン", "files-view.list": "リスト", "files-view.sort-by": "並び替え", "files-view.view-as": "表示形式", "files-widgets.favorites.no-items-text": "お気に入りにフォルダを追加すると、ここに表示されます", "files-widgets.recents.no-items-text": "最近使用したファイルはありません", "generic-in": "in", "hide-details": "詳細を非表示", "install-first.install-app": "{{app}}をインストール", "install-first.title": "{{app}}はこれらのアプリを必要とします", "install-your-first-app": "最初のアプリをインストール", "language": "言語", "language-description": "あなたが好むumbrelOSの言語", "language.select-description": "好みのumbrelOS言語を選択", "live-usage": "ライブ使用状況", "loading": "読み込み中", "local-ip": "ローカルIP", "login-2fa.subtitle": "認証アプリに表示される2FAコードを入力してください", "login-2fa.title": "認証", "login-with-umbrel.description": "{{app}}を開くためにUmbrelのパスワードを入力してください", "login-with-umbrel.title": "Umbrelでログイン", "login.password-label": "パスワード", "login.password.submit": "ログイン", "login.subtitle": "Umbrelのパスワードを入力してログインしてください", "login.title": "おかえりなさい", "logout": "ログアウト", "logout-error-generic": "エラー: ログアウトに失敗しました", "logout.confirm.submit": "ログアウト", "logout.confirm.title": "ログアウトしてもよろしいですか?", "memory": "メモリ", "memory.low": "メモリ不足", "migrate": "移行", "migrate.callout": "移行が完了するまでUmbrelをオフにしないでください", "migrate.failed.retry": "再試行", "migrate.failed.title": "移行に失敗しました", "migrate.success.description": "あなたのすべてのアプリ、アプリデータ、アカウント詳細がUmbrel Homeに移行されました。", "migrate.success.title": "移行成功", "migration-assistant": "移行アシスタント", "migration-assistant-description": "Raspberry Pi から {{deviceName}} へアプリとデータをすべて移行します", "migration-assistant-unsupported-device-description": "Migration Assistant は現在、umbrelOS を実行している Raspberry Pi から Umbrel Home または Umbrel Pro へ、すべてのデータとアプリを転送することをサポートしています。始めるには、Umbrel Home または Umbrel Pro で Migration Assistant を開いてください。", "migration-assistant.continue-migration.ready.submit": "移行を開始", "migration-assistant.failed": "何か問題が発生しました...", "migration-assistant.failed.retrying-message": "再試行中...", "migration-assistant.mobile.start-button": "移行を開始", "migration-assistant.prep.body": "移行の準備", "migration-assistant.prep.button-continue": "続行", "migration-assistant.prep.callout": "{{deviceName}} にあるデータは、ある場合でも完全に削除されます。", "migration-assistant.prep.connect-disk-to-home": "{{deviceName}} の任意の USB ポートに外付けドライブを接続してください。", "migration-assistant.prep.prep-done-continue-message": "完了したら、以下の'{{button}}'をクリックしてください。", "migration-assistant.prep.shut-down-rpi": "Raspberry Pi Umbrelをシャットダウンしてください。", "migration-assistant.ready.description": "すべてのデータとアプリが {{deviceName}} に移行する準備ができました", "migration-assistant.ready.hint-header": "留意事項", "migration-assistant.ready.hint-keep-pi-off.description": "Lightning Nodeなどのアプリで問題が発生しないようにするためです", "migration-assistant.ready.hint-keep-pi-off.title": "アップデート後はRaspberry Piをオフに保つ", "migration-assistant.ready.hint-use-same-password.description": "Raspberry Pi の Umbrel パスワードを使って {{deviceName}} にログインするのを忘れないでください。", "migration-assistant.ready.hint-use-same-password.title": "同じパスワードを使用", "migration-assistant.ready.title": "移行の準備が整いました!", "mini-browser.default-title": "フォルダを選択", "mini-browser.empty-external": "ここに表示するには外付けドライブを接続しましょう。", "mini-browser.empty-network": "ここに表示するにはUmbrelかNASを追加しましょう。", "mini-browser.load-more": "さらに読み込む", "mini-browser.load-more-in-folder": "{{name}} でさらに読み込む", "mini-browser.loading-more": "さらに読み込み中…", "mini-browser.select": "選択", "mini-browser.select-folder": "フォルダを選択", "name": "名前", "nas": "NAS", "no-forgot-password-message": "パスワードを失った場合、Umbrelにログインできなくなります。安全に保管してください。", "no-results-found": "結果が見つかりませんでした", "not-found-404": "エラーコード: 404", "not-found-404.back": "戻る", "not-found-404.home": "ホームへ行く", "notifications.backups-failing-location.description": "自動Backupsが{{location}}への保存に失敗しているよ。接続を確認して、Backupsの設定を見直してね。", "notifications.backups-failing.description": "自動Backupsの作成に失敗しています。Backupsの保存先を確認し、設定を見直してください。", "notifications.backups-failing.go-to-backups": "Backupsを開く", "notifications.backups-failing.title": "過去24時間にBackupsが作成されていません", "notifications.cpu.too-hot": "CPU温度が高い", "notifications.memory.low": "デバイスのメモリが不足しています", "notifications.new-version-available": "{{update}}がインストール可能になりました", "notifications.raid.issue.description": "ストレージの問題が検出されました。詳しくは Storage Manager を確認してください。", "notifications.raid.issue.title": "至急対応が必要", "notifications.ssd.health.description": "1台以上のSSDが注意を要する可能性があります。詳しくは Storage Manager を確認してください。", "notifications.ssd.health.title": "SSDの健全性警告", "notifications.storage.full": "デバイスのストレージがいっぱいです", "notifications.view": "表示", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "'次へ'をクリックすることで、umbrelOSの利用規約に同意することになります", "onboarding.account-created.youre-all-set-name": "準備完了、{{name}}。", "onboarding.contact-support": "サポート", "onboarding.create-account": "アカウントを作成", "onboarding.create-account.confirm-password.input-label": "パスワードの確認", "onboarding.create-account.failed.name-required": "名前が必要です", "onboarding.create-account.failed.passwords-dont-match": "パスワードが一致しません", "onboarding.create-account.name.input-placeholder": "あなたの名前", "onboarding.create-account.password.input-label": "パスワード", "onboarding.create-account.submit": "作成", "onboarding.create-account.submitting": "作成中", "onboarding.create-account.subtitle": "あなたのアカウント情報はあなたのUmbrelにのみ保存されます。パスワードをリセットする方法がないので、安全にバックアップしてください。", "onboarding.create-instead-long": "新しいアカウントを作成する", "onboarding.create-instead-short": "新しいアカウント", "onboarding.launch-umbrelos": "umbrelOS を起動", "onboarding.raid.available-storage": "利用可能なストレージ", "onboarding.raid.change-drives-link": "ドライブを追加または交換する必要がありますか?", "onboarding.raid.configuring.subtitle": "数分かかる場合があります。", "onboarding.raid.configuring.title": "ストレージを構成しています", "onboarding.raid.configuring.warning": "ストレージを構成している間は、このページを更新したり Umbrel の電源を切ったりしないでください。", "onboarding.raid.continue": "続ける", "onboarding.raid.error.detection-instructions": "Umbrel Pro の電源を切り、SSDが正しく装着されているか確認してから、再試行してください。", "onboarding.raid.error.no-ssds-detected": "SSDが検出されませんでした", "onboarding.raid.error.no-ssds-instructions": "Umbrel Pro の電源を切り、続行するには少なくとも1台のSSDを挿入してください。", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "まだ FailSafe を有効にできません", "onboarding.raid.failsafe.enable": "FailSafe を有効にする", "onboarding.raid.failsafe.mixed-sizes": "FailSafeは最も小さいSSD({{smallest}})に制限されます。より大きいSSDの余剰領域は使用されず、{{wasted}}が使用不可になります。", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} はデータ保護のために使われます。さらにもう1台({{smallest}})のSSDを追加すると、使用可能なストレージは {{futureWith3}} に増えます。さらに2台追加すると {{futureWith4}} になります。SSDはいつでも追加できます。", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} はデータ保護のために使われます。さらにもう1台({{smallest}})のSSDを追加すると、使用可能なストレージは {{futureWith4}} に増えます。SSDはいつでも追加できます。", "onboarding.raid.failsafe.single-ssd-info": "現在 SSD は1台だけです。データ保護のために FailSafe を有効にするには、少なくとももう1台の {{size}} SSD を追加してください。SSDはいつでも追加できます。", "onboarding.raid.failsafe.subtitle": "どれか1台のSSDが故障してもデータは安全です。", "onboarding.raid.failsafe.tip": "最大容量を得て無駄な領域をゼロにするには、同じサイズのSSDを使ってください。", "onboarding.raid.failsafe.warning-now-only": "複数のSSDがある場合、FailSafeは初回セットアップ中にのみ有効にできます。後から有効にすることはできません。", "onboarding.raid.health-warning": "このドライブに異常が報告されています", "onboarding.raid.launching": "起動中...", "onboarding.raid.no-ssds-alt": "SSDが見つかりません", "onboarding.raid.recommended": "推奨", "onboarding.raid.scanning": "SSDスロットを確認しています", "onboarding.raid.scanning-alt": "SSDをスキャン中", "onboarding.raid.setup-failed.description-no-retry": "電源を切ってから再度お試しください。", "onboarding.raid.setup-failed.description-retry": "再試行するか、電源を切ってドライブを確認してください。", "onboarding.raid.setup-failed.title": "ストレージのセットアップに失敗しました", "onboarding.raid.shutdown-dialog.description": "ドライブを追加・交換するには Umbrel Pro の電源を切ってください。作業が終わったら電源を入れ直してセットアップを続行できます。", "onboarding.raid.shutdown-dialog.title": "ドライブを変更しますか?", "onboarding.raid.ssd-in-slot": "{{size}} の SSD が Slot {{slot}} に1台あります", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSDトレイ", "onboarding.raid.ssds-found": "Umbrel Pro で次の SSD が見つかりました", "onboarding.raid.storage": "ストレージ", "onboarding.raid.storage-label": "ストレージ", "onboarding.raid.success.storage-info": "ストレージ {{available}}", "onboarding.raid.success.storage-info-failsafe": "ストレージ {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "もう一度試す", "onboarding.raid.wasted": "使用不可", "onboarding.restore-long": "Umbrelを復元する", "onboarding.restore-short": "復元", "onboarding.start.continue": "始めよう", "onboarding.start.subtitle": "あなたのホームクラウドサーバーのセットアップが準備できました。", "onboarding.start.title": "umbrelOSへようこそ", "open": "開く", "open-live-usage": "ライブ使用状況を開く", "password": "パスワード", "preferences": "環境設定", "raid-error.description": "ストレージシステムが正常に起動できませんでした。下のSSDの状態を確認し、トラブルシューティング手順に従ってください。問題が続く場合、影響を受けているSSDの交換が必要になることがあります。", "raid-error.factory-reset-dialog.description": "これによりUmbrel Proのすべてのデータが消去され、工場出荷時の設定に戻ります。この操作は元に戻せません。", "raid-error.factory-reset-dialog.title": "工場出荷時リセットしますか?", "raid-error.factory-reset-failed": "工場出荷時リセットに失敗しました", "raid-error.health-warning": "ヘルス警告", "raid-error.missing-ssd-multiple": "{{count}}台のSSDが応答していません", "raid-error.missing-ssd-one": "1台のSSDが応答していません", "raid-error.shutdown-dialog.description": "Umbrel Proの電源を切り、すべてのSSDがスロットに正しく装着されていることを確認してから、再度電源を入れてください。", "raid-error.shutdown-dialog.title": "ドライブを確認するためにシャットダウンしますか?", "raid-error.ssd-in-slot": "スロット {{slot}}{{size}}のSSDが1台あります", "raid-error.step-check-connections.button": "シャットダウン", "raid-error.step-check-connections.description": "電源を切り、すべてのSSDが正しく挿入されているか確認してください。", "raid-error.step-check-connections.title": "SSDの接続を確認", "raid-error.step-factory-reset.button": "工場出荷時リセット", "raid-error.step-factory-reset.description": "他に手がない場合の最終手段です。これにより全てのデータが消去されます。", "raid-error.step-factory-reset.title": "工場出荷時リセット", "raid-error.step-restart.button": "再起動", "raid-error.step-restart.description": "最初に試す簡単な方法で、よく効果があります。", "raid-error.step-restart.title": "再起動を試す", "raid-error.title": "ストレージに問題が検出されました", "read-less": "もっと少なく読む", "read-more": "もっと読む", "reconnect": "再接続", "redirect.to-home": "読み込み中...", "redirect.to-login": "読み込み中...", "redirect.to-onboarding": "読み込み中...", "redirect.to-raid-error": "読み込み中…", "reload": "再読み込み", "remote-tor-access": "リモートTorアクセス", "reset": "リセット", "restart": "再起動", "restart.confirm.submit": "再起動", "restart.confirm.title": "Umbrelを再起動してもよろしいですか?", "restart.restarting": "再起動中", "restart.restarting-message": "このページを更新したり、再起動中にUmbrelをオフにしないでください。", "rewind": "Rewind", "rewind.files-as-of": "時点のファイル", "rewind.loading-snapshots": "スナップショットを読み込み中…", "rewind.now": "今", "rewind.preflight.description": "過去のバックアップからファイルやフォルダを見つけ、現在に復元できます。", "rewind.preflight.enable-backups": "Rewind を使い始めるには設定でバックアップをセットアップしてください", "rewind.restore-complete": "復元が完了しました", "rewind.restore-error-description": "もう一度お試しください。", "rewind.restore-failed": "復元に失敗しました", "rewind.restore-running-description": "復元が完了するまで、このページを閉じたり更新したりしないでください", "rewind.restore-selected": "選択した項目を復元", "rewind.restore-success-description": "ファイルは復元されました", "rewind.restoring": "復元中", "rewind.snapshots-count_one": "{{count}} 件のバックアップ", "rewind.snapshots-count_other": "{{count}} 件のバックアップ", "search": "検索", "settings": "設定", "settings.app-store-preferences.title": "App Storeの設定", "settings.contact-support": "助けが必要ですか?サポートに連絡する。", "settings.file-sharing": "ファイル共有", "settings.file-sharing.add-folder": "追加", "settings.file-sharing.add-folder-title": "共有するフォルダを選択", "settings.file-sharing.choice-entire-description": "Umbrel 上のすべてのファイルを共有します", "settings.file-sharing.choice-entire-title": "すべて", "settings.file-sharing.choice-heading": "何を共有しますか?", "settings.file-sharing.choice-specific-description": "共有するフォルダを選択してください", "settings.file-sharing.choice-specific-title": "特定のフォルダ", "settings.file-sharing.choice-subtitle": "コンピュータやスマートフォンから、Dropboxのようにネットワークフォルダとしてファイルやフォルダにアクセスできます", "settings.file-sharing.configure": "設定", "settings.file-sharing.description": "他のデバイスから、Dropboxのようにネットワークフォルダ(SMB)としてファイルにアクセスできます", "settings.file-sharing.home-shared-note": "あなたの \"{{homeDirectoryName}}\" フォルダ全体が共有されています。個々のフォルダを別途共有する必要はありません。", "settings.file-sharing.share-entire-home-dir": "ホームフォルダ全体を共有する", "settings.file-sharing.share-entire-home-dir-description": "ネットワーク上の他のデバイスから \"{{homeDirectoryName}}\" のすべてのファイルとフォルダにアクセスできます", "settings.file-sharing.shared-folders": "共有フォルダ", "show-details": "詳細を表示", "shut-down": "シャットダウン", "shut-down.complete": "シャットダウン完了", "shut-down.complete-text": "これでデバイスの電源を抜くことができます。", "shut-down.confirm.submit": "シャットダウン", "shut-down.confirm.title": "Umbrelをシャットダウンしてもよろしいですか?", "shut-down.failed": "シャットダウンに失敗しました: {{message}}", "shut-down.shutting-down": "シャットダウン中", "shut-down.shutting-down-message": "このページを更新したり、シャットダウン中にUmbrelをオフにしないでください。", "software-update.callout": "このページを更新したり、アップデート中にUmbrelをオフにしないでください。", "software-update.check": "アップデートを確認", "software-update.checking": "アップデートを確認中...", "software-update.current-running": "現在のバージョン", "software-update.failed": "更新に失敗しました", "software-update.failed-to-check": "アップデートの確認に失敗しました", "software-update.failed.retry": "再試行", "software-update.install-now": "今すぐインストール", "software-update.new-version": "新しい{{name}}がインストール可能です", "software-update.on-latest": "最新のumbrelOSを使用中", "software-update.see-whats-new": "新機能を確認する", "software-update.title": "ソフトウェアアップデート", "software-update.updating-to": "{{name}}に更新中", "software-update.view": "表示", "something-left": "{{left}}残っています", "something-went-wrong": "⚠ 何か問題が発生しました", "start": "開始", "stop": "停止", "storage": "ストレージ", "storage-manager": "ストレージ管理", "storage-manager.add": "追加", "storage-manager.add-to-raid.add-ssd": "SSDを追加", "storage-manager.add-to-raid.available": "利用可能:", "storage-manager.add-to-raid.description": "新しいSSDが検出され、追加する準備ができています。", "storage-manager.add-to-raid.enable-failsafe": "FailSafeを有効にする", "storage-manager.add-to-raid.failed-add": "SSDを追加できませんでした", "storage-manager.add-to-raid.failed-enable-failsafe": "FailSafeを有効にできませんでした", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "新しい{{size}}のSSDが利用可能なストレージに追加されます。", "storage-manager.add-to-raid.info-capacity-adds-available": "新しい{{size}}のSSDにより、{{available}}の利用可能ストレージが追加されます。", "storage-manager.add-to-raid.info-capacity-adds-both": "新しい{{size}}のSSDにより、{{available}}の利用可能ストレージと{{protection}}のデータ保護容量が追加されます。", "storage-manager.add-to-raid.info-capacity-protection-only": "新しい{{size}}のSSDにより、データ保護用として{{protection}}が追加されます。", "storage-manager.add-to-raid.info-capacity-protection-only-full": "新しい{{size}}のSSDはデータ保護のために全容量が使用されます。", "storage-manager.add-to-raid.info-data-safe": "SSDが1台故障してもデータは安全です。", "storage-manager.add-to-raid.info-no-protection": "SSDが故障するとデータを失う可能性があります。", "storage-manager.add-to-raid.info-total-wasted": "異なるSSDサイズのため、合計で{{size}}が使用不可です。", "storage-manager.add-to-raid.info-wasted": "異なるSSDサイズのため{{size}}は使用不可になります。", "storage-manager.add-to-raid.recommended": "推奨", "storage-manager.add-to-raid.recommended-inline": "(推奨)", "storage-manager.add-to-raid.restart-active-tasks": "進行中のタスクは中断されます", "storage-manager.add-to-raid.restart-after": "再起動後、FailSafeの設定は自動で完了し、通常通り使用を再開できます。", "storage-manager.add-to-raid.restart-during": "再起動中:", "storage-manager.add-to-raid.restart-intro": "この処理中は umbrelOS を通常通り使用できます。ただし、進捗が50%に達した時点で自動的にUmbrelが再起動します。", "storage-manager.add-to-raid.restart-required": "システムの再起動が必要です", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOSは一時的に利用できなくなります", "storage-manager.add-to-raid.ssd-in-slot": "スロット {{slot}}{{size}}のSSDがあります", "storage-manager.add-to-raid.title": "ストレージにSSDを追加", "storage-manager.add-to-raid.too-small": "SSDが小さすぎます", "storage-manager.add-to-raid.too-small-description": "このSSD({{deviceSize}})は、現在インストールされている最小のSSD({{minSize}})より小さいです。FailSafeは、すべてのSSDが使用中の最小SSD以上の容量であることを要求します。", "storage-manager.add-to-raid.understand-continue": "理解しました、続行する", "storage-manager.add-to-raid.warning-failsafe-now-only": "SSDが複数ある場合、FailSafeは今だけ有効化できます。後から有効化することはできません。", "storage-manager.add-to-raid.wasted-label": "使用不可:", "storage-manager.available-storage": "利用可能なストレージ", "storage-manager.description": "SSDの容量、状態、設定を表示", "storage-manager.empty": "空", "storage-manager.failsafe-transition-failed": "FailSafeを有効にできませんでした", "storage-manager.for-failsafe": "FailSafe用", "storage-manager.health.checksum-errors": "チェックサムエラー: {{count}}", "storage-manager.health.critical": "重大", "storage-manager.health.critical-threshold": "重大しきい値", "storage-manager.health.current-temperature": "現在の温度", "storage-manager.health.estimated-life": "推定残り寿命", "storage-manager.health.general": "全般", "storage-manager.health.health-status": "ヘルスステータス", "storage-manager.health.low": "低い", "storage-manager.health.model-and-capacity": "モデルと容量", "storage-manager.health.overheating": "過熱", "storage-manager.health.raid-failed-advice": "このSSDに問題があります。UmbrelをシャットダウンしてSSDの接続を確認してください。問題が解決しない場合はSSDを交換する必要があるかもしれません。", "storage-manager.health.read-errors": "読み取りエラー: {{count}}", "storage-manager.health.serial-number": "シリアル番号", "storage-manager.health.status-healthy": "良好", "storage-manager.health.status-unhealthy": "異常", "storage-manager.health.status-unknown": "不明", "storage-manager.health.temperature": "温度", "storage-manager.health.title": "SSDの状態", "storage-manager.health.warning-life-advice": "このSSDは早めに交換を検討してください。", "storage-manager.health.warning-life-message": "残り寿命は{{percent}}%です", "storage-manager.health.warning-temp-advice": "Umbrel Proの通気性を確保し、SSDが正しく装着されていることを確認してください。", "storage-manager.health.warning-temp-critical": "温度が危険域です({{temperature}})", "storage-manager.health.warning-temp-overheating": "ドライブが過熱しています({{temperature}})", "storage-manager.health.warning-threshold": "警告のしきい値", "storage-manager.health.warning-unhealthy-advice": "このSSDは間もなく故障する可能性があります。交換を検討してください。", "storage-manager.health.warning-unhealthy-message": "このSSDに問題がある可能性があります", "storage-manager.health.warnings": "警告", "storage-manager.health.wear": "摩耗", "storage-manager.health.write-errors": "書き込みエラー: {{count}}", "storage-manager.install-ssd.description": "ストレージを拡張するにはSSDを追加してください", "storage-manager.install-ssd.step-insert": "空いているスロットに新しいSSDを挿入します", "storage-manager.install-ssd.step-power-on": "{{deviceName}}の電源を入れてください", "storage-manager.install-ssd.step-remove-bottom-cover": "マグネット式底面カバーを取り外します", "storage-manager.install-ssd.step-replace-bottom-cover": "底面カバーを元に戻してください", "storage-manager.install-ssd.step-return": "ここに戻ってSSDをストレージに追加してください", "storage-manager.install-ssd.step-shut-down": "{{deviceName}}の電源を切ってください", "storage-manager.install-ssd.title": "SSDの追加", "storage-manager.install-tips.image-alt": "SSD取り付け手順", "storage-manager.install-tips.instructions": "取り付け方法: サムスクリューを外し、SSDを斜めにスロットに差し込みます。SSDをスクリューピラーに当てるまで押し下げ、サムスクリューで固定してください。", "storage-manager.install-tips.toggle": "SSDの取り付け方を忘れた?", "storage-manager.manage": "管理", "storage-manager.missing-ssd-warning": "SSDが見つからないようです。Umbrelをシャットダウンして全てのSSDが接続されているか確認してください。問題が続く場合はSSDを交換する必要があるかもしれません。", "storage-manager.mode": "モード", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "SSDが故障した場合にデータを安全に保ちます。SSDのサイズが異なる場合、大きいSSDの余剰容量は使用されません。", "storage-manager.mode.failsafe.info-description": "FailSafeはデータのコピーをSSD間で保持してデータを保護します。単一のSSDが故障してもデータは保護され、交換用のSSDを追加すれば復元できます。", "storage-manager.mode.failsafe.info-title": "FailSafeについて", "storage-manager.mode.full-storage": "Full Storage", "storage-manager.mode.full-storage.description": "すべてのSSD容量をまとめて使用します。SSDが故障するとデータを失う可能性があります。", "storage-manager.mode.full-storage.info-description": "Full StorageはすべてのSSDを一つの大容量スペースに統合し、最大のストレージ容量を提供します。ただし、どれか1つのSSDが故障すると全データが失われます。", "storage-manager.mode.full-storage.info-title": "Full Storageについて", "storage-manager.mode.switch-from-failsafe-unavailable": "FailSafeからFull Storageモードに切り替えるには、データのバックアップ、デバイスの工場出荷時リセット、バックアップからの復元が必要です。", "storage-manager.mode.switch-to-failsafe-unavailable": "複数のSSDがFull Storageモードで使用されている場合、データはすべてのドライブに分散されます。FailSafeに切り替えるには、データのバックアップ、工場出荷時リセット、復元が必要です。", "storage-manager.mode.why-cant-switch": "なぜ切り替えられないの?", "storage-manager.operation-in-progress.shutdown-description": "シャットダウンしても大丈夫です。操作は一時停止し、再起動後に再開しますが、他の変更を行う前に完了する必要があります。", "storage-manager.operation-in-progress.shutdown-title": "ストレージを更新しています", "storage-manager.operation-in-progress.wait-description": "現在の操作が完了するまでお待ちください。完了するまでは、他の変更は行わないでください。", "storage-manager.operation-in-progress.wait-title": "ストレージを更新しています", "storage-manager.operation.adding-ssd": "SSDを追加しています...", "storage-manager.operation.enabling-failsafe": "FailSafeを有効にしています…", "storage-manager.operation.expanding": "ストレージを拡張しています…", "storage-manager.operation.rebuilding": "データを再構築しています…", "storage-manager.operation.replacing": "ドライブを交換しています…", "storage-manager.operation.restarting": "再起動中...", "storage-manager.operation.starting": "起動中...", "storage-manager.operation.syncing-restarts": "データを同期中 • 進捗50%で再起動します", "storage-manager.raid-status.degraded": "劣化", "storage-manager.raid-status.failed": "故障", "storage-manager.raid-status.offline": "オフライン", "storage-manager.raid-status.online": "オンライン", "storage-manager.raid-status.removed": "取り外し済み", "storage-manager.raid-status.unavailable": "利用不可", "storage-manager.replace": "交換", "storage-manager.replace-failed.degraded": "FailSafe 保護が低下しています", "storage-manager.replace-failed.degraded-description": "FailSafe ストレージから SSD が外れています。交換して完全な保護を回復してください。", "storage-manager.replace-failed.description": "この SSD を使って FailSafe の保護を回復できます。", "storage-manager.replace-failed.error": "交換を開始できませんでした", "storage-manager.replace-failed.replace-now": "今すぐ交換", "storage-manager.replace-failed.ssd-in-slot": "スロット {{slot}} の {{size}} SSD", "storage-manager.replace-failed.step-protected": "完了後、データは再び完全に保護されます", "storage-manager.replace-failed.step-rebuild": "データは新しい SSD に再構築されます", "storage-manager.replace-failed.step-time": "データ量によっては時間がかかることがあります", "storage-manager.replace-failed.title": "SSD を交換", "storage-manager.replace-failed.too-small": "SSD が小さすぎます", "storage-manager.replace-failed.too-small-description": "この SSD({{deviceSize}})は FailSafe ストレージに必要な最小容量({{minSize}})より小さいです。", "storage-manager.replace-failed.what-happens": "今後の流れ:", "storage-manager.ssd-failing": "故障の可能性あり", "storage-manager.swap": "交換", "storage-manager.swap.data-erased-description": "Full Storageモードにはデータ保護がありません。工場出荷時リセット中に{{deviceName}}上の全データが消去されます。事前に必ずすべてをバックアップしてください。", "storage-manager.swap.data-protected": "データは保護されています", "storage-manager.swap.data-protected-description": "FailSafeが有効な場合、単一のSSDを交換してもデータを失いません。バックアップは不要です。", "storage-manager.swap.data-will-be-erased": "データが消去されます", "storage-manager.swap.description-failsafe": "FailSafeストレージのドライブを交換します。", "storage-manager.swap.description-full-storage": "Full Storage構成のドライブを交換します。", "storage-manager.swap.description-no-free-slot": "Full Storageモードで全スロットが使用中の場合、SSDの交換には完全なバックアップと復元が必要です。", "storage-manager.swap.description-replace": "データを新しいSSDに移行してから、古いSSDを取り外してください。", "storage-manager.swap.failed-to-start": "交換の開始に失敗しました", "storage-manager.swap.no-data-loss": "データ損失なし", "storage-manager.swap.no-data-loss-description": "データは新しいSSDにコピーされます。完了後に古いSSDを安全に取り外せます。", "storage-manager.swap.safe-swap-available": "安全な交換が可能です", "storage-manager.swap.safe-swap-description": "空きスロットがあるため、先に新しいSSDを追加してデータを移行してから古いSSDを取り外せます。バックアップは不要です。", "storage-manager.swap.select-new-ssd": "使用する新しいSSDを選択してください:", "storage-manager.swap.ssd-in-slot": "{{size}}のSSDがスロット {{slot}} にあります", "storage-manager.swap.step-backup": "データをバックアップする", "storage-manager.swap.step-backup-description": "設定 → Backups に移動し、すべてのデータのバックアップを作成してください。", "storage-manager.swap.step-data-copied": "データは古いSSDから新しいSSDにコピーされます", "storage-manager.swap.step-factory-reset": "工場出荷時リセット", "storage-manager.swap.step-factory-reset-description": "設定 → Advanced → Factory Reset に移動し、{{deviceName}}を消去してください。", "storage-manager.swap.step-insert-new-ssd": "新しいSSDを空きスロットに挿入してください", "storage-manager.swap.step-may-take-while": "データ量によっては時間がかかる場合があります", "storage-manager.swap.step-power-on": "{{deviceName}}の電源を入れてください", "storage-manager.swap.step-remove-bottom-cover": "マグネット式底面カバーを取り外してください", "storage-manager.swap.step-remove-old": "完了したら、電源を切って{{ssd}}を取り外してください", "storage-manager.swap.step-replace-bottom-cover": "底面カバーを元に戻してください", "storage-manager.swap.step-restore": "データを復元する", "storage-manager.swap.step-restore-description": "設定 → Backups に移動し、バックアップから復元してください。", "storage-manager.swap.step-return-to-storage-manager": "Storage Managerに戻り、交換を確認して新しいSSDをストレージに追加してください", "storage-manager.swap.step-return-to-swap": "ここに戻ってStorage Managerで \"Swap\" をもう一度クリックして交換を開始してください", "storage-manager.swap.step-setup-new-storage": "新しいストレージを設定する", "storage-manager.swap.step-setup-new-storage-description": "{{deviceName}}の電源を入れ、新しいSSDでセットアップを完了してください。", "storage-manager.swap.step-shut-down": "{{deviceName}}の電源を切ってください", "storage-manager.swap.step-shut-down-and-swap": "電源を切って{{ssd}}を交換してください", "storage-manager.swap.step-shut-down-and-swap-description-other": "電源を切り、デバイスを開けてSSDを交換し、再組み立てしてください。", "storage-manager.swap.step-shut-down-and-swap-description-pro": "電源を切り、底面カバーを取り外してSSDを交換し、カバーを閉めてください。", "storage-manager.swap.step-swap-ssd": "{{ssd}}を同じ容量の新しいものと交換してください", "storage-manager.swap.too-small": "小さすぎます({{size}}が必要です)", "storage-manager.swap.what-happens-next": "次に行われること:", "storage-manager.total-capacity-added": "追加された総容量", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "使用済み", "storage-manager.wasted": "使用不可", "storage-manager.wasted-size": "{{size}} 使用不可", "storage.full": "ストレージがいっぱいです", "storage.low": "ストレージ不足", "temperature": "温度", "temperature.dangerously-hot": "非常に熱い", "temperature.nice": "快適", "temperature.normal": "正常", "temperature.too-hot-suggestion": "デバイスの環境を変更することを検討してください。", "temperature.warm": "暖かい", "terminal": "Terminal", "terminal-description": "umbrelOSまたはアプリ内でカスタムコマンドを実行", "terminal.app": "アプリ", "terminal.app-description": "特定のアプリ内でカスタムコマンドを実行", "terminal.umbrelos-description": "umbrelOSでカスタムコマンドを実行", "tor-description": "Torブラウザを使用してどこからでもあなたのUmbrelにアクセス", "tor-enabled-description": "次のURLをTorブラウザで開けば、どこからでもUmbrelにアクセスできます:", "tor-error": "Tor 設定の更新に失敗しました: {{message}}", "tor.disable.description": "これには数分かかる場合があります", "tor.disable.progress": "リモートTorアクセスを無効にしています", "tor.enable.description": "これには数分かかる場合があります", "tor.enable.mobile.switch-label": "リモートTorアクセスを有効にする", "tor.hidden-service": "Tor非公開サービスURL", "troubleshoot": "トラブルシューティング", "troubleshoot-description": "umbrelOSまたはアプリのトラブルシューティング", "troubleshoot-no-logs-yet": "まだログはありません", "troubleshoot-pick-title": "トラブルシューティング", "troubleshoot.app": "アプリ", "troubleshoot.app-description": "Umbrelにインストールされているアプリのログを表示", "troubleshoot.app-download": "{{app}}ログのダウンロード", "troubleshoot.share-with-umbrel-support": "Umbrelサポートと共有", "troubleshoot.system-download": "{{label}}のダウンロード", "troubleshoot.umbrelos-description": "umbrelOSのログを表示", "troubleshoot.umbrelos-logs": "umbrelOSログ", "trpc.backend-unavailable": "エラー: システムAPIへの接続に失敗しました", "trpc.checking-backend": "読み込み中...", "try-again": "再試行", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "不明", "unknown-app": "不明なアプリ", "unknown-error": "不明なエラー", "uptime": "稼働時間", "url": "URL", "wallpaper": "壁紙", "wallpaper-description": "あなたのUmbrelの壁紙とテーマ", "whats-new.continue": "続ける", "whats-new.feature-1.description": "Umbrel全体を外付けUSBドライブ、NAS、または別のUmbrelに自動で暗号化してバックアップするよう設定できます。", "whats-new.feature-2.description": "過去のバックアップに遡って特定のファイルやフォルダを復元できます。", "whats-new.feature-3.description": "または、アプリ、ファイル、データを含むUmbrel全体を丸ごと復元できます。", "whats-new.feature-4.description": "NASや別のUmbrelを接続して、Filesからそのストレージにアクセスできます。", "whats-new.feature-4.title": "ネットワークデバイス", "whats-new.feature-5.description": "外付けのUSBドライブを接続(Umbrel Home、またはIntelやAMD搭載のデバイスで)して、Filesからアクセスできます。", "whats-new.feature-5.helper-text": "電力の問題が起きる可能性があるため、Raspberry Piではサポートされていません。", "whats-new.feature-5.title": "外付けストレージ", "whats-new.next": "次へ", "whats-new.title": "{{version}} の新機能", "widget.progress.in-progress": "進行中", "widgets.edit.select-up-to-3-widgets": "最大3つのウィジェットを選択", "widgets.install-an-app-before-using-widgets": "ウィジェットを使ってホームスクリーンをカスタマイズするには、アプリをインストールしてください。", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "オープンネットワークは安全でない可能性があります", "wifi-connection-failed": "接続できません", "wifi-dangerous-change-confirmation-description": "Wi-Fiネットワークを変更すると、Umbrelから切断される可能性があります。再接続するには、Umbrelとアクセスしているデバイスの両方が同じネットワーク上にあることを確認してください。", "wifi-dangerous-change-confirmation-title": "本当にWi-Fiネットワークを変更しますか?", "wifi-dangerous-disable-confirmation-description": "Wi-Fiを無効にすると、Umbrelから切断される可能性があります。再接続するには、UmbrelにEthernetケーブルを接続し、Umbrelとアクセスしているデバイスの両方が同じネットワーク上にあることを確認してください。", "wifi-dangerous-disable-confirmation-title": "本当にWi-Fiを無効にしますか?", "wifi-description": "デバイスをWi-Fiネットワークに接続します", "wifi-description-long": "デバイスは選択したWi-Fiに接続されたままになります。Ethernetケーブルが取り外されても、起動時に自動的にWi-Fiに再接続されます。", "wifi-no-networks-message": "Wi-Fiネットワークが見つかりません", "wifi-searching": "Wi-Fiネットワークを検索しています...", "wifi-unsupported-device-description": "このデバイスではWi-Fiがサポートされていません。これは、ワイヤレスアダプタがないか、互換性がないためです。", "wifi-view-networks": "ネットワークを表示" } ================================================ FILE: packages/ui/public/locales/ko.json ================================================ { "2fa": "2FA", "2fa-description": "Umbrel 로그인과 앱을 위한 2단계 인증", "2fa.disable.title": "2단계 인증 해제", "2fa.enable.or-paste": "또는 인증 앱에 아래 코드를 붙여넣으세요", "2fa.enable.scan-this": "Google Authenticator나 Authy 같은 인증 앱으로 이 QR 코드를 스캔하세요", "2fa.enable.title": "2단계 인증 활성화", "2fa.enter-code": "인증 앱에 표시된 코드를 입력하세요", "account": "계정", "account-description": "이름과 비밀번호", "advanced-settings": "고급 설정", "advanced-settings-description": "터미널, umbrelOS Beta Program, Cloudflare DNS 등", "app-not-found": "앱을 찾을 수 없습니다: {{app}}", "app-only-over-tor": "{{app}} 앱은 Tor 브라우저에서만 사용할 수 있어요. 이 앱을 열려면 원격 접속 URL(설정 > 고급 설정 > 원격 Tor 접속)에서 Tor 브라우저로 Umbrel에 접속하세요.", "app-page.section.about": "정보", "app-page.section.credentials.title": "기본 자격 증명", "app-page.section.dependencies.n-alternatives": "{{count}}개 대안을 확인하세요", "app-page.section.info.compatibility": "호환성", "app-page.section.info.compatibility-compatible": "호환됨", "app-page.section.info.compatibility-not-compatible": "호환되지 않음", "app-page.section.info.developer": "개발자", "app-page.section.info.source-code": "소스 코드", "app-page.section.info.source-code.public": "공개", "app-page.section.info.submitted-by": "제공자", "app-page.section.info.support": "지원 받기", "app-page.section.info.title": "정보", "app-page.section.info.version": "버전", "app-page.section.recommendations.title": "이 앱들도 추천해요", "app-page.section.release-notes.title": "새로운 점", "app-page.section.release-notes.version": "버전 {{version}}", "app-page.section.requires": "필요", "app-picker.search": "검색...", "app-picker.select-app": "앱 선택...", "app-settings.connected-to": "{{appName}}가(이) 다음 앱들과 연결되어 있습니다", "app-settings.save-changes": "변경사항 저장", "app-settings.title": "설정", "app-store.browse-category-apps": "{{category}} 앱 둘러보기", "app-store.category.ai": "AI", "app-store.category.all": "전체 앱", "app-store.category.automation": "홈 & 자동화", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "암호화폐", "app-store.category.developer": "개발자 도구", "app-store.category.discover": "새로 발견하기", "app-store.category.files": "파일 & 생산성", "app-store.category.finance": "금융", "app-store.category.media": "미디어", "app-store.category.networking": "네트워킹", "app-store.category.social": "소셜", "app-store.description": "앱 업데이트 설정", "app-store.discover.temporarily-unavailable-description": "위 카테고리를 둘러보거나 검색해서 앱을 찾아보세요", "app-store.discover.temporarily-unavailable-title": "추천 콘텐츠를 일시적으로 이용할 수 없어요", "app-store.menu.community-app-stores": "Community App Stores", "app-store.search-apps": "앱 검색", "app-store.search.no-results": "결과가 없습니다", "app-store.search.results-for": "다음에 대한 결과", "app-store.title": "App Store", "app-store.updates": "업데이트", "app-updates.less": "간단히", "app-updates.more": "자세히", "app-updates.no-updates": "모든 앱이 최신 버전이에요!", "app-updates.update": "업데이트", "app-updates.update-all": "모두 업데이트", "app-updates.updates-available-count_one": "{{count}}개 업데이트가 가능해요", "app-updates.updates-available-count_other": "{{count}}개 업데이트가 가능해요", "app-updates.updating": "업데이트 중...", "app.install": "설치", "app.installed": "설치됨", "app.installing": "설치 중...", "app.offline": "실행 중이 아님", "app.open": "열기", "app.optimized-for-umbrel-home": "Umbrel Home에 최적화됨", "app.os-update-required.confirm": "umbrelOS 업데이트 확인", "app.os-update-required.description": "{{appName}}을(를) 사용하려면 umbrelOS {{version}} 이상이 필요합니다", "app.os-update-required.title": "umbrelOS 업데이트", "app.restarting": "다시 시작 중...", "app.starting": "시작하는 중...", "app.stopping": "중지 중...", "app.uninstall.confirm.description": "{{app}}와 관련된 모든 데이터가 영구적으로 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", "app.uninstall.confirm.submit": "제거", "app.uninstall.confirm.title": "{{app}} 제거?", "app.uninstall.deps.used-by.description_one": "{{app}}을(를) 제거하려면 우선 {{firstAppToUninstall}}을(를) 제거해주세요.", "app.uninstall.deps.used-by.description_other": "{{app}}을(를) 제거하려면 먼저 다음 앱들을 제거해주세요.", "app.uninstall.deps.used-by.title": "{{app}}을(를) 사용하는 앱", "app.uninstalling": "제거 중...", "app.updating": "업데이트 중...", "app.view": "보기", "app_one": "앱", "app_other": "앱", "apps.uninstall.failed-to-get-required-apps": "필요한 앱을 가져오는 데 실패했습니다", "apps.uninstalled-all.success": "모든 앱을 제거했습니다", "auth.checking-backend-for-user": "불러오는 중...", "auth.failed-checking-if-user-logged-in": "오류: 로그인 확인에 실패했습니다", "auth.failed-to-check-if-user-exists": "오류: 사용자 존재 여부 확인 실패", "back": "뒤로", "backups": "Backups", "backups-configure": "설정", "backups-configure.add-backup-location": "백업 위치 추가", "backups-configure.available": "사용 가능", "backups-configure.awaiting-next-backup": "다음 자동 백업 대기 중", "backups-configure.back-up-now": "지금 백업", "backups-configure.backing-up-now": "백업 중...", "backups-configure.connected": "연결됨", "backups-configure.connection": "연결", "backups-configure.in-progress": "진행 중", "backups-configure.last-backup": "마지막 백업", "backups-configure.locations": "위치", "backups-configure.no-backup-locations": "데이터 백업을 시작하려면 백업 위치를 추가하세요", "backups-configure.not-connected": "연결되지 않음", "backups-configure.path": "경로", "backups-configure.remove-backup-location": "백업 위치 제거", "backups-configure.remove-backup-location-confirmation": "정말 삭제하시겠어요?", "backups-configure.remove-backup-location-confirmation-description": "이 작업은 백업 위치 목록에서 '{{device}}'를 제거합니다. 이 장치에 있는 기존 백업은 삭제되지 않지만 자동 백업은 중지됩니다.", "backups-configure.status": "상태", "backups-configure.total-backups": "총 Backups", "backups-configure.used": "사용됨", "backups-configure.view": "보기", "backups-description": "파일, 앱 및 데이터를 다른 Umbrel, NAS 또는 외장 드라이브에 백업하세요", "backups-error.backup-not-found": "백업을 찾을 수 없습니다.", "backups-error.generic": "문제가 발생했어요: {{details}}", "backups-error.in-progress": "백업이 이미 진행 중입니다. 완료될 때까지 기다려 주세요.", "backups-error.invalid-exclusion-path": "백업에서 제외할 수 있는 항목은 홈 디렉터리 내의 파일과 폴더뿐입니다.", "backups-error.invalid-password": "암호화 비밀번호가 올바르지 않습니다.", "backups-error.invalid-path": "선택한 위치는 백업에 적합하지 않습니다.", "backups-error.mount-failed": "백업 스냅샷에 접근할 수 없습니다.", "backups-error.mount-timeout": "백업 스냅샷에 접근할 수 없습니다. 다시 시도하거나 장치가 제대로 연결되어 있는지 확인하세요.", "backups-error.not-enough-space": "백업 장치에 사용 가능한 공간이 부족합니다.", "backups-error.not-found": "백업 또는 백업 위치를 찾을 수 없습니다.", "backups-error.repository-exists": "이 폴더에 이미 백업 위치가 존재합니다.", "backups-error.repository-not-found": "백업 위치를 찾을 수 없습니다.", "backups-exclusions.add": "추가", "backups-exclusions.app-paths-cannot-be-modified": "다음 파일/폴더는 앱 개발자가 설정한 항목으로 수정할 수 없습니다:", "backups-exclusions.app-paths-explanation": "이 앱은 다음 데이터를 백업에서 제외합니다. 이러한 경로는 일반적으로 재생성 가능한 캐시나 로그 같은 비필수 항목이거나, 복원 시 충돌이나 불일치를 일으킬 수 있는 오래된 앱 상태 등 문제를 일으킬 수 있는 데이터가 포함되어 있습니다.", "backups-exclusions.auto-excluded": "자동 제외됨", "backups-exclusions.exclude-entire-app": "앱 전체 제외", "backups-exclusions.excluded-apps": "제외된 앱", "backups-exclusions.files-and-folders": "제외된 파일 및 폴더", "backups-exclusions.no-excluded-apps": "제외된 앱이 없습니다", "backups-exclusions.no-excluded-files-or-folders": "제외된 파일이나 폴더가 없습니다", "backups-exclusions.select-item-to-exclude": "제외할 항목 선택", "backups-exclusions.stop-excluding": "제외 중지", "backups-floating-island.backing-up": "백업 중...", "backups-floating-island.backing-up-to": "Umbrel을 백업 중...", "backups-restore": "복원", "backups-restore-full": "전체 복원", "backups-restore-full-description": "백업에서 Umbrel 전체를 복원해보세요", "backups-restore-header": "Umbrel 복원", "backups-restore-pro.after-restore": "복원 후 임시 계정은 백업된 계정과 데이터로 교체됩니다.", "backups-restore-pro.step1": "아래의 \"시작하기\"를 클릭해 온보딩을 완료하세요. 복원할 때까지 이 계정은 임시 계정으로 유지됩니다.", "backups-restore-pro.step2": "설정이 완료되면 <0>설정 → Backups → Restore로 이동하세요", "backups-restore-pro.step3": "복원 마법사의 안내에 따라 진행하세요.", "backups-restore-pro.subtitle": "Umbrel Pro에서 백업을 복원하려면 몇 가지 추가 단계가 필요합니다", "backups-restore.backup-date": "백업 날짜", "backups-restore.backup-location": "백업 위치", "backups-restore.browse-cloud-subtitle": "Umbrel Private Cloud에서 복원(곧 제공 예정)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "외부 USB 드라이브에서 복원", "backups-restore.browse-external-title": "외장 드라이브", "backups-restore.browse-nas-or-external": "다른 Umbrel, NAS 또는 외장 드라이브에서 복원할 백업을 찾아보세요", "backups-restore.browse-nas-subtitle": "네트워크에 있는 다른 Umbrel 또는 NAS 기기에서 복원하세요", "backups-restore.browse-nas-title": "다른 Umbrel 또는 NAS", "backups-restore.choose": "선택", "backups-restore.choose-backup-location": "백업 위치 선택", "backups-restore.connect-to-backup-location": "백업 위치에 연결", "backups-restore.encryption-password": "암호화 비밀번호", "backups-restore.encryption-password-description": "백업을 활성화할 때 설정한 암호를 입력하세요", "backups-restore.enter-password-to-confirm": "확인하려면 Umbrel 비밀번호를 입력하세요", "backups-restore.final-confirmation": "정말 진행하시겠어요?", "backups-restore.final-confirmation-description": "이 백업에서 복원하면 현재의 umbrelOS 앱과 데이터가 선택한 백업의 내용으로 대체됩니다. 이 백업에서 제외된 파일, 폴더 또는 앱은 Umbrel에서 제거됩니다. 이 작업은 되돌릴 수 없습니다.", "backups-restore.invalid-password": "잘못된 비밀번호", "backups-restore.last-backup": "마지막 백업: {{date}}", "backups-restore.latest": "최신", "backups-restore.no-backups-found": "백업을 찾을 수 없음", "backups-restore.no-backups-yet": "아직 백업이 없습니다", "backups-restore.please-select-backup": "백업을 선택하세요", "backups-restore.please-select-repository": "저장소를 선택하세요", "backups-restore.restore-from-nas-or-external": "다른 Umbrel, NAS 또는 외부 드라이브에 있는 백업에서 Umbrel을 복원하세요", "backups-restore.restore-from-unlisted": "다른 위치에서 복원", "backups-restore.restore-umbrel": "Umbrel 복원", "backups-restore.restore-warning": "이 백업에서 복원하면 현재의 umbrelOS 앱과 데이터가 선택한 백업의 내용으로 대체됩니다. 이 백업에서 제외된 파일, 폴더 또는 앱은 Umbrel에서 제거됩니다. 대신 특정 파일이나 폴더만 복원하려면 <0>Rewind를 열어보세요.", "backups-restore.restoring-from": "다음 백업에서 복원하려고 합니다:", "backups-restore.review-description": "복원하면 이 백업이 만들어졌을 당시 포함되어 있던 계정, 파일, 앱 및 설정으로 Umbrel이 구성됩니다. 이 작업은 다소 시간이 걸릴 수 있습니다. 완료되면 로그인 비밀번호는 백업 생성 시 사용한 비밀번호로 설정됩니다.", "backups-restore.select-backup": "백업 선택", "backups-restore.select-backup-description": "복원하려는 백업을 선택하세요", "backups-restore.select-backup-file": "백업 파일 선택", "backups-restore.select-backup-file-only": "선택할 수 있는 항목은 {{backupFileName}}뿐이에요", "backups-restore.total-size": "전체 크기", "backups-restore.unknown-date": "알 수 없는 날짜", "backups-restore.unknown-repository": "알 수 없는 저장소", "backups-rewind": "Rewind", "backups-rewind-description": "특정 파일과 폴더를 복원하려면 시간을 되돌려보세요", "backups-rewind.start": "Rewind 시작", "backups-setup": "설정", "backups-setup-confirm": "설정 완료", "backups-setup-external-description": "외부 USB 드라이브에 백업", "backups-setup-nas-or-umbrel-description": "네트워크의 다른 Umbrel 또는 NAS 장치에 백업하세요", "backups-setup-umbrel-or-nas": "다른 Umbrel 또는 NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Umbrel Private Cloud로 종단 간 암호화된 백업을 보내 집 밖에서도 안심하세요.", "backups-setup-umbrel-private-cloud-cta-link": "조기 액세스 신청", "backups-setup-umbrel-private-cloud-description": "Umbrel Private Cloud로의 종단 간 암호화된 백업", "backups-setup-umbrel-private-cloud-subtitle": "곧 제공 예정", "backups.add-umbrel-or-nas": "Umbrel 또는 NAS 추가", "backups.all-apps-and-data-will-be-backed-up": "모든 앱과 데이터가 백업됩니다", "backups.apps-and-data": "앱 및 데이터", "backups.backup-location": "백업 위치", "backups.browse": "찾아보기", "backups.choose-folder-within-device": "백업을 저장할 {{device}} 내 폴더를 선택하세요", "backups.confirm-password": "비밀번호 확인", "backups.copy": "복사", "backups.encryption": "암호화", "backups.encryption-password-warning": "암호화 비밀번호는 비밀번호 관리자 등 안전한 곳에 보관하세요. 다시 확인할 수 없으며 백업을 복원하려면 필요합니다.", "backups.exclude-from-backups": "Backups에서 제외", "backups.exclude-from-backups-description": "백업에서 특정 파일, 폴더 및 앱을 제외하세요.", "backups.hide": "숨기기", "backups.i-understand": "이해했습니다", "backups.location": "위치", "backups.modals.already-in-use.description": "이 백업 위치는 이미 이 Umbrel의 Backups에서 사용 중이에요.", "backups.modals.already-in-use.manage": "Backups에서 관리", "backups.modals.already-in-use.title": "백업 위치가 이미 사용 중이에요", "backups.modals.connect-existing.description": "이 위치에는 이미 Umbrel 백업이 있습니다. 이 Umbrel에 추가하려면 암호(암호화 비밀번호)를 입력해 주세요.", "backups.modals.connect-existing.title": "기존 Umbrel 백업 연결", "backups.no-external-drives-detected": "외장 드라이브를 찾을 수 없음", "backups.no-password-set": "비밀번호가 설정되어 있지 않습니다", "backups.password-is-set": "비밀번호가 설정되어 있습니다", "backups.password-minimum-length": "비밀번호는 최소 8자 이상이어야 합니다", "backups.password-safety-warning": "이 비밀번호로 백업이 암호화됩니다. 다시 확인할 수 없으니 안전하게 보관하세요. 복원 시 이 비밀번호가 필요합니다.", "backups.passwords-do-not-match": "비밀번호가 일치하지 않습니다", "backups.please-choose-folder": "폴더를 선택하세요", "backups.restore-failed.message": "Umbrel을 복원하는 동안 오류가 발생했어요. 현재 앱과 데이터는 변경되지 않았어요.", "backups.restore-failed.retry": "복원으로 가기", "backups.restore-failed.title": "복원 실패", "backups.restoring": "Umbrel 복원 중", "backups.restoring-completing": "마무리 중이에요. Umbrel이 곧 재시작될 거예요...", "backups.restoring-progress": "복원됨 {{percent}}%", "backups.restoring-time-remaining": "{{time}} 남음", "backups.restoring-warning": "복원 중에는 Umbrel의 전원을 끄거나 백업 위치의 연결을 끊지 마세요", "backups.review": "검토 및 확인", "backups.review-description": "백업 세부 정보를 검토하고 선택을 확인하세요", "backups.scanning-for-external-drives": "외장 드라이브 검색 중...", "backups.schedule-description": "umbrelOS는 데이터를 자동으로 시간별로 백업합니다. 지난 24시간은 암호화된 시간별 백업을 보관하고, 지난 주는 일별 백업을, 지난 달은 주별 백업을, 지난 해는 월별 백업을 보관합니다. 1년을 초과한 백업은 자동으로 삭제됩니다.", "backups.select-backup-folder": "백업 폴더 선택", "backups.select-backup-folder-description": "백업을 저장할 폴더를 선택하세요.", "backups.select-backup-location": "백업 위치 선택", "backups.set-encryption-password": "암호화 비밀번호 설정", "backups.set-encryption-password-description": "비밀번호로 백업을 보호하세요. 이렇게 하면 데이터가 비공개로 유지되며 이 비밀번호로만 복원할 수 있습니다.", "backups.show": "표시", "backups.storage-capacity-warning": "{{device}}에는 백업 용량의 최소 2배에 해당하는 여유 공간이 필요합니다", "backups.store-encryption-password-safely": "암호화 비밀번호를 안전하게 보관하세요", "beta-program": "umbrelOS Beta Program", "beta-program-description": "umbrelOS 베타 업데이트를 받아서 새로운 기능을 미리 체험하고 피드백을 통해 개선에 참여해보세요. 베타 업데이트는 안정적이지 않을 수 있으며, 문제 해결에는 터미널에 대한 이해가 필요할 수 있습니다.", "cancel": "취소", "change": "변경", "change-name": "이름 바꾸기", "change-name.failed.name-required": "이름은 필수입니다", "change-name.input-placeholder": "이름", "change-password": "비밀번호 바꾸기", "change-password.callout": "비밀번호를 분실하면 Umbrel에 로그인할 수 없습니다. 안전하게 보관하세요.", "change-password.current-password": "현재 비밀번호", "change-password.failed.current-required": "현재 비밀번호가 필요합니다", "change-password.failed.min-length": "비밀번호는 최소 {{characters}}자 이상이어야 합니다", "change-password.failed.must-be-unique": "새 비밀번호는 현재 비밀번호와 달라야 합니다", "change-password.failed.new-required": "새 비밀번호가 필요합니다", "change-password.failed.no-match": "비밀번호가 일치하지 않습니다", "change-password.failed.repeat-required": "비밀번호 확인이 필요합니다", "change-password.new-password": "새 비밀번호", "change-password.repeat-password": "비밀번호 확인", "check-for-latest-version": "최신 umbrelOS 업데이트 확인", "clipboard.copied": "복사됨", "close": "닫기", "cmdk.change-wallpaper": "배경화면 변경", "cmdk.frequent-apps": "자주 사용하는 앱", "cmdk.input-placeholder": "앱, 설정 또는 작업 검색", "cmdk.live-usage": "Live Usage", "cmdk.restart-umbrel": "Umbrel 다시 시작", "cmdk.shutdown-umbrel": "Umbrel 종료", "cmdk.update-all-apps": "모든 앱 업데이트", "cmdk.widgets": "위젯", "community-app-store": "Community App Store", "community-app-store.add-error": "앱 스토어 추가에 실패했습니다: {{message}}", "community-app-store.back-to-umbrel-app-store": "Umbrel App Store로 돌아가기", "community-app-store.open-button": "열기", "community-app-store.remove-button": "삭제", "community-app-store.remove-error": "앱 스토어 제거에 실패했습니다: {{message}}", "community-app-stores.add-button": "추가", "community-app-stores.description": "Community App Stores를 통해 공식 Umbrel App Store에 없는 앱도 설치할 수 있어요. 또한 개발자가 공식 Umbrel App Store에 출시하기 전 Umbrel 앱의 베타 버전을 간편하게 테스트해볼 수도 있습니다.", "community-app-stores.learn-more": "자세히 알아보기", "community-app-stores.warning": "Community App Stores는 누구나 만들 수 있습니다. 이곳에 게시된 앱들은 공식 Umbrel App Store 팀이 검증하지 않았으므로 보안 또는 악성 앱일 수 있습니다. 신뢰할 수 있는 개발자의 앱 스토어만 추가하세요.", "confirm": "확인", "connect": "연결", "connecting": "연결 중...", "connection-lost": "연결 끊김", "connection-lost-description": "브라우저 탭이 비활성 상태였거나 네트워크 연결이 끊기거나 기기가 오프라인일 때 발생할 수 있어요.", "continue": "계속", "continue-to-log-in": "로그인 계속", "cpu": "CPU", "cpu-core-count": "{{cores}} 스레드", "default-credentials.close": "알겠어요", "default-credentials.description": "앱 로그인에 필요한 기본 자격 증명입니다.", "default-credentials.dont-show-again": "다시 표시하지 않기", "default-credentials.dont-show-again-notice": "앱 아이콘을 마우스 오른쪽 버튼으로 클릭하면 언제든 이 자격 증명을 다시 볼 수 있습니다.", "default-credentials.open": "{{app}} 열기", "default-credentials.password": "기본 비밀번호", "default-credentials.title": "{{app}} 자격 증명", "default-credentials.username": "기본 사용자명", "desktop.app.context.go-to-store-page": "App Store에서 보기", "desktop.app.context.settings": "설정", "desktop.app.context.show-default-credentials": "기본 자격 증명 보기", "desktop.app.context.uninstall": "제거", "desktop.context-menu.change-wallpaper": "배경화면 변경", "desktop.context-menu.edit-widgets": "위젯 편집", "desktop.context-menu.logout": "로그아웃", "desktop.greeting.afternoon": "안녕하세요, {{name}}님. 좋은 오후예요!", "desktop.greeting.evening": "안녕하세요, {{name}}님. 좋은 저녁이에요!", "desktop.greeting.morning": "안녕하세요, {{name}}님. 좋은 아침이에요!", "desktop.install-first.for-the-ai-enthusiast": "Viber를 위한", "desktop.install-first.for-the-bitcoiner": "비트코인 사용자에게 추천", "desktop.install-first.for-the-self-hoster": "셀프 호스팅 사용자에게 추천", "desktop.install-first.for-the-streamer": "스트리머에게 추천", "desktop.install-first.link-to-app-store": "더 많은 앱을 App Store에서 둘러보기", "desktop.not-enough-room": "더 큰 화면에서 앱을 확인하세요.", "device": "디바이스", "device-info": "디바이스 정보", "device-info-description": "디바이스에 대한 정보", "device-info.device": "디바이스", "device-info.model-number": "모델 번호", "device-info.serial-number": "일련번호", "device-info.view-info": "정보 보기", "device-name.home-or-pro": "Umbrel Home or Umbrel Pro", "disable": "비활성화", "done": "완료", "download-logs": "로그 다운로드", "enabling-tor": "원격 Tor 접속 활성화 중", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS를 사용하면 네트워크 안정성이 향상됩니다. 비활성화하면 라우터의 DNS 설정이 사용됩니다.", "external-dns-error": "DNS 설정 업데이트에 실패했습니다: {{message}}", "external-drive": "외장 드라이브", "factory-reset": "공장 초기화", "factory-reset-description": "모든 데이터와 앱을 삭제하고 umbrelOS를 초기 설정으로 복원합니다.", "factory-reset-failed": "기기 초기화에 실패했습니다: {{message}}", "factory-reset.confirm.body": "비밀번호를 입력해 초기화를 진행하세요", "factory-reset.confirm.ethernet-required-warning": "디바이스가 라우터에 Ethernet(와이파이가 아닌)으로 연결되어 있고, 로컬 네트워크(예: http://umbrel.local 또는 디바이스의 로컬 IP 주소)에서 접속 중인지 확인해주세요.", "factory-reset.confirm.submit": "모두 삭제하고 초기화", "factory-reset.confirm.submit-callout": "이 작업은 되돌릴 수 없습니다.", "factory-reset.rebooting.message": "기기가 재시작되며 모든 데이터가 삭제됩니다. 이 페이지를 닫지 마세요.", "factory-reset.rebooting.status": "초기화 중...", "factory-reset.rebooting.title": "공장 초기화 진행 중", "factory-reset.review.account-info": "계정 정보와 비밀번호", "factory-reset.review.apps": "앱", "factory-reset.review.following-will-be-removed": "다음 항목들이 디바이스에서 삭제됩니다", "factory-reset.review.installed-apps_one": "설치된 앱 {{count}}개", "factory-reset.review.installed-apps_other": "설치된 앱 {{count}}개", "factory-reset.review.submit": "계속", "factory-reset.review.total-data": "전체 데이터", "files": "Files", "files-action.add-favorite": "즐겨찾기에 추가", "files-action.add-network-device": "기기 추가", "files-action.cancel-upload": "업로드 취소", "files-action.compress": "압축", "files-action.copy": "복사", "files-action.cut": "잘라내기", "files-action.delete": "영구 삭제", "files-action.download": "다운로드", "files-action.download-items": "항목 {{count}}개 다운로드", "files-action.drop-to-upload": "업로드하려면 여기로 끌어다 놓으세요", "files-action.eject-disk": "꺼내기", "files-action.empty-trash": "휴지통 비우기", "files-action.format-drive": "포맷", "files-action.go-to-path": "이동...", "files-action.new-folder": "새 폴더", "files-action.open": "열기", "files-action.paste": "붙여넣기", "files-action.remove-favorite": "즐겨찾기에서 제거", "files-action.remove-network-host": "네트워크 드라이브 꺼내기", "files-action.remove-network-share": "네트워크 공유 꺼내기", "files-action.rename": "이름 바꾸기", "files-action.restore": "복원", "files-action.select": "선택", "files-action.share": "네트워크로 공유...", "files-action.sharing": "공유 중...", "files-action.show-in-folder": "포함 폴더에서 보기", "files-action.trash": "휴지통으로 이동", "files-action.uncompress": "압축 해제", "files-action.upload": "업로드", "files-add-network-share.add-manually": "직접 추가", "files-add-network-share.add-share": "공유 추가", "files-add-network-share.back": "뒤로", "files-add-network-share.continue": "계속", "files-add-network-share.description": "네트워크에 있는 NAS나 다른 공유 드라이브를 Files에 연결해 바로 접근할 수 있어요.", "files-add-network-share.discovering": "검색 중...", "files-add-network-share.enter-details-manually": "서버 정보를 입력하세요", "files-add-network-share.host-label": "서버 주소", "files-add-network-share.host-required": "서버 주소를 입력해주세요", "files-add-network-share.manual-share-help": "서버에 표시된 정확한 공유 폴더 이름을 입력하세요", "files-add-network-share.no-shares-found": "이 서버에서 공유 폴더를 찾을 수 없습니다", "files-add-network-share.not-seeing-share": "공유 폴더가 보이지 않나요?", "files-add-network-share.password-label": "비밀번호", "files-add-network-share.password-required": "비밀번호를 입력해주세요", "files-add-network-share.retrieving-shares": "공유를 불러오는 중…", "files-add-network-share.retry-discovery": "네트워크 다시 검색", "files-add-network-share.select-share": "추가할 공유를 선택하세요", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "공유 이름을 입력해주세요", "files-add-network-share.title": "네트워크 공유 추가", "files-add-network-share.username-label": "사용자 이름", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "사용자 이름을 입력해주세요", "files-audio-island.now-playing": "재생 중", "files-audio-island.pause": "일시정지", "files-audio-island.play": "재생", "files-backend-error.base-directory-not-found": "기본 디렉터리를 찾을 수 없습니다", "files-backend-error.cant-find-root": "파일 경로를 확인할 수 없습니다", "files-backend-error.destination-already-exists": "대상 위치에 같은 이름의 항목이 이미 존재합니다", "files-backend-error.destination-not-exist": "대상 폴더가 존재하지 않습니다", "files-backend-error.does-not-exist": "파일 또는 폴더가 존재하지 않습니다", "files-backend-error.escapes-base": "경로가 허용된 디렉터리 범위를 벗어났습니다", "files-backend-error.invalid-base": "경로가 유효한 디렉터리에 속하지 않습니다", "files-backend-error.invalid-filename": "파일 이름이 유효하지 않습니다", "files-backend-error.invalid-path": "파일 경로가 유효하지 않습니다", "files-backend-error.mkdir-failed": "폴더 생성에 실패했습니다", "files-backend-error.move-failed": "항목 이동에 실패했습니다", "files-backend-error.not-enough-space": "저장 공간이 부족합니다", "files-backend-error.operation-not-allowed": "이 작업은 허용되지 않습니다", "files-backend-error.parent-not-directory": "상위 경로가 폴더가 아닙니다", "files-backend-error.parent-not-exist": "상위 폴더가 존재하지 않습니다", "files-backend-error.path-not-absolute": "파일 경로가 유효하지 않습니다", "files-backend-error.share-already-exists": "이 폴더는 이미 공유되어 있습니다", "files-backend-error.share-name-generation-failed": "고유한 공유 이름을 생성할 수 없습니다", "files-backend-error.source-not-exists": "원본 파일 또는 폴더가 존재하지 않습니다", "files-backend-error.subdir-of-self": "폴더를 자기 자신의 하위 폴더로 이동하거나 복사할 수 없습니다", "files-backend-error.trash-meta-not-exists": "이 항목의 원래 위치를 찾을 수 없습니다", "files-backend-error.unique-name-index-exceeded": "고유한 이름을 생성할 수 없습니다. 유사한 이름의 항목이 너무 많습니다", "files-backend-error.upload-failed": "업로드에 실패했습니다", "files-collision.action.keep-both": "둘 다 유지", "files-collision.action.replace": "교체하기", "files-collision.action.skip": "건너뛰기", "files-collision.destination.original-location": "원래 위치", "files-collision.message": "기존 항목을 교체할까요, 아니면 둘 다 유지할까요?", "files-collision.title": "“{{itemName}}”이(가) 이미 {{destinationName}}에 있어요", "files-download.confirm": "다운로드", "files-download.description": "파일 앱에서 이 유형의 파일을 열 수 없어요. 대신 다운로드하시겠어요?", "files-download.title": "{{name}}을(를) 다운로드할까요?", "files-empty-trash.confirm": "비우기", "files-empty-trash.description": "정말 휴지통의 모든 항목을 영구적으로 삭제할까요? 이 작업은 되돌릴 수 없어요.", "files-empty-trash.title": "휴지통 비우기?", "files-empty.directory": "이 폴더에는 항목이 없어요", "files-empty.network": "네트워크 기기가 없어요", "files-empty.network-host-offline": "네트워크 기기가 오프라인입니다", "files-error.add-favorite": "즐겨찾기 추가에 실패했습니다: {{message}}", "files-error.add-share": "폴더 공유에 실패했습니다: {{message}}", "files-error.compress": "압축에 실패했습니다: {{message}}", "files-error.copy": "복사에 실패했습니다: {{message}}", "files-error.create-folder": "폴더 생성에 실패했습니다: {{message}}", "files-error.delete": "삭제에 실패했습니다: {{message}}", "files-error.eject-disk": "드라이브 꺼내기에 실패했습니다: {{message}}", "files-error.empty-trash": "휴지통 비우기에 실패했습니다: {{message}}", "files-error.extract": "압축 해제에 실패했습니다: {{message}}", "files-error.folder-already-exists": "같은 이름의 폴더가 이미 존재합니다", "files-error.move": "이동에 실패했습니다: {{message}}", "files-error.remove-favorite": "즐겨찾기 제거에 실패했습니다: {{message}}", "files-error.remove-share": "공유 폴더 제거에 실패했습니다: {{message}}", "files-error.rename": "이름 변경에 실패했습니다: {{message}}", "files-error.restore": "복원에 실패했습니다: {{message}}", "files-error.trash": "휴지통으로 이동에 실패했습니다: {{message}}", "files-error.upload": "업로드에 실패했습니다: {{message}}", "files-error.upload-network-error": "{{name}} 업로드에 실패했습니다: 네트워크 오류가 발생했습니다", "files-extension-change.confirm": "계속", "files-extension-change.description-add": "정말 '{{fileName}}'의 확장자를 '{{extension}}'(으)로 바꾸시겠어요? 이로 인해 파일을 읽을 수 없게 될 수도 있어요.", "files-extension-change.description-remove": "정말 '{{fileName}}'의 확장자를 제거하시겠어요?", "files-extension-change.title-add": "확장자를 '{{extension}}'(으)로 바꾸기?", "files-extension-change.title-remove": "확장자 제거하기?", "files-external-storage.unsupported.description": "연결된 외장 저장소는 전력 문제로 Raspberry Pi에서 사용할 수 없습니다. 외장 저장소는 Umbrel Home, Umbrel Pro 및 모든 x86 (Intel 또는 AMD) 기기에서 사용할 수 있습니다.", "files-external-storage.unsupported.description-general": "전력 문제로 Raspberry Pi에서는 외장 저장소를 사용할 수 없습니다. 외장 저장소는 Umbrel Home, Umbrel Pro 및 모든 x86 (Intel 또는 AMD) 장치에서 사용할 수 있습니다.", "files-external-storage.unsupported.title": "외장 스토리지를 지원하지 않아요", "files-folder": "폴더", "files-format.confirm": "포맷", "files-format.description": "포맷하면 {{driveName}}의 모든 데이터가 삭제됩니다. 이 작업은 되돌릴 수 없습니다.", "files-format.description-unreadable": "umbrelOS가 {{driveName}}의 내용을 읽을 수 없습니다. umbrelOS에서 사용하려면 포맷하세요.", "files-format.drive-label": "이름", "files-format.error": "드라이브 포맷에 실패했어요", "files-format.exfat-description": "Windows, macOS, Linux와의 최대 호환성", "files-format.ext4-description": "umbrelOS와 Linux에서 더 나은 성능", "files-format.filesystem": "파일 시스템", "files-format.filesystem-label": "포맷 형식", "files-format.formatting": "포맷 중...", "files-format.title": "드라이브 포맷", "files-format.title-requires-format": "포맷 필요", "files-formatting-island.formatting": "포맷 중...", "files-formatting-island.formatting-drives": "드라이브 {{count}}개 포맷 중", "files-listing.empty": "항목이 없습니다", "files-listing.error": "오류가 발생했어요", "files-listing.item-count-truncated": "{{formattedCount}}+개 항목", "files-listing.item-count_one": "{{formattedCount}}개 항목", "files-listing.item-count_other": "{{formattedCount}}개 항목", "files-listing.loading": "불러오는 중...", "files-listing.no-such-file": "해당 파일이나 폴더가 없어요", "files-listing.selected-count": "{{totalCount}}개 중 {{selectedCount}}개 선택됨", "files-listing.selected-count-truncated": "전체 {{totalCount}}+개 중 {{selectedCount}}개 선택", "files-name-drawer.new-folder": "새 폴더", "files-name-drawer.new-folder-description": "새 폴더의 이름을 입력하세요.", "files-name-drawer.new-folder-input": "폴더 이름", "files-name-drawer.rename-file": "파일 이름 바꾸기", "files-name-drawer.rename-file-description": "이 파일의 새 이름을 입력하세요.", "files-name-drawer.rename-file-input": "파일 이름", "files-name-drawer.rename-folder": "폴더 이름 바꾸기", "files-name-drawer.rename-folder-description": "이 폴더의 새 이름을 입력하세요.", "files-name-drawer.rename-folder-input": "폴더 이름", "files-network-storage-error.add-share": "네트워크 공유 추가에 실패했습니다: {{message}}", "files-network-storage-error.discover-servers": "네트워크 장치 검색에 실패했습니다: {{message}}", "files-network-storage-error.discover-shares": "네트워크 공유 검색에 실패했습니다: {{message}}", "files-network-storage-error.remove-share": "네트워크 공유 제거에 실패했습니다: {{message}}", "files-operations-island.copying": "\"{{from}}\"을 \"{{to}}\"로 복사 중이에요", "files-operations-island.moving": "\"{{from}}\"을 \"{{to}}\"로 이동 중이에요", "files-operations-island.restoring": "\"{{from}}\"을 \"{{to}}\"로 복원 중", "files-path.input-group": "경로 입력", "files-path.input-label": "현재 경로", "files-permanently-delete.confirm": "영구적으로 삭제", "files-permanently-delete.description-multiple": "정말 이 {{count}}개의 항목을 영구적으로 삭제할까요? 이 작업은 되돌릴 수 없어요.", "files-permanently-delete.description-single": "정말 \"{{fileName}}\"을(를) 영구적으로 삭제할까요? 이 작업은 되돌릴 수 없어요.", "files-permanently-delete.title-multiple": "{{count}}개 항목을 영구적으로 삭제할까요?", "files-permanently-delete.title-single": "영구적으로 삭제할까요?", "files-search.default": "파일 및 폴더 검색", "files-search.no-results": "\"{{query}}\"에 대한 검색 결과가 없습니다", "files-search.placeholder": "검색", "files-search.searching-label": "{{name}}님의 Umbrel을 검색 중입니다", "files-share.home-description": "네트워크의 다른 기기에서 \"{{homeDirectoryName}}\" 안의 모든 파일에 접근할 수 있어요.", "files-share.home-title": "\"{{homeDirectoryName}}\"을(를) 네트워크에서 공유하기", "files-share.instructions.how-to-access": "접근 방법", "files-share.instructions.ios.enter-password": "비밀번호로 {{password}}을(를) 입력하세요.", "files-share.instructions.ios.enter-server": "서버 주소로 {{smbUrl}}을(를) 입력하세요.", "files-share.instructions.ios.enter-username": "사용자 이름으로 {{username}}을(를) 입력하세요.", "files-share.instructions.ios.install-files": "App Store에서 \"Files\" 앱을 설치하세요(설치하지 않았다면).", "files-share.instructions.ios.tap-connect": "접속하려면 \"Connect\"를 탭하세요.", "files-share.instructions.ios.tap-dots": "오른쪽 상단의 세 점 (...)을 탭하고 \"Connect to Server\"를 선택하세요.", "files-share.instructions.macos.click-connect": "\"Connect\"를 클릭하여 접속하세요.", "files-share.instructions.macos.enter-password": "비밀번호로 {{password}}을(를) 입력하세요.", "files-share.instructions.macos.enter-url": "{{smbUrl}}을(를) 입력하고 Connect를 클릭하세요.", "files-share.instructions.macos.enter-username": "사용자 이름으로 {{username}}을(를) 입력하세요.", "files-share.instructions.macos.open-finder": "\"Finder\"를 열고, ⌘ + K를 누르세요.", "files-share.instructions.macos.select-registered": "프롬프트가 표시되면 \"Registered User\"를 선택하세요.", "files-share.instructions.macos.time-machine": "Time Machine 백업 위치로 사용하는 방법", "files-share.instructions.macos.time-machine.choose-encryption": "암호화된 백업 또는 암호화되지 않은 백업 중에서 선택하세요.", "files-share.instructions.macos.time-machine.disk-limit": "'Disk Usage Limit'에서 Time Machine 백업을 위해 Umbrel에 할당할 최대 용량을 지정하고, \"Done\"을 클릭하세요.", "files-share.instructions.macos.time-machine.follow-steps": "위 단계를 따라 Mac의 System Settings를 여세요.", "files-share.instructions.macos.time-machine.go-settings": "Time Machine으로 이동해 \"Add Backup Disk...\"를 클릭하세요.", "files-share.instructions.macos.time-machine.select-disk": "폴더를 선택한 다음 \"디스크 설정...\"을 클릭하세요.", "files-share.instructions.umbrelos.backup.follow-onscreen": "화면 안내에 따라 백업을 설정하세요.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "위 단계를 따라한 다음 다른 Umbrel에서 \"{{settings}}\" > \"{{backups}}\"로 이동하세요.", "files-share.instructions.umbrelos.backup.select-add": "\"{{addUmbrelOrNas}}\" 옵션을 선택하세요.", "files-share.instructions.umbrelos.backup.select-connected": "연결된 기기 목록에서 이 Umbrel 기기를 선택하세요.", "files-share.instructions.umbrelos.backup.title": "다른 Umbrel의 백업 위치로 사용하는 방법", "files-share.instructions.umbrelos.cant-find-note": "찾을 수 없나요? \"수동으로 추가\"를 선택한 후 아래의 자격 증명을 사용해 보세요. 그래도 추가할 수 없다면 두 기기가 같은 네트워크에 연결되어 있는지 확인해 보세요.", "files-share.instructions.umbrelos.enter-password": "{{password}}를 비밀번호로 입력하세요.", "files-share.instructions.umbrelos.enter-username": "{{username}}를 사용자 이름으로 입력하세요.", "files-share.instructions.umbrelos.open-and-click": "다른 Umbrel에서 \"Files\"를 열고 사이드바에서 \" {{deviceLabel}}\" 옆의 를 클릭하세요.", "files-share.instructions.umbrelos.select-device": "네트워크에서 자동으로 감지된 기기 목록에서 이 Umbrel 기기를 선택하세요.", "files-share.instructions.umbrelos.select-sharename": "\"{{sharename}}\"을 선택한 다음 클릭해 공유를 추가하세요.", "files-share.instructions.windows.enter-password": "비밀번호로 {{password}}을(를) 입력하세요.", "files-share.instructions.windows.enter-url": "{{smbUrl}}을(를) 입력하고 Enter 키를 누르세요.", "files-share.instructions.windows.enter-username": "사용자 이름으로 {{username}}을(를) 입력하세요.", "files-share.instructions.windows.open-run": "Windows + R 키를 눌러 Run 대화 상자를 여세요.", "files-share.instructions.windows.remember-credentials": "\"Remember my credentials\"를 체크하고 OK를 클릭하세요.", "files-share.regular-description": "네트워크의 다른 기기에서 이 폴더에 접근할 수 있도록 공유하세요.", "files-share.regular-title": "폴더를 네트워크로 공유하기", "files-share.toggle": "네트워크에서 \"{{name}}\"(을)를 공유하기", "files-sidebar.apps": "앱", "files-sidebar.external-storage": "외장 스토리지", "files-sidebar.favorites": "즐겨찾기", "files-sidebar.home": "홈", "files-sidebar.navigation": "파일 탐색", "files-sidebar.network": "네트워크", "files-sidebar.network-pathbar": "네트워크 기기", "files-sidebar.network-sidebar": "기기", "files-sidebar.recents": "최근 항목", "files-sidebar.shared-folders": "공유된 폴더", "files-sidebar.trash": "휴지통", "files-sidebar.trash.open": "열기", "files-sort.created": "추가됨", "files-sort.modified": "수정됨", "files-sort.name": "이름", "files-sort.size": "크기", "files-sort.type": "유형", "files-state.uploading": "업로드 중...", "files-state.waiting": "대기 중...", "files-type.3gp": "3GP 비디오", "files-type.3gp2": "3GP2 비디오", "files-type.7z": "7Z 압축 파일", "files-type.aac": "AAC 오디오", "files-type.ai": "Illustrator 파일", "files-type.aiff": "AIFF 오디오", "files-type.au": "AU 오디오", "files-type.avi": "AVI 비디오", "files-type.avif": "AVIF 이미지", "files-type.bmp": "BMP 이미지", "files-type.bzip2": "BZIP2 압축 파일", "files-type.caf": "CAF 오디오", "files-type.compressed": "압축 파일", "files-type.csv": "CSV 파일", "files-type.directory": "폴더", "files-type.dmg": "디스크 이미지", "files-type.dv": "DV 비디오", "files-type.epub": "EPUB 전자책", "files-type.excel": "Excel 스프레드시트", "files-type.exe": "Windows 실행 파일", "files-type.executable": "실행 파일", "files-type.external-drive": "드라이브", "files-type.flac": "FLAC 오디오", "files-type.flv": "FLV 비디오", "files-type.gif": "GIF 이미지", "files-type.gzip": "GZIP 압축 파일", "files-type.heic": "HEIC 이미지", "files-type.ico": "ICO 이미지", "files-type.iso": "ISO 이미지", "files-type.jpeg": "JPEG 이미지", "files-type.keynote": "Keynote 프레젠테이션", "files-type.lzip": "LZIP 압축 파일", "files-type.lzma": "LZMA 압축 파일", "files-type.lzop": "LZOP 압축 파일", "files-type.m3u": "M3U 재생목록", "files-type.m4a": "M4A 오디오", "files-type.m4v": "M4V 비디오", "files-type.midi": "MIDI 오디오", "files-type.mka": "MKA 오디오", "files-type.mkv": "MKV 비디오", "files-type.mng": "MNG 비디오", "files-type.mobi": "MOBI 전자책", "files-type.mp3": "MP3 오디오", "files-type.mp4": "MP4 비디오", "files-type.mp4-audio": "MP4 오디오", "files-type.mpeg": "MPEG 비디오", "files-type.mpeg-ts": "MPEG 전송 스트림", "files-type.network-drive": "네트워크 드라이브", "files-type.numbers": "Numbers 스프레드시트", "files-type.ogg": "OGG 오디오", "files-type.ogv": "OGV 비디오", "files-type.pages": "Pages 문서", "files-type.pdf": "PDF 문서", "files-type.png": "PNG 이미지", "files-type.powerpoint": "PowerPoint 프레젠테이션", "files-type.psd": "Photoshop 문서", "files-type.quicktime": "QuickTime 비디오", "files-type.rar": "RAR 압축 파일", "files-type.sgi": "SGI 동영상", "files-type.svg": "SVG 이미지", "files-type.tar": "TAR 압축 파일", "files-type.tiff": "TIFF 이미지", "files-type.ts": "TS 비디오", "files-type.txt": "텍스트 파일", "files-type.umbrel-backup": "Umbrel 백업", "files-type.wav": "WAV 오디오", "files-type.webm": "WebM 비디오", "files-type.webm-audio": "WebM 오디오", "files-type.webp": "WebP 이미지", "files-type.wma": "WMA 오디오", "files-type.wmv": "WMV 비디오", "files-type.word": "Word 문서", "files-type.xz": "XZ 압축 파일", "files-type.zip": "ZIP 압축 파일", "files-upload-island.uploading-count": "{{count}}개 항목 업로드 중", "files-view.icons": "아이콘", "files-view.list": "목록", "files-view.sort-by": "정렬 기준", "files-view.view-as": "보기 방식", "files-widgets.favorites.no-items-text": "폴더를 즐겨찾기에 추가하면 여기에서 볼 수 있어요", "files-widgets.recents.no-items-text": "최근에 사용한 파일이 없어요", "generic-in": "에서", "hide-details": "세부 정보 숨기기", "install-first.install-app": "{{app}} 설치", "install-first.title": "{{app}}을(를) 사용하려면 다음 앱들이 필요합니다", "install-your-first-app": "처음 앱을 설치해보세요", "language": "언어", "language-description": "원하는 umbrelOS 언어", "language.select-description": "원하는 umbrelOS 언어를 선택하세요", "live-usage": "Live Usage", "loading": "불러오는 중", "local-ip": "로컬 IP", "login-2fa.subtitle": "인증 앱에 표시된 2FA 코드를 입력하세요", "login-2fa.title": "인증", "login-with-umbrel.description": "{{app}}을(를) 열려면 Umbrel 비밀번호를 입력하세요", "login-with-umbrel.title": "Umbrel로 로그인", "login.password-label": "비밀번호", "login.password.submit": "로그인", "login.subtitle": "Umbrel 비밀번호를 입력해 로그인하세요", "login.title": "다시 오신 걸 환영해요", "logout": "로그아웃", "logout-error-generic": "오류: 로그아웃 실패", "logout.confirm.submit": "로그아웃", "logout.confirm.title": "정말 로그아웃하시겠어요?", "memory": "메모리", "memory.low": "메모리 부족", "migrate": "이전", "migrate.callout": "마이그레이션이 완료될 때까지 Umbrel 전원을 끄지 마세요", "migrate.failed.retry": "다시 시도", "migrate.failed.title": "마이그레이션 실패", "migrate.success.description": "모든 앱과 앱 데이터, 계정 정보가 Umbrel Home으로 마이그레이션되었습니다.", "migrate.success.title": "마이그레이션 완료", "migration-assistant": "Migration Assistant", "migration-assistant-description": "Raspberry Pi에서 {{deviceName}}로 모든 앱과 데이터를 전송합니다.", "migration-assistant-unsupported-device-description": "Migration Assistant는 현재 umbrelOS가 설치된 Raspberry Pi에서 Umbrel Home 또는 Umbrel Pro로 모든 데이터와 앱을 전송하는 것을 지원합니다. 시작하려면 Umbrel Home 또는 Umbrel Pro에서 Migration Assistant를 여세요.", "migration-assistant.continue-migration.ready.submit": "마이그레이션 시작", "migration-assistant.failed": "문제가 발생했어요...", "migration-assistant.failed.retrying-message": "다시 시도 중...", "migration-assistant.mobile.start-button": "마이그레이션 시작", "migration-assistant.prep.body": "마이그레이션 준비", "migration-assistant.prep.button-continue": "계속", "migration-assistant.prep.callout": "{{deviceName}}에 데이터가 있다면 영구적으로 삭제됩니다.", "migration-assistant.prep.connect-disk-to-home": "외장 드라이브를 {{deviceName}}의 아무 USB 포트에 연결하세요.", "migration-assistant.prep.prep-done-continue-message": "준비가 완료되면 아래 '{{button}}'을(를) 클릭하세요.", "migration-assistant.prep.shut-down-rpi": "Raspberry Pi Umbrel을(를) 종료하세요.", "migration-assistant.ready.description": "모든 데이터와 앱이 {{deviceName}}로 이전할 준비가 되었습니다.", "migration-assistant.ready.hint-header": "주의 사항", "migration-assistant.ready.hint-keep-pi-off.description": "이는 Lightning Node와 같은 앱에서 문제가 발생하는 것을 예방합니다", "migration-assistant.ready.hint-keep-pi-off.title": "Raspberry Pi는 업데이트 뒤에 계속 꺼두세요", "migration-assistant.ready.hint-use-same-password.description": "Raspberry Pi에서 사용하던 Umbrel 비밀번호로 {{deviceName}}에 로그인하세요.", "migration-assistant.ready.hint-use-same-password.title": "같은 비밀번호를 사용하세요", "migration-assistant.ready.title": "마이그레이션할 준비가 완료되었습니다!", "mini-browser.default-title": "폴더 선택", "mini-browser.empty-external": "여기에 표시하려면 외장 드라이브를 연결해 보세요.", "mini-browser.empty-network": "여기에 표시하려면 Umbrel 또는 NAS를 추가해 보세요.", "mini-browser.load-more": "더 보기", "mini-browser.load-more-in-folder": "{{name}}에서 더 보기", "mini-browser.loading-more": "더 불러오는 중…", "mini-browser.select": "선택", "mini-browser.select-folder": "폴더 선택", "name": "이름", "nas": "NAS", "no-forgot-password-message": "비밀번호를 분실하면 Umbrel에 로그인할 수 없습니다. 안전하게 보관하세요.", "no-results-found": "결과가 없습니다", "not-found-404": "오류 코드: 404", "not-found-404.back": "뒤로 가기", "not-found-404.home": "홈으로 가기", "notifications.backups-failing-location.description": "{{location}}로의 자동 Backups가 계속 실패하고 있어요. 연결을 확인하고 백업 설정을 검토해보세요.", "notifications.backups-failing.description": "자동 Backups가 실패하고 있어요. Backups 위치를 확인하고 설정을 검토해 보세요.", "notifications.backups-failing.go-to-backups": "Backups로 이동", "notifications.backups-failing.title": "최근 24시간 동안 Backups가 없어요", "notifications.cpu.too-hot": "CPU 온도가 너무 높습니다", "notifications.memory.low": "디바이스 메모리가 부족합니다", "notifications.new-version-available": "{{update}} 설치 가능", "notifications.raid.issue.description": "스토리지 문제가 감지되었습니다. 자세한 내용은 Storage Manager에서 확인하세요.", "notifications.raid.issue.title": "긴급 조치 필요", "notifications.ssd.health.description": "하나 이상의 SSD에 조치가 필요할 수 있습니다. 자세한 내용은 Storage Manager에서 확인하세요.", "notifications.ssd.health.title": "SSD 상태 경고", "notifications.storage.full": "디바이스 저장 공간이 가득 찼습니다", "notifications.view": "보기", "ok": "확인", "onboarding.account-created.by-clicking-button-you-agree": "'다음'을 누르면 umbrelOS 이용 약관에 동의하는 것으로 간주됩니다", "onboarding.account-created.youre-all-set-name": "이제 다 됐어요, {{name}}!", "onboarding.contact-support": "지원", "onboarding.create-account": "계정 생성", "onboarding.create-account.confirm-password.input-label": "비밀번호 확인", "onboarding.create-account.failed.name-required": "이름은 필수입니다", "onboarding.create-account.failed.passwords-dont-match": "비밀번호가 일치하지 않습니다", "onboarding.create-account.name.input-placeholder": "이름", "onboarding.create-account.password.input-label": "비밀번호", "onboarding.create-account.submit": "생성", "onboarding.create-account.submitting": "생성 중...", "onboarding.create-account.subtitle": "계정 정보는 오직 Umbrel에만 저장됩니다. 비밀번호를 안전하게 백업하세요. 재설정 방식이 없으니까요.", "onboarding.create-instead-long": "새 계정 만들기", "onboarding.create-instead-short": "새 계정", "onboarding.launch-umbrelos": "umbrelOS 시작하기", "onboarding.raid.available-storage": "사용 가능한 저장 공간", "onboarding.raid.change-drives-link": "드라이브를 추가하거나 교체해야 하나요?", "onboarding.raid.configuring.subtitle": "몇 분 정도 걸릴 수 있어요.", "onboarding.raid.configuring.title": "저장 공간 구성 중", "onboarding.raid.configuring.warning": "저장 공간을 구성하는 동안에는 이 페이지를 새로 고치거나 Umbrel의 전원을 끄지 마세요.", "onboarding.raid.continue": "계속", "onboarding.raid.error.detection-instructions": "Umbrel Pro의 전원을 끄고 SSD가 제대로 장착되었는지 확인한 다음 다시 시도하세요.", "onboarding.raid.error.no-ssds-detected": "SSD가 감지되지 않았습니다", "onboarding.raid.error.no-ssds-instructions": "Umbrel Pro의 전원을 끄고 계속하려면 최소 하나의 SSD를 장착하세요.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "아직 FailSafe를 활성화할 수 없어요", "onboarding.raid.failsafe.enable": "FailSafe 활성화", "onboarding.raid.failsafe.mixed-sizes": "FailSafe는 가장 작은 SSD ({{smallest}}) 용량에 맞춰집니다. 더 큰 SSD의 남는 공간은 사용되지 않아 {{wasted}}가 사용 불가로 남습니다.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}}는 데이터 보호에 사용됩니다. 추가로 {{smallest}} SSD 하나를 더 넣으면 사용 가능한 저장 공간이 {{futureWith3}}로 늘어나고, 두 개를 더 추가하면 {{futureWith4}}가 됩니다. 언제든 SSD를 추가할 수 있어요.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}}는 데이터 보호에 사용됩니다. 추가로 {{smallest}} SSD 하나를 더 넣으면 사용 가능한 저장 공간이 {{futureWith4}}로 늘어납니다. 언제든 SSD를 추가할 수 있어요.", "onboarding.raid.failsafe.single-ssd-info": "현재 SSD가 하나뿐이에요. 데이터 보호를 위해 최소 하나 이상의 {{size}} SSD를 추가하세요. 언제든 SSD를 추가할 수 있어요.", "onboarding.raid.failsafe.subtitle": "SSD 한 개가 고장 나더라도 데이터는 안전해요", "onboarding.raid.failsafe.tip": "최대 저장공간과 사용 불가 공간 0을 원한다면 같은 크기의 SSD를 사용하세요.", "onboarding.raid.failsafe.warning-now-only": "SSD가 2개 이상인 경우 FailSafe는 초기 설정 중에만 활성화할 수 있어요. 나중에는 활성화할 수 없습니다.", "onboarding.raid.health-warning": "이 드라이브에서 상태 이상이 보고되었어요", "onboarding.raid.launching": "실행 중...", "onboarding.raid.no-ssds-alt": "SSD가 없습니다", "onboarding.raid.recommended": "권장", "onboarding.raid.scanning": "SSD 슬롯 확인 중", "onboarding.raid.scanning-alt": "SSD 스캔 중", "onboarding.raid.setup-failed.description-no-retry": "시스템을 종료한 후 다시 시도하세요.", "onboarding.raid.setup-failed.description-retry": "다시 시도하거나, 드라이브를 확인하려면 시스템을 종료하세요.", "onboarding.raid.setup-failed.title": "저장 공간 설정 실패", "onboarding.raid.shutdown-dialog.description": "드라이브를 추가하거나 교체하려면 Umbrel Pro의 전원을 끄세요. 변경을 마친 후 전원을 켜면 설정을 계속할 수 있어요.", "onboarding.raid.shutdown-dialog.title": "드라이브를 변경하시겠어요?", "onboarding.raid.ssd-in-slot": "{{size}} SSD 1개가 슬롯 {{slot}}에 장착되어 있어요.", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSD 트레이", "onboarding.raid.ssds-found": "다음 SSD가 Umbrel Pro에서 발견되었습니다", "onboarding.raid.storage": "저장 공간", "onboarding.raid.storage-label": "저장 공간", "onboarding.raid.success.storage-info": "저장 공간 {{available}}", "onboarding.raid.success.storage-info-failsafe": "저장 공간 {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "다시 시도", "onboarding.raid.wasted": "사용 불가", "onboarding.restore-long": "내 Umbrel 복원하기", "onboarding.restore-short": "복원", "onboarding.start.continue": "시작하기", "onboarding.start.subtitle": "당신의 홈 클라우드 서버를 설정할 준비가 되었습니다.", "onboarding.start.title": "umbrelOS에 오신 걸 환영해요", "open": "열기", "open-live-usage": "Live Usage 열기", "password": "비밀번호", "preferences": "환경설정", "raid-error.description": "스토리지 시스템이 정상적으로 시작되지 않았습니다. 아래에서 SSD 상태를 확인하고 문제 해결 단계를 따라주세요. 문제가 계속되면 영향받은 SSD를 교체해야 할 수 있습니다.", "raid-error.factory-reset-dialog.description": "이 작업은 Umbrel Pro의 모든 데이터를 지우고 공장 설정으로 초기화합니다. 되돌릴 수 없습니다.", "raid-error.factory-reset-dialog.title": "공장 초기화를 진행할까요?", "raid-error.factory-reset-failed": "공장 초기화에 실패했습니다.", "raid-error.health-warning": "상태 경고", "raid-error.missing-ssd-multiple": "{{count}}개의 SSD가 응답하지 않습니다.", "raid-error.missing-ssd-one": "SSD 1개가 응답하지 않습니다.", "raid-error.shutdown-dialog.description": "Umbrel Pro의 전원을 끄고 모든 SSD가 슬롯에 제대로 장착되어 있는지 확인한 뒤 전원을 다시 켜세요.", "raid-error.shutdown-dialog.title": "드라이브를 확인하려면 전원을 끌까요?", "raid-error.ssd-in-slot": "{{size}} SSD 1개가 슬롯 {{slot}}에 있습니다.", "raid-error.step-check-connections.button": "전원 끄기", "raid-error.step-check-connections.description": "전원을 끄고 모든 SSD가 제대로 장착되어 있는지 확인하세요.", "raid-error.step-check-connections.title": "SSD 연결 확인", "raid-error.step-factory-reset.button": "공장 초기화", "raid-error.step-factory-reset.description": "다른 방법이 모두 실패했을 때의 마지막 수단입니다. 이 작업은 모든 데이터를 지웁니다.", "raid-error.step-factory-reset.title": "공장 초기화", "raid-error.step-restart.button": "다시 시작", "raid-error.step-restart.description": "자주 도움이 되는 간단한 첫 단계입니다.", "raid-error.step-restart.title": "다시 시작해 보기", "raid-error.title": "스토리지 문제 감지", "read-less": "간단히 보기", "read-more": "자세히 보기", "reconnect": "다시 연결", "redirect.to-home": "불러오는 중...", "redirect.to-login": "불러오는 중...", "redirect.to-onboarding": "불러오는 중...", "redirect.to-raid-error": "로딩 중...", "reload": "새로고침", "remote-tor-access": "원격 Tor 액세스", "reset": "초기화", "restart": "다시 시작", "restart.confirm.submit": "다시 시작", "restart.confirm.title": "Umbrel을(를) 다시 시작하시겠어요?", "restart.restarting": "다시 시작 중...", "restart.restarting-message": "재시작 중에는 이 페이지를 새로고침하거나 Umbrel 전원을 끄지 마세요.", "rewind": "Rewind", "rewind.files-as-of": "기준 시점의 파일", "rewind.loading-snapshots": "스냅샷을 불러오는 중...", "rewind.now": "지금", "rewind.preflight.description": "과거 백업에서 파일과 폴더를 찾아 현재로 복원하세요.", "rewind.preflight.enable-backups": "Rewind를 사용하려면 설정에서 Backups를 설정하세요", "rewind.restore-complete": "복원 완료", "rewind.restore-error-description": "다시 시도해 주세요.", "rewind.restore-failed": "복원 실패", "rewind.restore-running-description": "복원이 완료될 때까지 이 페이지를 닫거나 새로고침하지 마세요", "rewind.restore-selected": "선택 항목 복원", "rewind.restore-success-description": "파일이 복원되었습니다", "rewind.restoring": "복원 중", "rewind.snapshots-count_one": "{{count}}개의 백업 이후", "rewind.snapshots-count_other": "{{count}}개의 백업 이후", "search": "검색", "settings": "설정", "settings.app-store-preferences.title": "App Store 환경설정", "settings.contact-support": "도움이 필요하신가요? 지원 문의", "settings.file-sharing": "파일 공유", "settings.file-sharing.add-folder": "추가", "settings.file-sharing.add-folder-title": "공유할 폴더 선택", "settings.file-sharing.choice-entire-description": "Umbrel의 모든 파일을 공유합니다.", "settings.file-sharing.choice-entire-title": "전체", "settings.file-sharing.choice-heading": "무엇을 공유하시겠어요?", "settings.file-sharing.choice-specific-description": "공유할 폴더를 선택하세요.", "settings.file-sharing.choice-specific-title": "특정 폴더", "settings.file-sharing.choice-subtitle": "컴퓨터나 휴대폰에서 Dropbox처럼 네트워크 폴더(SMB)로 파일과 폴더에 접근하세요.", "settings.file-sharing.configure": "구성", "settings.file-sharing.description": "다른 기기에서 네트워크 폴더(SMB)로 Dropbox처럼 파일에 접근하세요.", "settings.file-sharing.home-shared-note": "전체 \"{{homeDirectoryName}}\" 폴더가 공유되어 있습니다. 개별 폴더를 따로 공유할 필요가 없습니다.", "settings.file-sharing.share-entire-home-dir": "Home 폴더 전체 공유", "settings.file-sharing.share-entire-home-dir-description": "네트워크에 연결된 다른 기기에서 \"{{homeDirectoryName}}\"의 모든 파일과 폴더에 접근할 수 있습니다.", "settings.file-sharing.shared-folders": "공유 폴더", "show-details": "세부 정보 표시", "shut-down": "종료", "shut-down.complete": "종료 완료", "shut-down.complete-text": "이제 디바이스 전원을 분리해도 좋습니다.", "shut-down.confirm.submit": "종료", "shut-down.confirm.title": "정말 Umbrel을 종료하시겠어요?", "shut-down.failed": "시스템 종료에 실패했습니다: {{message}}", "shut-down.shutting-down": "종료 중...", "shut-down.shutting-down-message": "종료 중에는 이 페이지를 새로고침하거나 Umbrel 전원을 끄지 마세요.", "software-update.callout": "업데이트 중에는 이 페이지를 새로고침하거나 Umbrel 전원을 끄지 마세요.", "software-update.check": "업데이트 확인", "software-update.checking": "업데이트 확인 중...", "software-update.current-running": "현재 버전:", "software-update.failed": "업데이트에 실패했습니다", "software-update.failed-to-check": "업데이트 확인에 실패했습니다", "software-update.failed.retry": "다시 시도", "software-update.install-now": "지금 설치", "software-update.new-version": "새로운 {{name}}을(를) 설치할 수 있습니다", "software-update.on-latest": "최신 umbrelOS를 사용 중입니다", "software-update.see-whats-new": "자세히 보기 새로운 기능", "software-update.title": "소프트웨어 업데이트", "software-update.updating-to": "{{name}}으로 업데이트 중...", "software-update.view": "보기", "something-left": "{{left}} 남음", "something-went-wrong": "⚠ 문제가 발생했어요", "start": "시작", "stop": "중지", "storage": "저장 공간", "storage-manager": "저장소 관리자", "storage-manager.add": "추가", "storage-manager.add-to-raid.add-ssd": "SSD 추가", "storage-manager.add-to-raid.available": "사용 가능:", "storage-manager.add-to-raid.description": "새 SSD가 감지되었으며 추가할 준비가 되었습니다.", "storage-manager.add-to-raid.enable-failsafe": "FailSafe 활성화", "storage-manager.add-to-raid.failed-add": "SSD를 추가할 수 없습니다.", "storage-manager.add-to-raid.failed-enable-failsafe": "FailSafe를 활성화할 수 없습니다.", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "새 {{size}} SSD가 사용 가능한 저장공간에 추가됩니다.", "storage-manager.add-to-raid.info-capacity-adds-available": "새 {{size}} SSD가 {{available}}의 사용 가능한 저장공간을 추가합니다.", "storage-manager.add-to-raid.info-capacity-adds-both": "새 {{size}} SSD가 {{available}}의 사용 가능한 저장공간과 {{protection}}의 데이터 보호 용량을 추가합니다.", "storage-manager.add-to-raid.info-capacity-protection-only": "새 {{size}} SSD가 데이터 보호를 위해 {{protection}}를 추가합니다.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "새 {{size}} SSD는 데이터 보호 용도로 전부 사용됩니다.", "storage-manager.add-to-raid.info-data-safe": "SSD가 하나만 고장 나도 데이터는 안전합니다.", "storage-manager.add-to-raid.info-no-protection": "SSD가 고장나면 데이터가 손실될 수 있습니다.", "storage-manager.add-to-raid.info-total-wasted": "SSD 크기 차이로 인해 총 {{size}}가 사용 불가합니다.", "storage-manager.add-to-raid.info-wasted": "SSD 크기 차이로 인해 {{size}}가 사용 불가합니다.", "storage-manager.add-to-raid.recommended": "권장", "storage-manager.add-to-raid.recommended-inline": "(권장)", "storage-manager.add-to-raid.restart-active-tasks": "진행 중인 작업은 중단됩니다", "storage-manager.add-to-raid.restart-after": "재시작 후 FailSafe 설정이 자동으로 완료되며 정상 사용을 재개할 수 있습니다.", "storage-manager.add-to-raid.restart-during": "재시작 중:", "storage-manager.add-to-raid.restart-intro": "이 과정 동안 umbrelOS를 정상적으로 계속 사용할 수 있습니다. 다만 진행률이 50%에 도달하면 Umbrel이 자동으로 재시작합니다.", "storage-manager.add-to-raid.restart-required": "시스템 재시작 필요", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS에 일시적으로 접근할 수 없습니다.", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD가 슬롯 {{slot}}에 있습니다.", "storage-manager.add-to-raid.title": "스토리지에 SSD 추가", "storage-manager.add-to-raid.too-small": "SSD가 너무 작음", "storage-manager.add-to-raid.too-small-description": "이 SSD ({{deviceSize}})는 현재 설치된 가장 작은 SSD ({{minSize}})보다 작습니다. FailSafe는 모든 SSD가 사용 중인 가장 작은 SSD와 같거나 더 커야 합니다.", "storage-manager.add-to-raid.understand-continue": "이해했어요, 계속하기", "storage-manager.add-to-raid.warning-failsafe-now-only": "SSD가 둘 이상이면 FailSafe는 지금만 활성화할 수 있습니다. 나중에는 활성화할 수 없습니다.", "storage-manager.add-to-raid.wasted-label": "사용 불가:", "storage-manager.available-storage": "사용 가능 저장 공간", "storage-manager.description": "SSD의 저장공간, 상태 및 설정을 확인하세요.", "storage-manager.empty": "비어 있음", "storage-manager.failsafe-transition-failed": "FailSafe를 활성화할 수 없습니다.", "storage-manager.for-failsafe": "FailSafe용", "storage-manager.health.checksum-errors": "체크섬 오류: {{count}}", "storage-manager.health.critical": "심각", "storage-manager.health.critical-threshold": "심각 임계값", "storage-manager.health.current-temperature": "현재 온도", "storage-manager.health.estimated-life": "예상 남은 수명", "storage-manager.health.general": "일반", "storage-manager.health.health-status": "상태", "storage-manager.health.low": "낮음", "storage-manager.health.model-and-capacity": "모델 및 용량", "storage-manager.health.overheating": "과열", "storage-manager.health.raid-failed-advice": "이 SSD에 문제가 있습니다. Umbrel의 전원을 끄고 SSD 연결을 확인하세요. 문제가 계속되면 SSD를 교체해야 할 수 있습니다.", "storage-manager.health.read-errors": "읽기 오류: {{count}}", "storage-manager.health.serial-number": "일련번호", "storage-manager.health.status-healthy": "정상", "storage-manager.health.status-unhealthy": "비정상", "storage-manager.health.status-unknown": "알 수 없음", "storage-manager.health.temperature": "온도", "storage-manager.health.title": "SSD 상태", "storage-manager.health.warning-life-advice": "이 SSD를 곧 교체하는 것을 고려하세요.", "storage-manager.health.warning-life-message": "수명 {{percent}}%만 남음", "storage-manager.health.warning-temp-advice": "Umbrel Pro의 통풍이 잘 되는지, SSD가 제대로 장착되어 있는지 확인하세요.", "storage-manager.health.warning-temp-critical": "온도가 위험 수준입니다 ({{temperature}})", "storage-manager.health.warning-temp-overheating": "드라이브가 과열되고 있습니다 ({{temperature}})", "storage-manager.health.warning-threshold": "경고 임계값", "storage-manager.health.warning-unhealthy-advice": "이 SSD는 곧 고장날 수 있습니다. 교체를 고려하세요.", "storage-manager.health.warning-unhealthy-message": "이 SSD에 문제가 있을 수 있습니다.", "storage-manager.health.warnings": "경고", "storage-manager.health.wear": "마모", "storage-manager.health.write-errors": "쓰기 오류: {{count}}", "storage-manager.install-ssd.description": "저장공간을 확장하려면 SSD를 추가하세요.", "storage-manager.install-ssd.step-insert": "빈 슬롯에 새 SSD를 삽입하세요.", "storage-manager.install-ssd.step-power-on": "{{deviceName}}의 전원을 켜세요", "storage-manager.install-ssd.step-remove-bottom-cover": "자석식 하단 커버를 제거하세요.", "storage-manager.install-ssd.step-replace-bottom-cover": "하단 커버를 다시 끼워주세요.", "storage-manager.install-ssd.step-return": "여기로 돌아와 SSD를 스토리지에 추가하세요.", "storage-manager.install-ssd.step-shut-down": "{{deviceName}}의 전원을 끄세요", "storage-manager.install-ssd.title": "SSD 추가", "storage-manager.install-tips.image-alt": "SSD 설치 안내", "storage-manager.install-tips.instructions": "설치하려면 손나사를 빼고 SSD를 약간 각도로 슬롯에 밀어 넣으세요. SSD를 나사 기둥 위에 얹힌 뒤 손나사로 고정하세요.", "storage-manager.install-tips.toggle": "SSD를 어떻게 넣는지 기억이 안 나세요?", "storage-manager.manage": "관리", "storage-manager.missing-ssd-warning": "SSD가 없어 보입니다. Umbrel의 전원을 끄고 모든 SSD가 연결되어 있는지 확인하세요. 문제가 계속되면 SSD를 교체해야 할 수 있습니다.", "storage-manager.mode": "모드", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "SSD가 고장나더라도 데이터를 안전하게 지켜줍니다. SSD 크기가 다르면 큰 쪽의 남는 공간은 사용되지 않습니다.", "storage-manager.mode.failsafe.info-description": "FailSafe는 SSD들에 데이터를 복제하여 보호합니다. SSD 하나가 고장나더라도 데이터는 안전하며 교체 SSD를 추가하면 복구할 수 있습니다.", "storage-manager.mode.failsafe.info-title": "FailSafe에 대해", "storage-manager.mode.full-storage": "Full Storage", "storage-manager.mode.full-storage.description": "모든 SSD 용량을 하나로 합쳐 사용합니다. SSD가 고장나면 데이터가 손실될 수 있습니다.", "storage-manager.mode.full-storage.info-description": "Full Storage는 모든 SSD를 하나의 큰 저장공간으로 결합하여 최대 용량을 제공합니다. 하지만 SSD 하나라도 고장나면 모든 데이터가 손실됩니다.", "storage-manager.mode.full-storage.info-title": "Full Storage에 대해", "storage-manager.mode.switch-from-failsafe-unavailable": "FailSafe에서 Full Storage 모드로 전환하려면 데이터를 백업하고 기기를 공장 초기화한 뒤 백업에서 복원해야 합니다.", "storage-manager.mode.switch-to-failsafe-unavailable": "Full Storage 모드에서 SSD가 여러 개이면 데이터가 모든 드라이브에 분산됩니다. FailSafe로 전환하려면 데이터를 백업하고 공장 초기화한 뒤 복원해야 합니다.", "storage-manager.mode.why-cant-switch": "왜 전환할 수 없나요?", "storage-manager.operation-in-progress.shutdown-description": "지금 종료해도 안전해요. 작업은 일시 중지되었다가 재시작 후에 다시 진행되지만, 다른 변경을 하려면 작업이 완료되어야 해요.", "storage-manager.operation-in-progress.shutdown-title": "저장소가 업데이트되고 있어요", "storage-manager.operation-in-progress.wait-description": "다른 변경을 하기 전에 현재 작업이 완료될 때까지 기다려 주세요.", "storage-manager.operation-in-progress.wait-title": "저장소가 업데이트되고 있어요", "storage-manager.operation.adding-ssd": "SSD 추가 중...", "storage-manager.operation.enabling-failsafe": "FailSafe 활성화 중...", "storage-manager.operation.expanding": "저장소 확장 중...", "storage-manager.operation.rebuilding": "데이터 재구성 중...", "storage-manager.operation.replacing": "드라이브 교체 중...", "storage-manager.operation.restarting": "재시작 중...", "storage-manager.operation.starting": "시작 중...", "storage-manager.operation.syncing-restarts": "데이터 동기화 중 • 50%에서 재시작됩니다", "storage-manager.raid-status.degraded": "저하됨", "storage-manager.raid-status.failed": "고장", "storage-manager.raid-status.offline": "오프라인", "storage-manager.raid-status.online": "온라인", "storage-manager.raid-status.removed": "제거됨", "storage-manager.raid-status.unavailable": "사용 불가", "storage-manager.replace": "교체", "storage-manager.replace-failed.degraded": "FailSafe 보호 수준이 저하되었습니다", "storage-manager.replace-failed.degraded-description": "FailSafe 저장소에서 SSD가 하나 없습니다. 교체하면 보호가 다시 완전히 복원됩니다.", "storage-manager.replace-failed.description": "이 SSD를 사용해 FailSafe 보호를 복원하세요.", "storage-manager.replace-failed.error": "교체를 시작할 수 없습니다.", "storage-manager.replace-failed.replace-now": "지금 교체", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD — 슬롯 {{slot}}", "storage-manager.replace-failed.step-protected": "완료되면 데이터는 다시 완전히 보호됩니다.", "storage-manager.replace-failed.step-rebuild": "데이터가 새 SSD에 재구축됩니다.", "storage-manager.replace-failed.step-time": "데이터 양에 따라 시간이 오래 걸릴 수 있습니다.", "storage-manager.replace-failed.title": "SSD 교체", "storage-manager.replace-failed.too-small": "SSD 용량 부족", "storage-manager.replace-failed.too-small-description": "이 SSD ({{deviceSize}})는 FailSafe 저장소에 필요한 최소 용량 ({{minSize}})보다 작습니다.", "storage-manager.replace-failed.what-happens": "다음에 일어날 일:", "storage-manager.ssd-failing": "문제 있음", "storage-manager.swap": "교체", "storage-manager.swap.data-erased-description": "Full Storage 모드는 데이터 보호가 없습니다. 공장 초기화하는 동안 {{deviceName}}의 모든 데이터가 삭제됩니다. 먼저 반드시 모든 데이터를 백업하세요.", "storage-manager.swap.data-protected": "데이터가 보호됩니다", "storage-manager.swap.data-protected-description": "FailSafe가 활성화되어 있으면 단일 SSD를 교체해도 데이터가 손실되지 않습니다. 백업이 필요 없습니다.", "storage-manager.swap.data-will-be-erased": "데이터가 삭제됩니다", "storage-manager.swap.description-failsafe": "FailSafe 스토리지에서 드라이브를 교체하세요.", "storage-manager.swap.description-full-storage": "Full Storage 구성에서 드라이브를 교체하세요.", "storage-manager.swap.description-no-free-slot": "Full Storage 모드에서 모든 슬롯이 사용 중이면 SSD 교체는 전체 백업 및 복원 과정이 필요합니다.", "storage-manager.swap.description-replace": "데이터를 새 SSD로 옮긴 다음 기존 SSD를 제거하세요.", "storage-manager.swap.failed-to-start": "교체를 시작할 수 없습니다.", "storage-manager.swap.no-data-loss": "데이터 손실 없음", "storage-manager.swap.no-data-loss-description": "데이터가 새 SSD로 복사됩니다. 완료되면 기존 SSD를 안전하게 제거할 수 있습니다.", "storage-manager.swap.safe-swap-available": "안전 교체 가능", "storage-manager.swap.safe-swap-description": "빈 슬롯이 있으므로 먼저 새 SSD를 추가하고 데이터를 이전한 뒤 기존 SSD를 제거할 수 있습니다. 백업 불필요.", "storage-manager.swap.select-new-ssd": "사용할 새 SSD를 선택하세요:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD가 슬롯 {{slot}}에 있습니다", "storage-manager.swap.step-backup": "데이터 백업하기", "storage-manager.swap.step-backup-description": "설정 → Backups로 이동해 모든 데이터의 백업을 생성하세요.", "storage-manager.swap.step-data-copied": "데이터가 기존 SSD에서 새 SSD로 복사됩니다", "storage-manager.swap.step-factory-reset": "공장 초기화", "storage-manager.swap.step-factory-reset-description": "설정 → Advanced → Factory Reset으로 이동해 {{deviceName}}를 초기화하세요.", "storage-manager.swap.step-insert-new-ssd": "새 SSD를 빈 슬롯에 삽입하세요", "storage-manager.swap.step-may-take-while": "데이터 양에 따라 시간이 걸릴 수 있습니다.", "storage-manager.swap.step-power-on": "{{deviceName}}의 전원을 켜세요", "storage-manager.swap.step-remove-bottom-cover": "자석식 하단 커버를 제거하세요.", "storage-manager.swap.step-remove-old": "완료되면 전원을 끄고 {{ssd}}를 제거하세요", "storage-manager.swap.step-replace-bottom-cover": "하단 커버를 다시 장착하세요.", "storage-manager.swap.step-restore": "데이터 복원하기", "storage-manager.swap.step-restore-description": "설정 → Backups로 이동해 백업에서 복원하세요.", "storage-manager.swap.step-return-to-storage-manager": "여기로 돌아와 Storage Manager에서 교체를 확인하고 새 SSD를 스토리지에 추가하세요.", "storage-manager.swap.step-return-to-swap": "여기로 돌아와 Storage Manager에서 \"Swap\"을 다시 클릭해 교체를 시작하세요.", "storage-manager.swap.step-setup-new-storage": "새 스토리지 설정", "storage-manager.swap.step-setup-new-storage-description": "{{deviceName}}의 전원을 켜고 새 SSD로 설정 과정을 완료하세요.", "storage-manager.swap.step-shut-down": "{{deviceName}}의 전원을 끄세요", "storage-manager.swap.step-shut-down-and-swap": "전원을 끄고 {{ssd}}를 교체하세요", "storage-manager.swap.step-shut-down-and-swap-description-other": "전원을 끄고 기기를 열어 SSD를 교체한 다음 다시 조립하세요.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "전원을 끄고 하단 커버를 제거한 다음 SSD를 교체하고 커버를 닫으세요.", "storage-manager.swap.step-swap-ssd": "{{ssd}}를 같은 용량의 새 SSD로 교체하세요.", "storage-manager.swap.too-small": "너무 작음 (필요: {{size}})", "storage-manager.swap.what-happens-next": "다음에 일어나는 일:", "storage-manager.total-capacity-added": "추가된 총 용량", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "사용 중", "storage-manager.wasted": "사용 불가", "storage-manager.wasted-size": "{{size}} 사용 불가", "storage.full": "저장 공간 가득 참", "storage.low": "저장 공간 부족", "temperature": "온도", "temperature.dangerously-hot": "매우 뜨거움", "temperature.nice": "양호", "temperature.normal": "정상", "temperature.too-hot-suggestion": "디바이스 주위 환경을 바꿔보세요.", "temperature.warm": "따뜻함", "terminal": "터미널", "terminal-description": "umbrelOS나 앱 내에서 직접 명령어를 실행해보세요", "terminal.app": "앱", "terminal.app-description": "특정 앱 내에서 직접 명령어를 실행", "terminal.umbrelos-description": "umbrelOS에서 직접 명령어를 실행", "tor-description": "Tor 브라우저를 사용해 어디서든 Umbrel에 접속할 수 있어요", "tor-enabled-description": "다음 URL에서 Tor 브라우저를 사용해 어디서든 Umbrel에 접속할 수 있어요:", "tor-error": "Tor 설정 업데이트에 실패했습니다: {{message}}", "tor.disable.description": "몇 분 정도 걸릴 수 있습니다", "tor.disable.progress": "원격 Tor 접속 비활성화 중", "tor.enable.description": "몇 분 정도 걸릴 수 있습니다", "tor.enable.mobile.switch-label": "원격 Tor 액세스 활성화", "tor.hidden-service": "Tor hidden service URL", "troubleshoot": "문제 해결", "troubleshoot-description": "umbrelOS 또는 앱 문제를 해결해보세요", "troubleshoot-no-logs-yet": "아직 로그가 없습니다", "troubleshoot-pick-title": "문제 해결", "troubleshoot.app": "앱", "troubleshoot.app-description": "Umbrel에 설치된 앱의 로그를 확인", "troubleshoot.app-download": "{{app}} 로그 다운로드", "troubleshoot.share-with-umbrel-support": "Umbrel Support와 공유", "troubleshoot.system-download": "{{label}} 다운로드", "troubleshoot.umbrelos-description": "umbrelOS 로그 보기", "troubleshoot.umbrelos-logs": "umbrelOS 로그", "trpc.backend-unavailable": "오류: 시스템 API 연결 실패", "trpc.checking-backend": "불러오는 중...", "try-again": "다시 시도", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "알 수 없음", "unknown-app": "알 수 없는 앱", "unknown-error": "알 수 없는 오류", "uptime": "가동 시간", "url": "URL", "wallpaper": "배경화면", "wallpaper-description": "Umbrel 배경화면과 테마", "whats-new.continue": "계속", "whats-new.feature-1.description": "전체 Umbrel의 자동 암호화 Backups를 외장 USB 드라이브, NAS 또는 다른 Umbrel에 설정하세요.", "whats-new.feature-2.description": "이전 Backups에서 특정 파일과 폴더를 골라 복구할 수 있어요.", "whats-new.feature-3.description": "또는 모든 앱, 파일 및 데이터를 포함해 전체 Umbrel을 복원할 수 있어요.", "whats-new.feature-4.description": "NAS 또는 다른 Umbrel을 연결하면 Files에서 해당 저장소에 액세스할 수 있어요.", "whats-new.feature-4.title": "네트워크 장치", "whats-new.feature-5.description": "Umbrel Home 또는 Intel 또는 AMD 기반 장치에서 외장 USB 드라이브를 연결하고 Files에서 접근하세요.", "whats-new.feature-5.helper-text": "전력 문제 가능성 때문에 Raspberry Pi 장치에서는 지원되지 않아요.", "whats-new.feature-5.title": "외장 저장소", "whats-new.next": "다음", "whats-new.title": "{{version}}의 새로운 기능", "widget.progress.in-progress": "진행 중", "widgets.edit.select-up-to-3-widgets": "최대 3개의 위젯을 선택하세요", "widgets.install-an-app-before-using-widgets": "위젯으로 홈 화면을 꾸미려면 먼저 앱을 설치하세요.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "공개 네트워크는 안전하지 않을 수 있습니다", "wifi-connection-failed": "연결할 수 없습니다", "wifi-dangerous-change-confirmation-description": "Wi-Fi 네트워크를 변경하면 Umbrel과 연결이 끊길 수 있습니다. 다시 연결하려면 Umbrel과 접속 중인 디바이스가 동일한 네트워크에 있어야 합니다.", "wifi-dangerous-change-confirmation-title": "정말 Wi-Fi 네트워크를 변경하시겠어요?", "wifi-dangerous-disable-confirmation-description": "Wi-Fi를 비활성화하면 Umbrel과 연결이 끊길 수 있습니다. 다시 연결하려면 Umbrel에 Ethernet 케이블을 연결하고 Umbrel과 접속 중인 디바이스가 동일한 네트워크에 있는지 확인하세요.", "wifi-dangerous-disable-confirmation-title": "정말 Wi-Fi를 비활성화하시겠어요?", "wifi-description": "디바이스를 Wi-Fi 네트워크에 연결하세요", "wifi-description-long": "이더넷 케이블을 제거해도 디바이스는 선택한 Wi-Fi 네트워크에 연결된 상태를 유지하며, 부팅 시 자동으로 다시 Wi-Fi에 연결됩니다.", "wifi-no-networks-message": "Wi-Fi 네트워크를 찾을 수 없습니다", "wifi-searching": "Wi-Fi 네트워크 검색 중...", "wifi-unsupported-device-description": "이 디바이스는 Wi-Fi를 지원하지 않습니다. 무선 어댑터가 없거나 호환되지 않을 수 있습니다.", "wifi-view-networks": "네트워크 보기" } ================================================ FILE: packages/ui/public/locales/nl.json ================================================ { "2fa": "2FA", "2fa-description": "Een tweede beveiligingslaag voor je Umbrel login en apps", "2fa.disable.title": "Twee-factor authenticatie uitschakelen", "2fa.enable.or-paste": "Of plak de volgende code in je authenticator-app", "2fa.enable.scan-this": "Scan deze QR-code met een authenticator-app zoals Google Authenticator of Authy", "2fa.enable.title": "Twee-factor authenticatie inschakelen", "2fa.enter-code": "Voer de code in die wordt weergegeven in je authenticator-app", "account": "Account", "account-description": "Je naam en wachtwoord", "advanced-settings": "Geavanceerde instellingen", "advanced-settings-description": "Terminal, umbrelOS Beta Programma, Cloudflare DNS en meer", "app-not-found": "App niet gevonden: {{app}}", "app-only-over-tor": "{{app}} kan alleen via Tor worden gebruikt. Open deze app door je Umbrel in een Tor-browser te benaderen via je URL voor externe toegang (Instellingen > Geavanceerde instellingen > Tor-toegang op afstand).", "app-page.section.about": "Over", "app-page.section.credentials.title": "Standaard inloggegevens", "app-page.section.dependencies.n-alternatives": "Zie {{count}} alternatieven", "app-page.section.info.compatibility": "Compatibiliteit", "app-page.section.info.compatibility-compatible": "Compatibel", "app-page.section.info.compatibility-not-compatible": "Niet compatibel", "app-page.section.info.developer": "Ontwikkelaar", "app-page.section.info.source-code": "Broncode", "app-page.section.info.source-code.public": "Publiek", "app-page.section.info.submitted-by": "Ingediend door", "app-page.section.info.support": "Ondersteuning krijgen", "app-page.section.info.title": "Info", "app-page.section.info.version": "Versie", "app-page.section.recommendations.title": "Dit vind je misschien ook leuk", "app-page.section.release-notes.title": "Wat is nieuw", "app-page.section.release-notes.version": "Versie {{version}}", "app-page.section.requires": "Vereist", "app-picker.search": "Zoeken...", "app-picker.select-app": "Selecteer app...", "app-settings.connected-to": "{{appName}} is verbonden met deze apps", "app-settings.save-changes": "Wijzigingen opslaan", "app-settings.title": "Instellingen", "app-store.browse-category-apps": "Blader door {{category}} apps", "app-store.category.ai": "AI", "app-store.category.all": "Alle apps", "app-store.category.automation": "Huis & Automatisering", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Crypto", "app-store.category.developer": "Ontwikkelaarshulpmiddelen", "app-store.category.discover": "Ontdekken", "app-store.category.files": "Bestanden & Productiviteit", "app-store.category.finance": "Financiën", "app-store.category.media": "Media", "app-store.category.networking": "Netwerken", "app-store.category.social": "Sociaal", "app-store.description": "Je app-update instellingen", "app-store.discover.temporarily-unavailable-description": "Blader door de categorieën hierboven of zoek om apps te vinden", "app-store.discover.temporarily-unavailable-title": "Uitgelichte inhoud tijdelijk niet beschikbaar", "app-store.menu.community-app-stores": "Community App Stores", "app-store.search-apps": "Apps zoeken", "app-store.search.no-results": "Geen resultaten", "app-store.search.results-for": "Resultaten voor", "app-store.title": "App Store", "app-store.updates": "Updates", "app-updates.less": "minder", "app-updates.more": "meer", "app-updates.no-updates": "Alle apps zijn up-to-date!", "app-updates.update": "Update", "app-updates.update-all": "Alles updaten", "app-updates.updates-available-count_one": "{{count}} update beschikbaar", "app-updates.updates-available-count_other": "{{count}} updates beschikbaar", "app-updates.updating": "Updaten...", "app.install": "Installeren", "app.installed": "Geïnstalleerd", "app.installing": "Installeren", "app.offline": "Niet actief", "app.open": "Open", "app.optimized-for-umbrel-home": "Geoptimaliseerd voor Umbrel Home", "app.os-update-required.confirm": "Controleer op umbrelOS-update", "app.os-update-required.description": "{{appName}} vereist umbrelOS {{version}} of later", "app.os-update-required.title": "Update umbrelOS", "app.restarting": "Herstarten", "app.starting": "Starten", "app.stopping": "Stoppen", "app.uninstall.confirm.description": "Alle gegevens geassocieerd met {{app}} worden permanent verwijderd. Deze actie kan niet ongedaan worden gemaakt.", "app.uninstall.confirm.submit": "Deïnstalleren", "app.uninstall.confirm.title": "{{app}} deïnstalleren?", "app.uninstall.deps.used-by.description_one": "Deïnstalleer eerst {{firstAppToUninstall}} om {{app}} te deïnstalleren.", "app.uninstall.deps.used-by.description_other": "Deïnstalleer deze apps eerst om {{app}} te deïnstalleren.", "app.uninstall.deps.used-by.title": "{{app}} wordt gebruikt door", "app.uninstalling": "Verwijderen", "app.updating": "Updaten", "app.view": "Bekijk", "app_one": "app", "app_other": "apps", "apps.uninstall.failed-to-get-required-apps": "Kon vereiste apps niet ophalen", "apps.uninstalled-all.success": "Alle apps gedeïnstalleerd", "auth.checking-backend-for-user": "Laden...", "auth.failed-checking-if-user-logged-in": "Fout: Controle op inloggen mislukt", "auth.failed-to-check-if-user-exists": "Fout: Controle op bestaan mislukt", "back": "Terug", "backups": "Back-ups", "backups-configure": "Configureren", "backups-configure.add-backup-location": "Back-uplocatie toevoegen", "backups-configure.available": "Beschikbaar", "backups-configure.awaiting-next-backup": "Wacht op de volgende automatische back-up", "backups-configure.back-up-now": "Nu back-up maken", "backups-configure.backing-up-now": "Bezig met back-up...", "backups-configure.connected": "Verbonden", "backups-configure.connection": "Verbinding", "backups-configure.in-progress": "Bezig", "backups-configure.last-backup": "Laatste back-up", "backups-configure.locations": "Locaties", "backups-configure.no-backup-locations": "Voeg een back-uplocatie toe om je gegevens te back-uppen", "backups-configure.not-connected": "Niet verbonden", "backups-configure.path": "Pad", "backups-configure.remove-backup-location": "Back-uplocatie verwijderen", "backups-configure.remove-backup-location-confirmation": "Weet je het zeker?", "backups-configure.remove-backup-location-confirmation-description": "Hierdoor wordt '{{device}}' verwijderd uit je back-uplocaties. Bestaande back-ups op dit apparaat worden niet verwijderd, maar automatische back-ups stoppen.", "backups-configure.status": "Status", "backups-configure.total-backups": "Totaal Backups", "backups-configure.used": "Gebruikt", "backups-configure.view": "Bekijken", "backups-description": "Maak back-ups van je bestanden, apps en gegevens naar een andere Umbrel, NAS of externe schijf", "backups-error.backup-not-found": "De backup kon niet worden gevonden.", "backups-error.generic": "Er is iets misgegaan: {{details}}", "backups-error.in-progress": "Er is al een backup-proces bezig. Wacht tot het klaar is.", "backups-error.invalid-exclusion-path": "Alleen bestanden en mappen in je Home-map kunnen van backups worden uitgesloten.", "backups-error.invalid-password": "Het encryptiewachtwoord is onjuist.", "backups-error.invalid-path": "De geselecteerde locatie is niet geschikt voor backups.", "backups-error.mount-failed": "Kon geen toegang krijgen tot de backup-snapshot.", "backups-error.mount-timeout": "Kon geen toegang krijgen tot de backup-snapshot. Probeer het opnieuw of controleer of het apparaat goed is aangesloten.", "backups-error.not-enough-space": "Er is niet genoeg vrije ruimte op het backup-apparaat.", "backups-error.not-found": "De backup of backup-locatie kon niet worden gevonden.", "backups-error.repository-exists": "Er bestaat al een backup-locatie in deze map.", "backups-error.repository-not-found": "De backup-locatie kon niet worden gevonden.", "backups-exclusions.add": "Toevoegen", "backups-exclusions.app-paths-cannot-be-modified": "Deze bestanden/mappen worden door de app-ontwikkelaar ingesteld en kunnen niet worden gewijzigd:", "backups-exclusions.app-paths-explanation": "Deze app sluit de volgende data uit van back-ups. Deze paden bevatten meestal niet-essentiële items (zoals caches of logbestanden die opnieuw aangemaakt kunnen worden) of data die problemen kan veroorzaken bij het terugzetten (bijvoorbeeld verouderde app-statussen die conflicten of inconsistenties kunnen geven).", "backups-exclusions.auto-excluded": "Automatisch uitgesloten", "backups-exclusions.exclude-entire-app": "Hele app uitsluiten", "backups-exclusions.excluded-apps": "Uitgesloten apps", "backups-exclusions.files-and-folders": "Uitgesloten bestanden en mappen", "backups-exclusions.no-excluded-apps": "Geen uitgesloten apps", "backups-exclusions.no-excluded-files-or-folders": "Geen uitgesloten bestanden of mappen", "backups-exclusions.select-item-to-exclude": "Selecteer een item om uit te sluiten", "backups-exclusions.stop-excluding": "Niet meer uitsluiten", "backups-floating-island.backing-up": "Back-uppen...", "backups-floating-island.backing-up-to": "Back-uppen van je Umbrel...", "backups-restore": "Herstellen", "backups-restore-full": "Volledig herstel", "backups-restore-full-description": "Zet je hele Umbrel terug vanaf een back-up", "backups-restore-header": "Herstel je Umbrel", "backups-restore-pro.after-restore": "Na het terugzetten wordt je tijdelijke account vervangen door je geback-upte account en bijbehorende gegevens.", "backups-restore-pro.step1": "Rond de onboarding af door hieronder op \"Aan de slag\" te klikken. Dit wordt je tijdelijke account totdat je je geback-upte account hebt hersteld.", "backups-restore-pro.step2": "Zodra de installatie is voltooid, ga naar <0>Instellingen → Backups → Terugzetten", "backups-restore-pro.step3": "Volg de aanwijzingen in de Herstelassistent.", "backups-restore-pro.subtitle": "Het terugzetten van een backup op Umbrel Pro vereist een paar extra stappen", "backups-restore.backup-date": "Back-updatum", "backups-restore.backup-location": "Back-uplocatie", "backups-restore.browse-cloud-subtitle": "Herstel vanaf Umbrel Private Cloud (binnenkort beschikbaar)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Herstellen vanaf een externe USB-drive", "backups-restore.browse-external-title": "Externe schijf", "backups-restore.browse-nas-or-external": "Doorzoek een andere Umbrel, NAS of externe schijf om een back-up van te herstellen", "backups-restore.browse-nas-subtitle": "Herstel vanaf een andere Umbrel of NAS op je netwerk", "backups-restore.browse-nas-title": "Een andere Umbrel of NAS", "backups-restore.choose": "Kies", "backups-restore.choose-backup-location": "Kies een back-uplocatie", "backups-restore.connect-to-backup-location": "Verbinden met een back-uplocatie", "backups-restore.encryption-password": "Encryptiewachtwoord", "backups-restore.encryption-password-description": "Voer het wachtwoord voor encryptie in dat je hebt ingesteld toen je back-ups inschakelde", "backups-restore.enter-password-to-confirm": "Voer je Umbrel-wachtwoord in om te bevestigen", "backups-restore.final-confirmation": "Weet je het zeker?", "backups-restore.final-confirmation-description": "Het terugzetten van deze back-up zal je huidige umbrelOS-apps en -gegevens vervangen door de inhoud van de geselecteerde back-up. Alle bestanden, mappen of apps die uitgesloten zijn van deze back-up worden van je Umbrel verwijderd. Deze actie kan niet ongedaan worden gemaakt.", "backups-restore.invalid-password": "Ongeldig wachtwoord", "backups-restore.last-backup": "Laatste back-up: {{date}}", "backups-restore.latest": "Nieuwste", "backups-restore.no-backups-found": "Geen back-ups gevonden", "backups-restore.no-backups-yet": "Nog geen back-ups", "backups-restore.please-select-backup": "Selecteer een back-up", "backups-restore.please-select-repository": "Selecteer een repository", "backups-restore.restore-from-nas-or-external": "Herstel je Umbrel vanaf een back-up op een andere Umbrel, een NAS of een externe schijf", "backups-restore.restore-from-unlisted": "Terugzetten vanaf een andere locatie", "backups-restore.restore-umbrel": "Umbrel herstellen", "backups-restore.restore-warning": "Het terugzetten van deze back-up vervangt je huidige umbrelOS-apps en -gegevens door de inhoud van de geselecteerde back-up. Alle bestanden, mappen of apps die van deze back-up zijn uitgesloten, worden van je Umbrel verwijderd. Open <0>Rewind als je in plaats daarvan specifieke bestanden of mappen wilt terugzetten.", "backups-restore.restoring-from": "Je staat op het punt de volgende back-up terug te zetten:", "backups-restore.review-description": "Het herstellen zet je Umbrel terug naar het account, de bestanden, apps en instellingen die in deze back-up zaten. Dit kan even duren. Als het klaar is, wordt je inlogwachtwoord ingesteld op het wachtwoord dat je gebruikte toen je de back-up maakte.", "backups-restore.select-backup": "Selecteer een back-up", "backups-restore.select-backup-description": "Selecteer de back-up die je wilt terugzetten", "backups-restore.select-backup-file": "Selecteer je back-upbestand", "backups-restore.select-backup-file-only": "Je kunt alleen {{backupFileName}} selecteren.", "backups-restore.total-size": "Totale grootte", "backups-restore.unknown-date": "Onbekende datum", "backups-restore.unknown-repository": "Onbekende repository", "backups-rewind": "Rewind", "backups-rewind-description": "Ga terug in de tijd om specifieke bestanden en mappen te herstellen", "backups-rewind.start": "Start Rewind", "backups-setup": "Instellen", "backups-setup-confirm": "Instellen voltooien", "backups-setup-external-description": "Maak een back-up naar een externe USB-drive", "backups-setup-nas-or-umbrel-description": "Maak back-ups naar een andere Umbrel of een NAS op je netwerk", "backups-setup-umbrel-or-nas": "Een andere Umbrel of NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Vergroot je gemoedsrust buiten je huis met end-to-end versleutelde back-ups naar Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Vraag vroege toegang aan", "backups-setup-umbrel-private-cloud-description": "End-to-end versleutelde back-ups naar Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Komt binnenkort", "backups.add-umbrel-or-nas": "Voeg Umbrel of NAS toe", "backups.all-apps-and-data-will-be-backed-up": "Alle apps en gegevens worden geback-upt", "backups.apps-and-data": "Apps & gegevens", "backups.backup-location": "Back-uplocatie", "backups.browse": "Bladeren", "backups.choose-folder-within-device": "Kies een map binnen {{device}} om je back-ups op te slaan", "backups.confirm-password": "Bevestig wachtwoord", "backups.copy": "Kopiëren", "backups.encryption": "Encryptie", "backups.encryption-password-warning": "Zorg dat je encryptiewachtwoord veilig is opgeslagen, bijvoorbeeld in een wachtwoordmanager. Je kunt het niet opnieuw bekijken en je hebt het nodig om je back-ups te herstellen.", "backups.exclude-from-backups": "Uitsluiten van back-ups", "backups.exclude-from-backups-description": "Sluit specifieke bestanden, mappen en apps uit van je back-ups.", "backups.hide": "Verbergen", "backups.i-understand": "Ik begrijp het", "backups.location": "Locatie", "backups.modals.already-in-use.description": "Deze back-uplocatie wordt al gebruikt voor Backups op deze Umbrel.", "backups.modals.already-in-use.manage": "Beheren in Backups", "backups.modals.already-in-use.title": "Back-uplocatie al in gebruik", "backups.modals.connect-existing.description": "Op deze locatie staat al een Umbrel-backup. Voer het versleutelingswachtwoord in om deze aan deze Umbrel toe te voegen.", "backups.modals.connect-existing.title": "Bestaande Umbrel-backup verbinden", "backups.no-external-drives-detected": "Geen externe schijven gedetecteerd", "backups.no-password-set": "Geen wachtwoord ingesteld", "backups.password-is-set": "Wachtwoord is ingesteld", "backups.password-minimum-length": "Wachtwoord moet minstens 8 tekens lang zijn", "backups.password-safety-warning": "Je back-ups worden met dit wachtwoord versleuteld. Bewaar het goed, je kunt het niet opnieuw bekijken en je hebt het nodig om je back-ups te herstellen.", "backups.passwords-do-not-match": "Wachtwoorden komen niet overeen", "backups.please-choose-folder": "Kies een map", "backups.restore-failed.message": "Er is een fout opgetreden tijdens het herstellen van je Umbrel. Je huidige apps en gegevens zijn niet gewijzigd.", "backups.restore-failed.retry": "Ga naar Herstel", "backups.restore-failed.title": "Herstel mislukt", "backups.restoring": "Je Umbrel wordt hersteld", "backups.restoring-completing": "Bezig met afronden. Je Umbrel wordt binnenkort opnieuw opgestart...", "backups.restoring-progress": "Hersteld {{percent}}%", "backups.restoring-time-remaining": "Nog {{time}}", "backups.restoring-warning": "Zet je Umbrel niet uit en ontkoppel je back-uplocatie niet tijdens het terugzetten", "backups.review": "Controleren en bevestigen", "backups.review-description": "Bekijk de details van je back-up en bevestig je keuze", "backups.scanning-for-external-drives": "Zoeken naar externe schijven...", "backups.schedule-description": "umbrelOS maakt elk uur automatisch een back-up van je gegevens. Het bewaart versleutelde uur-back-ups van de afgelopen 24 uur, dagelijkse back-ups van de afgelopen week, wekelijkse back-ups van de afgelopen maand en maandelijkse back-ups van het afgelopen jaar. Back-ups ouder dan een jaar worden automatisch verwijderd.", "backups.select-backup-folder": "Selecteer back-upmap", "backups.select-backup-folder-description": "Kies een map waarin je je back-ups wilt opslaan.", "backups.select-backup-location": "Selecteer een back-uplocatie", "backups.set-encryption-password": "Stel encryptiewachtwoord in", "backups.set-encryption-password-description": "Beveilig je back-ups met een wachtwoord. Zo blijven je gegevens privé en kunnen ze alleen met dit wachtwoord hersteld worden.", "backups.show": "Tonen", "backups.storage-capacity-warning": "{{device}} moet vrije ruimte hebben van minimaal twee keer de grootte van je back-up", "backups.store-encryption-password-safely": "Bewaar je encryptiewachtwoord veilig", "beta-program": "umbrelOS Beta Programma", "beta-program-description": "Meld je aan om beta-updates van umbrelOS te ontvangen, krijg vroegtijdig toegang tot nieuwe functies en help ons deze te verfijnen door jouw feedback te geven. Beta-updates kunnen onstabiel zijn en het oplossen van problemen kan bekendheid met de terminal vereisen.", "cancel": "Annuleren", "change": "Veranderen", "change-name": "Naam wijzigen", "change-name.failed.name-required": "Naam is vereist", "change-name.input-placeholder": "Jouw naam", "change-password": "Wachtwoord wijzigen", "change-password.callout": "Als je je wachtwoord verliest, kun je niet inloggen op je Umbrel. Zorg ervoor dat je het veilig bewaart.", "change-password.current-password": "Huidig wachtwoord", "change-password.failed.current-required": "Huidig wachtwoord is vereist", "change-password.failed.min-length": "Wachtwoord moet minstens {{characters}} tekens lang zijn", "change-password.failed.must-be-unique": "Nieuw wachtwoord moet anders zijn dan het huidige wachtwoord", "change-password.failed.new-required": "Nieuw wachtwoord is vereist", "change-password.failed.no-match": "Wachtwoorden komen niet overeen", "change-password.failed.repeat-required": "Herhaal wachtwoord is vereist", "change-password.new-password": "Nieuw wachtwoord", "change-password.repeat-password": "Herhaal wachtwoord", "check-for-latest-version": "Controleer op de nieuwste update van umbrelOS", "clipboard.copied": "Gekopieerd", "close": "Sluiten", "cmdk.change-wallpaper": "Wijzig achtergrond", "cmdk.frequent-apps": "Veel gebruikt", "cmdk.input-placeholder": "Zoek naar apps, instellingen of acties", "cmdk.live-usage": "Live Usage", "cmdk.restart-umbrel": "Herstart Umbrel", "cmdk.shutdown-umbrel": "Umbrel afsluiten", "cmdk.update-all-apps": "Update alle apps", "cmdk.widgets": "Widgets", "community-app-store": "Community App Store", "community-app-store.add-error": "Kon de App Store niet toevoegen: {{message}}", "community-app-store.back-to-umbrel-app-store": "Terug naar Umbrel App Store", "community-app-store.open-button": "Open", "community-app-store.remove-button": "Verwijderen", "community-app-store.remove-error": "Kon de App Store niet verwijderen: {{message}}", "community-app-stores.add-button": "Toevoegen", "community-app-stores.description": "Community App Stores stellen je in staat om apps op je Umbrel te installeren die mogelijk niet beschikbaar zijn in de officiële Umbrel App Store. Ze maken het ook makkelijk om bètaversies van Umbrel-apps te testen voordat ontwikkelaars deze uitbrengen in de officiële Umbrel App Store.", "community-app-stores.learn-more": "Meer informatie", "community-app-stores.warning": "Community App Stores kunnen door iedereen worden gemaakt. De apps die erin worden gepubliceerd zijn niet geverifieerd of gecontroleerd door het officiële Umbrel App Store-team en kunnen mogelijk onveilig of kwaadaardig zijn. Wees voorzichtig en voeg alleen app-winkels toe van ontwikkelaars die je vertrouwt.", "confirm": "Bevestigen", "connect": "Verbinden", "connecting": "Verbinden...", "connection-lost": "Verbinding verloren", "connection-lost-description": "Dit kan gebeuren als je tabblad inactief was, je netwerkverbinding onderbroken werd of je apparaat offline staat.", "continue": "Doorgaan", "continue-to-log-in": "Ga verder om in te loggen", "cpu": "CPU", "cpu-core-count": "{{cores}} threads", "default-credentials.close": "Begrepen", "default-credentials.description": "Hier zijn de inloggegevens die je nodig hebt om in te loggen op de app.", "default-credentials.dont-show-again": "Niet meer tonen", "default-credentials.dont-show-again-notice": "Je kunt deze inloggegevens op elk moment in de toekomst inzien door met de rechtermuisknop op het app-pictogram te klikken.", "default-credentials.open": "Open {{app}}", "default-credentials.password": "Standaard wachtwoord", "default-credentials.title": "Inloggegevens voor {{app}}", "default-credentials.username": "Standaard gebruikersnaam", "desktop.app.context.go-to-store-page": "Bekijk in App Store", "desktop.app.context.settings": "Instellingen", "desktop.app.context.show-default-credentials": "Standaard inloggegevens tonen", "desktop.app.context.uninstall": "Deïnstalleren", "desktop.context-menu.change-wallpaper": "Achtergrond wijzigen", "desktop.context-menu.edit-widgets": "Widgets bewerken", "desktop.context-menu.logout": "Uitloggen", "desktop.greeting.afternoon": "Goedemiddag, {{name}}", "desktop.greeting.evening": "Goedenavond, {{name}}", "desktop.greeting.morning": "Goedemorgen, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Voor Viber", "desktop.install-first.for-the-bitcoiner": "Voor de Bitcoiner", "desktop.install-first.for-the-self-hoster": "Voor de zelf-hostende", "desktop.install-first.for-the-streamer": "Voor de streamer", "desktop.install-first.link-to-app-store": "Ontdek meer in App Store", "desktop.not-enough-room": "Gebruik een groter scherm om je apps te bekijken.", "device": "Apparaat", "device-info": "Apparaatinformatie", "device-info-description": "Informatie over je apparaat", "device-info.device": "Apparaat", "device-info.model-number": "Modelnummer", "device-info.serial-number": "Serienummer", "device-info.view-info": "Bekijk info", "device-name.home-or-pro": "Umbrel Home of Umbrel Pro", "disable": "Uitschakelen", "done": "Gereed", "download-logs": "Logbestanden downloaden", "enabling-tor": "Tor-toegang op afstand inschakelen", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS biedt betere netwerkbetrouwbaarheid. Uitschakelen om de DNS-instellingen van je router te gebruiken.", "external-dns-error": "Kon DNS-instelling niet bijwerken: {{message}}", "external-drive": "Externe schijf", "factory-reset": "Fabrieksinstellingen", "factory-reset-description": "Wis al je data en apps en herstel umbrelOS naar de standaardinstellingen", "factory-reset-failed": "Het terugzetten van je apparaat naar fabrieksinstellingen is mislukt: {{message}}", "factory-reset.confirm.body": "Bevestig je wachtwoord om te resetten", "factory-reset.confirm.ethernet-required-warning": "Zorg ervoor dat je apparaat is verbonden met je router via Ethernet (niet via Wi-Fi) en dat je er toegang toe hebt vanaf je lokale netwerk (bijv. http://umbrel.local of het lokale IP-adres van je apparaat).", "factory-reset.confirm.submit": "Alles wissen en resetten", "factory-reset.confirm.submit-callout": "Deze actie kan niet ongedaan worden gemaakt.", "factory-reset.rebooting.message": "Je apparaat wordt opnieuw opgestart en alle gegevens worden gewist. Sluit deze pagina niet.", "factory-reset.rebooting.status": "Bezig met resetten...", "factory-reset.rebooting.title": "Fabrieksreset wordt uitgevoerd", "factory-reset.review.account-info": "Accountinformatie en wachtwoord", "factory-reset.review.apps": "Apps", "factory-reset.review.following-will-be-removed": "Het volgende wordt verwijderd van je apparaat", "factory-reset.review.installed-apps_one": "{{count}} geïnstalleerde app", "factory-reset.review.installed-apps_other": "{{count}} geïnstalleerde apps", "factory-reset.review.submit": "Doorgaan", "factory-reset.review.total-data": "Totale data", "files": "Files", "files-action.add-favorite": "Toevoegen aan favorieten", "files-action.add-network-device": "Apparaat toevoegen", "files-action.cancel-upload": "Upload annuleren", "files-action.compress": "Comprimeren", "files-action.copy": "Kopiëren", "files-action.cut": "Knippen", "files-action.delete": "Permanent verwijderen", "files-action.download": "Downloaden", "files-action.download-items": "Download {{count}} onderdelen", "files-action.drop-to-upload": "Sleep hierheen om te uploaden", "files-action.eject-disk": "Uitwerpen", "files-action.empty-trash": "Prullenmand legen", "files-action.format-drive": "Formatteren", "files-action.go-to-path": "Ga naar...", "files-action.new-folder": "Nieuwe map", "files-action.open": "Openen", "files-action.paste": "Plakken", "files-action.remove-favorite": "Verwijderen uit favorieten", "files-action.remove-network-host": "Netwerkschijf uitwerpen", "files-action.remove-network-share": "Netwerkshare uitwerpen", "files-action.rename": "Hernoemen", "files-action.restore": "Herstellen", "files-action.select": "Selecteren", "files-action.share": "Delen over het netwerk...", "files-action.sharing": "Bezig met delen...", "files-action.show-in-folder": "Toon in bovenliggende map", "files-action.trash": "Naar prullenmand", "files-action.uncompress": "Uitpakken", "files-action.upload": "Uploaden", "files-add-network-share.add-manually": "Handmatig toevoegen", "files-add-network-share.add-share": "Share toevoegen", "files-add-network-share.back": "Terug", "files-add-network-share.continue": "Doorgaan", "files-add-network-share.description": "Maak verbinding met een NAS of een andere gedeelde schijf op je netwerk om er in Bestanden toegang toe te krijgen.", "files-add-network-share.discovering": "Bezig met zoeken...", "files-add-network-share.enter-details-manually": "Voer servergegevens in", "files-add-network-share.host-label": "Serveradres", "files-add-network-share.host-required": "Serveradres is vereist", "files-add-network-share.manual-share-help": "Voer exact de naam in van de gedeelde map zoals die op je server staat", "files-add-network-share.no-shares-found": "Geen gedeelde mappen gevonden op deze server", "files-add-network-share.not-seeing-share": "Zie je je gedeelde map niet?", "files-add-network-share.password-label": "Wachtwoord", "files-add-network-share.password-required": "Wachtwoord is vereist", "files-add-network-share.retrieving-shares": "Shares ophalen...", "files-add-network-share.retry-discovery": "Netwerk opnieuw scannen", "files-add-network-share.select-share": "Selecteer een share om toe te voegen", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Share is vereist", "files-add-network-share.title": "Een netwerkshare toevoegen", "files-add-network-share.username-label": "Gebruikersnaam", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Gebruikersnaam is vereist", "files-audio-island.now-playing": "Nu aan het afspelen", "files-audio-island.pause": "Pauzeren", "files-audio-island.play": "Afspelen", "files-backend-error.base-directory-not-found": "De basismap kon niet gevonden worden", "files-backend-error.cant-find-root": "Kon het bestandspad niet verifiëren", "files-backend-error.destination-already-exists": "Er bestaat al een item met dezelfde naam op de bestemming", "files-backend-error.destination-not-exist": "De doelmap bestaat niet", "files-backend-error.does-not-exist": "Het bestand of de map bestaat niet", "files-backend-error.escapes-base": "Het pad bevindt zich buiten de toegestane map", "files-backend-error.invalid-base": "Het pad behoort niet tot een geldige map", "files-backend-error.invalid-filename": "De bestandsnaam is ongeldig", "files-backend-error.invalid-path": "Het bestandspad is ongeldig", "files-backend-error.mkdir-failed": "Het aanmaken van de map is mislukt", "files-backend-error.move-failed": "Het verplaatsen van het item is mislukt", "files-backend-error.not-enough-space": "Niet genoeg opslagruimte beschikbaar", "files-backend-error.operation-not-allowed": "Deze bewerking is niet toegestaan", "files-backend-error.parent-not-directory": "Het bovenliggende pad is geen map", "files-backend-error.parent-not-exist": "De bovenliggende map bestaat niet", "files-backend-error.path-not-absolute": "Het bestandspad is ongeldig", "files-backend-error.share-already-exists": "Deze map is al gedeeld", "files-backend-error.share-name-generation-failed": "Kon geen unieke naam voor de gedeelde map genereren", "files-backend-error.source-not-exists": "Het bronbestand of de map bestaat niet", "files-backend-error.subdir-of-self": "Een map kan niet in zichzelf worden verplaatst of gekopieerd", "files-backend-error.trash-meta-not-exists": "Kon de oorspronkelijke locatie van dit item niet vinden", "files-backend-error.unique-name-index-exceeded": "Kon geen unieke naam genereren. Er bestaan te veel items met vergelijkbare namen", "files-backend-error.upload-failed": "Upload mislukt", "files-collision.action.keep-both": "Beide behouden", "files-collision.action.replace": "Vervangen", "files-collision.action.skip": "Overslaan", "files-collision.destination.original-location": "de oorspronkelijke locatie", "files-collision.message": "Wil je het bestaande item vervangen of beide behouden?", "files-collision.title": "\"{{itemName}}\" bestaat al in {{destinationName}}", "files-download.confirm": "Downloaden", "files-download.description": "Bestanden kan dit bestandstype niet openen. Wil je het in plaats daarvan downloaden?", "files-download.title": "'{{name}}' downloaden?", "files-empty-trash.confirm": "Leeg", "files-empty-trash.description": "Weet je zeker dat je alle items in de prullenmand definitief wilt verwijderen? Je kunt dit niet ongedaan maken.", "files-empty-trash.title": "Prullenmand leegmaken?", "files-empty.directory": "Geen items in deze map", "files-empty.network": "Geen netwerkapparaten", "files-empty.network-host-offline": "Netwerkapparaat offline", "files-error.add-favorite": "Toevoegen aan favorieten mislukt: {{message}}", "files-error.add-share": "Delen van map mislukt: {{message}}", "files-error.compress": "Comprimeren mislukt: {{message}}", "files-error.copy": "Kopiëren mislukt: {{message}}", "files-error.create-folder": "Map aanmaken mislukt: {{message}}", "files-error.delete": "Verwijderen mislukt: {{message}}", "files-error.eject-disk": "Uitwerpen van schijf mislukt: {{message}}", "files-error.empty-trash": "Prullenbak legen mislukt: {{message}}", "files-error.extract": "Uitpakken mislukt: {{message}}", "files-error.folder-already-exists": "Er bestaat al een map met deze naam", "files-error.move": "Verplaatsen mislukt: {{message}}", "files-error.remove-favorite": "Verwijderen uit favorieten mislukt: {{message}}", "files-error.remove-share": "Verwijderen van gedeelde map mislukt: {{message}}", "files-error.rename": "Hernoemen mislukt: {{message}}", "files-error.restore": "Herstellen mislukt: {{message}}", "files-error.trash": "Verplaatsen naar prullenbak mislukt: {{message}}", "files-error.upload": "Upload mislukt: {{message}}", "files-error.upload-network-error": "Upload voor {{name}} mislukt: er is een netwerkfout opgetreden", "files-extension-change.confirm": "Doorgaan", "files-extension-change.description-add": "Weet je zeker dat je de extensie van '{{fileName}}' wilt wijzigen in '{{extension}}'? Dit kan ervoor zorgen dat het bestand onleesbaar wordt.", "files-extension-change.description-remove": "Weet je zeker dat je de extensie van '{{fileName}}' wilt verwijderen?", "files-extension-change.title-add": "Extensie wijzigen in '{{extension}}'?", "files-extension-change.title-remove": "Extensie verwijderen?", "files-external-storage.unsupported.description": "Je aangesloten externe schijf kan niet worden gebruikt op een Raspberry Pi vanwege stroomproblemen. Externe opslag is beschikbaar op Umbrel Home, Umbrel Pro en alle x86 (Intel or AMD) apparaten.", "files-external-storage.unsupported.description-general": "Externe opslag is niet beschikbaar op een Raspberry Pi vanwege stroomproblemen. Externe opslag is beschikbaar op Umbrel Home, Umbrel Pro en alle x86 (Intel of AMD) apparaten.", "files-external-storage.unsupported.title": "Externe opslag niet ondersteund", "files-folder": "Map", "files-format.confirm": "Formatteren", "files-format.description": "Formatteren verwijdert alle gegevens op {{driveName}}. Deze actie kan niet ongedaan worden gemaakt.", "files-format.description-unreadable": "umbrelOS kan de inhoud van {{driveName}} niet lezen. Je kunt de schijf formatteren om hem met umbrelOS te gebruiken.", "files-format.drive-label": "Naam", "files-format.error": "Formatteren van de schijf is mislukt", "files-format.exfat-description": "Maximale compatibiliteit met Windows, macOS en Linux", "files-format.ext4-description": "Betere prestaties met umbrelOS en Linux", "files-format.filesystem": "Bestandssysteem", "files-format.filesystem-label": "Formatteren als", "files-format.formatting": "Formatteren...", "files-format.title": "Schijf formatteren", "files-format.title-requires-format": "Formatteren vereist", "files-formatting-island.formatting": "Formatteren...", "files-formatting-island.formatting-drives": "Formatteren van {{count}} schijven", "files-listing.empty": "Geen items", "files-listing.error": "Er is een fout opgetreden", "files-listing.item-count-truncated": "{{formattedCount}}+ onderdelen", "files-listing.item-count_one": "{{formattedCount}} bestand", "files-listing.item-count_other": "{{formattedCount}} bestanden", "files-listing.loading": "Laden...", "files-listing.no-such-file": "Het bestand of de map bestaat niet", "files-listing.selected-count": "{{selectedCount}} van {{totalCount}} geselecteerd", "files-listing.selected-count-truncated": "{{selectedCount}} van de {{totalCount}}+ geselecteerd", "files-name-drawer.new-folder": "Nieuwe map", "files-name-drawer.new-folder-description": "Voer een naam in voor de nieuwe map.", "files-name-drawer.new-folder-input": "Mapnaam", "files-name-drawer.rename-file": "Bestand hernoemen", "files-name-drawer.rename-file-description": "Voer een nieuwe naam in voor dit bestand.", "files-name-drawer.rename-file-input": "Bestandsnaam", "files-name-drawer.rename-folder": "Map hernoemen", "files-name-drawer.rename-folder-description": "Voer een nieuwe naam in voor deze map.", "files-name-drawer.rename-folder-input": "Mapnaam", "files-network-storage-error.add-share": "Netwerkshare toevoegen mislukt: {{message}}", "files-network-storage-error.discover-servers": "Ontdekken van netwerkapparaten mislukt: {{message}}", "files-network-storage-error.discover-shares": "Ontdekking van netwerkshares mislukt: {{message}}", "files-network-storage-error.remove-share": "Verwijderen van netwerkshare mislukt: {{message}}", "files-operations-island.copying": "Kopiëren van \"{{from}}\" naar \"{{to}}\"", "files-operations-island.moving": "Verplaatsen van \"{{from}}\" naar \"{{to}}\"", "files-operations-island.restoring": "Herstellen van \"{{from}}\" naar \"{{to}}\"", "files-path.input-group": "Padinvoer", "files-path.input-label": "Huidig pad", "files-permanently-delete.confirm": "Definitief verwijderen", "files-permanently-delete.description-multiple": "Weet je zeker dat je deze {{count}} items definitief wilt verwijderen? Dit kan niet ongedaan worden gemaakt.", "files-permanently-delete.description-single": "Weet je zeker dat je \"{{fileName}}\" definitief wilt verwijderen? Dit kan niet ongedaan worden gemaakt.", "files-permanently-delete.title-multiple": "{{count}} items definitief verwijderen?", "files-permanently-delete.title-single": "Definitief verwijderen?", "files-search.default": "Zoek naar bestanden en mappen", "files-search.no-results": "Geen resultaten gevonden voor \"{{query}}\"", "files-search.placeholder": "Zoeken", "files-search.searching-label": "Zoeken in de Umbrel van {{name}}", "files-share.home-description": "Toegang tot alle bestanden in \"{{homeDirectoryName}}\" vanaf andere apparaten in je netwerk", "files-share.home-title": "\"{{homeDirectoryName}}\" delen over het netwerk", "files-share.instructions.how-to-access": "Hoe krijg je toegang", "files-share.instructions.ios.enter-password": "Voer {{password}} in als wachtwoord.", "files-share.instructions.ios.enter-server": "Voer {{smbUrl}} in als serveradres.", "files-share.instructions.ios.enter-username": "Voer {{username}} in als gebruikersnaam.", "files-share.instructions.ios.install-files": "Installeer de app \"Bestanden\" uit de App Store als deze nog niet is geïnstalleerd.", "files-share.instructions.ios.tap-connect": "Tik op \"Verbind\" om toegang te krijgen.", "files-share.instructions.ios.tap-dots": "Tik op de drie puntjes (...) rechtsboven en kies \"Verbind met server\".", "files-share.instructions.macos.click-connect": "Klik op \"Verbind\" om er toegang toe te krijgen.", "files-share.instructions.macos.enter-password": "Voer {{password}} in als wachtwoord.", "files-share.instructions.macos.enter-url": "Voer {{smbUrl}} in en klik op \"Verbind\".", "files-share.instructions.macos.enter-username": "Voer {{username}} in als gebruikersnaam.", "files-share.instructions.macos.open-finder": "Open \"Finder\" en druk op ⌘ + K.", "files-share.instructions.macos.select-registered": "Selecteer \"Geregistreerde gebruiker\" wanneer daarom wordt gevraagd.", "files-share.instructions.macos.time-machine": "Hoe te gebruiken als Time Machine-backuplocatie", "files-share.instructions.macos.time-machine.choose-encryption": "Kies tussen een gecodeerde of niet-gecodeerde reservekopie.", "files-share.instructions.macos.time-machine.disk-limit": "Geef bij 'Disk Usage Limit' op hoeveel ruimte je op je Umbrel wilt gebruiken voor Time Machine-reservekopieën en klik vervolgens op \"Gereed\".", "files-share.instructions.macos.time-machine.follow-steps": "Volg de bovenstaande stappen en open Systeeminstellingen op je Mac.", "files-share.instructions.macos.time-machine.go-settings": "Ga naar Time Machine en klik op \"Voeg reservekopieschijf toe...\".", "files-share.instructions.macos.time-machine.select-disk": "Selecteer de map en klik op \"Set Up Disk...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Volg de stappen om je back-up in te stellen.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Volg bovenstaande stappen en ga daarna op je andere Umbrel naar \"{{settings}}\" > \"{{backups}}\".", "files-share.instructions.umbrelos.backup.select-add": "Selecteer de optie \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Selecteer dit Umbrel-apparaat in de lijst met verbonden apparaten.", "files-share.instructions.umbrelos.backup.title": "Hoe te gebruiken als backuplocatie voor je andere Umbrel", "files-share.instructions.umbrelos.cant-find-note": "Kun je het niet vinden? Probeer \"Handmatig toevoegen\" te selecteren en gebruik de volgende inloggegevens. Als je het nog steeds niet kunt toevoegen, controleer dan of beide apparaten op hetzelfde netwerk zitten.", "files-share.instructions.umbrelos.enter-password": "Vul {{password}} in als wachtwoord.", "files-share.instructions.umbrelos.enter-username": "Vul {{username}} in als gebruikersnaam.", "files-share.instructions.umbrelos.open-and-click": "Open op je andere Umbrel \"Files\" en klik op naast \" {{deviceLabel}}\" in de zijbalk.", "files-share.instructions.umbrelos.select-device": "Selecteer dit Umbrel-apparaat uit de lijst met automatisch gedetecteerde apparaten op je netwerk.", "files-share.instructions.umbrelos.select-sharename": "Selecteer \"{{sharename}}\" en klik om de gedeelde map toe te voegen.", "files-share.instructions.windows.enter-password": "Voer {{password}} in als wachtwoord.", "files-share.instructions.windows.enter-url": "Typ {{smbUrl}} en druk op Enter.", "files-share.instructions.windows.enter-username": "Voer {{username}} in als gebruikersnaam.", "files-share.instructions.windows.open-run": "Druk op Windows + R om het Uitvoeren-venster te openen.", "files-share.instructions.windows.remember-credentials": "Vink \"Remember my credentials\" aan en klik op OK.", "files-share.regular-description": "Deel deze map om er vanaf andere apparaten in je netwerk toegang toe te krijgen", "files-share.regular-title": "Map delen over het netwerk", "files-share.toggle": "\"{{name}}\" delen over je netwerk", "files-sidebar.apps": "Apps", "files-sidebar.external-storage": "Externe opslag", "files-sidebar.favorites": "Favorieten", "files-sidebar.home": "Thuismap", "files-sidebar.navigation": "Bestandsnavigatie", "files-sidebar.network": "Netwerk", "files-sidebar.network-pathbar": "Netwerkapparaten", "files-sidebar.network-sidebar": "Apparaten", "files-sidebar.recents": "Recente items", "files-sidebar.shared-folders": "Gedeelde mappen", "files-sidebar.trash": "Prullenmand", "files-sidebar.trash.open": "Openen", "files-sort.created": "Toegevoegd", "files-sort.modified": "Gewijzigd", "files-sort.name": "Naam", "files-sort.size": "Grootte", "files-sort.type": "Type", "files-state.uploading": "Uploaden...", "files-state.waiting": "Wachten...", "files-type.3gp": "3GP-video", "files-type.3gp2": "3GP2-video", "files-type.7z": "7Z-archief", "files-type.aac": "AAC-audio", "files-type.ai": "Illustrator-bestand", "files-type.aiff": "AIFF-audio", "files-type.au": "AU-audio", "files-type.avi": "AVI-video", "files-type.avif": "AVIF-afbeelding", "files-type.bmp": "BMP-afbeelding", "files-type.bzip2": "BZIP2-archief", "files-type.caf": "CAF-audio", "files-type.compressed": "Gecomprimeerd archief", "files-type.csv": "CSV-bestand", "files-type.directory": "Map", "files-type.dmg": "Schijfkopie", "files-type.dv": "DV-video", "files-type.epub": "EPUB-e-boek", "files-type.excel": "Excel-werkblad", "files-type.exe": "Windows-uitvoerbaar bestand", "files-type.executable": "Uitvoerbaar bestand", "files-type.external-drive": "Schijf", "files-type.flac": "FLAC-audio", "files-type.flv": "FLV-video", "files-type.gif": "GIF-afbeelding", "files-type.gzip": "GZIP-archief", "files-type.heic": "HEIC-afbeelding", "files-type.ico": "ICO-afbeelding", "files-type.iso": "ISO-schijfkopie", "files-type.jpeg": "JPEG-afbeelding", "files-type.keynote": "Keynote-presentatie", "files-type.lzip": "LZIP-archief", "files-type.lzma": "LZMA-archief", "files-type.lzop": "LZOP-archief", "files-type.m3u": "M3U-afspeellijst", "files-type.m4a": "M4A-audio", "files-type.m4v": "M4V-video", "files-type.midi": "MIDI-audio", "files-type.mka": "MKA-audio", "files-type.mkv": "MKV-video", "files-type.mng": "MNG-video", "files-type.mobi": "MOBI-e-boek", "files-type.mp3": "MP3-audio", "files-type.mp4": "MP4-video", "files-type.mp4-audio": "MP4-audio", "files-type.mpeg": "MPEG-video", "files-type.mpeg-ts": "MPEG-transportstream", "files-type.network-drive": "Netwerkschijf", "files-type.numbers": "Numbers-werkblad", "files-type.ogg": "OGG-audio", "files-type.ogv": "OGV-video", "files-type.pages": "Pages-document", "files-type.pdf": "PDF-document", "files-type.png": "PNG-afbeelding", "files-type.powerpoint": "PowerPoint-presentatie", "files-type.psd": "Photoshop-document", "files-type.quicktime": "QuickTime-video", "files-type.rar": "RAR-archief", "files-type.sgi": "SGI-video", "files-type.svg": "SVG-afbeelding", "files-type.tar": "TAR-archief", "files-type.tiff": "TIFF-afbeelding", "files-type.ts": "TS-video", "files-type.txt": "Tekstbestand", "files-type.umbrel-backup": "Umbrel Back-up", "files-type.wav": "WAV-audio", "files-type.webm": "WebM-video", "files-type.webm-audio": "WebM-audio", "files-type.webp": "WebP-afbeelding", "files-type.wma": "WMA-audio", "files-type.wmv": "WMV-video", "files-type.word": "Word-document", "files-type.xz": "XZ-archief", "files-type.zip": "ZIP-archief", "files-upload-island.uploading-count": "Bezig met uploaden van {{count}} items", "files-view.icons": "Pictogrammen", "files-view.list": "Lijst", "files-view.sort-by": "Sorteren op", "files-view.view-as": "Weergeven als", "files-widgets.favorites.no-items-text": "Voeg een map toe aan je favorieten om deze hier te zien", "files-widgets.recents.no-items-text": "Geen recente bestanden", "generic-in": "in", "hide-details": "Verberg details", "install-first.install-app": "Installeer {{app}}", "install-first.title": "{{app}} vereist deze apps", "install-your-first-app": "Installeer je eerste app", "language": "Taal", "language-description": "Je voorkeurstaal voor umbrelOS", "language.select-description": "Selecteer voorkeurstaal voor umbrelOS", "live-usage": "Live Usage", "loading": "Laden", "local-ip": "Lokale IP", "login-2fa.subtitle": "Voer de 2FA-code in die wordt weergegeven in je authenticator-app", "login-2fa.title": "Authenticeren", "login-with-umbrel.description": "Voer je Umbrel wachtwoord in om {{app}} te openen", "login-with-umbrel.title": "Inloggen met Umbrel", "login.password-label": "Wachtwoord", "login.password.submit": "Inloggen", "login.subtitle": "Voer je Umbrel wachtwoord in om in te loggen", "login.title": "Welkom terug", "logout": "Uitloggen", "logout-error-generic": "Fout: Uitloggen mislukt", "logout.confirm.submit": "Uitloggen", "logout.confirm.title": "Weet je zeker dat je wilt uitloggen?", "memory": "Geheugen", "memory.low": "Weinig geheugen", "migrate": "Migreren", "migrate.callout": "Zet je Umbrel niet uit tot de migratie voltooid is", "migrate.failed.retry": "Probeer opnieuw", "migrate.failed.title": "Migratie mislukt", "migrate.success.description": "Al je apps, app-gegevens en accountgegevens zijn gemigreerd naar je Umbrel Home.", "migrate.success.title": "Migratie succesvol", "migration-assistant": "Migratieassistent", "migration-assistant-description": "Verplaats al je apps en gegevens van een Raspberry Pi naar {{deviceName}}", "migration-assistant-unsupported-device-description": "Migration Assistant ondersteunt momenteel het overzetten van alle gegevens en apps van een Raspberry Pi met umbrelOS naar Umbrel Home of Umbrel Pro. Open Migration Assistant op je Umbrel Home of Umbrel Pro om te beginnen.", "migration-assistant.continue-migration.ready.submit": "Start migratie", "migration-assistant.failed": "Er klopt iets niet...", "migration-assistant.failed.retrying-message": "Opnieuw proberen...", "migration-assistant.mobile.start-button": "Start migratie", "migration-assistant.prep.body": "Voorbereiden voor migratie", "migration-assistant.prep.button-continue": "Doorgaan", "migration-assistant.prep.callout": "De gegevens op je {{deviceName}}, indien aanwezig, worden permanent verwijderd.", "migration-assistant.prep.connect-disk-to-home": "Sluit de externe schijf ervan aan op een willekeurige USB-poort van je {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Klik op '{{button}}' hieronder als je klaar bent.", "migration-assistant.prep.shut-down-rpi": "Zet je Raspberry Pi Umbrel uit.", "migration-assistant.ready.description": "Al je gegevens en apps zijn klaar om naar je {{deviceName}} overgezet te worden.", "migration-assistant.ready.hint-header": "Dingen om in gedachten te houden", "migration-assistant.ready.hint-keep-pi-off.description": "Dit helpt problemen met apps zoals Lightning Node te voorkomen", "migration-assistant.ready.hint-keep-pi-off.title": "Houd je Raspberry Pi uit na de update", "migration-assistant.ready.hint-use-same-password.description": "Vergeet niet het Umbrel-wachtwoord van je Raspberry Pi te gebruiken om in te loggen op je {{deviceName}}", "migration-assistant.ready.hint-use-same-password.title": "Gebruik hetzelfde wachtwoord", "migration-assistant.ready.title": "Je bent klaar voor migratie!", "mini-browser.default-title": "Map selecteren", "mini-browser.empty-external": "Sluit een externe schijf aan zodat deze hier verschijnt.", "mini-browser.empty-network": "Voeg een Umbrel of NAS toe zodat deze hier verschijnt.", "mini-browser.load-more": "Meer laden", "mini-browser.load-more-in-folder": "Meer laden in {{name}}", "mini-browser.loading-more": "Meer laden…", "mini-browser.select": "Selecteer", "mini-browser.select-folder": "Map selecteren", "name": "Naam", "nas": "NAS", "no-forgot-password-message": "Als je je wachtwoord verliest, kun je niet inloggen op je Umbrel. Zorg ervoor dat je het veilig bewaart.", "no-results-found": "Geen resultaten gevonden", "not-found-404": "Foutcode: 404", "not-found-404.back": "Terug", "not-found-404.home": "Ga naar Home", "notifications.backups-failing-location.description": "Automatische Backups naar {{location}} slagen niet. Controleer de verbinding en bekijk je Backups-instellingen.", "notifications.backups-failing.description": "Automatische Backups zijn mislukt. Controleer je Backups-locatie en bekijk je instellingen.", "notifications.backups-failing.go-to-backups": "Ga naar Backups", "notifications.backups-failing.title": "Geen Backups in de afgelopen 24 uur", "notifications.cpu.too-hot": "Hoge CPU-temperatuur", "notifications.memory.low": "Het geheugen van je apparaat is laag", "notifications.new-version-available": "{{update}} is nu beschikbaar om te installeren", "notifications.raid.issue.description": "Er is een opslagprobleem gedetecteerd. Kijk in Opslagbeheer voor details.", "notifications.raid.issue.title": "Dringende actie vereist", "notifications.ssd.health.description": "Een of meer SSD's hebben mogelijk aandacht nodig. Kijk in Opslagbeheer voor details.", "notifications.ssd.health.title": "Waarschuwing: SSD-gezondheid", "notifications.storage.full": "De opslag van je apparaat is vol", "notifications.view": "Bekijken", "ok": "Oké", "onboarding.account-created.by-clicking-button-you-agree": "Door op 'Volgende' te klikken, ga je akkoord met de umbrelOS Servicevoorwaarden", "onboarding.account-created.youre-all-set-name": "Je bent helemaal klaar, {{name}}.", "onboarding.contact-support": "Ondersteuning", "onboarding.create-account": "Account aanmaken", "onboarding.create-account.confirm-password.input-label": "Bevestig wachtwoord", "onboarding.create-account.failed.name-required": "Naam is vereist", "onboarding.create-account.failed.passwords-dont-match": "Wachtwoorden komen niet overeen", "onboarding.create-account.name.input-placeholder": "Jouw naam", "onboarding.create-account.password.input-label": "Wachtwoord", "onboarding.create-account.submit": "Aanmaken", "onboarding.create-account.submitting": "Wordt aangemaakt", "onboarding.create-account.subtitle": "Je accountgegevens worden alleen op je Umbrel opgeslagen. Zorg ervoor dat je je wachtwoord veilig back-upt, want er is geen manier om het te resetten.", "onboarding.create-instead-long": "Maak een nieuw account aan", "onboarding.create-instead-short": "Nieuw account", "onboarding.launch-umbrelos": "Start umbrelOS", "onboarding.raid.available-storage": "Beschikbare opslag", "onboarding.raid.change-drives-link": "Wil je schijven toevoegen of vervangen?", "onboarding.raid.configuring.subtitle": "Dit kan een paar minuten duren.", "onboarding.raid.configuring.title": "Je opslag configureren", "onboarding.raid.configuring.warning": "Ververs deze pagina niet en zet je Umbrel niet uit terwijl je opslag wordt geconfigureerd.", "onboarding.raid.continue": "Doorgaan", "onboarding.raid.error.detection-instructions": "Zet Umbrel Pro uit, controleer of je SSD's goed zijn geplaatst en probeer het opnieuw.", "onboarding.raid.error.no-ssds-detected": "Geen SSD's gevonden", "onboarding.raid.error.no-ssds-instructions": "Zet Umbrel Pro uit en plaats minstens één SSD om door te gaan.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Je kunt FailSafe nog niet inschakelen", "onboarding.raid.failsafe.enable": "FailSafe inschakelen", "onboarding.raid.failsafe.mixed-sizes": "FailSafe wordt beperkt door je kleinste SSD ({{smallest}}). Extra ruimte op grotere SSD's kan niet worden gebruikt, waardoor {{wasted}} niet bruikbaar is.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} wordt gebruikt voor gegevensbescherming. Voeg nog een {{smallest}} SSD toe om de beschikbare opslag te verhogen naar {{futureWith3}}, of voeg er twee extra toe voor {{futureWith4}}. Je kunt op elk moment meer SSD's toevoegen.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} wordt gebruikt voor gegevensbescherming. Voeg nog een {{smallest}} SSD toe om de beschikbare opslag te verhogen naar {{futureWith4}}. Je kunt op elk moment meer SSD's toevoegen.", "onboarding.raid.failsafe.single-ssd-info": "Je hebt maar één SSD. Voeg minstens één extra {{size}} SSD toe om FailSafe-bescherming voor je gegevens in te schakelen. Je kunt op elk moment meer SSD's toevoegen.", "onboarding.raid.failsafe.subtitle": "Je data blijft veilig als één SSD uitvalt", "onboarding.raid.failsafe.tip": "Gebruik SSD's van gelijke grootte voor maximale opslag en geen onbruikbare ruimte.", "onboarding.raid.failsafe.warning-now-only": "Bij meer dan één SSD kan FailSafe alleen tijdens de eerste installatie worden ingeschakeld. Je kunt het later niet meer inschakelen.", "onboarding.raid.health-warning": "Deze schijf meldt gezondheidsproblemen", "onboarding.raid.launching": "Starten...", "onboarding.raid.no-ssds-alt": "Geen SSD's gevonden", "onboarding.raid.recommended": "Aanbevolen", "onboarding.raid.scanning": "Je SSD-sleuven controleren", "onboarding.raid.scanning-alt": "SSD's scannen", "onboarding.raid.setup-failed.description-no-retry": "Zet Umbrel Pro uit en probeer het opnieuw.", "onboarding.raid.setup-failed.description-retry": "Probeer het opnieuw, of zet Umbrel Pro uit om je schijven te controleren.", "onboarding.raid.setup-failed.title": "Opslagconfiguratie mislukt", "onboarding.raid.shutdown-dialog.description": "Om schijven toe te voegen of te vervangen, zet Umbrel Pro uit. Zodra je klaar bent, kun je hem weer aanzetten en doorgaan met de installatie.", "onboarding.raid.shutdown-dialog.title": "Schijven wijzigen?", "onboarding.raid.ssd-in-slot": "Eén {{size}} SSD in Slot {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSD-lade", "onboarding.raid.ssds-found": "De volgende SSD's zijn gevonden in je Umbrel Pro", "onboarding.raid.storage": "Opslag", "onboarding.raid.storage-label": "Opslag", "onboarding.raid.success.storage-info": "Opslag {{available}}", "onboarding.raid.success.storage-info-failsafe": "Opslag {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Opnieuw proberen", "onboarding.raid.wasted": "Niet bruikbaar", "onboarding.restore-long": "Herstel mijn Umbrel", "onboarding.restore-short": "Herstellen", "onboarding.start.continue": "Aan de slag", "onboarding.start.subtitle": "Je thuis-cloudserver is klaar voor installatie.", "onboarding.start.title": "Welkom bij umbrelOS", "open": "Openen", "open-live-usage": "Open Live Usage", "password": "Wachtwoord", "preferences": "Voorkeuren", "raid-error.description": "Je opslag systeem kon niet goed starten. Controleer hieronder de status van je SSD's en volg de stappen voor probleemoplossing. Als het probleem blijft bestaan, moeten mogelijk de aangedane SSD's worden vervangen.", "raid-error.factory-reset-dialog.description": "Dit wist alle data op je Umbrel Pro en zet hem terug naar de fabrieksinstellingen. Deze actie kan niet ongedaan worden gemaakt.", "raid-error.factory-reset-dialog.title": "Fabrieksreset?", "raid-error.factory-reset-failed": "Kon de fabrieksreset niet uitvoeren", "raid-error.health-warning": "Gezondheidswaarschuwing", "raid-error.missing-ssd-multiple": "{{count}} SSD's reageren niet", "raid-error.missing-ssd-one": "1 SSD reageert niet", "raid-error.shutdown-dialog.description": "Schakel je Umbrel Pro uit, zorg dat alle SSD's goed in hun sleuven zitten en zet hem daarna weer aan.", "raid-error.shutdown-dialog.title": "Uitschakelen om schijven te controleren?", "raid-error.ssd-in-slot": "One {{size}} SSD in Slot {{slot}}", "raid-error.step-check-connections.button": "Uitschakelen", "raid-error.step-check-connections.description": "Schakel uit en controleer of alle SSD's goed zijn geplaatst.", "raid-error.step-check-connections.title": "Controleer SSD-verbindingen", "raid-error.step-factory-reset.button": "Fabrieksreset", "raid-error.step-factory-reset.description": "Laatste redmiddel als niets anders werkt. Dit zal alle gegevens wissen.", "raid-error.step-factory-reset.title": "Fabrieksreset", "raid-error.step-restart.button": "Opnieuw opstarten", "raid-error.step-restart.description": "Een snelle eerste stap die vaak helpt", "raid-error.step-restart.title": "Probeer opnieuw op te starten", "raid-error.title": "Opslagprobleem gedetecteerd", "read-less": "Lees minder", "read-more": "Lees meer", "reconnect": "Opnieuw verbinden", "redirect.to-home": "Laden...", "redirect.to-login": "Laden...", "redirect.to-onboarding": "Laden...", "redirect.to-raid-error": "Bezig met laden...", "reload": "Opnieuw laden", "remote-tor-access": "Toegang op afstand via Tor", "reset": "Reset", "restart": "Herstarten", "restart.confirm.submit": "Herstart", "restart.confirm.title": "Weet je zeker dat je je Umbrel opnieuw wilt opstarten?", "restart.restarting": "Opnieuw opstarten", "restart.restarting-message": "Vernieuw deze pagina niet of zet je Umbrel niet uit terwijl het opnieuw opstart.", "rewind": "Rewind", "rewind.files-as-of": "Je bestanden per", "rewind.loading-snapshots": "Snapshots laden...", "rewind.now": "Nu", "rewind.preflight.description": "Vind bestanden en mappen uit je eerdere back-ups en zet ze terug naar het heden.", "rewind.preflight.enable-backups": "Stel Back-ups in via Instellingen om Rewind te gebruiken", "rewind.restore-complete": "Herstel voltooid", "rewind.restore-error-description": "Probeer het opnieuw.", "rewind.restore-failed": "Herstel mislukt", "rewind.restore-running-description": "Sluit of ververs deze pagina niet totdat het herstel is voltooid", "rewind.restore-selected": "Geselecteerde items herstellen", "rewind.restore-success-description": "Je bestanden zijn hersteld", "rewind.restoring": "Bezig met herstellen", "rewind.snapshots-count_one": "{{count}} back-up sinds", "rewind.snapshots-count_other": "{{count}} back-ups sinds", "search": "Zoeken", "settings": "Instellingen", "settings.app-store-preferences.title": "App Store voorkeuren", "settings.contact-support": "Hulp nodig? Contact opnemen met ondersteuning.", "settings.file-sharing": "Bestandsdeling", "settings.file-sharing.add-folder": "Toevoegen", "settings.file-sharing.add-folder-title": "Selecteer een map om te delen", "settings.file-sharing.choice-entire-description": "Deel alle bestanden op je Umbrel", "settings.file-sharing.choice-entire-title": "Alles", "settings.file-sharing.choice-heading": "Wat wil je delen?", "settings.file-sharing.choice-specific-description": "Kies welke mappen je wilt delen", "settings.file-sharing.choice-specific-title": "Specifieke mappen", "settings.file-sharing.choice-subtitle": "Toegang tot je bestanden en mappen, net als in Dropbox, als netwerkmappen op je computer of telefoon", "settings.file-sharing.configure": "Instellen", "settings.file-sharing.description": "Toegang tot je bestanden, zoals in Dropbox, als netwerkmap (SMB) op andere apparaten", "settings.file-sharing.home-shared-note": "Je hele map \"{{homeDirectoryName}}\" is gedeeld. Individuele mappen hoeven niet apart gedeeld te worden.", "settings.file-sharing.share-entire-home-dir": "Deel je hele thuismap", "settings.file-sharing.share-entire-home-dir-description": "Toegang tot alle bestanden en mappen in \"{{homeDirectoryName}}\" vanaf andere apparaten op je netwerk", "settings.file-sharing.shared-folders": "Gedeelde mappen", "show-details": "Toon details", "shut-down": "Afsluiten", "shut-down.complete": "Afsluiten voltooid", "shut-down.complete-text": "Je kunt je apparaat nu loskoppelen van de stroom.", "shut-down.confirm.submit": "Afsluiten", "shut-down.confirm.title": "Weet je zeker dat je je Umbrel wilt afsluiten?", "shut-down.failed": "Afsluiten mislukt: {{message}}", "shut-down.shutting-down": "Afsluiten", "shut-down.shutting-down-message": "Vernieuw deze pagina niet of zet je Umbrel niet uit terwijl het afsluit.", "software-update.callout": "Vernieuw deze pagina niet of zet je Umbrel niet uit terwijl het aan het updaten is.", "software-update.check": "Controleer op update", "software-update.checking": "Controleren op updates...", "software-update.current-running": "Je gebruikt", "software-update.failed": "Update mislukt", "software-update.failed-to-check": "Kon niet controleren op updates", "software-update.failed.retry": "Opnieuw proberen", "software-update.install-now": "Nu installeren", "software-update.new-version": "Nieuwe versie {{name}} is beschikbaar om te installeren", "software-update.on-latest": "Je gebruikt de nieuwste versie van umbrelOS", "software-update.see-whats-new": "Bekijk wat er nieuw is", "software-update.title": "Software-update", "software-update.updating-to": "Update naar {{name}}", "software-update.view": "Bekijken", "something-left": "{{left}} over", "something-went-wrong": "⚠ Er ging iets mis", "start": "Starten", "stop": "Stoppen", "storage": "Opslag", "storage-manager": "Opslagbeheer", "storage-manager.add": "Toevoegen", "storage-manager.add-to-raid.add-ssd": "SSD toevoegen", "storage-manager.add-to-raid.available": "Beschikbaar:", "storage-manager.add-to-raid.description": "Er is een nieuwe SSD gedetecteerd en deze is klaar om toe te voegen.", "storage-manager.add-to-raid.enable-failsafe": "FailSafe inschakelen", "storage-manager.add-to-raid.failed-add": "Kon de SSD niet toevoegen", "storage-manager.add-to-raid.failed-enable-failsafe": "Kon FailSafe niet inschakelen", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Je nieuwe {{size}} SSD wordt toegevoegd aan de beschikbare opslag.", "storage-manager.add-to-raid.info-capacity-adds-available": "Je nieuwe {{size}} SSD voegt {{available}} toe aan de beschikbare opslag.", "storage-manager.add-to-raid.info-capacity-adds-both": "Je nieuwe {{size}} SSD voegt {{available}} toe aan de beschikbare opslag en {{protection}} voor gegevensbescherming.", "storage-manager.add-to-raid.info-capacity-protection-only": "Je nieuwe {{size}} SSD voegt {{protection}} toe voor gegevensbescherming.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Je nieuwe {{size}} SSD wordt volledig gebruikt voor gegevensbescherming.", "storage-manager.add-to-raid.info-data-safe": "Je gegevens zijn veilig als één SSD uitvalt.", "storage-manager.add-to-raid.info-no-protection": "Als een SSD uitvalt, kun je je gegevens kwijtraken.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} in totaal niet bruikbaar door verschillende SSD-groottes.", "storage-manager.add-to-raid.info-wasted": "{{size}} zal niet bruikbaar zijn vanwege verschillende SSD-groottes.", "storage-manager.add-to-raid.recommended": "Aanbevolen", "storage-manager.add-to-raid.recommended-inline": "(aanbevolen)", "storage-manager.add-to-raid.restart-active-tasks": "Eventuele actieve taken worden onderbroken", "storage-manager.add-to-raid.restart-after": "Na de herstart voltooit de FailSafe-configuratie automatisch en kun je de normale werking hervatten.", "storage-manager.add-to-raid.restart-during": "Tijdens de herstart:", "storage-manager.add-to-raid.restart-intro": "Je kunt umbrelOS normaal blijven gebruiken tijdens dit proces. Bij 50% voortgang start je Umbrel automatisch opnieuw op.", "storage-manager.add-to-raid.restart-required": "Systeemherstart vereist", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS is tijdelijk niet toegankelijk", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD in Slot {{slot}}", "storage-manager.add-to-raid.title": "SSD toevoegen aan opslag", "storage-manager.add-to-raid.too-small": "SSD te klein", "storage-manager.add-to-raid.too-small-description": "Deze SSD ({{deviceSize}}) is kleiner dan de kleinste momenteel geïnstalleerde SSD ({{minSize}}). FailSafe vereist dat alle SSD's minstens even groot zijn als de kleinste gebruikte SSD.", "storage-manager.add-to-raid.understand-continue": "Ik begrijp het, ga door", "storage-manager.add-to-raid.warning-failsafe-now-only": "Als je meer dan één SSD hebt, kan FailSafe nu alleen nog worden ingeschakeld. Je kunt het later niet meer inschakelen.", "storage-manager.add-to-raid.wasted-label": "Niet bruikbaar:", "storage-manager.available-storage": "Beschikbare opslag", "storage-manager.description": "Bekijk opslag, gezondheid en instellingen van je SSD's", "storage-manager.empty": "Leeg", "storage-manager.failsafe-transition-failed": "Kon FailSafe niet inschakelen", "storage-manager.for-failsafe": "Voor FailSafe", "storage-manager.health.checksum-errors": "Checksum-fouten: {{count}}", "storage-manager.health.critical": "Kritiek", "storage-manager.health.critical-threshold": "Kritieke drempel", "storage-manager.health.current-temperature": "Huidige temperatuur", "storage-manager.health.estimated-life": "Geschatte resterende levensduur", "storage-manager.health.general": "Algemeen", "storage-manager.health.health-status": "Status", "storage-manager.health.low": "Laag", "storage-manager.health.model-and-capacity": "Model & capaciteit", "storage-manager.health.overheating": "Oververhitting", "storage-manager.health.raid-failed-advice": "Deze SSD heeft een probleem. Schakel je Umbrel uit en controleer de SSD-verbinding. Als het probleem blijft, moet de SSD mogelijk worden vervangen.", "storage-manager.health.read-errors": "Leesfouten: {{count}}", "storage-manager.health.serial-number": "Serienummer", "storage-manager.health.status-healthy": "Gezond", "storage-manager.health.status-unhealthy": "Ongezond", "storage-manager.health.status-unknown": "Onbekend", "storage-manager.health.temperature": "Temperatuur", "storage-manager.health.title": "SSD-status", "storage-manager.health.warning-life-advice": "Overweeg deze SSD binnenkort te vervangen.", "storage-manager.health.warning-life-message": "Nog maar {{percent}}% levensduur over", "storage-manager.health.warning-temp-advice": "Zorg dat je Umbrel Pro goede luchtstroom heeft en dat de SSD goed is geplaatst.", "storage-manager.health.warning-temp-critical": "Temperatuur is kritiek ({{temperature}})", "storage-manager.health.warning-temp-overheating": "Schijf oververhit ({{temperature}})", "storage-manager.health.warning-threshold": "Waarschuwingsdrempel", "storage-manager.health.warning-unhealthy-advice": "Deze SSD kan binnenkort uitvallen. Overweeg deze te vervangen.", "storage-manager.health.warning-unhealthy-message": "Deze SSD heeft mogelijk een probleem", "storage-manager.health.warnings": "Waarschuwingen", "storage-manager.health.wear": "Slijtage", "storage-manager.health.write-errors": "Schrijffouten: {{count}}", "storage-manager.install-ssd.description": "Voeg meer SSD's toe om je opslag uit te breiden", "storage-manager.install-ssd.step-insert": "Plaats nieuwe SSD's in de lege sleuven", "storage-manager.install-ssd.step-power-on": "Zet je {{deviceName}} aan", "storage-manager.install-ssd.step-remove-bottom-cover": "Verwijder de magnetische bodemkap", "storage-manager.install-ssd.step-replace-bottom-cover": "Plaats de bodemplaat terug", "storage-manager.install-ssd.step-return": "Kom hier terug om de SSD's aan je opslag toe te voegen", "storage-manager.install-ssd.step-shut-down": "Schakel je {{deviceName}} uit", "storage-manager.install-ssd.title": "SSD's toevoegen", "storage-manager.install-tips.image-alt": "SSD-installatie instructie", "storage-manager.install-tips.instructions": "Om te installeren: verwijder de duimschroef en schuif de SSD onder een hoek in de sleuf. Druk de SSD naar beneden totdat deze rust op de schroefpilaar en zet hem vast met de duimschroef.", "storage-manager.install-tips.toggle": "Weet je niet meer hoe je een SSD moet plaatsen?", "storage-manager.manage": "Beheren", "storage-manager.missing-ssd-warning": "Het lijkt alsof er een SSD ontbreekt. Schakel je Umbrel uit en controleer of alle SSD's aangesloten zijn. Als het probleem blijft, moet de SSD mogelijk worden vervangen.", "storage-manager.mode": "Modus", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Houdt je gegevens veilig als een SSD uitvalt. Als je SSD's verschillende groottes hebben, blijft extra ruimte op de grotere ongebruikt.", "storage-manager.mode.failsafe.info-description": "FailSafe beschermt je gegevens door kopieën over je SSD's te bewaren. Als één SSD uitvalt, blijven je gegevens veilig en kunnen ze worden hersteld wanneer je een vervangende SSD toevoegt.", "storage-manager.mode.failsafe.info-title": "Over FailSafe", "storage-manager.mode.full-storage": "Volledige opslag", "storage-manager.mode.full-storage.description": "Gebruik al je SSD-ruimte samen. Als een SSD uitvalt, kun je je gegevens kwijtraken.", "storage-manager.mode.full-storage.info-description": "Full Storage combineert al je SSD's tot één grote ruimte voor maximale opslag. Als één SSD uitvalt, gaan al je gegevens verloren.", "storage-manager.mode.full-storage.info-title": "Over Volledige opslag", "storage-manager.mode.switch-from-failsafe-unavailable": "Overschakelen van FailSafe naar Full Storage vereist dat je je gegevens back-upt, het apparaat terugzet naar de fabrieksinstellingen en vervolgens herstelt vanaf een back-up.", "storage-manager.mode.switch-to-failsafe-unavailable": "Met meerdere SSD's in Full Storage-modus zijn je gegevens verspreid over alle schijven. Overschakelen naar FailSafe vereist dat je je gegevens back-upt, het apparaat naar fabrieksinstellingen terugzet en herstelt.", "storage-manager.mode.why-cant-switch": "Waarom kan ik niet overschakelen?", "storage-manager.operation-in-progress.shutdown-description": "Het is veilig om uit te schakelen. De bewerking wordt gepauzeerd en hervat na het opnieuw opstarten, maar moet voltooid zijn voordat je andere wijzigingen kunt aanbrengen.", "storage-manager.operation-in-progress.shutdown-title": "Je opslag wordt bijgewerkt", "storage-manager.operation-in-progress.wait-description": "Wacht tot de huidige bewerking is voltooid voordat je meer wijzigingen aanbrengt.", "storage-manager.operation-in-progress.wait-title": "Je opslag wordt bijgewerkt", "storage-manager.operation.adding-ssd": "SSD toevoegen...", "storage-manager.operation.enabling-failsafe": "FailSafe inschakelen...", "storage-manager.operation.expanding": "Opslag uitbreiden...", "storage-manager.operation.rebuilding": "Gegevens herstellen...", "storage-manager.operation.replacing": "Schijf vervangen...", "storage-manager.operation.restarting": "Opnieuw opstarten...", "storage-manager.operation.starting": "Starten...", "storage-manager.operation.syncing-restarts": "Data synchroniseren • Herstart bij 50%", "storage-manager.raid-status.degraded": "Gedegradeerd", "storage-manager.raid-status.failed": "Uitgevallen", "storage-manager.raid-status.offline": "Offline", "storage-manager.raid-status.online": "Online", "storage-manager.raid-status.removed": "Verwijderd", "storage-manager.raid-status.unavailable": "Niet beschikbaar", "storage-manager.replace": "Vervangen", "storage-manager.replace-failed.degraded": "FailSafe-bescherming verminderd", "storage-manager.replace-failed.degraded-description": "Er ontbreekt een SSD in je FailSafe-opslag. Vervang deze om de volledige bescherming te herstellen.", "storage-manager.replace-failed.description": "Gebruik deze SSD om je FailSafe-bescherming te herstellen.", "storage-manager.replace-failed.error": "Kon vervanging niet starten", "storage-manager.replace-failed.replace-now": "Nu vervangen", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD in sleuf {{slot}}", "storage-manager.replace-failed.step-protected": "Als het klaar is, zijn je gegevens weer volledig beschermd", "storage-manager.replace-failed.step-rebuild": "Je gegevens worden op de nieuwe SSD herbouwd", "storage-manager.replace-failed.step-time": "Dit kan even duren, afhankelijk van hoeveel data je hebt", "storage-manager.replace-failed.title": "SSD vervangen", "storage-manager.replace-failed.too-small": "SSD te klein", "storage-manager.replace-failed.too-small-description": "Deze SSD ({{deviceSize}}) is kleiner dan het minimaal vereiste ({{minSize}}) voor je FailSafe-opslag.", "storage-manager.replace-failed.what-happens": "Wat gebeurt er nu:", "storage-manager.ssd-failing": "Defect", "storage-manager.swap": "Wissel", "storage-manager.swap.data-erased-description": "In Full Storage-modus is er geen databeveiliging. Alle gegevens op je {{deviceName}} worden tijdens de fabrieksreset gewist. Zorg dat je eerst alles back-upt.", "storage-manager.swap.data-protected": "Je gegevens zijn beschermd", "storage-manager.swap.data-protected-description": "Met FailSafe ingeschakeld kun je elke enkele SSD vervangen zonder je gegevens te verliezen. Geen back-up nodig.", "storage-manager.swap.data-will-be-erased": "Gegevens worden gewist", "storage-manager.swap.description-failsafe": "Vervang een schijf in je FailSafe-opslag.", "storage-manager.swap.description-full-storage": "Vervang een schijf in je Full Storage-configuratie.", "storage-manager.swap.description-no-free-slot": "In Full Storage-modus met alle sleuven in gebruik vereist het wisselen van een SSD een volledige back-up- en herstelprocedure.", "storage-manager.swap.description-replace": "Migreer je gegevens naar een nieuwe SSD en verwijder daarna de oude.", "storage-manager.swap.failed-to-start": "Kon de vervanging niet starten", "storage-manager.swap.no-data-loss": "Geen dataverlies", "storage-manager.swap.no-data-loss-description": "Je gegevens worden naar de nieuwe SSD gekopieerd. Zodra dat klaar is, kun je de oude veilig verwijderen.", "storage-manager.swap.safe-swap-available": "Veilige wissel beschikbaar", "storage-manager.swap.safe-swap-description": "Omdat je een lege sleuf hebt, kun je eerst de nieuwe SSD toevoegen en je gegevens migreren voordat je de oude verwijdert. Geen back-up nodig.", "storage-manager.swap.select-new-ssd": "Selecteer de nieuwe SSD die je wilt gebruiken:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD in Slot {{slot}}", "storage-manager.swap.step-backup": "Maak een back-up van je gegevens", "storage-manager.swap.step-backup-description": "Ga naar Instellingen → Backups en maak een back-up van alle gegevens.", "storage-manager.swap.step-data-copied": "Gegevens worden van de oude SSD naar de nieuwe gekopieerd", "storage-manager.swap.step-factory-reset": "Fabrieksreset", "storage-manager.swap.step-factory-reset-description": "Ga naar Instellingen → Geavanceerd → Fabrieksreset om je {{deviceName}} te wissen.", "storage-manager.swap.step-insert-new-ssd": "Plaats de nieuwe SSD in een lege sleuf", "storage-manager.swap.step-may-take-while": "Dit kan even duren, afhankelijk van hoeveel gegevens je hebt", "storage-manager.swap.step-power-on": "Zet je {{deviceName}} aan", "storage-manager.swap.step-remove-bottom-cover": "Verwijder de magnetische bodemkap", "storage-manager.swap.step-remove-old": "Als het klaar is, schakel je uit en verwijder je {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Plaats de bodemkap terug", "storage-manager.swap.step-restore": "Herstel je gegevens", "storage-manager.swap.step-restore-description": "Ga naar Instellingen → Backups en herstel vanaf je back-up.", "storage-manager.swap.step-return-to-storage-manager": "Ga terug naar Opslagbeheer om de wissel te bevestigen en de nieuwe SSD aan je opslag toe te voegen", "storage-manager.swap.step-return-to-swap": "Ga terug naar Opslagbeheer en klik opnieuw op \"Wissel\" om de vervanging te starten", "storage-manager.swap.step-setup-new-storage": "Stel je nieuwe opslag in", "storage-manager.swap.step-setup-new-storage-description": "Zet je {{deviceName}} aan en doorloop de setup met je nieuwe SSD.", "storage-manager.swap.step-shut-down": "Schakel je {{deviceName}} uit", "storage-manager.swap.step-shut-down-and-swap": "Schakel uit en vervang {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Uitschakelen, open je apparaat, vervang de SSD en zet alles weer in elkaar.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Uitschakelen, verwijder de bodemkap, vervang de SSD en plaats de kap terug.", "storage-manager.swap.step-swap-ssd": "Vervang {{ssd}} door een nieuwe van dezelfde grootte", "storage-manager.swap.too-small": "Te klein (vereist: {{size}})", "storage-manager.swap.what-happens-next": "Wat gebeurt er daarna:", "storage-manager.total-capacity-added": "Totaal toegevoegde capaciteit", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Gebruikt", "storage-manager.wasted": "Onbruikbaar", "storage-manager.wasted-size": "{{size}} Onbruikbaar", "storage.full": "Opslag vol", "storage.low": "Weinig opslag", "temperature": "Temperatuur", "temperature.dangerously-hot": "Erg heet", "temperature.nice": "Aangenaam", "temperature.normal": "Normaal", "temperature.too-hot-suggestion": "Overweeg om de omgeving van je apparaat te veranderen.", "temperature.warm": "Warm", "terminal": "Terminal", "terminal-description": "Voer aangepaste commando's uit in umbrelOS of binnen een app", "terminal.app": "App", "terminal.app-description": "Voer aangepaste commando's uit binnen een specifieke app", "terminal.umbrelos-description": "Voer aangepaste commando's uit in umbrelOS", "tor-description": "Toegang tot je Umbrel van overal met een Tor browser", "tor-enabled-description": "Toegang tot je Umbrel van overal met een Tor-browser op de volgende URL:", "tor-error": "Kon Tor-instelling niet bijwerken: {{message}}", "tor.disable.description": "Dit kan enkele minuten duren", "tor.disable.progress": "Tor-toegang op afstand uitschakelen", "tor.enable.description": "Dit kan enkele minuten duren", "tor.enable.mobile.switch-label": "Toegang op afstand via Tor inschakelen", "tor.hidden-service": "Tor verborgen dienst URL", "troubleshoot": "Probleemoplossing", "troubleshoot-description": "Los problemen op met umbrelOS of een app", "troubleshoot-no-logs-yet": "Nog geen logbestanden", "troubleshoot-pick-title": "Probleemoplossing", "troubleshoot.app": "App", "troubleshoot.app-description": "Bekijk logbestanden van een app geïnstalleerd op je Umbrel", "troubleshoot.app-download": "Download {{app}} logbestanden", "troubleshoot.share-with-umbrel-support": "Delen met Umbrel ondersteuning", "troubleshoot.system-download": "Download {{label}}", "troubleshoot.umbrelos-description": "Bekijk umbrelOS-logboeken", "troubleshoot.umbrelos-logs": "umbrelOS logbestanden", "trpc.backend-unavailable": "Fout: Verbinding met de systeem-API mislukt", "trpc.checking-backend": "Laden...", "try-again": "Probeer opnieuw", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Onbekend", "unknown-app": "Onbekende app", "unknown-error": "Onbekende fout", "uptime": "Uptime", "url": "URL", "wallpaper": "Achtergrond", "wallpaper-description": "Je Umbrel achtergrond en thema", "whats-new.continue": "Doorgaan", "whats-new.feature-1.description": "Stel geautomatiseerde, versleutelde back-ups in van je hele Umbrel naar een externe USB-drive, een NAS of een andere Umbrel.", "whats-new.feature-2.description": "Ga terug in de tijd om specifieke bestanden en mappen uit eerdere back-ups te herstellen.", "whats-new.feature-3.description": "Of herstel je hele Umbrel, inclusief al je apps, bestanden en gegevens.", "whats-new.feature-4.description": "Sluit een NAS of een andere Umbrel aan en krijg toegang tot de opslag ervan vanuit Files.", "whats-new.feature-4.title": "Netwerkapparaten", "whats-new.feature-5.description": "Sluit externe USB-schijven aan (op de Umbrel Home of op elk Intel- of AMD-apparaat) en toegang ze via Files.", "whats-new.feature-5.helper-text": "Niet ondersteund op Raspberry Pi-apparaten vanwege mogelijke stroomproblemen.", "whats-new.feature-5.title": "Externe opslag", "whats-new.next": "Volgende", "whats-new.title": "Nieuw in {{version}}", "widget.progress.in-progress": "Bezig", "widgets.edit.select-up-to-3-widgets": "Selecteer tot 3 widgets", "widgets.install-an-app-before-using-widgets": "Installeer een app om je startscherm aan te passen met widgets.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Open netwerken kunnen onveilig zijn", "wifi-connection-failed": "Kan niet verbinden", "wifi-dangerous-change-confirmation-description": "Het veranderen van het Wi-Fi-netwerk kan je loskoppelen van je Umbrel. Om opnieuw verbinding te maken, zorg ervoor dat zowel je Umbrel als het apparaat waarmee je toegang hebt tot hetzelfde netwerk behoren.", "wifi-dangerous-change-confirmation-title": "Weet je zeker dat je van Wi-Fi-netwerk wilt veranderen?", "wifi-dangerous-disable-confirmation-description": "Het uitschakelen van Wi-Fi kan je loskoppelen van je Umbrel. Om opnieuw verbinding te maken, sluit je een Ethernet-kabel aan op je Umbrel en zorg je ervoor dat zowel je Umbrel als het apparaat waarmee je toegang hebt tot hetzelfde netwerk behoren.", "wifi-dangerous-disable-confirmation-title": "Weet je zeker dat je Wi-Fi wilt uitschakelen?", "wifi-description": "Verbind je apparaat met een Wi-Fi-netwerk", "wifi-description-long": "Je apparaat blijft verbonden met je gekozen Wi-Fi, zelfs als de Ethernet-kabel wordt verwijderd, en verbindt automatisch opnieuw met Wi-Fi bij het opstarten.", "wifi-no-networks-message": "Geen Wi-Fi-netwerken gevonden", "wifi-searching": "Zoeken naar Wi-Fi-netwerken...", "wifi-unsupported-device-description": "Wi-Fi wordt niet ondersteund op dit apparaat. Dit kan te wijten zijn aan een ontbrekende of incompatibele draadloze adapter.", "wifi-view-networks": "Netwerken bekijken" } ================================================ FILE: packages/ui/public/locales/pt.json ================================================ { "2fa": "2FA", "2fa-description": "Uma segunda camada de segurança para o seu login no Umbrel e aplicativos", "2fa.disable.title": "Desativar autenticação de dois fatores", "2fa.enable.or-paste": "Ou cole o seguinte código no seu aplicativo autenticador", "2fa.enable.scan-this": "Escanee este código QR usando um aplicativo autenticador como Google Authenticator ou Authy", "2fa.enable.title": "Ativar autenticação de dois fatores", "2fa.enter-code": "Digite o código exibido no seu aplicativo autenticador", "account": "Conta", "account-description": "Seu nome e senha", "advanced-settings": "Configurações avançadas", "advanced-settings-description": "Terminal, Programa Beta do umbrelOS, Cloudflare DNS e mais", "app-not-found": "Aplicativo não encontrado: {{app}}", "app-only-over-tor": "{{app}} só pode ser usado via Tor. Por favor, acesse seu Umbrel em um navegador Tor pela sua URL de acesso remoto (Settings > Advanced settings > Remote Tor access) para abrir este aplicativo.", "app-page.section.about": "Sobre", "app-page.section.credentials.title": "Credenciais padrão", "app-page.section.dependencies.n-alternatives": "Ver {{count}} alternativas", "app-page.section.info.compatibility": "Compatibilidade", "app-page.section.info.compatibility-compatible": "Compatível", "app-page.section.info.compatibility-not-compatible": "Não compatível", "app-page.section.info.developer": "Desenvolvedor", "app-page.section.info.source-code": "Código-fonte", "app-page.section.info.source-code.public": "Público", "app-page.section.info.submitted-by": "Enviado por", "app-page.section.info.support": "Obter suporte", "app-page.section.info.title": "Informações", "app-page.section.info.version": "Versão", "app-page.section.recommendations.title": "Você também pode gostar", "app-page.section.release-notes.title": "O que há de novo", "app-page.section.release-notes.version": "Versão {{version}}", "app-page.section.requires": "Requer", "app-picker.search": "Pesquisar...", "app-picker.select-app": "Selecionar aplicativo...", "app-settings.connected-to": "{{appName}} está conectado a estes aplicativos", "app-settings.save-changes": "Salvar alterações", "app-settings.title": "Configurações", "app-store.browse-category-apps": "Navegar por aplicativos {{category}}", "app-store.category.ai": "IA", "app-store.category.all": "Todos os aplicativos", "app-store.category.automation": "Casa & Automação", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Cripto", "app-store.category.developer": "Ferramentas de Desenvolvedor", "app-store.category.discover": "Descobrir", "app-store.category.files": "Arquivos & Produtividade", "app-store.category.finance": "Finanças", "app-store.category.media": "Mídia", "app-store.category.networking": "Redes", "app-store.category.social": "Social", "app-store.description": "Suas configurações de atualização de aplicativos", "app-store.discover.temporarily-unavailable-description": "Navegue pelas categorias acima ou pesquise para encontrar apps", "app-store.discover.temporarily-unavailable-title": "Conteúdo em destaque temporariamente indisponível", "app-store.menu.community-app-stores": "Lojas de Aplicativos da Comunidade", "app-store.search-apps": "Pesquisar aplicativos", "app-store.search.no-results": "Nenhum resultado", "app-store.search.results-for": "Resultados para", "app-store.title": "App Store", "app-store.updates": "Atualizações", "app-updates.less": "menos", "app-updates.more": "mais", "app-updates.no-updates": "Todos os aplicativos estão atualizados!", "app-updates.update": "Atualizar", "app-updates.update-all": "Atualizar todos", "app-updates.updates-available-count_one": "{{count}} atualização disponível", "app-updates.updates-available-count_other": "{{count}} atualizações disponíveis", "app-updates.updating": "Atualizando...", "app.install": "Instalar", "app.installed": "Instalado", "app.installing": "Instalando", "app.offline": "Não está em execução", "app.open": "Abrir", "app.optimized-for-umbrel-home": "Otimizado para Umbrel Home", "app.os-update-required.confirm": "Verificar atualização do umbrelOS", "app.os-update-required.description": "{{appName}} requer o umbrelOS {{version}} ou posterior", "app.os-update-required.title": "Atualizar umbrelOS", "app.restarting": "Reiniciando", "app.starting": "Iniciando", "app.stopping": "Parando", "app.uninstall.confirm.description": "Todos os dados associados a {{app}} serão permanentemente excluídos. Esta ação não pode ser desfeita.", "app.uninstall.confirm.submit": "Desinstalar", "app.uninstall.confirm.title": "Desinstalar {{app}}?", "app.uninstall.deps.used-by.description_one": "Desinstale {{firstAppToUninstall}} primeiro para desinstalar {{app}}.", "app.uninstall.deps.used-by.description_other": "Desinstale estes aplicativos primeiro para desinstalar {{app}}.", "app.uninstall.deps.used-by.title": "{{app}} é usado por", "app.uninstalling": "Desinstalando", "app.updating": "Atualizando", "app.view": "Visualizar", "app_one": "aplicativo", "app_other": "aplicativos", "apps.uninstall.failed-to-get-required-apps": "Falha ao obter aplicativos necessários", "apps.uninstalled-all.success": "Todos os aplicativos foram desinstalados", "auth.checking-backend-for-user": "Carregando...", "auth.failed-checking-if-user-logged-in": "Erro: A verificação de login falhou", "auth.failed-to-check-if-user-exists": "Erro: A verificação de existência falhou", "back": "Voltar", "backups": "Backups", "backups-configure": "Configurar", "backups-configure.add-backup-location": "Adicionar local de backup", "backups-configure.available": "Disponível", "backups-configure.awaiting-next-backup": "Aguardando o próximo backup automático", "backups-configure.back-up-now": "Fazer backup agora", "backups-configure.backing-up-now": "Fazendo backup...", "backups-configure.connected": "Conectado", "backups-configure.connection": "Conexão", "backups-configure.in-progress": "Em andamento", "backups-configure.last-backup": "Último backup", "backups-configure.locations": "Locais", "backups-configure.no-backup-locations": "Adicione um local de backup para começar a fazer backup dos seus dados", "backups-configure.not-connected": "Não conectado", "backups-configure.path": "Caminho", "backups-configure.remove-backup-location": "Remover local de backup", "backups-configure.remove-backup-location-confirmation": "Tem certeza?", "backups-configure.remove-backup-location-confirmation-description": "Isso removerá '{{device}}' dos seus locais de backup. Os backups existentes neste dispositivo não serão excluídos, mas os backups automáticos serão interrompidos.", "backups-configure.status": "Status", "backups-configure.total-backups": "Total de backups", "backups-configure.used": "Usado", "backups-configure.view": "Ver", "backups-description": "Faça backup dos seus arquivos, apps e dados para outro Umbrel, NAS ou disco externo", "backups-error.backup-not-found": "Não foi possível encontrar o backup.", "backups-error.generic": "Algo deu errado: {{details}}", "backups-error.in-progress": "Já existe um processo de backup em andamento. Aguarde até ele terminar.", "backups-error.invalid-exclusion-path": "Só é possível excluir dos backups arquivos e pastas do seu diretório Home.", "backups-error.invalid-password": "A senha de criptografia está incorreta.", "backups-error.invalid-path": "O local selecionado não é válido para backups.", "backups-error.mount-failed": "Não foi possível acessar o snapshot de backup.", "backups-error.mount-timeout": "Não foi possível acessar o snapshot de backup. Tente novamente ou verifique se o dispositivo está conectado corretamente.", "backups-error.not-enough-space": "Espaço insuficiente disponível no dispositivo de backup.", "backups-error.not-found": "Não foi possível encontrar o backup ou o local de backup.", "backups-error.repository-exists": "Já existe um local de backup nesta pasta.", "backups-error.repository-not-found": "Não foi possível encontrar o local de backup.", "backups-exclusions.add": "Adicionar", "backups-exclusions.app-paths-cannot-be-modified": "Estes arquivos/pastas são definidos pelo desenvolvedor do app e não podem ser modificados:", "backups-exclusions.app-paths-explanation": "Este app exclui os seguintes dados do backup. Esses caminhos geralmente contêm itens não essenciais (como caches ou logs que podem ser recriados) ou dados que podem causar problemas se forem restaurados (como estados antigos do app que podem gerar conflitos ou inconsistências).", "backups-exclusions.auto-excluded": "Excluído automaticamente", "backups-exclusions.exclude-entire-app": "Excluir o app inteiro", "backups-exclusions.excluded-apps": "Apps excluídos", "backups-exclusions.files-and-folders": "Arquivos e pastas excluídos", "backups-exclusions.no-excluded-apps": "Nenhum app excluído", "backups-exclusions.no-excluded-files-or-folders": "Nenhum arquivo ou pasta excluído", "backups-exclusions.select-item-to-exclude": "Selecione um item para excluir", "backups-exclusions.stop-excluding": "Parar de excluir", "backups-floating-island.backing-up": "Fazendo backup...", "backups-floating-island.backing-up-to": "Fazendo backup do seu Umbrel...", "backups-restore": "Restaurar", "backups-restore-full": "Restauração completa", "backups-restore-full-description": "Restaure todo o seu Umbrel a partir de um backup", "backups-restore-header": "Restaurar seu Umbrel", "backups-restore-pro.after-restore": "Após a restauração, sua conta temporária será substituída pela sua conta e dados do backup.", "backups-restore-pro.step1": "Complete o processo de configuração clicando em \"Começar\" abaixo. Essa será sua conta temporária até você restaurar a sua conta do backup.", "backups-restore-pro.step2": "Quando a configuração estiver concluída, vá para <0>Configurações → Backups → Restaurar", "backups-restore-pro.step3": "Siga as instruções do Assistente de Restauração.", "backups-restore-pro.subtitle": "Restaurar um backup no Umbrel Pro exige alguns passos a mais", "backups-restore.backup-date": "Data do backup", "backups-restore.backup-location": "Local do backup", "backups-restore.browse-cloud-subtitle": "Restaurar a partir do Umbrel Private Cloud (em breve)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Restaurar a partir de um disco USB externo", "backups-restore.browse-external-title": "Disco externo", "backups-restore.browse-nas-or-external": "Procure outro Umbrel, NAS ou disco externo para restaurar a partir de um backup", "backups-restore.browse-nas-subtitle": "Restaurar a partir de outro Umbrel ou dispositivo NAS na sua rede", "backups-restore.browse-nas-title": "Outro Umbrel ou NAS", "backups-restore.choose": "Escolher", "backups-restore.choose-backup-location": "Escolha um local de backup", "backups-restore.connect-to-backup-location": "Conectar a um local de backup", "backups-restore.encryption-password": "Senha de criptografia", "backups-restore.encryption-password-description": "Digite a senha de criptografia que você definiu quando ativou os backups", "backups-restore.enter-password-to-confirm": "Insira a senha do Umbrel para confirmar", "backups-restore.final-confirmation": "Tem certeza?", "backups-restore.final-confirmation-description": "Restaurar a partir deste backup substituirá os apps e dados atuais do umbrelOS pelo conteúdo do backup selecionado. Quaisquer arquivos, pastas ou apps excluídos deste backup serão removidos do seu Umbrel. Esta ação não pode ser desfeita.", "backups-restore.invalid-password": "Senha inválida", "backups-restore.last-backup": "Último backup: {{date}}", "backups-restore.latest": "Mais recente", "backups-restore.no-backups-found": "Nenhum backup encontrado", "backups-restore.no-backups-yet": "Ainda não há backups", "backups-restore.please-select-backup": "Por favor, selecione um backup", "backups-restore.please-select-repository": "Por favor, selecione um repositório", "backups-restore.restore-from-nas-or-external": "Restaure seu Umbrel a partir de um backup em outro Umbrel, em um NAS ou em um disco externo", "backups-restore.restore-from-unlisted": "Restaurar de outro local", "backups-restore.restore-umbrel": "Restaurar Umbrel", "backups-restore.restore-warning": "Restaurar a partir deste backup substituirá os apps e dados atuais do umbrelOS pelo conteúdo do backup selecionado. Quaisquer arquivos, pastas ou apps excluídos deste backup serão removidos do seu Umbrel. Abra <0>Rewind se quiser restaurar arquivos ou pastas específicos em vez disso.", "backups-restore.restoring-from": "Você está prestes a restaurar a partir do seguinte backup:", "backups-restore.review-description": "A restauração configurará seu Umbrel com a conta, arquivos, apps e configurações que estavam incluídos na época deste backup. Isso pode levar algum tempo. Quando for concluída, sua senha de login será definida para a que você usou quando o backup foi criado.", "backups-restore.select-backup": "Selecione um backup", "backups-restore.select-backup-description": "Selecione o backup do qual você deseja restaurar", "backups-restore.select-backup-file": "Selecione seu arquivo de backup", "backups-restore.select-backup-file-only": "Somente {{backupFileName}} pode ser selecionado", "backups-restore.total-size": "Tamanho total", "backups-restore.unknown-date": "Data desconhecida", "backups-restore.unknown-repository": "Repositório desconhecido", "backups-rewind": "Rewind", "backups-rewind-description": "Volte no tempo para restaurar arquivos e pastas específicos", "backups-rewind.start": "Iniciar Rewind", "backups-setup": "Configurar", "backups-setup-confirm": "Concluir configuração", "backups-setup-external-description": "Fazer backup em um disco USB externo", "backups-setup-nas-or-umbrel-description": "Faça backup para outro Umbrel ou um dispositivo NAS na sua rede", "backups-setup-umbrel-or-nas": "Outro Umbrel ou NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Amplie sua tranquilidade além de casa com backups criptografados de ponta a ponta para Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Peça acesso antecipado", "backups-setup-umbrel-private-cloud-description": "Backups criptografados de ponta a ponta para Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Em breve", "backups.add-umbrel-or-nas": "Adicionar Umbrel ou NAS", "backups.all-apps-and-data-will-be-backed-up": "Todos os apps e dados serão incluídos no backup", "backups.apps-and-data": "Apps e dados", "backups.backup-location": "Local de backup", "backups.browse": "Procurar", "backups.choose-folder-within-device": "Escolha uma pasta dentro de {{device}} para salvar seus backups", "backups.confirm-password": "Confirme a senha", "backups.copy": "Copiar", "backups.encryption": "Criptografia", "backups.encryption-password-warning": "Certifique-se de armazenar sua senha de criptografia em um local seguro, como um gerenciador de senhas. Você não poderá vê-la novamente e precisará dela para restaurar seus backups.", "backups.exclude-from-backups": "Excluir do Backups", "backups.exclude-from-backups-description": "Exclua arquivos, pastas e apps específicos dos seus backups.", "backups.hide": "Ocultar", "backups.i-understand": "Entendi", "backups.location": "Local", "backups.modals.already-in-use.description": "Este local de backup já está sendo usado para os Backups deste Umbrel.", "backups.modals.already-in-use.manage": "Gerenciar em Backups", "backups.modals.already-in-use.title": "Local de backup já em uso", "backups.modals.connect-existing.description": "Um backup do Umbrel já existe neste local. Digite a senha de criptografia para adicioná-lo a este Umbrel.", "backups.modals.connect-existing.title": "Conectar backup existente do Umbrel", "backups.no-external-drives-detected": "Nenhum disco externo detectado", "backups.no-password-set": "Nenhuma senha definida", "backups.password-is-set": "Senha definida", "backups.password-minimum-length": "A senha deve ter pelo menos 8 caracteres", "backups.password-safety-warning": "Seus backups serão criptografados com esta senha. Guarde-a em segurança, pois você não poderá vê-la novamente e precisará dela para restaurar seus backups.", "backups.passwords-do-not-match": "As senhas não coincidem", "backups.please-choose-folder": "Por favor, escolha uma pasta", "backups.restore-failed.message": "Ocorreu um erro ao restaurar seu Umbrel. Seus aplicativos e dados atuais não foram alterados.", "backups.restore-failed.retry": "Ir para Restaurar", "backups.restore-failed.title": "Falha na restauração", "backups.restoring": "Restaurando seu Umbrel", "backups.restoring-completing": "Finalizando. Seu Umbrel será reiniciado em breve...", "backups.restoring-progress": "Restaurado {{percent}}%", "backups.restoring-time-remaining": "{{time}} restantes", "backups.restoring-warning": "Não desligue seu Umbrel nem desconecte o local de backup durante a restauração", "backups.review": "Revisar e confirmar", "backups.review-description": "Revise os detalhes do seu backup e confirme sua seleção", "backups.scanning-for-external-drives": "Procurando discos externos...", "backups.schedule-description": "umbrelOS faz backup dos seus dados automaticamente a cada hora. Ele mantém backups criptografados por hora das últimas 24 horas, backups diários da última semana, backups semanais do último mês e backups mensais do último ano. Backups com mais de um ano são removidos automaticamente.", "backups.select-backup-folder": "Selecione a pasta de backup", "backups.select-backup-folder-description": "Escolha uma pasta onde você gostaria de armazenar seus backups.", "backups.select-backup-location": "Selecione um local de backup", "backups.set-encryption-password": "Definir senha de criptografia", "backups.set-encryption-password-description": "Proteja seus backups com uma senha. Isso garante que seus dados permaneçam privados e só possam ser restaurados com essa senha.", "backups.show": "Mostrar", "backups.storage-capacity-warning": "{{device}} deve ter espaço livre igual a, no mínimo, duas vezes o tamanho do seu backup", "backups.store-encryption-password-safely": "Armazene sua senha de criptografia em local seguro", "beta-program": "Programa Beta do umbrelOS", "beta-program-description": "Opte por receber atualizações beta do umbrelOS, obtenha acesso antecipado a novas funcionalidades e ajude-nos a refiná-las fornecendo seu feedback. Atualizações beta podem ser instáveis e a solução de problemas pode requerer familiaridade com o terminal.", "cancel": "Cancelar", "change": "Mudar", "change-name": "Mudar nome", "change-name.failed.name-required": "O nome é necessário", "change-name.input-placeholder": "Seu nome", "change-password": "Mudar senha", "change-password.callout": "Se você perder sua senha, não será possível fazer login no seu Umbrel. Certifique-se de guardá-la em segurança.", "change-password.current-password": "Senha atual", "change-password.failed.current-required": "A senha atual é necessária", "change-password.failed.min-length": "A senha deve ter pelo menos {{characters}} caracteres", "change-password.failed.must-be-unique": "A nova senha deve ser diferente da senha atual", "change-password.failed.new-required": "A nova senha é necessária", "change-password.failed.no-match": "As senhas não coincidem", "change-password.failed.repeat-required": "É necessário repetir a senha", "change-password.new-password": "Nova senha", "change-password.repeat-password": "Repetir senha", "check-for-latest-version": "Verificar a última atualização do umbrelOS", "clipboard.copied": "Copiado", "close": "Fechar", "cmdk.change-wallpaper": "Mudar papel de parede", "cmdk.frequent-apps": "Usados frequentemente", "cmdk.input-placeholder": "Pesquise por aplicativos, configurações ou ações", "cmdk.live-usage": "Uso ao Vivo", "cmdk.restart-umbrel": "Reiniciar Umbrel", "cmdk.shutdown-umbrel": "Desligar Umbrel", "cmdk.update-all-apps": "Atualizar todos os aplicativos", "cmdk.widgets": "Widgets", "community-app-store": "Loja de Aplicativos da Comunidade", "community-app-store.add-error": "Falha ao adicionar App Store: {{message}}", "community-app-store.back-to-umbrel-app-store": "Voltar para a App Store do Umbrel", "community-app-store.open-button": "Abrir", "community-app-store.remove-button": "Remover", "community-app-store.remove-error": "Falha ao remover App Store: {{message}}", "community-app-stores.add-button": "Adicionar", "community-app-stores.description": "As Lojas de Aplicativos da Comunidade permitem instalar aplicativos no seu Umbrel que podem não estar disponíveis na App Store oficial do Umbrel. Eles também facilitam o teste de versões beta de aplicativos Umbrel antes que os desenvolvedores os lancem na App Store oficial do Umbrel.", "community-app-stores.learn-more": "Saiba mais", "community-app-stores.warning": "As Lojas de Aplicativos da Comunidade podem ser criadas por qualquer pessoa. Os aplicativos publicados nelas não são verificados ou avaliados pela equipe da App Store oficial do Umbrel e podem ser potencialmente inseguros ou maliciosos. Use cautela e adicione apenas lojas de aplicativos de desenvolvedores em quem você confia.", "confirm": "Confirmar", "connect": "Conectar", "connecting": "Conectando...", "connection-lost": "Conexão perdida", "connection-lost-description": "Isso pode acontecer quando a aba do navegador ficou inativa, sua conexão de rede foi interrompida ou seu dispositivo está offline.", "continue": "Continuar", "continue-to-log-in": "Continuar para o login", "cpu": "CPU", "cpu-core-count": "{{cores}} núcleos", "default-credentials.close": "Entendi", "default-credentials.description": "Aqui estão as credenciais que você precisará para fazer login no aplicativo.", "default-credentials.dont-show-again": "Não mostrar isso novamente", "default-credentials.dont-show-again-notice": "Você pode acessar estas credenciais a qualquer momento no futuro clicando com o botão direito no ícone do app.", "default-credentials.open": "Abrir {{app}}", "default-credentials.password": "Senha padrão", "default-credentials.title": "Credenciais para {{app}}", "default-credentials.username": "Nome de usuário padrão", "desktop.app.context.go-to-store-page": "Ver na App Store", "desktop.app.context.settings": "Configurações", "desktop.app.context.show-default-credentials": "Mostrar credenciais padrão", "desktop.app.context.uninstall": "Desinstalar", "desktop.context-menu.change-wallpaper": "Mudar papel de parede", "desktop.context-menu.edit-widgets": "Editar widgets", "desktop.context-menu.logout": "Sair", "desktop.greeting.afternoon": "Boa tarde, {{name}}", "desktop.greeting.evening": "Boa noite, {{name}}", "desktop.greeting.morning": "Bom dia, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Para o viber", "desktop.install-first.for-the-bitcoiner": "Para o bitcoiner", "desktop.install-first.for-the-self-hoster": "Para o auto-hospedeiro", "desktop.install-first.for-the-streamer": "Para o streamer", "desktop.install-first.link-to-app-store": "Explorar mais na App Store", "desktop.not-enough-room": "Use uma tela maior para ver seus aplicativos.", "device": "Dispositivo", "device-info": "Informações do dispositivo", "device-info-description": "Informações sobre o seu dispositivo", "device-info.device": "Dispositivo", "device-info.model-number": "Número do modelo", "device-info.serial-number": "Número de série", "device-info.view-info": "Ver informações", "device-name.home-or-pro": "Umbrel Home or Umbrel Pro", "disable": "Desativar", "done": "Concluído", "download-logs": "Baixar registros", "enabling-tor": "Ativando o acesso remoto via Tor", "external-dns": "Cloudflare DNS", "external-dns-description": "O DNS da Cloudflare oferece melhor confiabilidade de rede. Desative para usar as configurações de DNS do seu roteador.", "external-dns-error": "Falha ao atualizar a configuração de DNS: {{message}}", "external-drive": "Disco Externo", "factory-reset": "Restauração de Fábrica", "factory-reset-description": "Apague todos os seus dados e aplicativos, restaurando o umbrelOS para as configurações padrão", "factory-reset-failed": "Falha ao restaurar as configurações de fábrica do seu dispositivo: {{message}}", "factory-reset.confirm.body": "Confirme sua senha para redefinir", "factory-reset.confirm.ethernet-required-warning": "Certifique-se de que seu dispositivo esteja conectado ao roteador via Ethernet (não Wi-Fi) e que você esteja acessando a partir da sua rede local (por exemplo, http://umbrel.local ou o endereço IP local do seu dispositivo).", "factory-reset.confirm.submit": "Apagar tudo e resetar", "factory-reset.confirm.submit-callout": "Esta ação não pode ser desfeita.", "factory-reset.rebooting.message": "Seu dispositivo será reiniciado e todos os dados serão apagados. Por favor, não feche esta página.", "factory-reset.rebooting.status": "Redefinindo...", "factory-reset.rebooting.title": "Redefinição de fábrica em andamento", "factory-reset.review.account-info": "Informações da conta e senha", "factory-reset.review.apps": "Aplicativos", "factory-reset.review.following-will-be-removed": "O seguinte será removido do seu dispositivo", "factory-reset.review.installed-apps_one": "{{count}} aplicativo instalado", "factory-reset.review.installed-apps_other": "{{count}} aplicativos instalados", "factory-reset.review.submit": "Continuar", "factory-reset.review.total-data": "Dados totais", "files": "Files", "files-action.add-favorite": "Adicionar aos favoritos", "files-action.add-network-device": "Adicionar dispositivo", "files-action.cancel-upload": "Cancelar envio", "files-action.compress": "Comprimir", "files-action.copy": "Copiar", "files-action.cut": "Recortar", "files-action.delete": "Excluir permanentemente", "files-action.download": "Baixar", "files-action.download-items": "Baixar {{count}} itens", "files-action.drop-to-upload": "Solte para enviar", "files-action.eject-disk": "Ejetar", "files-action.empty-trash": "Esvaziar Lixeira", "files-action.format-drive": "Formatar", "files-action.go-to-path": "Ir para...", "files-action.new-folder": "Nova pasta", "files-action.open": "Abrir", "files-action.paste": "Colar", "files-action.remove-favorite": "Remover dos favoritos", "files-action.remove-network-host": "Ejetar unidade de rede", "files-action.remove-network-share": "Ejetar compartilhamento de rede", "files-action.rename": "Renomear", "files-action.restore": "Restaurar", "files-action.select": "Selecionar", "files-action.share": "Compartilhar pela rede...", "files-action.sharing": "Compartilhando...", "files-action.show-in-folder": "Mostrar na pasta correspondente", "files-action.trash": "Lixeira", "files-action.uncompress": "Descomprimir", "files-action.upload": "Enviar", "files-add-network-share.add-manually": "Adicionar manualmente", "files-add-network-share.add-share": "Adicionar compartilhamento", "files-add-network-share.back": "Voltar", "files-add-network-share.continue": "Continuar", "files-add-network-share.description": "Conecte-se a um NAS ou outro drive compartilhado na sua rede para acessá-los no Files.", "files-add-network-share.discovering": "Descobrindo...", "files-add-network-share.enter-details-manually": "Digite os detalhes do servidor", "files-add-network-share.host-label": "Endereço do servidor", "files-add-network-share.host-required": "Endereço do servidor é obrigatório", "files-add-network-share.manual-share-help": "Digite o nome exato do compartilhamento como aparece no seu servidor", "files-add-network-share.no-shares-found": "Nenhum compartilhamento encontrado neste servidor", "files-add-network-share.not-seeing-share": "Não está vendo seu compartilhamento?", "files-add-network-share.password-label": "Senha", "files-add-network-share.password-required": "Senha é obrigatória", "files-add-network-share.retrieving-shares": "Obtendo compartilhamentos...", "files-add-network-share.retry-discovery": "Escanear rede novamente", "files-add-network-share.select-share": "Selecione um compartilhamento para adicionar", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Compartilhamento é obrigatório", "files-add-network-share.title": "Adicionar um compartilhamento de rede", "files-add-network-share.username-label": "Nome de usuário", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Nome de usuário é obrigatório", "files-audio-island.now-playing": "Reproduzindo agora", "files-audio-island.pause": "Pausar", "files-audio-island.play": "Reproduzir", "files-backend-error.base-directory-not-found": "Não foi possível encontrar o diretório base", "files-backend-error.cant-find-root": "Não foi possível verificar o caminho do arquivo", "files-backend-error.destination-already-exists": "Já existe um item com o mesmo nome no destino", "files-backend-error.destination-not-exist": "A pasta de destino não existe", "files-backend-error.does-not-exist": "O arquivo ou a pasta não existe", "files-backend-error.escapes-base": "O caminho está fora do diretório permitido", "files-backend-error.invalid-base": "O caminho não pertence a um diretório válido", "files-backend-error.invalid-filename": "O nome do arquivo não é válido", "files-backend-error.invalid-path": "O caminho do arquivo não é válido", "files-backend-error.mkdir-failed": "Não foi possível criar a pasta", "files-backend-error.move-failed": "Não foi possível mover o item", "files-backend-error.not-enough-space": "Não há espaço de armazenamento suficiente", "files-backend-error.operation-not-allowed": "Esta operação não é permitida", "files-backend-error.parent-not-directory": "O caminho pai não é uma pasta", "files-backend-error.parent-not-exist": "A pasta pai não existe", "files-backend-error.path-not-absolute": "O caminho do arquivo não é válido", "files-backend-error.share-already-exists": "Esta pasta já está compartilhada", "files-backend-error.share-name-generation-failed": "Não foi possível gerar um nome único para o compartilhamento", "files-backend-error.source-not-exists": "O arquivo ou pasta de origem não existe", "files-backend-error.subdir-of-self": "Uma pasta não pode ser movida ou copiada para dentro de si mesma", "files-backend-error.trash-meta-not-exists": "Não foi possível encontrar a localização original deste item", "files-backend-error.unique-name-index-exceeded": "Não foi possível gerar um nome único. Existem muitos itens com nomes semelhantes", "files-backend-error.upload-failed": "Falha no upload", "files-collision.action.keep-both": "Manter ambos", "files-collision.action.replace": "Substituir", "files-collision.action.skip": "Ignorar", "files-collision.destination.original-location": "Localização original", "files-collision.message": "Deseja substituir o item existente ou manter ambos?", "files-collision.title": "\"{{itemName}}\" já existe em {{destinationName}}", "files-download.confirm": "Fazer download", "files-download.description": "O Files não consegue abrir este tipo de arquivo. Deseja baixá-lo em vez disso?", "files-download.title": "Baixar {{name}}?", "files-empty-trash.confirm": "Esvaziar", "files-empty-trash.description": "Tem certeza de que deseja excluir permanentemente todos os itens na lixeira? Você não pode desfazer essa ação.", "files-empty-trash.title": "Esvaziar Lixeira?", "files-empty.directory": "Nenhum item nesta pasta", "files-empty.network": "Nenhum dispositivo de rede", "files-empty.network-host-offline": "Dispositivo de rede offline", "files-error.add-favorite": "Falha ao adicionar aos favoritos: {{message}}", "files-error.add-share": "Falha ao compartilhar a pasta: {{message}}", "files-error.compress": "Falha na compactação: {{message}}", "files-error.copy": "Falha ao copiar: {{message}}", "files-error.create-folder": "Falha ao criar a pasta: {{message}}", "files-error.delete": "Falha ao excluir: {{message}}", "files-error.eject-disk": "Falha ao ejetar a unidade: {{message}}", "files-error.empty-trash": "Falha ao esvaziar a lixeira: {{message}}", "files-error.extract": "Falha na extração: {{message}}", "files-error.folder-already-exists": "Uma pasta com esse nome já existe", "files-error.move": "Falha ao mover: {{message}}", "files-error.remove-favorite": "Falha ao remover dos favoritos: {{message}}", "files-error.remove-share": "Falha ao remover a pasta compartilhada: {{message}}", "files-error.rename": "Falha ao renomear: {{message}}", "files-error.restore": "Falha ao restaurar: {{message}}", "files-error.trash": "Falha ao mover para a lixeira: {{message}}", "files-error.upload": "Falha no upload: {{message}}", "files-error.upload-network-error": "Falha no upload de {{name}}: ocorreu um erro de rede", "files-extension-change.confirm": "Continuar", "files-extension-change.description-add": "Tem certeza de que deseja alterar a extensão de '{{fileName}}' para '{{extension}}'? Isso pode tornar o arquivo ilegível.", "files-extension-change.description-remove": "Tem certeza de que deseja remover a extensão de '{{fileName}}'?", "files-extension-change.title-add": "Alterar extensão para '{{extension}}'?", "files-extension-change.title-remove": "Remover extensão?", "files-external-storage.unsupported.description": "O disco externo conectado não pode ser usado em um Raspberry Pi devido a problemas de energia. O armazenamento externo está disponível no Umbrel Home, Umbrel Pro e em todos os dispositivos x86 (Intel ou AMD).", "files-external-storage.unsupported.description-general": "O armazenamento externo não está disponível no Raspberry Pi devido a problemas de energia. O armazenamento externo está disponível no Umbrel Home, Umbrel Pro e em todos os dispositivos x86 (Intel ou AMD).", "files-external-storage.unsupported.title": "Armazenamento Externo Não É Suportado", "files-folder": "Pasta", "files-format.confirm": "Formatar", "files-format.description": "A formatação apagará todos os dados em {{driveName}}. Esta ação não pode ser desfeita.", "files-format.description-unreadable": "O umbrelOS não consegue ler o conteúdo de {{driveName}}. Você pode formatá-la para usar com o umbrelOS.", "files-format.drive-label": "Nome", "files-format.error": "Não foi possível formatar a unidade", "files-format.exfat-description": "Máxima compatibilidade com Windows, macOS e Linux", "files-format.ext4-description": "Melhor desempenho com o umbrelOS e Linux", "files-format.filesystem": "Sistema de arquivos", "files-format.filesystem-label": "Formatar como", "files-format.formatting": "Formatando...", "files-format.title": "Formatar unidade", "files-format.title-requires-format": "Formatação necessária", "files-formatting-island.formatting": "Formatando...", "files-formatting-island.formatting-drives": "Formatando {{count}} unidades", "files-listing.empty": "Nenhum item", "files-listing.error": "Ocorreu um erro", "files-listing.item-count-truncated": "{{formattedCount}}+ itens", "files-listing.item-count_one": "{{formattedCount}} item", "files-listing.item-count_other": "{{formattedCount}} itens", "files-listing.loading": "Carregando...", "files-listing.no-such-file": "Não há tal arquivo ou pasta", "files-listing.selected-count": "{{selectedCount}} de {{totalCount}} selecionados", "files-listing.selected-count-truncated": "{{selectedCount}} de {{totalCount}}+ selecionados", "files-name-drawer.new-folder": "Nova pasta", "files-name-drawer.new-folder-description": "Digite um nome para a nova pasta.", "files-name-drawer.new-folder-input": "Nome da pasta", "files-name-drawer.rename-file": "Renomear arquivo", "files-name-drawer.rename-file-description": "Digite um novo nome para este arquivo.", "files-name-drawer.rename-file-input": "Nome do arquivo", "files-name-drawer.rename-folder": "Renomear pasta", "files-name-drawer.rename-folder-description": "Digite um novo nome para esta pasta.", "files-name-drawer.rename-folder-input": "Nome da pasta", "files-network-storage-error.add-share": "Falha ao adicionar um compartilhamento de rede: {{message}}", "files-network-storage-error.discover-servers": "Falha na descoberta de dispositivos de rede: {{message}}", "files-network-storage-error.discover-shares": "Falha na descoberta de compartilhamentos de rede: {{message}}", "files-network-storage-error.remove-share": "Falha ao remover o compartilhamento de rede: {{message}}", "files-operations-island.copying": "Copiando \"{{from}}\" para \"{{to}}\"", "files-operations-island.moving": "Movendo \"{{from}}\" para \"{{to}}\"", "files-operations-island.restoring": "Restaurando \"{{from}}\" para \"{{to}}\"", "files-path.input-group": "Campo de caminho", "files-path.input-label": "Caminho atual", "files-permanently-delete.confirm": "Excluir permanentemente", "files-permanently-delete.description-multiple": "Tem certeza de que deseja excluir permanentemente esses {{count}} itens? Você não pode desfazer essa ação.", "files-permanently-delete.description-single": "Tem certeza de que deseja excluir permanentemente \"{{fileName}}\"? Você não pode desfazer essa ação.", "files-permanently-delete.title-multiple": "Excluir {{count}} itens permanentemente?", "files-permanently-delete.title-single": "Excluir permanentemente?", "files-search.default": "Pesquisar arquivos e pastas", "files-search.no-results": "Nenhum resultado encontrado para \"{{query}}\"", "files-search.placeholder": "Pesquisar", "files-search.searching-label": "Procurando o Umbrel de {{name}}", "files-share.home-description": "Acesse todos os arquivos em \"{{homeDirectoryName}}\" de outros dispositivos na sua rede", "files-share.home-title": "Compartilhar \"{{homeDirectoryName}}\" pela rede", "files-share.instructions.how-to-access": "Como acessar", "files-share.instructions.ios.enter-password": "Insira {{password}} como senha.", "files-share.instructions.ios.enter-server": "Insira {{smbUrl}} como endereço do servidor.", "files-share.instructions.ios.enter-username": "Insira {{username}} como nome de usuário.", "files-share.instructions.ios.install-files": "Instale o app \"Arquivos\" da App Store, se ainda não estiver instalado.", "files-share.instructions.ios.tap-connect": "Toque em \"Conectar\" para acessá-lo.", "files-share.instructions.ios.tap-dots": "Toque nos três pontos (...) no canto superior direito e selecione \"Conectar ao Servidor\".", "files-share.instructions.macos.click-connect": "Clique em \"Conectar\" para acessá-lo.", "files-share.instructions.macos.enter-password": "Insira {{password}} como senha.", "files-share.instructions.macos.enter-url": "Insira {{smbUrl}} e clique em Conectar.", "files-share.instructions.macos.enter-username": "Insira {{username}} como nome de usuário.", "files-share.instructions.macos.open-finder": "Abra o Finder e pressione ⌘ + K.", "files-share.instructions.macos.select-registered": "Selecione \"Usuário Registrado\" quando solicitado.", "files-share.instructions.macos.time-machine": "Como usar como local de backup do Time Machine", "files-share.instructions.macos.time-machine.choose-encryption": "Escolha entre backups criptografados ou não criptografados.", "files-share.instructions.macos.time-machine.disk-limit": "Em \"Limite de Uso do Disco\", especifique a quantidade máxima de espaço que deseja reservar no seu Umbrel para backups do Time Machine, depois clique em \"Concluído\".", "files-share.instructions.macos.time-machine.follow-steps": "Siga os passos acima e abra Ajustes do Sistema no seu Mac.", "files-share.instructions.macos.time-machine.go-settings": "Vá em Time Machine e clique em \"Adicionar Disco de Backup...\".", "files-share.instructions.macos.time-machine.select-disk": "Selecione a pasta e clique em \"Configurar Disco...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Siga os passos guiados para configurar seu backup.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Siga os passos acima e depois vá para \"{{settings}}\" > \"{{backups}}\" no seu outro Umbrel.", "files-share.instructions.umbrelos.backup.select-add": "Selecione a opção \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Selecione este dispositivo Umbrel na lista de dispositivos conectados.", "files-share.instructions.umbrelos.backup.title": "Como usar como local de backup para seu outro Umbrel", "files-share.instructions.umbrelos.cant-find-note": "Não consegue encontrar? Tente selecionar \"Adicionar manualmente\" e usar as credenciais abaixo. Se ainda não conseguir adicioná-lo, verifique se os dois dispositivos estão na mesma rede.", "files-share.instructions.umbrelos.enter-password": "Digite {{password}} como senha.", "files-share.instructions.umbrelos.enter-username": "Digite {{username}} como nome de usuário.", "files-share.instructions.umbrelos.open-and-click": "No seu outro Umbrel, abra \"Files\" e clique em ao lado de \" {{deviceLabel}}\" na barra lateral.", "files-share.instructions.umbrelos.select-device": "Selecione este dispositivo Umbrel na lista de dispositivos detectados automaticamente na sua rede.", "files-share.instructions.umbrelos.select-sharename": "Selecione \"{{sharename}}\" e clique para adicionar o compartilhamento.", "files-share.instructions.windows.enter-password": "Insira {{password}} como senha.", "files-share.instructions.windows.enter-url": "Digite {{smbUrl}} e pressione Enter.", "files-share.instructions.windows.enter-username": "Insira {{username}} como nome de usuário.", "files-share.instructions.windows.open-run": "Pressione Windows + R para abrir a janela Executar.", "files-share.instructions.windows.remember-credentials": "Marque \"Remember my credentials\" e clique em OK.", "files-share.regular-description": "Compartilhe esta pasta para acessá-la de outros dispositivos na sua rede", "files-share.regular-title": "Compartilhar pasta pela rede", "files-share.toggle": "Compartilhar \"{{name}}\" na sua rede", "files-sidebar.apps": "Apps", "files-sidebar.external-storage": "Armazenamento externo", "files-sidebar.favorites": "Favoritos", "files-sidebar.home": "Início", "files-sidebar.navigation": "Navegação de arquivos", "files-sidebar.network": "Rede", "files-sidebar.network-pathbar": "Dispositivos de rede", "files-sidebar.network-sidebar": "Dispositivos", "files-sidebar.recents": "Recentes", "files-sidebar.shared-folders": "Pastas compartilhadas", "files-sidebar.trash": "Lixeira", "files-sidebar.trash.open": "Abrir", "files-sort.created": "Adicionado", "files-sort.modified": "Modificado", "files-sort.name": "Nome", "files-sort.size": "Tamanho", "files-sort.type": "Tipo", "files-state.uploading": "Enviando...", "files-state.waiting": "Aguardando...", "files-type.3gp": "Vídeo 3GP", "files-type.3gp2": "Vídeo 3GP2", "files-type.7z": "Arquivo 7Z", "files-type.aac": "Áudio AAC", "files-type.ai": "Arquivo do Illustrator", "files-type.aiff": "Áudio AIFF", "files-type.au": "Áudio AU", "files-type.avi": "Vídeo AVI", "files-type.avif": "Imagem AVIF", "files-type.bmp": "Imagem BMP", "files-type.bzip2": "Arquivo BZIP2", "files-type.caf": "Áudio CAF", "files-type.compressed": "Arquivo compactado", "files-type.csv": "Arquivo CSV", "files-type.directory": "Pasta", "files-type.dmg": "Imagem de disco", "files-type.dv": "Vídeo DV", "files-type.epub": "eBook EPUB", "files-type.excel": "Planilha do Excel", "files-type.exe": "Executável do Windows", "files-type.executable": "Executável", "files-type.external-drive": "Unidade", "files-type.flac": "Áudio FLAC", "files-type.flv": "Vídeo FLV", "files-type.gif": "Imagem GIF", "files-type.gzip": "Arquivo GZIP", "files-type.heic": "Imagem HEIC", "files-type.ico": "Imagem ICO", "files-type.iso": "Imagem ISO", "files-type.jpeg": "Imagem JPEG", "files-type.keynote": "Apresentação do Keynote", "files-type.lzip": "Arquivo LZIP", "files-type.lzma": "Arquivo LZMA", "files-type.lzop": "Arquivo LZOP", "files-type.m3u": "Playlist M3U", "files-type.m4a": "Áudio M4A", "files-type.m4v": "Vídeo M4V", "files-type.midi": "Áudio MIDI", "files-type.mka": "Áudio MKA", "files-type.mkv": "Vídeo MKV", "files-type.mng": "Vídeo MNG", "files-type.mobi": "eBook MOBI", "files-type.mp3": "Áudio MP3", "files-type.mp4": "Vídeo MP4", "files-type.mp4-audio": "Áudio MP4", "files-type.mpeg": "Vídeo MPEG", "files-type.mpeg-ts": "Fluxo de transporte MPEG", "files-type.network-drive": "Unidade de rede", "files-type.numbers": "Planilha do Numbers", "files-type.ogg": "Áudio OGG", "files-type.ogv": "Vídeo OGV", "files-type.pages": "Documento do Pages", "files-type.pdf": "Documento PDF", "files-type.png": "Imagem PNG", "files-type.powerpoint": "Apresentação do PowerPoint", "files-type.psd": "Documento do Photoshop", "files-type.quicktime": "Vídeo QuickTime", "files-type.rar": "Arquivo RAR", "files-type.sgi": "Vídeo SGI", "files-type.svg": "Imagem SVG", "files-type.tar": "Arquivo TAR", "files-type.tiff": "Imagem TIFF", "files-type.ts": "Vídeo TS", "files-type.txt": "Arquivo de texto", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "Áudio WAV", "files-type.webm": "Vídeo WebM", "files-type.webm-audio": "Áudio WebM", "files-type.webp": "Imagem WebP", "files-type.wma": "Áudio WMA", "files-type.wmv": "Vídeo WMV", "files-type.word": "Documento do Word", "files-type.xz": "Arquivo XZ", "files-type.zip": "Arquivo ZIP", "files-upload-island.uploading-count": "Enviando {{count}} itens", "files-view.icons": "Ícones", "files-view.list": "Lista", "files-view.sort-by": "Classificar por", "files-view.view-as": "Exibir como", "files-widgets.favorites.no-items-text": "Adicione uma pasta aos favoritos para vê-la aqui", "files-widgets.recents.no-items-text": "Nenhum arquivo recente", "generic-in": "em", "hide-details": "Ocultar detalhes", "install-first.install-app": "Instalar {{app}}", "install-first.title": "{{app}} requer estes aplicativos", "install-your-first-app": "Instale seu primeiro aplicativo", "language": "Idioma", "language-description": "Seu idioma preferido do umbrelOS", "language.select-description": "Selecionar o idioma preferido do umbrelOS", "live-usage": "Uso ao Vivo", "loading": "Carregando", "local-ip": "IP Local", "login-2fa.subtitle": "Digite o código 2FA exibido no seu aplicativo autenticador", "login-2fa.title": "Autenticar", "login-with-umbrel.description": "Digite sua senha do Umbrel para abrir {{app}}", "login-with-umbrel.title": "Entrar com Umbrel", "login.password-label": "Senha", "login.password.submit": "Entrar", "login.subtitle": "Digite sua senha do Umbrel para fazer login", "login.title": "Bem-vindo de volta", "logout": "Sair", "logout-error-generic": "Erro: Falha ao sair", "logout.confirm.submit": "Sair", "logout.confirm.title": "Você tem certeza que deseja sair?", "memory": "Memória", "memory.low": "Memória baixa", "migrate": "Migrar", "migrate.callout": "Não desligue seu Umbrel até a migração estar completa", "migrate.failed.retry": "Tentar novamente", "migrate.failed.title": "Falha na migração", "migrate.success.description": "Todos os seus aplicativos, dados de aplicativos e detalhes da conta foram migrados para o seu Umbrel Home.", "migrate.success.title": "Migração bem-sucedida", "migration-assistant": "Assistente de Migração", "migration-assistant-description": "Transfira todos os seus aplicativos e dados de um Raspberry Pi para {{deviceName}}", "migration-assistant-unsupported-device-description": "O Assistente de Migração atualmente suporta a transferência de todos os dados e aplicativos de um Raspberry Pi com umbrelOS para Umbrel Home ou Umbrel Pro. Abra o Assistente de Migração no seu Umbrel Home ou Umbrel Pro para começar.", "migration-assistant.continue-migration.ready.submit": "Iniciar migração", "migration-assistant.failed": "Algo não está certo...", "migration-assistant.failed.retrying-message": "Tentando novamente...", "migration-assistant.mobile.start-button": "Iniciar migração", "migration-assistant.prep.body": "Preparar para migração", "migration-assistant.prep.button-continue": "Continuar", "migration-assistant.prep.callout": "Os dados no seu {{deviceName}}, se houver, serão excluídos permanentemente.", "migration-assistant.prep.connect-disk-to-home": "Conecte o disco externo a qualquer porta USB do seu {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Uma vez feito, clique em '{{button}}' abaixo.", "migration-assistant.prep.shut-down-rpi": "Desligue seu Umbrel Raspberry Pi.", "migration-assistant.ready.description": "Todos os seus dados e aplicativos estão prontos para serem migrados para o seu {{deviceName}}", "migration-assistant.ready.hint-header": "Coisas a ter em mente", "migration-assistant.ready.hint-keep-pi-off.description": "Isso ajuda a evitar problemas com aplicativos como o Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Mantenha seu Raspberry Pi desligado após a atualização", "migration-assistant.ready.hint-use-same-password.description": "Lembre-se de usar a senha do seu Umbrel no Raspberry Pi para fazer login no seu {{deviceName}}", "migration-assistant.ready.hint-use-same-password.title": "Use a mesma senha", "migration-assistant.ready.title": "Tudo pronto para migrar!", "mini-browser.default-title": "Selecionar pasta", "mini-browser.empty-external": "Conecte uma unidade externa para que ela apareça aqui.", "mini-browser.empty-network": "Adicione um Umbrel ou um NAS para que ele apareça aqui.", "mini-browser.load-more": "Carregar mais", "mini-browser.load-more-in-folder": "Carregar mais em {{name}}", "mini-browser.loading-more": "Carregando mais…", "mini-browser.select": "Selecionar", "mini-browser.select-folder": "Selecionar pasta", "name": "Nome", "nas": "NAS", "no-forgot-password-message": "Se você perder sua senha, não será possível fazer login no seu Umbrel. Certifique-se de guardá-la em segurança.", "no-results-found": "Nenhum resultado encontrado", "not-found-404": "Código de erro: 404", "not-found-404.back": "Voltar", "not-found-404.home": "Ir para Início", "notifications.backups-failing-location.description": "Backups automáticos para {{location}} estão falhando. Verifique a conexão e reveja suas configurações de Backups.", "notifications.backups-failing.description": "Os Backups automáticos estão falhando. Verifique o local dos Backups e reveja suas configurações.", "notifications.backups-failing.go-to-backups": "Ir para Backups", "notifications.backups-failing.title": "Sem Backups nas últimas 24 horas", "notifications.cpu.too-hot": "Temperatura alta da CPU", "notifications.memory.low": "A memória do seu dispositivo está baixa", "notifications.new-version-available": "{{update}} agora está disponível para instalação", "notifications.raid.issue.description": "Detectado um problema de armazenamento. Verifique o Storage Manager para obter detalhes.", "notifications.raid.issue.title": "Ação urgente necessária", "notifications.ssd.health.description": "Um ou mais SSDs podem precisar de atenção. Verifique o Storage Manager para obter detalhes.", "notifications.ssd.health.title": "Aviso de saúde do SSD", "notifications.storage.full": "O armazenamento do seu dispositivo está cheio", "notifications.view": "Visualizar", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "Ao clicar em 'Próximo', você concorda com os Termos de Serviço do umbrelOS", "onboarding.account-created.youre-all-set-name": "Tudo pronto, {{name}}.", "onboarding.contact-support": "Suporte", "onboarding.create-account": "Criar conta", "onboarding.create-account.confirm-password.input-label": "Confirmar senha", "onboarding.create-account.failed.name-required": "Nome é necessário", "onboarding.create-account.failed.passwords-dont-match": "As senhas não coincidem", "onboarding.create-account.name.input-placeholder": "Seu nome", "onboarding.create-account.password.input-label": "Senha", "onboarding.create-account.submit": "Criar", "onboarding.create-account.submitting": "Criando", "onboarding.create-account.subtitle": "Suas informações de conta são armazenadas apenas no seu Umbrel. Certifique-se de fazer um backup seguro da sua senha, pois não há como redefini-la.", "onboarding.create-instead-long": "Criar nova conta", "onboarding.create-instead-short": "Nova conta", "onboarding.launch-umbrelos": "Iniciar umbrelOS", "onboarding.raid.available-storage": "Armazenamento disponível", "onboarding.raid.change-drives-link": "Precisa adicionar ou trocar as unidades?", "onboarding.raid.configuring.subtitle": "Isso pode levar alguns minutos.", "onboarding.raid.configuring.title": "Configurando seu armazenamento", "onboarding.raid.configuring.warning": "Por favor, não atualize esta página nem desligue seu Umbrel enquanto ele estiver configurando seu armazenamento.", "onboarding.raid.continue": "Continuar", "onboarding.raid.error.detection-instructions": "Desligue o Umbrel Pro, verifique se os SSDs estão corretamente encaixados e tente novamente.", "onboarding.raid.error.no-ssds-detected": "Nenhum SSD detectado", "onboarding.raid.error.no-ssds-instructions": "Desligue o Umbrel Pro e insira pelo menos um SSD para continuar.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Ainda não é possível ativar o FailSafe", "onboarding.raid.failsafe.enable": "Ativar FailSafe", "onboarding.raid.failsafe.mixed-sizes": "O FailSafe é limitado pelo seu menor SSD ({{smallest}}). Espaço extra em SSDs maiores não pode ser usado, deixando {{wasted}} inutilizável.", "onboarding.raid.failsafe.protection-info-2ssds": "O {{protection}} é usado para proteção de dados. Adicione mais um SSD de {{smallest}} para aumentar o armazenamento disponível para {{futureWith3}}, ou adicione mais dois para {{futureWith4}}. Você pode adicionar mais SSDs a qualquer momento.", "onboarding.raid.failsafe.protection-info-3ssds": "O {{protection}} é usado para proteção de dados. Adicione mais um SSD de {{smallest}} para aumentar o armazenamento disponível para {{futureWith4}}. Você pode adicionar mais SSDs a qualquer momento.", "onboarding.raid.failsafe.single-ssd-info": "Você tem apenas um SSD. Adicione pelo menos mais um SSD de {{size}} para ativar a proteção FailSafe dos seus dados. Você pode adicionar mais SSDs a qualquer momento.", "onboarding.raid.failsafe.subtitle": "Se qualquer SSD falhar, seus dados ficam protegidos", "onboarding.raid.failsafe.tip": "Use SSDs do mesmo tamanho para obter o máximo de armazenamento e zero espaço inutilizável.", "onboarding.raid.failsafe.warning-now-only": "Com mais de um SSD, o FailSafe só pode ser ativado durante a configuração inicial. Você não poderá ativá-lo depois.", "onboarding.raid.health-warning": "Esta unidade está apresentando problemas de integridade", "onboarding.raid.launching": "Iniciando...", "onboarding.raid.no-ssds-alt": "Nenhum SSD encontrado", "onboarding.raid.recommended": "Recomendado", "onboarding.raid.scanning": "Verificando os slots de SSD", "onboarding.raid.scanning-alt": "Escaneando SSDs", "onboarding.raid.setup-failed.description-no-retry": "Desligue o Umbrel Pro e tente novamente.", "onboarding.raid.setup-failed.description-retry": "Tente novamente ou desligue o Umbrel Pro para verificar seus SSDs.", "onboarding.raid.setup-failed.title": "Falha na configuração do armazenamento", "onboarding.raid.shutdown-dialog.description": "Para adicionar ou trocar unidades, desligue o Umbrel Pro. Depois de terminar, você pode ligá‑lo novamente e continuar a configuração.", "onboarding.raid.shutdown-dialog.title": "Trocar unidades?", "onboarding.raid.ssd-in-slot": "Um {{size}} SSD em Slot {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "Bandeja do SSD", "onboarding.raid.ssds-found": "Os seguintes SSDs foram encontrados no seu Umbrel Pro", "onboarding.raid.storage": "Armazenamento", "onboarding.raid.storage-label": "Armazenamento", "onboarding.raid.success.storage-info": "Armazenamento {{available}}", "onboarding.raid.success.storage-info-failsafe": "Armazenamento {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Tentar novamente", "onboarding.raid.wasted": "Inutilizável", "onboarding.restore-long": "Restaurar meu Umbrel", "onboarding.restore-short": "Restaurar", "onboarding.start.continue": "Começar", "onboarding.start.subtitle": "Seu servidor de nuvem doméstico está pronto para ser configurado.", "onboarding.start.title": "Bem-vindo ao umbrelOS", "open": "Abrir", "open-live-usage": "Abrir Uso ao Vivo", "password": "Senha", "preferences": "Preferências", "raid-error.description": "Seu sistema de armazenamento não pôde iniciar corretamente. Verifique o status dos seus SSDs abaixo e siga os passos de solução. Se o problema persistir, os SSDs afetados podem precisar ser substituídos.", "raid-error.factory-reset-dialog.description": "Isso apagará todos os dados do seu Umbrel Pro e o resetará para as configurações de fábrica. Esta ação não pode ser desfeita.", "raid-error.factory-reset-dialog.title": "Restaurar de fábrica?", "raid-error.factory-reset-failed": "Não foi possível restaurar as configurações de fábrica", "raid-error.health-warning": "Aviso de saúde", "raid-error.missing-ssd-multiple": "{{count}} SSDs não estão respondendo", "raid-error.missing-ssd-one": "1 SSD não está respondendo", "raid-error.shutdown-dialog.description": "Desligue seu Umbrel Pro, verifique se todos os SSDs estão corretamente encaixados em seus slots e ligue novamente.", "raid-error.shutdown-dialog.title": "Desligar para verificar os SSDs?", "raid-error.ssd-in-slot": "Um SSD de {{size}} em Slot {{slot}}", "raid-error.step-check-connections.button": "Desligar", "raid-error.step-check-connections.description": "Desligue e verifique se todos os SSDs estão devidamente encaixados.", "raid-error.step-check-connections.title": "Verifique as conexões dos SSDs", "raid-error.step-factory-reset.button": "Restaurar de fábrica", "raid-error.step-factory-reset.description": "Último recurso se nada mais funcionar. Isso apaga todos os dados.", "raid-error.step-factory-reset.title": "Restaurar de fábrica", "raid-error.step-restart.button": "Reiniciar", "raid-error.step-restart.description": "Um primeiro passo rápido que costuma ajudar", "raid-error.step-restart.title": "Tente reiniciar", "raid-error.title": "Problema de armazenamento detectado", "read-less": "Ler menos", "read-more": "Ler mais", "reconnect": "Reconectar", "redirect.to-home": "Carregando...", "redirect.to-login": "Carregando...", "redirect.to-onboarding": "Carregando...", "redirect.to-raid-error": "Carregando...", "reload": "Recarregar", "remote-tor-access": "Acesso remoto Tor", "reset": "Restaurar", "restart": "Reiniciar", "restart.confirm.submit": "Reiniciar", "restart.confirm.title": "Você tem certeza de que deseja reiniciar seu Umbrel?", "restart.restarting": "Reiniciando", "restart.restarting-message": "Por favor, não atualize esta página ou desligue seu Umbrel enquanto ele está reiniciando.", "rewind": "Rewind", "rewind.files-as-of": "Seus arquivos em", "rewind.loading-snapshots": "Carregando instantâneos...", "rewind.now": "Agora", "rewind.preflight.description": "Encontre arquivos e pastas dos seus backups antigos e recupere-os para o presente.", "rewind.preflight.enable-backups": "Configure Backups em Configurações para começar a usar Rewind", "rewind.restore-complete": "Restauração concluída", "rewind.restore-error-description": "Por favor, tente novamente.", "rewind.restore-failed": "Falha na restauração", "rewind.restore-running-description": "Não feche nem atualize esta página até que a restauração seja concluída", "rewind.restore-selected": "Restaurar selecionados", "rewind.restore-success-description": "Seus arquivos foram restaurados", "rewind.restoring": "Restaurando", "rewind.snapshots-count_one": "{{count}} backup desde", "rewind.snapshots-count_other": "{{count}} backups desde", "search": "Pesquisar", "settings": "Configurações", "settings.app-store-preferences.title": "Preferências da App Store", "settings.contact-support": "Precisa de ajuda? Contate o suporte.", "settings.file-sharing": "Compartilhamento de arquivos", "settings.file-sharing.add-folder": "Adicionar", "settings.file-sharing.add-folder-title": "Selecione uma pasta para compartilhar", "settings.file-sharing.choice-entire-description": "Compartilhe todos os arquivos no seu Umbrel", "settings.file-sharing.choice-entire-title": "Tudo", "settings.file-sharing.choice-heading": "O que você gostaria de compartilhar?", "settings.file-sharing.choice-specific-description": "Escolha quais pastas compartilhar", "settings.file-sharing.choice-specific-title": "Pastas específicas", "settings.file-sharing.choice-subtitle": "Acesse seus arquivos e pastas no estilo Dropbox como pastas de rede no seu computador ou celular", "settings.file-sharing.configure": "Configurar", "settings.file-sharing.description": "Acesse seus arquivos no estilo Dropbox como uma pasta de rede (SMB) em outros dispositivos", "settings.file-sharing.home-shared-note": "Sua pasta inteira \"{{homeDirectoryName}}\" está compartilhada. Pastas individuais não precisam ser compartilhadas separadamente.", "settings.file-sharing.share-entire-home-dir": "Compartilhar toda a pasta Home", "settings.file-sharing.share-entire-home-dir-description": "Acesse todos os arquivos e pastas em \"{{homeDirectoryName}}\" em outros dispositivos da sua rede", "settings.file-sharing.shared-folders": "Pastas compartilhadas", "show-details": "Mostrar detalhes", "shut-down": "Desligar", "shut-down.complete": "Desligamento completo", "shut-down.complete-text": "Agora você pode desconectar seu dispositivo da energia.", "shut-down.confirm.submit": "Desligar", "shut-down.confirm.title": "Você tem certeza de que deseja desligar seu Umbrel?", "shut-down.failed": "Falha ao desligar: {{message}}", "shut-down.shutting-down": "Desligando", "shut-down.shutting-down-message": "Por favor, não atualize esta página ou desligue seu Umbrel enquanto ele está desligando.", "software-update.callout": "Por favor, não atualize esta página ou desligue seu Umbrel enquanto estiver atualizando.", "software-update.check": "Verificar atualização", "software-update.checking": "Verificando atualização...", "software-update.current-running": "Você está em", "software-update.failed": "Falha ao atualizar", "software-update.failed-to-check": "Falha ao verificar atualizações", "software-update.failed.retry": "Tentar novamente", "software-update.install-now": "Instalar agora", "software-update.new-version": "Nova versão do {{name}} disponível para instalação", "software-update.on-latest": "Você está na última versão do umbrelOS", "software-update.see-whats-new": "Veja o que há de novo", "software-update.title": "Atualização de software", "software-update.updating-to": "Atualizando para {{name}}", "software-update.view": "Visualizar", "something-left": "{{left}} restantes", "something-went-wrong": "⚠ Algo deu errado", "start": "Iniciar", "stop": "Parar", "storage": "Armazenamento", "storage-manager": "Gerenciador de Armazenamento", "storage-manager.add": "Adicionar", "storage-manager.add-to-raid.add-ssd": "Adicionar SSD", "storage-manager.add-to-raid.available": "Disponível:", "storage-manager.add-to-raid.description": "Um novo SSD foi detectado e está pronto para ser adicionado.", "storage-manager.add-to-raid.enable-failsafe": "Ativar FailSafe", "storage-manager.add-to-raid.failed-add": "Não foi possível adicionar o SSD", "storage-manager.add-to-raid.failed-enable-failsafe": "Não foi possível ativar o FailSafe", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Seu novo SSD de {{size}} será adicionado ao armazenamento disponível.", "storage-manager.add-to-raid.info-capacity-adds-available": "Seu novo SSD de {{size}} adicionará {{available}} ao armazenamento disponível.", "storage-manager.add-to-raid.info-capacity-adds-both": "Seu novo SSD de {{size}} adicionará {{available}} ao armazenamento disponível e {{protection}} para proteção de dados.", "storage-manager.add-to-raid.info-capacity-protection-only": "Seu novo SSD de {{size}} adicionará {{protection}} para proteção de dados.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Seu novo SSD de {{size}} será usado inteiramente para proteção de dados.", "storage-manager.add-to-raid.info-data-safe": "Se qualquer SSD falhar, seus dados estarão protegidos.", "storage-manager.add-to-raid.info-no-protection": "Se um SSD falhar, você pode perder seus dados.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} total inutilizável devido a tamanhos diferentes de SSD.", "storage-manager.add-to-raid.info-wasted": "{{size}} ficará inutilizável devido a tamanhos diferentes de SSD.", "storage-manager.add-to-raid.recommended": "Recomendado", "storage-manager.add-to-raid.recommended-inline": "(recomendado)", "storage-manager.add-to-raid.restart-active-tasks": "Quaisquer tarefas ativas serão interrompidas", "storage-manager.add-to-raid.restart-after": "Após a reinicialização, a configuração do FailSafe será concluída automaticamente e você poderá retomar o uso normal.", "storage-manager.add-to-raid.restart-during": "Durante a reinicialização:", "storage-manager.add-to-raid.restart-intro": "Você pode continuar usando o umbrelOS normalmente durante este processo. Entretanto, ao atingir 50% de progresso seu Umbrel reiniciará automaticamente.", "storage-manager.add-to-raid.restart-required": "Reinicialização do sistema necessária", "storage-manager.add-to-raid.restart-ui-inaccessible": "O umbrelOS ficará temporariamente inacessível", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD em Slot {{slot}}", "storage-manager.add-to-raid.title": "Adicionar SSD ao armazenamento", "storage-manager.add-to-raid.too-small": "SSD pequeno demais", "storage-manager.add-to-raid.too-small-description": "Este SSD ({{deviceSize}}) é menor que o menor SSD atualmente instalado ({{minSize}}). O FailSafe exige que todos os SSDs sejam, no mínimo, do mesmo tamanho do menor SSD em uso.", "storage-manager.add-to-raid.understand-continue": "Entendi, continuar", "storage-manager.add-to-raid.warning-failsafe-now-only": "Ter mais de um SSD significa que o FailSafe só pode ser ativado agora. Você não poderá ativá-lo depois.", "storage-manager.add-to-raid.wasted-label": "Inutilizável:", "storage-manager.available-storage": "Armazenamento disponível", "storage-manager.description": "Veja o armazenamento, a saúde e as configurações dos seus SSDs", "storage-manager.empty": "Vazio", "storage-manager.failsafe-transition-failed": "Não foi possível ativar o FailSafe", "storage-manager.for-failsafe": "Para FailSafe", "storage-manager.health.checksum-errors": "Erros de checksum: {{count}}", "storage-manager.health.critical": "Crítico", "storage-manager.health.critical-threshold": "Limite crítico", "storage-manager.health.current-temperature": "Temperatura atual", "storage-manager.health.estimated-life": "Vida útil estimada restante", "storage-manager.health.general": "Geral", "storage-manager.health.health-status": "Estado de saúde", "storage-manager.health.low": "Baixo", "storage-manager.health.model-and-capacity": "Modelo e tamanho", "storage-manager.health.overheating": "Superaquecimento", "storage-manager.health.raid-failed-advice": "Este SSD apresenta um problema. Desligue seu Umbrel e verifique a conexão do SSD. Se o problema continuar, pode ser necessário substituir o SSD.", "storage-manager.health.read-errors": "Erros de leitura: {{count}}", "storage-manager.health.serial-number": "Número de série", "storage-manager.health.status-healthy": "Saudável", "storage-manager.health.status-unhealthy": "Não saudável", "storage-manager.health.status-unknown": "Desconhecido", "storage-manager.health.temperature": "Temperatura", "storage-manager.health.title": "Saúde do SSD", "storage-manager.health.warning-life-advice": "Considere substituir este SSD em breve.", "storage-manager.health.warning-life-message": "Apenas {{percent}}% de vida restante", "storage-manager.health.warning-temp-advice": "Certifique-se de que seu Umbrel Pro tenha boa ventilação e que o SSD esteja bem encaixado.", "storage-manager.health.warning-temp-critical": "Temperatura crítica ({{temperature}})", "storage-manager.health.warning-temp-overheating": "A unidade está superaquecendo ({{temperature}})", "storage-manager.health.warning-threshold": "Limite de aviso", "storage-manager.health.warning-unhealthy-advice": "Este SSD pode falhar em breve. Considere substituí-lo.", "storage-manager.health.warning-unhealthy-message": "Este SSD pode ter um problema", "storage-manager.health.warnings": "Avisos", "storage-manager.health.wear": "Desgaste", "storage-manager.health.write-errors": "Erros de gravação: {{count}}", "storage-manager.install-ssd.description": "Adicione mais SSDs para expandir seu armazenamento", "storage-manager.install-ssd.step-insert": "Insira os novos SSDs nos slots vazios", "storage-manager.install-ssd.step-power-on": "Ligue seu {{deviceName}}", "storage-manager.install-ssd.step-remove-bottom-cover": "Remova a tampa inferior magnética", "storage-manager.install-ssd.step-replace-bottom-cover": "Recoloque a tampa inferior", "storage-manager.install-ssd.step-return": "Volte aqui para adicionar os SSDs ao seu armazenamento", "storage-manager.install-ssd.step-shut-down": "Desligue seu {{deviceName}}", "storage-manager.install-ssd.title": "Adicionando SSDs", "storage-manager.install-tips.image-alt": "Instrução de instalação do SSD", "storage-manager.install-tips.instructions": "Para instalar, remova o parafuso de aperto e deslize o SSD no slot em um ângulo. Pressione o SSD para baixo até que ele encoste no pilar do parafuso e então fixe-o com o parafuso de aperto.", "storage-manager.install-tips.toggle": "Esqueceu como inserir um SSD?", "storage-manager.manage": "Gerenciar", "storage-manager.missing-ssd-warning": "Parece que um SSD está faltando. Desligue seu Umbrel e verifique se todos os SSDs estão conectados. Se o problema persistir, pode ser necessário substituir o SSD.", "storage-manager.mode": "Modo", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Mantém seus dados seguros se um SSD falhar. Se seus SSDs tiverem tamanhos diferentes, o espaço extra nos maiores fica inutilizável.", "storage-manager.mode.failsafe.info-description": "O FailSafe protege seus dados mantendo cópias deles entre seus SSDs. Se qualquer SSD falhar, seus dados permanecem seguros e podem ser restaurados ao adicionar um SSD de substituição.", "storage-manager.mode.failsafe.info-title": "Sobre FailSafe", "storage-manager.mode.full-storage": "Full Storage", "storage-manager.mode.full-storage.description": "Use todo o espaço dos seus SSDs em conjunto. Se um SSD falhar, você pode perder seus dados.", "storage-manager.mode.full-storage.info-description": "Full Storage combina todos os seus SSDs em um único espaço grande, oferecendo o máximo de armazenamento. No entanto, se qualquer SSD falhar, todos os seus dados serão perdidos.", "storage-manager.mode.full-storage.info-title": "Sobre Full Storage", "storage-manager.mode.switch-from-failsafe-unavailable": "Mudar de FailSafe para Full Storage requer fazer backup dos seus dados, restaurar o dispositivo para as configurações de fábrica e restaurar a partir de um backup.", "storage-manager.mode.switch-to-failsafe-unavailable": "Com múltiplos SSDs em Full Storage, seus dados ficam distribuídos por todas as unidades. Mudar para FailSafe exige fazer backup dos dados, restaurar o dispositivo para as configurações de fábrica e restaurar o backup.", "storage-manager.mode.why-cant-switch": "Por que não consigo alternar?", "storage-manager.operation-in-progress.shutdown-description": "É seguro desligar. A operação será pausada e retomada após a reinicialização, mas precisa ser concluída antes que você possa fazer outras alterações.", "storage-manager.operation-in-progress.shutdown-title": "Seu armazenamento está sendo atualizado", "storage-manager.operation-in-progress.wait-description": "Aguarde a conclusão da operação atual antes de fazer mais alterações.", "storage-manager.operation-in-progress.wait-title": "Seu armazenamento está sendo atualizado", "storage-manager.operation.adding-ssd": "Adicionando SSD...", "storage-manager.operation.enabling-failsafe": "Ativando FailSafe...", "storage-manager.operation.expanding": "Expandindo o armazenamento...", "storage-manager.operation.rebuilding": "Reconstruindo dados...", "storage-manager.operation.replacing": "Substituindo unidade...", "storage-manager.operation.restarting": "Reiniciando...", "storage-manager.operation.starting": "Iniciando...", "storage-manager.operation.syncing-restarts": "Sincronizando dados • Reinicia aos 50%", "storage-manager.raid-status.degraded": "Degradado", "storage-manager.raid-status.failed": "Falha", "storage-manager.raid-status.offline": "Offline", "storage-manager.raid-status.online": "Online", "storage-manager.raid-status.removed": "Removido", "storage-manager.raid-status.unavailable": "Indisponível", "storage-manager.replace": "Substituir", "storage-manager.replace-failed.degraded": "Proteção FailSafe reduzida", "storage-manager.replace-failed.degraded-description": "Falta um SSD no seu armazenamento FailSafe. Substitua-o para restaurar a proteção completa.", "storage-manager.replace-failed.description": "Use este SSD para restaurar a proteção FailSafe.", "storage-manager.replace-failed.error": "Não foi possível iniciar a substituição", "storage-manager.replace-failed.replace-now": "Substituir agora", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD na baia {{slot}}", "storage-manager.replace-failed.step-protected": "Ao terminar, seus dados estarão totalmente protegidos novamente", "storage-manager.replace-failed.step-rebuild": "Os dados serão reconstruídos no novo SSD", "storage-manager.replace-failed.step-time": "Isso pode levar algum tempo, dependendo de quanto dados você tem", "storage-manager.replace-failed.title": "Substituir SSD", "storage-manager.replace-failed.too-small": "SSD pequeno demais", "storage-manager.replace-failed.too-small-description": "Este SSD ({{deviceSize}}) é menor que o mínimo exigido ({{minSize}}) para o seu armazenamento FailSafe.", "storage-manager.replace-failed.what-happens": "O que acontece a seguir:", "storage-manager.ssd-failing": "Com falha", "storage-manager.swap": "Trocar", "storage-manager.swap.data-erased-description": "O modo Full Storage não oferece proteção de dados. Todos os dados no seu {{deviceName}} serão apagados durante a restauração de fábrica. Certifique-se de fazer backup de tudo primeiro.", "storage-manager.swap.data-protected": "Seus dados estão protegidos", "storage-manager.swap.data-protected-description": "Com o FailSafe ativado, você pode trocar qualquer SSD individual sem perder seus dados. Nenhum backup necessário.", "storage-manager.swap.data-will-be-erased": "Os dados serão apagados", "storage-manager.swap.description-failsafe": "Substitua uma unidade no seu armazenamento FailSafe.", "storage-manager.swap.description-full-storage": "Substitua uma unidade na sua configuração Full Storage.", "storage-manager.swap.description-no-free-slot": "No modo Full Storage com todos os slots ocupados, trocar um SSD requer um processo completo de backup e restauração.", "storage-manager.swap.description-replace": "Migre seus dados para um novo SSD e então remova o antigo.", "storage-manager.swap.failed-to-start": "Não foi possível iniciar a substituição", "storage-manager.swap.no-data-loss": "Sem perda de dados", "storage-manager.swap.no-data-loss-description": "Seus dados serão copiados para o novo SSD. Quando concluído, você poderá remover o antigo com segurança.", "storage-manager.swap.safe-swap-available": "Troca segura disponível", "storage-manager.swap.safe-swap-description": "Como você tem um slot vazio, pode adicionar o novo SSD primeiro e migrar seus dados antes de remover o antigo. Nenhum backup necessário.", "storage-manager.swap.select-new-ssd": "Selecione o novo SSD a ser usado:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD no Slot {{slot}}", "storage-manager.swap.step-backup": "Faça backup dos seus dados", "storage-manager.swap.step-backup-description": "Vá em Configurações → Backups e crie um backup de todos os seus dados.", "storage-manager.swap.step-data-copied": "Os dados serão copiados do SSD antigo para o novo", "storage-manager.swap.step-factory-reset": "Restaurar de fábrica", "storage-manager.swap.step-factory-reset-description": "Vá em Configurações → Avançado → Restaurar de fábrica para apagar seu {{deviceName}}.", "storage-manager.swap.step-insert-new-ssd": "Insira o novo SSD em um slot vazio", "storage-manager.swap.step-may-take-while": "Isso pode demorar um pouco dependendo da quantidade de dados que você tem", "storage-manager.swap.step-power-on": "Ligue seu {{deviceName}}", "storage-manager.swap.step-remove-bottom-cover": "Remova a tampa inferior magnética", "storage-manager.swap.step-remove-old": "Quando concluído, desligue e remova {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Recoloque a tampa inferior", "storage-manager.swap.step-restore": "Restaure seus dados", "storage-manager.swap.step-restore-description": "Vá em Configurações → Backups e restaure a partir do seu backup.", "storage-manager.swap.step-return-to-storage-manager": "Volte aqui ao Gerenciador de Armazenamento para confirmar a troca e adicionar o novo SSD ao seu armazenamento", "storage-manager.swap.step-return-to-swap": "Volte aqui ao Gerenciador de Armazenamento e clique em \"Trocar\" novamente para iniciar a substituição", "storage-manager.swap.step-setup-new-storage": "Configure seu novo armazenamento", "storage-manager.swap.step-setup-new-storage-description": "Ligue seu {{deviceName}} e conclua o processo de configuração com seu novo SSD.", "storage-manager.swap.step-shut-down": "Desligue seu {{deviceName}}", "storage-manager.swap.step-shut-down-and-swap": "Desligue e troque {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Desligue, abra seu dispositivo, substitua o SSD e remonte-o.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Desligue, remova a tampa inferior, substitua o SSD e feche a tampa.", "storage-manager.swap.step-swap-ssd": "Troque {{ssd}} por um novo do mesmo tamanho", "storage-manager.swap.too-small": "Pequeno demais (requer {{size}})", "storage-manager.swap.what-happens-next": "O que acontece a seguir:", "storage-manager.total-capacity-added": "Capacidade total adicionada", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Usado", "storage-manager.wasted": "Inutilizável", "storage-manager.wasted-size": "{{size}} Inutilizável", "storage.full": "Armazenamento cheio", "storage.low": "Armazenamento baixo", "temperature": "Temperatura", "temperature.dangerously-hot": "Muito quente", "temperature.nice": "Agradável", "temperature.normal": "Normal", "temperature.too-hot-suggestion": "Considere mudar o ambiente do seu dispositivo.", "temperature.warm": "Morno", "terminal": "Terminal", "terminal-description": "Execute comandos personalizados no umbrelOS ou dentro de um app", "terminal.app": "App", "terminal.app-description": "Execute comandos personalizados dentro de um app específico", "terminal.umbrelos-description": "Execute comandos personalizados no umbrelOS", "tor-description": "Acesse seu Umbrel de qualquer lugar usando um navegador Tor", "tor-enabled-description": "Acesse seu Umbrel de qualquer lugar usando um navegador Tor na URL abaixo:", "tor-error": "Falha ao atualizar a configuração do Tor: {{message}}", "tor.disable.description": "Isso pode levar alguns minutos", "tor.disable.progress": "Desativando o acesso remoto via Tor", "tor.enable.description": "Isso pode levar alguns minutos", "tor.enable.mobile.switch-label": "Ativar acesso remoto Tor", "tor.hidden-service": "URL do serviço oculto Tor", "troubleshoot": "Solucionar problemas", "troubleshoot-description": "Solucione problemas do umbrelOS ou de um aplicativo", "troubleshoot-no-logs-yet": "Ainda não há registros", "troubleshoot-pick-title": "Solucionar problemas", "troubleshoot.app": "Aplicativo", "troubleshoot.app-description": "Ver registros de um aplicativo instalado no seu Umbrel", "troubleshoot.app-download": "Baixar registros do {{app}}", "troubleshoot.share-with-umbrel-support": "Compartilhar com o Suporte Umbrel", "troubleshoot.system-download": "Baixar {{label}}", "troubleshoot.umbrelos-description": "Ver logs do umbrelOS", "troubleshoot.umbrelos-logs": "Registros do umbrelOS", "trpc.backend-unavailable": "Erro: A conexão com a API do sistema falhou", "trpc.checking-backend": "Carregando...", "try-again": "Tentar novamente", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Desconhecido", "unknown-app": "Aplicativo desconhecido", "unknown-error": "Erro desconhecido", "uptime": "Tempo de funcionamento", "url": "URL", "wallpaper": "Papel de parede", "wallpaper-description": "Seu papel de parede e tema do Umbrel", "whats-new.continue": "Continuar", "whats-new.feature-1.description": "Configure backups automáticos e criptografados de todo o seu Umbrel para um disco USB externo, um NAS ou outro Umbrel.", "whats-new.feature-2.description": "Volte no tempo para recuperar arquivos e pastas específicos de backups anteriores.", "whats-new.feature-3.description": "Ou restaure todo o seu Umbrel, incluindo todos os seus aplicativos, arquivos e dados.", "whats-new.feature-4.description": "Conecte um NAS ou outro Umbrel e acesse o armazenamento dele pelo Files.", "whats-new.feature-4.title": "Dispositivos de Rede", "whats-new.feature-5.description": "Conecte unidades USB externas (no Umbrel Home ou em qualquer dispositivo Intel ou AMD) e acesse-as pelo Files.", "whats-new.feature-5.helper-text": "Não é compatível com dispositivos Raspberry Pi devido a possíveis problemas de energia.", "whats-new.feature-5.title": "Armazenamento externo", "whats-new.next": "Próximo", "whats-new.title": "Novidades em {{version}}", "widget.progress.in-progress": "Em andamento", "widgets.edit.select-up-to-3-widgets": "Selecione até 3 widgets", "widgets.install-an-app-before-using-widgets": "Instale um aplicativo para começar a personalizar sua tela inicial com widgets.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Redes abertas podem ser inseguras", "wifi-connection-failed": "Não foi possível conectar", "wifi-dangerous-change-confirmation-description": "Mudar a rede Wi-Fi pode desconectá-lo do seu Umbrel. Para reconectar, certifique-se de que tanto o seu Umbrel quanto o dispositivo de onde você está acessando estejam na mesma rede.", "wifi-dangerous-change-confirmation-title": "Tem certeza de que deseja mudar a rede Wi-Fi?", "wifi-dangerous-disable-confirmation-description": "Desativar o Wi-Fi pode desconectá-lo do seu Umbrel. Para reconectar, conecte um cabo Ethernet ao seu Umbrel e certifique-se de que tanto o seu Umbrel quanto o dispositivo de onde você está acessando estejam na mesma rede.", "wifi-dangerous-disable-confirmation-title": "Tem certeza de que deseja desativar o Wi-Fi?", "wifi-description": "Conecte seu dispositivo a uma rede Wi-Fi", "wifi-description-long": "Seu dispositivo permanece conectado ao Wi-Fi escolhido, mesmo que o cabo Ethernet seja removido, e reconecta-se automaticamente ao Wi-Fi ao iniciar.", "wifi-no-networks-message": "Nenhuma rede Wi-Fi encontrada", "wifi-searching": "Procurando redes Wi-Fi...", "wifi-unsupported-device-description": "O Wi-Fi não é suportado neste dispositivo. Isso pode ser devido a um adaptador sem fio ausente ou incompatível.", "wifi-view-networks": "Ver redes" } ================================================ FILE: packages/ui/public/locales/tr.json ================================================ { "2fa": "2FA", "2fa-description": "Umbrel girişiniz ve uygulamalarınız için ikinci bir güvenlik katmanı", "2fa.disable.title": "İki faktörlü kimlik doğrulamayı devre dışı bırak", "2fa.enable.or-paste": "Veya aşağıdaki kodu kimlik doğrulama uygulamanıza yapıştırın", "2fa.enable.scan-this": "Google Authenticator veya Authy gibi bir kimlik doğrulama uygulamasıyla bu QR kodunu tarayın", "2fa.enable.title": "İki faktörlü kimlik doğrulamayı etkinleştir", "2fa.enter-code": "Kimlik doğrulama uygulamanızda görüntülenen kodu girin", "account": "Hesap", "account-description": "Adınız ve şifreniz", "advanced-settings": "Gelişmiş ayarlar", "advanced-settings-description": "Terminal, umbrelOS Beta Programı, Cloudflare DNS ve daha fazlası", "app-not-found": "Uygulama bulunamadı: {{app}}", "app-only-over-tor": "{{app}} sadece Tor üzerinden kullanılabilir. Bu uygulamayı açmak için lütfen uzak erişim URL'nizde (Ayarlar > Gelişmiş ayarlar > Uzaktan Tor erişimi) Tor tarayıcısı ile Umbrel'inize erişin.", "app-page.section.about": "Hakkında", "app-page.section.credentials.title": "Varsayılan kimlik bilgileri", "app-page.section.dependencies.n-alternatives": "{{count}} alternatiflere bak", "app-page.section.info.compatibility": "Uyumluluk", "app-page.section.info.compatibility-compatible": "Uyumlu", "app-page.section.info.compatibility-not-compatible": "Uyumlu değil", "app-page.section.info.developer": "Geliştirici", "app-page.section.info.source-code": "Kaynak Kodu", "app-page.section.info.source-code.public": "Herkese açık", "app-page.section.info.submitted-by": "Gönderen", "app-page.section.info.support": "Destek al", "app-page.section.info.title": "Bilgi", "app-page.section.info.version": "Sürüm", "app-page.section.recommendations.title": "Bunları da beğenebilirsiniz", "app-page.section.release-notes.title": "Yenilikler", "app-page.section.release-notes.version": "Sürüm {{version}}", "app-page.section.requires": "Gereksinimler", "app-picker.search": "Ara...", "app-picker.select-app": "Uygulama seç...", "app-settings.connected-to": "{{appName}} bu uygulamalara bağlı", "app-settings.save-changes": "Değişiklikleri kaydet", "app-settings.title": "Ayarlar", "app-store.browse-category-apps": "{{category}} uygulamalarına göz at", "app-store.category.ai": "Yapay Zeka", "app-store.category.all": "Tüm uygulamalar", "app-store.category.automation": "Ev ve Otomasyon", "app-store.category.bitcoin": "Bitcoin", "app-store.category.crypto": "Kripto", "app-store.category.developer": "Geliştirici Araçları", "app-store.category.discover": "Keşfet", "app-store.category.files": "Dosyalar ve Üretkenlik", "app-store.category.finance": "Finans", "app-store.category.media": "Medya", "app-store.category.networking": "Ağ", "app-store.category.social": "Sosyal", "app-store.description": "Uygulama güncelleme ayarlarınız", "app-store.discover.temporarily-unavailable-description": "Uygulama bulmak için yukarıdaki kategorilere göz atabilir veya arama yapabilirsiniz", "app-store.discover.temporarily-unavailable-title": "Öne çıkan içerik şu anda kullanılamıyor", "app-store.menu.community-app-stores": "Topluluk Uygulama Mağazaları", "app-store.search-apps": "Uygulama ara", "app-store.search.no-results": "Sonuç yok", "app-store.search.results-for": "Sonuçlar", "app-store.title": "Uygulama Mağazası", "app-store.updates": "Güncellemeler", "app-updates.less": "daha az", "app-updates.more": "daha fazla", "app-updates.no-updates": "Tüm uygulamalar güncel!", "app-updates.update": "Güncelle", "app-updates.update-all": "Hepsini güncelle", "app-updates.updates-available-count_one": "{{count}} güncelleme mevcut", "app-updates.updates-available-count_other": "{{count}} güncelleme mevcut", "app-updates.updating": "Güncelleniyor...", "app.install": "Yükle", "app.installed": "Yüklendi", "app.installing": "Yükleniyor", "app.offline": "Çalışmıyor", "app.open": "Aç", "app.optimized-for-umbrel-home": "Umbrel Home için optimize edilmiş", "app.os-update-required.confirm": "umbrelOS güncellemelerini kontrol et", "app.os-update-required.description": "{{appName}} için umbrelOS {{version}} veya daha yenisi gerekiyor", "app.os-update-required.title": "umbrelOS'u güncelle", "app.restarting": "Yeniden başlatılıyor", "app.starting": "Başlatılıyor", "app.stopping": "Durduruluyor", "app.uninstall.confirm.description": "{{app}} ile ilgili tüm veriler kalıcı olarak silinecek. Bu işlem geri alınamaz.", "app.uninstall.confirm.submit": "Kaldır", "app.uninstall.confirm.title": "{{app}} kaldırılacak mı?", "app.uninstall.deps.used-by.description_one": "{{app}}'i kaldırmak için önce {{firstAppToUninstall}}'i kaldırın.", "app.uninstall.deps.used-by.description_other": "{{app}}'i kaldırmak için önce bu uygulamaları kaldırın.", "app.uninstall.deps.used-by.title": "{{app}} kullanılıyor", "app.uninstalling": "Kaldırılıyor", "app.updating": "Güncelleniyor", "app.view": "Görünüm", "app_one": "uygulama", "app_other": "uygulamalar", "apps.uninstall.failed-to-get-required-apps": "Gerekli uygulamalar alınamadı", "apps.uninstalled-all.success": "Tüm uygulamalar kaldırıldı", "auth.checking-backend-for-user": "Yükleniyor...", "auth.failed-checking-if-user-logged-in": "Hata: Kimlik doğrulama giriş kontrolü başarısız", "auth.failed-to-check-if-user-exists": "Hata: Kimlik doğrulama varlık kontrolü başarısız oldu", "back": "Geri", "backups": "Backups", "backups-configure": "Yapılandır", "backups-configure.add-backup-location": "Yedek konumu ekle", "backups-configure.available": "Kullanılabilir", "backups-configure.awaiting-next-backup": "Bir sonraki otomatik yedeği bekleniyor", "backups-configure.back-up-now": "Şimdi yedekle", "backups-configure.backing-up-now": "Yedekleniyor...", "backups-configure.connected": "Bağlı", "backups-configure.connection": "Bağlantı", "backups-configure.in-progress": "Devam ediyor", "backups-configure.last-backup": "Son yedek", "backups-configure.locations": "Konumlar", "backups-configure.no-backup-locations": "Verilerinizi yedeklemeye başlamak için bir yedek konumu ekleyin", "backups-configure.not-connected": "Bağlı değil", "backups-configure.path": "Yol", "backups-configure.remove-backup-location": "Yedek konumunu kaldır", "backups-configure.remove-backup-location-confirmation": "Emin misin?", "backups-configure.remove-backup-location-confirmation-description": "Bu, '{{device}}' öğesini yedek konumlarınızdan kaldıracaktır. Bu cihazdaki mevcut yedekler silinmeyecek, ancak otomatik yedeklemeler duracaktır.", "backups-configure.status": "Durum", "backups-configure.total-backups": "Toplam Backups", "backups-configure.used": "Kullanılan", "backups-configure.view": "Görüntüle", "backups-description": "Dosyalarınızı, uygulamalarınızı ve verilerinizi başka bir Umbrel'e, NAS'a veya harici sürücüye yedekleyin", "backups-error.backup-not-found": "Yedek bulunamadı.", "backups-error.generic": "Bir şeyler ters gitti: {{details}}", "backups-error.in-progress": "Bir yedekleme işlemi zaten çalışıyor. Bitmesini bekleyin lütfen.", "backups-error.invalid-exclusion-path": "Yedeklerden yalnızca Home dizininizdeki dosya ve klasörler hariç tutulabilir.", "backups-error.invalid-password": "Şifreleme parolası yanlış.", "backups-error.invalid-path": "Seçilen konum yedeklemeler için geçerli değil.", "backups-error.mount-failed": "Yedek anlık görüntüsüne erişilemedi.", "backups-error.mount-timeout": "Yedek anlık görüntüsüne erişilemedi. Tekrar deneyin veya cihazın düzgün bağlandığından emin olun.", "backups-error.not-enough-space": "Yedekleme cihazında yeterli alan yok.", "backups-error.not-found": "Yedek veya yedekleme konumu bulunamadı.", "backups-error.repository-exists": "Bu klasörde zaten bir yedekleme konumu var.", "backups-error.repository-not-found": "Yedekleme konumu bulunamadı.", "backups-exclusions.add": "Ekle", "backups-exclusions.app-paths-cannot-be-modified": "Bu dosya/klasör yolları uygulama geliştiricisi tarafından belirlenmiştir ve değiştirilemez:", "backups-exclusions.app-paths-explanation": "Bu uygulama aşağıdaki verileri yedeklemelerden hariç tutar. Bu yollar genellikle yeniden oluşturulabilecek önemsiz öğeler (ör. önbellekler veya günlükler) veya geri yüklendiğinde sorun yaratabilecek veriler (ör. çakışmalara veya tutarsızlıklara yol açabilecek eski uygulama durumları) içerir.", "backups-exclusions.auto-excluded": "Otomatik hariç tutuldu", "backups-exclusions.exclude-entire-app": "Uygulamayı tamamen hariç tut", "backups-exclusions.excluded-apps": "Hariç tutulan uygulamalar", "backups-exclusions.files-and-folders": "Hariç tutulan dosya ve klasörler", "backups-exclusions.no-excluded-apps": "Hariç tutulan uygulama yok", "backups-exclusions.no-excluded-files-or-folders": "Hariç tutulan dosya veya klasör yok", "backups-exclusions.select-item-to-exclude": "Hariç tutulacak öğeyi seç", "backups-exclusions.stop-excluding": "Hariç tutmayı bırak", "backups-floating-island.backing-up": "Yedekleniyor...", "backups-floating-island.backing-up-to": "Umbrel'iniz yedekleniyor...", "backups-restore": "Geri yükle", "backups-restore-full": "Tam Geri Yükleme", "backups-restore-full-description": "Umbrel'in tamamını bir yedekten geri yükleyin", "backups-restore-header": "Umbrel'inizi geri yükleyin", "backups-restore-pro.after-restore": "Geri yüklemeden sonra geçici hesabınız yedeklenmiş hesabınız ve verilerinizle değiştirilecek.", "backups-restore-pro.step1": "Aşağıdaki \"Başlayın\" düğmesine tıklayarak ilk kurulumu tamamlayın. Bu, yedeklenmiş hesabınızı geri yükleyene kadar geçici hesabınız olacak.", "backups-restore-pro.step2": "Kurulum tamamlandıktan sonra <0>Ayarlar → Yedekler → Geri Yükle yolunu izleyin.", "backups-restore-pro.step3": "Geri Yükleme Sihirbazı'ndaki yönergeleri izleyin.", "backups-restore-pro.subtitle": "Umbrel Pro'da bir yedekten geri yükleme birkaç ek adım gerektirir", "backups-restore.backup-date": "Yedek tarihi", "backups-restore.backup-location": "Yedek konumu", "backups-restore.browse-cloud-subtitle": "Umbrel Private Cloud'dan geri yükleyin (yakında)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Harici bir USB sürücüden geri yükle", "backups-restore.browse-external-title": "Harici Disk", "backups-restore.browse-nas-or-external": "Bir yedekten geri yüklemek için başka bir Umbrel, NAS veya harici sürücüye göz atın", "backups-restore.browse-nas-subtitle": "Ağınızdaki başka bir Umbrel veya NAS cihazından geri yükleyin.", "backups-restore.browse-nas-title": "Başka bir Umbrel veya NAS", "backups-restore.choose": "Seç", "backups-restore.choose-backup-location": "Bir yedek konumu seçin", "backups-restore.connect-to-backup-location": "Bir yedek konumuna bağlanın", "backups-restore.encryption-password": "Şifreleme parolası", "backups-restore.encryption-password-description": "Backups'ı etkinleştirdiğinizde belirlediğiniz şifreleme parolasını girin", "backups-restore.enter-password-to-confirm": "Onaylamak için Umbrel parolanızı girin", "backups-restore.final-confirmation": "Emin misin?", "backups-restore.final-confirmation-description": "Bu yedekten geri yükleme, mevcut umbrelOS uygulamalarınızı ve verilerinizi seçili yedeğin içeriğiyle değiştirecektir. Bu yedekten hariç tutulan dosya, klasör veya uygulamalar Umbrel'inizden kaldırılacaktır. Bu işlem geri alınamaz.", "backups-restore.invalid-password": "Geçersiz parola", "backups-restore.last-backup": "Son yedek: {{date}}", "backups-restore.latest": "En son", "backups-restore.no-backups-found": "Yedek bulunamadı", "backups-restore.no-backups-yet": "Henüz yedek yok", "backups-restore.please-select-backup": "Lütfen bir yedek seçin", "backups-restore.please-select-repository": "Lütfen bir depo seçin", "backups-restore.restore-from-nas-or-external": "Umbrel'inizi başka bir Umbrel'deki, bir NAS'taki veya harici bir sürücüdeki backup'tan geri yükleyin", "backups-restore.restore-from-unlisted": "Başka bir konumdan geri yükle", "backups-restore.restore-umbrel": "Umbrel'i geri yükle", "backups-restore.restore-warning": "Bu yedekten geri yükleme, mevcut umbrelOS uygulamalarınızı ve verilerinizi seçili yedeğin içeriğiyle değiştirecektir. Bu yedekten hariç tutulan dosya, klasör veya uygulamalar Umbrel'inizden kaldırılacaktır. Eğer belirli dosya veya klasörleri geri yüklemek istiyorsanız, <0>Rewind'i açın.", "backups-restore.restoring-from": "Aşağıdaki backup'tan geri yükleme yapacaksınız:", "backups-restore.review-description": "Geri yükleme, Umbrel'inizi bu backup'ın oluşturulduğu zamandaki hesap, dosyalar, uygulamalar ve ayarlarla yapılandırır. Bu biraz zaman alabilir. İşlem tamamlandığında, giriş şifreniz backup oluşturulurken kullandığınız şifre olarak ayarlanacaktır.", "backups-restore.select-backup": "Bir yedek seçin", "backups-restore.select-backup-description": "Geri yüklemek istediğiniz yedeği seçin", "backups-restore.select-backup-file": "Yedek dosyanızı seç", "backups-restore.select-backup-file-only": "Sadece {{backupFileName}} seçilebilir", "backups-restore.total-size": "Toplam boyut", "backups-restore.unknown-date": "Bilinmeyen tarih", "backups-restore.unknown-repository": "Bilinmeyen depo", "backups-rewind": "Rewind", "backups-rewind-description": "Zamanda geriye giderek belirli dosya ve klasörleri geri yükleyin", "backups-rewind.start": "Rewind'i başlat", "backups-setup": "Kur", "backups-setup-confirm": "Kurulumu tamamla", "backups-setup-external-description": "Harici bir USB sürücüye yedekleyin", "backups-setup-nas-or-umbrel-description": "Ağınızdaki başka bir Umbrel'e veya NAS cihazına yedekleyin", "backups-setup-umbrel-or-nas": "Başka bir Umbrel veya NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Evden dışarıda da içinizi rahatlatın: Umbrel Private Cloud'a uçtan uca şifrelenmiş yedekler gönderin.", "backups-setup-umbrel-private-cloud-cta-link": "Erken erişim alın", "backups-setup-umbrel-private-cloud-description": "Umbrel Private Cloud'a uçtan uca şifrelenmiş yedekler", "backups-setup-umbrel-private-cloud-subtitle": "Yakında", "backups.add-umbrel-or-nas": "Umbrel veya NAS ekle", "backups.all-apps-and-data-will-be-backed-up": "Tüm uygulamalar ve veriler yedeklenecek", "backups.apps-and-data": "Uygulamalar ve veriler", "backups.backup-location": "Yedek konumu", "backups.browse": "Göz at", "backups.choose-folder-within-device": "Yedeklerinizi kaydetmek için {{device}} içindeki bir klasörü seçin", "backups.confirm-password": "Parolayı onayla", "backups.copy": "Kopyala", "backups.encryption": "Şifreleme", "backups.encryption-password-warning": "Şifreleme parolanızı bir parola yöneticisi gibi güvenli bir yerde sakladığınızdan emin olun. Bu parolayı bir daha göremeyeceksiniz ve yedeklerden geri yüklemek için buna ihtiyacınız olacak.", "backups.exclude-from-backups": "Backups'tan hariç tut", "backups.exclude-from-backups-description": "Belirli dosya, klasör ve uygulamaları yedeklerinizden hariç tutun.", "backups.hide": "Gizle", "backups.i-understand": "Anladım", "backups.location": "Konum", "backups.modals.already-in-use.description": "Bu yedekleme konumu zaten bu Umbrel'de Backups için kullanılıyor.", "backups.modals.already-in-use.manage": "Backups'ta yönet", "backups.modals.already-in-use.title": "Yedekleme konumu zaten kullanılıyor", "backups.modals.connect-existing.description": "Bu konumda zaten bir Umbrel yedeği var. Bunu bu Umbrel'e eklemek için şifreleme parolasını girin.", "backups.modals.connect-existing.title": "Mevcut Umbrel yedeğini bağla", "backups.no-external-drives-detected": "Hiçbir harici sürücü tespit edilmedi", "backups.no-password-set": "Parola ayarlı değil", "backups.password-is-set": "Parola ayarlı", "backups.password-minimum-length": "Parola en az 8 karakter olmalı", "backups.password-safety-warning": "Yedekleriniz bu parola ile şifrelenecek. Parolayı güvende tutun; bir daha göremeyeceksiniz ve yedeklerden geri yüklemek için bu parolaya ihtiyacınız olacak.", "backups.passwords-do-not-match": "Parolalar eşleşmiyor", "backups.please-choose-folder": "Lütfen bir klasör seçin", "backups.restore-failed.message": "Umbrel'inizi geri yüklerken bir hata oluştu. Mevcut uygulamalarınız ve verileriniz değişmedi.", "backups.restore-failed.retry": "Geri yüklemeye git", "backups.restore-failed.title": "Geri yükleme başarısız oldu", "backups.restoring": "Umbrel'iniz geri yükleniyor", "backups.restoring-completing": "İşlemler tamamlanıyor. Birazdan Umbrel'iniz yeniden başlatılacak...", "backups.restoring-progress": "{{percent}}% geri yüklendi", "backups.restoring-time-remaining": "{{time}} kaldı", "backups.restoring-warning": "Geri yükleme sırasında Umbrel'inizin güç kaynağını kapatmayın veya yedek konumunuzun bağlantısını kesmeyin", "backups.review": "Gözden geçir ve onayla", "backups.review-description": "Yedeğinizin ayrıntılarını gözden geçirin ve seçiminizi onaylayın", "backups.scanning-for-external-drives": "Harici sürücüler aranıyor...", "backups.schedule-description": "umbrelOS verilerinizi saatlik olarak otomatik yedekler. Şifrelenmiş saatlik yedekleri son 24 saat için, günlük yedekleri son hafta için, haftalık yedekleri son ay için ve aylık yedekleri son yıl için tutar. Bir yıldan eski yedekler otomatik olarak silinir.", "backups.select-backup-folder": "Yedek klasörünü seçin", "backups.select-backup-folder-description": "Yedeklerinizi depolamak istediğiniz klasörü seçin.", "backups.select-backup-location": "Bir yedek konumu seçin", "backups.set-encryption-password": "Şifreleme parolası belirle", "backups.set-encryption-password-description": "Yedeklerinizi bir parolayla koruyun. Bu, verilerinizin gizli kalmasını sağlar ve yalnızca bu parola ile geri yüklenebilir.", "backups.show": "Göster", "backups.storage-capacity-warning": "{{device}}'de en az yedek boyutunuzun iki katı kadar boş alan olmalıdır", "backups.store-encryption-password-safely": "Şifreleme parolanızı güvenli bir yerde saklayın", "beta-program": "umbrelOS Beta Programı", "beta-program-description": "umbrelOS beta güncellemelerini almaya kaydolun, yeni özelliklere erken erişim kazanın ve geri bildirim sağlayarak bunları geliştirmemize yardımcı olun. Beta güncellemeleri kararsız olabilir ve sorun giderme terminal bilgisi gerektirebilir.", "cancel": "İptal", "change": "Değiştir", "change-name": "Adı değiştir", "change-name.failed.name-required": "Ad gerekli", "change-name.input-placeholder": "Adınız", "change-password": "Şifre değiştir", "change-password.callout": "Şifrenizi kaybederseniz, Umbrel'e giriş yapamazsınız. Şifrenizi güvenli bir şekilde sakladığınızdan emin olun.", "change-password.current-password": "Mevcut şifre", "change-password.failed.current-required": "Mevcut şifre gerekli", "change-password.failed.min-length": "Şifre en az {{characters}} karakter olmalıdır", "change-password.failed.must-be-unique": "Yeni şifre mevcut şifreden farklı olmalıdır", "change-password.failed.new-required": "Yeni şifre gerekli", "change-password.failed.no-match": "Şifreler eşleşmiyor", "change-password.failed.repeat-required": "Şifreyi tekrar girin", "change-password.new-password": "Yeni şifre", "change-password.repeat-password": "Şifreyi tekrar girin", "check-for-latest-version": "En son umbrelOS güncellemesini kontrol et", "clipboard.copied": "Kopyalandı", "close": "Kapat", "cmdk.change-wallpaper": "Duvar kağıdını değiştir", "cmdk.frequent-apps": "Sık kullanılanlar", "cmdk.input-placeholder": "Uygulamalar, ayarlar veya eylemler için ara", "cmdk.live-usage": "Canlı Kullanım", "cmdk.restart-umbrel": "Umbrel'i yeniden başlat", "cmdk.shutdown-umbrel": "Umbrel'i kapat", "cmdk.update-all-apps": "Tüm uygulamaları güncelle", "cmdk.widgets": "Widget'lar", "community-app-store": "Topluluk Uygulama Mağazası", "community-app-store.add-error": "Topluluk App Store'u ekleyemedik: {{message}}", "community-app-store.back-to-umbrel-app-store": "Umbrel Uygulama Mağazasına geri dön", "community-app-store.open-button": "Aç", "community-app-store.remove-button": "Kaldır", "community-app-store.remove-error": "Topluluk App Store'u kaldıramadık: {{message}}", "community-app-stores.add-button": "Ekle", "community-app-stores.description": "Topluluk Uygulama Mağazaları, Umbrel'inize resmi Umbrel Uygulama Mağazasında bulunmayan uygulamaları yüklemenizi sağlar.", "community-app-stores.learn-more": "Daha fazla bilgi edinin", "community-app-stores.warning": "Topluluk Uygulama Mağazaları herhangi biri tarafından oluşturulabilir. Bu mağazalarda yayımlanan uygulamalar, resmi Umbrel Uygulama Mağazası ekibi tarafından doğrulanmaz veya denetlenmez ve potansiyel olarak güvensiz veya kötü amaçlı olabilir. Dikkatli olun ve yalnızca güvendiğiniz geliştiricilerin uygulama mağazalarını ekleyin.", "confirm": "Onayla", "connect": "Bağlan", "connecting": "Bağlanıyor...", "connection-lost": "Bağlantı koptu", "connection-lost-description": "Bu, tarayıcı sekmeniz uzun süredir etkin olmadığında, ağ bağlantınız kesildiğinde veya cihazınız çevrimdışıysa olabilir.", "continue": "Devam et", "continue-to-log-in": "Girişe devam et", "cpu": "CPU", "cpu-core-count": "{{cores}} çekirdek", "default-credentials.close": "Anladım", "default-credentials.description": "Uygulamaya giriş yapmak için gerekli kimlik bilgileri burada.", "default-credentials.dont-show-again": "Bunu bir daha gösterme", "default-credentials.dont-show-again-notice": "Bu kimlik bilgilerine gelecekte herhangi bir zamanda uygulama simgesine sağ tıklayarak erişebilirsiniz.", "default-credentials.open": "{{app}}'i aç", "default-credentials.password": "Varsayılan şifre", "default-credentials.title": "{{app}} için kimlik bilgileri", "default-credentials.username": "Varsayılan kullanıcı adı", "desktop.app.context.go-to-store-page": "App Store'da görüntüle", "desktop.app.context.settings": "Ayarlar", "desktop.app.context.show-default-credentials": "Varsayılan kimlik bilgilerini göster", "desktop.app.context.uninstall": "Kaldır", "desktop.context-menu.change-wallpaper": "Duvar kağıdını değiştir", "desktop.context-menu.edit-widgets": "Widget'ları düzenle", "desktop.context-menu.logout": "Çıkış yap", "desktop.greeting.afternoon": "Tünaydın, {{name}}", "desktop.greeting.evening": "İyi akşamlar, {{name}}", "desktop.greeting.morning": "Günaydın, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Viber için", "desktop.install-first.for-the-bitcoiner": "Bitcoin kullanıcıları için", "desktop.install-first.for-the-self-hoster": "Kendi sunucusunu barındıranlar için", "desktop.install-first.for-the-streamer": "Yayıncılar için", "desktop.install-first.link-to-app-store": "App Store'da daha fazlasını keşfet", "desktop.not-enough-room": "Uygulamalarınızı görüntülemek için daha büyük bir ekran kullanın.", "device": "Cihaz", "device-info": "Cihaz bilgisi", "device-info-description": "Cihazınız hakkında bilgi", "device-info.device": "Cihaz", "device-info.model-number": "Model numarası", "device-info.serial-number": "Seri numarası", "device-info.view-info": "Bilgileri görüntüle", "device-name.home-or-pro": "Umbrel Home veya Umbrel Pro", "disable": "Devre dışı bırak", "done": "Bitti", "download-logs": "Günlükleri indir", "enabling-tor": "Uzaktan Tor erişimi etkinleştiriliyor", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS, daha iyi ağ güvenilirliği sunar. Yönlendiricinizin DNS ayarlarını kullanmak için devre dışı bırakın.", "external-dns-error": "DNS ayarını güncelleyemedik: {{message}}", "external-drive": "Harici Sürücü", "factory-reset": "Fabrika ayarlarına sıfırla", "factory-reset-description": "Tüm verilerinizi ve uygulamalarınızı silerek umbrelOS'i varsayılan ayarlara geri yükleyin", "factory-reset-failed": "Cihazınızı sıfırlayamadık: {{message}}", "factory-reset.confirm.body": "Sıfırlamak için şifrenizi doğrulayın", "factory-reset.confirm.ethernet-required-warning": "Cihazınızın, Wi-Fi yerine Ethernet ile router'a bağlı olduğundan ve yerel ağınızdan (örneğin, http://umbrel.local veya cihazınızın yerel IP adresi) eriştiğinizden emin olun.", "factory-reset.confirm.submit": "Her şeyi sil ve sıfırla", "factory-reset.confirm.submit-callout": "Bu işlem geri alınamaz.", "factory-reset.rebooting.message": "Cihazınız yeniden başlatılacak ve tüm veriler silinecek. Lütfen bu sayfayı kapatmayın.", "factory-reset.rebooting.status": "Sıfırlanıyor...", "factory-reset.rebooting.title": "Fabrika ayarlarına sıfırlanıyor", "factory-reset.review.account-info": "Hesap bilgileri ve şifre", "factory-reset.review.apps": "Uygulamalar", "factory-reset.review.following-will-be-removed": "Cihazınızdan aşağıdakiler kaldırılacak", "factory-reset.review.installed-apps_one": "{{count}} yüklü uygulama", "factory-reset.review.installed-apps_other": "{{count}} yüklü uygulama", "factory-reset.review.submit": "Devam et", "factory-reset.review.total-data": "Toplam veri", "files": "Files", "files-action.add-favorite": "Favorilere ekle", "files-action.add-network-device": "Cihaz ekle", "files-action.cancel-upload": "Yüklemeyi iptal et", "files-action.compress": "Sıkıştır", "files-action.copy": "Kopyala", "files-action.cut": "Kes", "files-action.delete": "Kalıcı olarak sil", "files-action.download": "İndir", "files-action.download-items": "{{count}} öğeyi indir", "files-action.drop-to-upload": "Yüklemek için bırakın", "files-action.eject-disk": "Çıkar", "files-action.empty-trash": "Çöpü boşalt", "files-action.format-drive": "Biçimlendir", "files-action.go-to-path": "Git...", "files-action.new-folder": "Yeni klasör", "files-action.open": "Aç", "files-action.paste": "Yapıştır", "files-action.remove-favorite": "Favorilerden kaldır", "files-action.remove-network-host": "Ağ sürücüsünü çıkar", "files-action.remove-network-share": "Ağ paylaşımını çıkar", "files-action.rename": "Yeniden adlandır", "files-action.restore": "Geri yükle", "files-action.select": "Seç", "files-action.share": "Ağ üzerinden paylaş...", "files-action.sharing": "Paylaşılıyor...", "files-action.show-in-folder": "İçeren klasörde göster", "files-action.trash": "Çöp kutusu", "files-action.uncompress": "Sıkıştırmayı aç", "files-action.upload": "Yükle", "files-add-network-share.add-manually": "Elle ekle", "files-add-network-share.add-share": "Paylaşımı ekle", "files-add-network-share.back": "Geri", "files-add-network-share.continue": "Devam et", "files-add-network-share.description": "Ağınızdaki bir NAS veya başka bir paylaşılan sürücüye bağlanarak onlara Dosyalar içinden erişin.", "files-add-network-share.discovering": "Ağ taranıyor...", "files-add-network-share.enter-details-manually": "Sunucu bilgilerini girin", "files-add-network-share.host-label": "Sunucu adresi", "files-add-network-share.host-required": "Sunucu adresi gerekli", "files-add-network-share.manual-share-help": "Sunucunuzda göründüğü gibi paylaşımın tam adını girin", "files-add-network-share.no-shares-found": "Bu sunucuda paylaşım bulunamadı", "files-add-network-share.not-seeing-share": "Paylaşımınızı göremiyor musunuz?", "files-add-network-share.password-label": "Şifre", "files-add-network-share.password-required": "Şifre gerekli", "files-add-network-share.retrieving-shares": "Paylaşımlar alınıyor...", "files-add-network-share.retry-discovery": "Ağı yeniden tara", "files-add-network-share.select-share": "Eklenecek bir paylaşım seç", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Paylaşım adı gerekli", "files-add-network-share.title": "Ağ paylaşımı ekle", "files-add-network-share.username-label": "Kullanıcı adı", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Kullanıcı adı gerekli", "files-audio-island.now-playing": "Şu An Çalıyor", "files-audio-island.pause": "Duraklat", "files-audio-island.play": "Oynat", "files-backend-error.base-directory-not-found": "Temel dizin bulunamadı", "files-backend-error.cant-find-root": "Dosya yolu doğrulanamadı", "files-backend-error.destination-already-exists": "Hedefte aynı isimde bir öğe zaten var", "files-backend-error.destination-not-exist": "Hedef klasör mevcut değil", "files-backend-error.does-not-exist": "Dosya veya klasör mevcut değil", "files-backend-error.escapes-base": "Yol izin verilen dizinin dışında", "files-backend-error.invalid-base": "Yol geçerli bir dizine ait değil", "files-backend-error.invalid-filename": "Dosya adı geçersiz", "files-backend-error.invalid-path": "Dosya yolu geçersiz", "files-backend-error.mkdir-failed": "Klasör oluşturulamadı", "files-backend-error.move-failed": "Öğe taşınamadı", "files-backend-error.not-enough-space": "Yeterli depolama alanı yok", "files-backend-error.operation-not-allowed": "Bu işlem izin verilmiyor", "files-backend-error.parent-not-directory": "Üst yol bir klasör değil", "files-backend-error.parent-not-exist": "Üst klasör mevcut değil", "files-backend-error.path-not-absolute": "Dosya yolu mutlak değil", "files-backend-error.share-already-exists": "Bu klasör zaten paylaşılıyor", "files-backend-error.share-name-generation-failed": "Benzersiz paylaşım adı oluşturulamadı", "files-backend-error.source-not-exists": "Kaynak dosya veya klasör mevcut değil", "files-backend-error.subdir-of-self": "Bir klasör kendisinin alt dizinine taşınamaz veya kopyalanamaz", "files-backend-error.trash-meta-not-exists": "Bu öğenin orijinal konumu bulunamadı", "files-backend-error.unique-name-index-exceeded": "Benzersiz isim oluşturulamadı. Benzer isimde çok fazla öğe var", "files-backend-error.upload-failed": "Yükleme başarısız oldu", "files-collision.action.keep-both": "İkisini de tut", "files-collision.action.replace": "Değiştir", "files-collision.action.skip": "Atla", "files-collision.destination.original-location": "orijinal konumu", "files-collision.message": "Mevcut öğeyi değiştirmek mi yoksa ikisini de tutmak mı istiyorsunuz?", "files-collision.title": "\"{{itemName}}\" zaten {{destinationName}}'de mevcut", "files-download.confirm": "İndir", "files-download.description": "Files bu dosya türünü açamıyor. Bunun yerine indirmek ister misiniz?", "files-download.title": "{{name}} dosyasını indirmek ister misiniz?", "files-empty-trash.confirm": "Boşalt", "files-empty-trash.description": "Çöp’teki tüm öğeleri kalıcı olarak silmek istediğinizden emin misiniz? Bu işlemi geri alamazsınız.", "files-empty-trash.title": "Çöp’ü Boşalt?", "files-empty.directory": "Bu klasörde öğe yok", "files-empty.network": "Ağda cihaz yok", "files-empty.network-host-offline": "Ağ cihazı çevrimdışı", "files-error.add-favorite": "Favorilere ekleme başarısız oldu: {{message}}", "files-error.add-share": "Klasör paylaşma başarısız oldu: {{message}}", "files-error.compress": "Sıkıştırma başarısız oldu: {{message}}", "files-error.copy": "Kopyalama başarısız oldu: {{message}}", "files-error.create-folder": "Klasör oluşturma başarısız oldu: {{message}}", "files-error.delete": "Silme başarısız oldu: {{message}}", "files-error.eject-disk": "Sürücü çıkarma başarısız oldu: {{message}}", "files-error.empty-trash": "Çöpü boşaltma başarısız oldu: {{message}}", "files-error.extract": "Arşivden çıkarma başarısız oldu: {{message}}", "files-error.folder-already-exists": "Bu isimde bir klasör zaten var", "files-error.move": "Taşıma başarısız oldu: {{message}}", "files-error.remove-favorite": "Favorilerden kaldırma başarısız oldu: {{message}}", "files-error.remove-share": "Paylaşılan klasörü kaldırma başarısız oldu: {{message}}", "files-error.rename": "Yeniden adlandırma başarısız oldu: {{message}}", "files-error.restore": "Geri yükleme başarısız oldu: {{message}}", "files-error.trash": "Çöpe taşıma başarısız oldu: {{message}}", "files-error.upload": "Yükleme başarısız oldu: {{message}}", "files-error.upload-network-error": "Yükleme başarısız oldu: {{name}} için ağ hatası oluştu", "files-extension-change.confirm": "Devam et", "files-extension-change.description-add": "“{{fileName}}” dosyasının uzantısını “{{extension}}” olarak değiştirmek istediğinizden emin misiniz? Bu, dosyanın okunamaz olmasına neden olabilir.", "files-extension-change.description-remove": "“{{fileName}}” dosyasının uzantısını kaldırmak istediğinizden emin misiniz?", "files-extension-change.title-add": "Uzantı “{{extension}}” olarak değiştirilsin mi?", "files-extension-change.title-remove": "Uzantı kaldırılsın mı?", "files-external-storage.unsupported.description": "Bağlı harici sürücünüz güç sorunları nedeniyle bir Raspberry Pi üzerinde kullanılamıyor. Harici depolama Umbrel Home, Umbrel Pro ve tüm x86 (Intel veya AMD) cihazlarda kullanılabilir.", "files-external-storage.unsupported.description-general": "Maalesef güç sorunları nedeniyle Raspberry Pi'de harici depolama kullanılamıyor. Umbrel Home, Umbrel Pro ve tüm x86 (Intel veya AMD) cihazlarda harici depolama kullanılabilir.", "files-external-storage.unsupported.title": "Harici Depolama Desteklenmiyor", "files-folder": "Klasör", "files-format.confirm": "Biçimlendir", "files-format.description": "Biçimlendirme, {{driveName}} içindeki tüm verileri silecektir. Bu işlem geri alınamaz.", "files-format.description-unreadable": "umbrelOS, {{driveName}} içeriğini okuyamıyor. umbrelOS ile kullanmak için biçimlendirebilirsiniz.", "files-format.drive-label": "Ad", "files-format.error": "Sürücü biçimlendirilemedi", "files-format.exfat-description": "Windows, macOS ve Linux ile maksimum uyumluluk", "files-format.ext4-description": "umbrelOS ve Linux ile daha iyi performans", "files-format.filesystem": "Dosya sistemi", "files-format.filesystem-label": "Biçimlendirme türü", "files-format.formatting": "Biçimlendiriliyor...", "files-format.title": "Sürücüyü Biçimlendir", "files-format.title-requires-format": "Biçimlendirme gerekli", "files-formatting-island.formatting": "Biçimlendiriliyor...", "files-formatting-island.formatting-drives": "{{count}} sürücü biçimlendiriliyor", "files-listing.empty": "Öğe yok", "files-listing.error": "Bir hata oluştu", "files-listing.item-count-truncated": "{{formattedCount}}+ öğe", "files-listing.item-count_one": "{{formattedCount}} öğe", "files-listing.item-count_other": "{{formattedCount}} öğe", "files-listing.loading": "Yükleniyor...", "files-listing.no-such-file": "Böyle bir dosya veya klasör yok", "files-listing.selected-count": "{{selectedCount}}/{{totalCount}} öğe seçili", "files-listing.selected-count-truncated": "Toplam {{totalCount}}+ öğeden {{selectedCount}}'i seçili", "files-name-drawer.new-folder": "Yeni Klasör", "files-name-drawer.new-folder-description": "Yeni klasör için bir ad girin.", "files-name-drawer.new-folder-input": "Klasör Adı", "files-name-drawer.rename-file": "Dosyayı Yeniden Adlandır", "files-name-drawer.rename-file-description": "Bu dosya için yeni bir ad girin.", "files-name-drawer.rename-file-input": "Dosya Adı", "files-name-drawer.rename-folder": "Klasörü Yeniden Adlandır", "files-name-drawer.rename-folder-description": "Bu klasör için yeni bir ad girin.", "files-name-drawer.rename-folder-input": "Klasör Adı", "files-network-storage-error.add-share": "Ağ paylaşımı ekleme başarısız oldu: {{message}}", "files-network-storage-error.discover-servers": "Ağ cihazı keşfi başarısız oldu: {{message}}", "files-network-storage-error.discover-shares": "Ağ paylaşımlarının keşfi başarısız oldu: {{message}}", "files-network-storage-error.remove-share": "Ağ paylaşımını kaldırma başarısız oldu: {{message}}", "files-operations-island.copying": "\"{{from}}\" öğesi \"{{to}}\" konumuna kopyalanıyor", "files-operations-island.moving": "\"{{from}}\" öğesi \"{{to}}\" konumuna taşınıyor", "files-operations-island.restoring": "\"{{from}}\" öğesi \"{{to}}\" konumuna geri yükleniyor", "files-path.input-group": "Yol girişi", "files-path.input-label": "Geçerli yol", "files-permanently-delete.confirm": "Kalıcı olarak sil", "files-permanently-delete.description-multiple": "Bu {{count}} öğeyi kalıcı olarak silmek istediğinizden emin misiniz? Bu işlemi geri alamazsınız.", "files-permanently-delete.description-single": "“{{fileName}}” öğesini kalıcı olarak silmek istediğinizden emin misiniz? Bu işlemi geri alamazsınız.", "files-permanently-delete.title-multiple": "{{count}} öğe kalıcı olarak silinsin mi?", "files-permanently-delete.title-single": "Kalıcı olarak silinsin mi?", "files-search.default": "Dosya ve klasörlerde ara", "files-search.no-results": "\"{{query}}\" için sonuç bulunamadı", "files-search.placeholder": "Ara", "files-search.searching-label": "{{name}}'in Umbrel'ini arıyor", "files-share.home-description": "Ağınızdaki diğer cihazlardan “{{homeDirectoryName}}” içindeki tüm dosyalara erişin", "files-share.home-title": "“{{homeDirectoryName}}” klasörünü ağ üzerinden paylaş", "files-share.instructions.how-to-access": "Nasıl erişilir", "files-share.instructions.ios.enter-password": "Şifre olarak {{password}} girin.", "files-share.instructions.ios.enter-server": "Sunucu adresi olarak {{smbUrl}} girin.", "files-share.instructions.ios.enter-username": "Kullanıcı adı olarak {{username}} girin.", "files-share.instructions.ios.install-files": "\"Files\" uygulaması yüklü değilse App Store’dan yükleyin.", "files-share.instructions.ios.tap-connect": "Erişim için \"Connect\" düğmesine dokunun.", "files-share.instructions.ios.tap-dots": "Sağ üstteki üç noktaya (...) dokunun ve \"Connect to Server\" öğesini seçin.", "files-share.instructions.macos.click-connect": "Erişim için \"Connect\" düğmesine tıklayın.", "files-share.instructions.macos.enter-password": "Şifre olarak {{password}} girin.", "files-share.instructions.macos.enter-url": "{{smbUrl}} girin ve \"Connect\"e tıklayın.", "files-share.instructions.macos.enter-username": "Kullanıcı adı olarak {{username}} girin.", "files-share.instructions.macos.open-finder": "\"Finder\"ı açın ve ⌘ + K tuşlarına basın.", "files-share.instructions.macos.select-registered": "İstendiğinde \"Registered User\"ı seçin.", "files-share.instructions.macos.time-machine": "Time Machine yedekleme konumu olarak nasıl kullanılır", "files-share.instructions.macos.time-machine.choose-encryption": "Şifrelenmiş veya şifrelenmemiş yedekler arasında seçim yapın.", "files-share.instructions.macos.time-machine.disk-limit": "'Disk Usage Limit' için, Time Machine yedekleri için Umbrel üzerinde ayırmak istediğiniz maksimum alanı belirleyin ve ardından \"Done\" düğmesine tıklayın.", "files-share.instructions.macos.time-machine.follow-steps": "Yukarıdaki adımları izleyin ve Mac’inizde Sistem Ayarları’nı açın.", "files-share.instructions.macos.time-machine.go-settings": "Time Machine’e gidin, \"Add Backup Disk...\" öğesine tıklayın.", "files-share.instructions.macos.time-machine.select-disk": "Klasörü seçin ve \"Set Up Disk...\" öğesine tıklayın.", "files-share.instructions.umbrelos.backup.follow-onscreen": "Yedeklemeyi ayarlamak için ekrandaki adımları takip et.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Yukarıdaki adımları uyguladıktan sonra diğer Umbrel'inde \"{{settings}}\" > \"{{backups}}\" bölümüne git.", "files-share.instructions.umbrelos.backup.select-add": "\"{{addUmbrelOrNas}}\" seçeneğini seç.", "files-share.instructions.umbrelos.backup.select-connected": "Bağlı cihazlar listesinden bu Umbrel cihazını seç.", "files-share.instructions.umbrelos.backup.title": "Diğer Umbrel cihazlarınız için yedekleme konumu olarak nasıl kullanılır", "files-share.instructions.umbrelos.cant-find-note": "Bulamıyor musunuz? \"Elle ekle\" seçeneğini deneyin ve aşağıdaki kimlik bilgilerini kullanın. Yine ekleyemiyorsanız, her iki cihazınızın da aynı ağa bağlı olduğundan emin olun.", "files-share.instructions.umbrelos.enter-password": "Şifre olarak {{password}} gir.", "files-share.instructions.umbrelos.enter-username": "Kullanıcı adı olarak {{username}} gir.", "files-share.instructions.umbrelos.open-and-click": "Diğer Umbrel'inde \"Files\"'ı aç ve kenar çubuğunda \" {{deviceLabel}}\"'in yanındaki öğesine tıkla.", "files-share.instructions.umbrelos.select-device": "Ağınızdaki otomatik algılanan cihazlar listesinden bu Umbrel cihazını seç.", "files-share.instructions.umbrelos.select-sharename": "\"{{sharename}}\"'ı seç ve paylaşımı eklemek için tıkla.", "files-share.instructions.windows.enter-password": "Şifre olarak {{password}} girin.", "files-share.instructions.windows.enter-url": "{{smbUrl}} yazın ve Enter’a basın.", "files-share.instructions.windows.enter-username": "Kullanıcı adı olarak {{username}} girin.", "files-share.instructions.windows.open-run": "Windows + R tuşuna basarak Çalıştır iletişim kutusunu açın.", "files-share.instructions.windows.remember-credentials": "\"Remember my credentials\" seçeneğini işaretleyin ve OK'ye tıklayın.", "files-share.regular-description": "Bu klasörü paylaşarak ağınızdaki diğer cihazlardan erişin", "files-share.regular-title": "Klasörü ağ üzerinde paylaş", "files-share.toggle": "“{{name}}” öğesini ağınız üzerinden paylaş", "files-sidebar.apps": "Uygulamalar", "files-sidebar.external-storage": "Harici depolama", "files-sidebar.favorites": "Favoriler", "files-sidebar.home": "Ev", "files-sidebar.navigation": "Dosya gezintisi", "files-sidebar.network": "Ağ", "files-sidebar.network-pathbar": "Ağ Cihazları", "files-sidebar.network-sidebar": "Cihazlar", "files-sidebar.recents": "Son açılanlar", "files-sidebar.shared-folders": "Paylaşılan klasörler", "files-sidebar.trash": "Çöp", "files-sidebar.trash.open": "Aç", "files-sort.created": "Eklendi", "files-sort.modified": "Değiştirildi", "files-sort.name": "Ad", "files-sort.size": "Boyut", "files-sort.type": "Tür", "files-state.uploading": "Yükleniyor...", "files-state.waiting": "Bekleniyor...", "files-type.3gp": "3GP Video Dosyası", "files-type.3gp2": "3GP2 Video Dosyası", "files-type.7z": "7Z Arşivi", "files-type.aac": "AAC Ses Dosyası", "files-type.ai": "Illustrator Dosyası", "files-type.aiff": "AIFF Ses Dosyası", "files-type.au": "AU Ses Dosyası", "files-type.avi": "AVI Video Dosyası", "files-type.avif": "AVIF Görseli", "files-type.bmp": "BMP Görseli", "files-type.bzip2": "BZIP2 Arşivi", "files-type.caf": "CAF Ses Dosyası", "files-type.compressed": "Sıkıştırılmış Arşiv", "files-type.csv": "CSV Dosyası", "files-type.directory": "Klasör", "files-type.dmg": "Disk İmajı", "files-type.dv": "DV Video Dosyası", "files-type.epub": "EPUB e-Kitap", "files-type.excel": "Excel Çalışma Sayfası", "files-type.exe": "Windows Yürütülebilir Dosyası", "files-type.executable": "Yürütülebilir Dosya", "files-type.external-drive": "Sürücü", "files-type.flac": "FLAC Ses Dosyası", "files-type.flv": "FLV Video Dosyası", "files-type.gif": "GIF Görseli", "files-type.gzip": "GZIP Arşivi", "files-type.heic": "HEIC Görseli", "files-type.ico": "ICO Görseli", "files-type.iso": "ISO Kalıbı", "files-type.jpeg": "JPEG Görseli", "files-type.keynote": "Keynote Sunumu", "files-type.lzip": "LZIP Arşivi", "files-type.lzma": "LZMA Arşivi", "files-type.lzop": "LZOP Arşivi", "files-type.m3u": "M3U Çalma Listesi", "files-type.m4a": "M4A Ses Dosyası", "files-type.m4v": "M4V Video Dosyası", "files-type.midi": "MIDI Ses Dosyası", "files-type.mka": "MKA Ses Dosyası", "files-type.mkv": "MKV Video Dosyası", "files-type.mng": "MNG Video Dosyası", "files-type.mobi": "MOBI e-Kitap", "files-type.mp3": "MP3 Ses Dosyası", "files-type.mp4": "MP4 Video Dosyası", "files-type.mp4-audio": "MP4 Ses Dosyası", "files-type.mpeg": "MPEG Video Dosyası", "files-type.mpeg-ts": "MPEG Taşıma Akışı Dosyası", "files-type.network-drive": "Ağ Sürücüsü", "files-type.numbers": "Numbers E-Tablosu", "files-type.ogg": "OGG Ses Dosyası", "files-type.ogv": "OGV Video Dosyası", "files-type.pages": "Pages Belgesi", "files-type.pdf": "PDF Belgesi", "files-type.png": "PNG Görseli", "files-type.powerpoint": "PowerPoint Sunumu", "files-type.psd": "Photoshop Belgesi", "files-type.quicktime": "QuickTime Video Dosyası", "files-type.rar": "RAR Arşivi", "files-type.sgi": "SGI Film Dosyası", "files-type.svg": "SVG Görseli", "files-type.tar": "TAR Arşivi", "files-type.tiff": "TIFF Görseli", "files-type.ts": "TS Video Dosyası", "files-type.txt": "Metin Dosyası", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "WAV Ses Dosyası", "files-type.webm": "WebM Video Dosyası", "files-type.webm-audio": "WebM Ses Dosyası", "files-type.webp": "WebP Görseli", "files-type.wma": "WMA Ses Dosyası", "files-type.wmv": "WMV Video Dosyası", "files-type.word": "Word Belgesi", "files-type.xz": "XZ Arşivi", "files-type.zip": "ZIP Arşivi", "files-upload-island.uploading-count": "{{count}} öğe yükleniyor", "files-view.icons": "Simgeler", "files-view.list": "Liste", "files-view.sort-by": "Şuna göre sırala", "files-view.view-as": "Görünüm biçimi", "files-widgets.favorites.no-items-text": "Burada görmek için bir klasörü favorilere ekleyin", "files-widgets.recents.no-items-text": "Son kullanılan dosya yok", "generic-in": "in", "hide-details": "Ayrıntıları gizle", "install-first.install-app": "{{app}} yükle", "install-first.title": "{{app}} bu uygulamalara ihtiyaç duyuyor", "install-your-first-app": "İlk uygulamanızı yükleyin", "language": "Dil", "language-description": "Tercih ettiğiniz umbrelOS dili", "language.select-description": "Tercih edilen umbrelOS dilini seçin", "live-usage": "Canlı Kullanım", "loading": "Yükleniyor", "local-ip": "Yerel IP", "login-2fa.subtitle": "Kimlik doğrulama uygulamanızda görüntülenen 2FA kodunu girin", "login-2fa.title": "Kimlik doğrulama", "login-with-umbrel.description": "{{app}}'i açmak için Umbrel şifrenizi girin", "login-with-umbrel.title": "Umbrel ile giriş yap", "login.password-label": "Şifre", "login.password.submit": "Giriş yap", "login.subtitle": "Giriş yapmak için Umbrel şifrenizi girin", "login.title": "Tekrar hoş geldiniz", "logout": "Çıkış yap", "logout-error-generic": "Hata: Çıkış yapılamadı", "logout.confirm.submit": "Çıkış yap", "logout.confirm.title": "Çıkış yapmak istediğinize emin misiniz?", "memory": "Bellek", "memory.low": "Düşük bellek", "migrate": "Geçiş yap", "migrate.callout": "Geçiş tamamlanana kadar Umbrel'inizi kapatmayın", "migrate.failed.retry": "Tekrar dene", "migrate.failed.title": "Geçiş başarısız", "migrate.success.description": "Tüm uygulamalarınız, uygulama verileriniz ve hesap detaylarınız Umbrel Home'a aktarıldı.", "migrate.success.title": "Geçiş başarılı", "migration-assistant": "Geçiş Asistanı", "migration-assistant-description": "Tüm uygulamalarını ve verilerini bir Raspberry Pi'den {{deviceName}}'e aktar", "migration-assistant-unsupported-device-description": "Migration Assistant şu anda umbrelOS yüklü bir Raspberry Pi'den Umbrel Home veya Umbrel Pro'ya tüm verileri ve uygulamaları aktarmayı destekliyor. Başlamak için Umbrel Home veya Umbrel Pro'da Migration Assistant'ı aç.", "migration-assistant.continue-migration.ready.submit": "Geçişi başlat", "migration-assistant.failed": "Bir şeyler doğru değil...", "migration-assistant.failed.retrying-message": "Tekrar deneniyor...", "migration-assistant.mobile.start-button": "Geçişi başlat", "migration-assistant.prep.body": "Geçiş için hazırlanın", "migration-assistant.prep.button-continue": "Devam et", "migration-assistant.prep.callout": "Varsa, {{deviceName}} üzerindeki verilerin kalıcı olarak silinecek.", "migration-assistant.prep.connect-disk-to-home": "Harici sürücüsünü {{deviceName}}'deki herhangi bir USB portuna tak.", "migration-assistant.prep.prep-done-continue-message": "İşlem tamamlandığında aşağıdaki '{{button}}' butonuna tıklayın.", "migration-assistant.prep.shut-down-rpi": "Raspberry Pi Umbrel'inizi kapatın.", "migration-assistant.ready.description": "Tüm verilerin ve uygulamaların {{deviceName}}'e taşınmaya hazır.", "migration-assistant.ready.hint-header": "Dikkat edilmesi gerekenler", "migration-assistant.ready.hint-keep-pi-off.description": "Bu, Lightning Node gibi uygulamalardaki sorunları önlemeye yardımcı olur", "migration-assistant.ready.hint-keep-pi-off.title": "Güncellemeden sonra Raspberry Pi'yi kapalı tutun", "migration-assistant.ready.hint-use-same-password.description": "Raspberry Pi'deki Umbrel şifreni {{deviceName}}'e giriş yapmak için kullanmayı unutma.", "migration-assistant.ready.hint-use-same-password.title": "Aynı şifreyi kullanın", "migration-assistant.ready.title": "Geçiş yapmaya hazırsınız!", "mini-browser.default-title": "Klasör seç", "mini-browser.empty-external": "Burada görünmesi için bir harici sürücü bağlayın.", "mini-browser.empty-network": "Burada görünmesi için bir Umbrel veya NAS ekleyin.", "mini-browser.load-more": "Daha fazla yükle", "mini-browser.load-more-in-folder": "{{name}} içinde daha fazla yükle", "mini-browser.loading-more": "Daha fazla yükleniyor…", "mini-browser.select": "Seç", "mini-browser.select-folder": "Klasör seç", "name": "Ad", "nas": "NAS", "no-forgot-password-message": "Şifrenizi kaybederseniz, Umbrel'e giriş yapamazsınız. Şifrenizi güvenli bir şekilde sakladığınızdan emin olun.", "no-results-found": "Sonuç bulunamadı", "not-found-404": "Hata kodu: 404", "not-found-404.back": "Geri", "not-found-404.home": "Ana sayfaya git", "notifications.backups-failing-location.description": "Otomatik Backups {{location}}'a yapılamıyor. Bağlantıyı kontrol et ve Backups ayarlarını gözden geçir.", "notifications.backups-failing.description": "Otomatik Backups başarısız oluyor. Backup konumunu kontrol et ve ayarlarını gözden geçir.", "notifications.backups-failing.go-to-backups": "Backups'a git", "notifications.backups-failing.title": "Son 24 saatte Backups yok", "notifications.cpu.too-hot": "Yüksek CPU sıcaklığı", "notifications.memory.low": "Cihazınızın belleği düşük", "notifications.new-version-available": "{{update}} artık indirilebilir", "notifications.raid.issue.description": "Depolama sorunu tespit edildi. Detaylar için Storage Manager'a göz atın.", "notifications.raid.issue.title": "Acil işlem gerekiyor", "notifications.ssd.health.description": "Bir veya daha fazla SSD dikkat gerektirebilir. Detaylar için Storage Manager'a göz atın.", "notifications.ssd.health.title": "SSD sağlık uyarısı", "notifications.storage.full": "Cihazınızın depolama alanı dolu", "notifications.view": "Görüntüle", "ok": "Tamam", "onboarding.account-created.by-clicking-button-you-agree": "'İleri' butonuna tıklayarak umbrelOS Hizmet Şartları'nı kabul ediyorsunuz", "onboarding.account-created.youre-all-set-name": "Hazırsınız, {{name}}.", "onboarding.contact-support": "Destek", "onboarding.create-account": "Hesap oluştur", "onboarding.create-account.confirm-password.input-label": "Şifreyi onayla", "onboarding.create-account.failed.name-required": "Ad gerekli", "onboarding.create-account.failed.passwords-dont-match": "Şifreler eşleşmiyor", "onboarding.create-account.name.input-placeholder": "Adınız", "onboarding.create-account.password.input-label": "Şifre", "onboarding.create-account.submit": "Oluştur", "onboarding.create-account.submitting": "Oluşturuluyor", "onboarding.create-account.subtitle": "Hesap bilgileriniz yalnızca Umbrel'inizde saklanır. Şifrenizi güvenli bir şekilde yedeklediğinizden emin olun çünkü sıfırlama imkanı yoktur.", "onboarding.create-instead-long": "Yeni hesap oluştur", "onboarding.create-instead-short": "Yeni hesap", "onboarding.launch-umbrelos": "umbrelOS'u başlat", "onboarding.raid.available-storage": "Kullanılabilir depolama alanı", "onboarding.raid.change-drives-link": "Sürücü eklemeniz veya değiştirmemiz mi gerekiyor?", "onboarding.raid.configuring.subtitle": "Bu birkaç dakika sürebilir.", "onboarding.raid.configuring.title": "Depolamanız yapılandırılıyor", "onboarding.raid.configuring.warning": "Depolamanız yapılandırılırken lütfen bu sayfayı yenilemeyin veya Umbrel'inizi kapatmayın.", "onboarding.raid.continue": "Devam et", "onboarding.raid.error.detection-instructions": "Umbrel Pro'yu kapatın, SSD'lerin doğru takıldığını kontrol edin ve tekrar deneyin.", "onboarding.raid.error.no-ssds-detected": "Hiç SSD tespit edilmedi", "onboarding.raid.error.no-ssds-instructions": "Devam etmek için Umbrel Pro'yu kapatın ve en az bir SSD takın.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "FailSafe henüz etkinleştirilemiyor", "onboarding.raid.failsafe.enable": "FailSafe'i etkinleştir", "onboarding.raid.failsafe.mixed-sizes": "FailSafe, en küçük SSD'niz ({{smallest}}) ile sınırlıdır. Daha büyük SSD'lerdeki ekstra alan kullanılamaz ve toplam {{wasted}} kullanılamaz hale gelir.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} veri koruması için kullanılır. Kullanılabilir depolamayı {{futureWith3}}'e artırmak için başka bir {{smallest}} SSD ekleyin veya {{futureWith4}} için iki tane daha ekleyin. Daha fazla SSD'yi istediğiniz zaman ekleyebilirsiniz.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} veri koruması için kullanılır. Kullanılabilir depolamayı {{futureWith4}}'e artırmak için başka bir {{smallest}} SSD ekleyin. Daha fazla SSD'yi istediğiniz zaman ekleyebilirsiniz.", "onboarding.raid.failsafe.single-ssd-info": "Sadece bir SSD'niz var. Verileriniz için FailSafe korumasını etkinleştirmek üzere en az bir {{size}} SSD daha ekleyin. Daha fazla SSD'yi istediğiniz zaman ekleyebilirsiniz.", "onboarding.raid.failsafe.subtitle": "Herhangi bir tek SSD arızalansa bile verileriniz güvende kalır", "onboarding.raid.failsafe.tip": "Maksimum depolama ve hiç kullanılmayan alan olmaması için aynı boyutta SSD'ler kullanın.", "onboarding.raid.failsafe.warning-now-only": "Birden fazla SSD varsa FailSafe yalnızca ilk kurulum sırasında etkinleştirilebilir. Daha sonra etkinleştiremezsiniz.", "onboarding.raid.health-warning": "Bu sürücü sağlık sorunları bildiriyor", "onboarding.raid.launching": "Başlatılıyor...", "onboarding.raid.no-ssds-alt": "SSD bulunamadı", "onboarding.raid.recommended": "Önerilen", "onboarding.raid.scanning": "SSD yuvalarınız kontrol ediliyor", "onboarding.raid.scanning-alt": "SSD'ler taranıyor", "onboarding.raid.setup-failed.description-no-retry": "Lütfen kapatıp tekrar deneyin.", "onboarding.raid.setup-failed.description-retry": "Tekrar deneyin veya sürücüleri kontrol etmek için kapatın.", "onboarding.raid.setup-failed.title": "Depolama kurulumu başarısız oldu", "onboarding.raid.shutdown-dialog.description": "Sürücü eklemek veya değiştirmek için Umbrel Pro'yu kapatın. İşlem tamamlandıktan sonra tekrar açıp kuruluma devam edebilirsiniz.", "onboarding.raid.shutdown-dialog.title": "Sürücüleri değiştirmek istiyor musunuz?", "onboarding.raid.ssd-in-slot": "Slot {{slot}}'ta bir {{size}} SSD", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "SSD tepsisi", "onboarding.raid.ssds-found": "Umbrel Pro'da aşağıdaki SSD'ler bulundu", "onboarding.raid.storage": "Depolama", "onboarding.raid.storage-label": "Depolama", "onboarding.raid.success.storage-info": "Depolama {{available}}", "onboarding.raid.success.storage-info-failsafe": "Depolama {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Tekrar dene", "onboarding.raid.wasted": "Kullanılamaz", "onboarding.restore-long": "Umbrel'imi geri yükle", "onboarding.restore-short": "Geri yükle", "onboarding.start.continue": "Hadi başlayalım", "onboarding.start.subtitle": "Ev bulut sunucunuz kuruluma hazır.", "onboarding.start.title": "umbrelOS'a hoş geldiniz", "open": "Aç", "open-live-usage": "Canlı Kullanımı Aç", "password": "Şifre", "preferences": "Tercihler", "raid-error.description": "Depolama sisteminiz düzgün başlatılamadı. Aşağıdan SSD'lerinizin durumunu kontrol et ve sorun giderme adımlarını uygula. Sorun devam ederse, etkilenen SSD'lerin değiştirilmesi gerekebilir.", "raid-error.factory-reset-dialog.description": "Bu işlem Umbrel Pro üzerindeki tüm verileri silecek ve cihazı fabrika ayarlarına döndürecek. Bu işlem geri alınamaz.", "raid-error.factory-reset-dialog.title": "Fabrika ayarlarına sıfırlansın mı?", "raid-error.factory-reset-failed": "Fabrika ayarlarına sıfırlama başarısız oldu", "raid-error.health-warning": "Sağlık uyarısı", "raid-error.missing-ssd-multiple": "{{count}} SSD yanıt vermiyor", "raid-error.missing-ssd-one": "1 SSD yanıt vermiyor", "raid-error.shutdown-dialog.description": "Umbrel Pro'nu kapat, tüm SSD'lerin yuvalarına düzgün oturduğundan emin ol ve ardından tekrar aç.", "raid-error.shutdown-dialog.title": "Sürücüleri kontrol etmek için kapat?", "raid-error.ssd-in-slot": "{{size}} boyutunda bir SSD Slot {{slot}}", "raid-error.step-check-connections.button": "Kapat", "raid-error.step-check-connections.description": "Kapat ve tüm SSD'lerin düzgün şekilde oturduğunu kontrol et.", "raid-error.step-check-connections.title": "SSD bağlantılarını kontrol et", "raid-error.step-factory-reset.button": "Fabrika Ayarlarına Sıfırla", "raid-error.step-factory-reset.description": "Diğer her şey işe yaramazsa son çare. Bu tüm verileri siler.", "raid-error.step-factory-reset.title": "Fabrika ayarlarına sıfırla", "raid-error.step-restart.button": "Yeniden Başlat", "raid-error.step-restart.description": "Genellikle işe yarayan hızlı bir ilk adım", "raid-error.step-restart.title": "Yeniden başlatmayı dene", "raid-error.title": "Depolama Sorunu Tespit Edildi", "read-less": "Daha az oku", "read-more": "Daha fazla oku", "reconnect": "Yeniden bağlan", "redirect.to-home": "Yükleniyor...", "redirect.to-login": "Yükleniyor...", "redirect.to-onboarding": "Yükleniyor...", "redirect.to-raid-error": "Yükleniyor...", "reload": "Yeniden yükle", "remote-tor-access": "Uzaktan Tor erişimi", "reset": "Sıfırla", "restart": "Yeniden başlat", "restart.confirm.submit": "Yeniden başlat", "restart.confirm.title": "Umbrel'inizi yeniden başlatmak istediğinizden emin misiniz?", "restart.restarting": "Yeniden başlatılıyor", "restart.restarting-message": "Yeniden başlatılırken bu sayfayı yenilemeyin veya Umbrel'inizi kapatmayın.", "rewind": "Rewind", "rewind.files-as-of": "Dosyalarınız şu tarihteki hali:", "rewind.loading-snapshots": "Anlık görüntüler yükleniyor...", "rewind.now": "Şimdi", "rewind.preflight.description": "Geçmiş yedeklerinizdeki dosya ve klasörleri bulun ve bunları güncel hâle geri getirin.", "rewind.preflight.enable-backups": "Rewind kullanmaya başlamak için Ayarlar'da Backups'ı kurun", "rewind.restore-complete": "Geri yükleme tamamlandı", "rewind.restore-error-description": "Lütfen tekrar deneyin.", "rewind.restore-failed": "Geri yükleme başarısız oldu", "rewind.restore-running-description": "Geri yükleme tamamlanana kadar bu sayfayı kapatmayın veya yenilemeyin", "rewind.restore-selected": "Seçileni geri yükle", "rewind.restore-success-description": "Dosyalarınız geri yüklendi", "rewind.restoring": "Geri yükleniyor", "rewind.snapshots-count_one": "{{count}} yedekten beri", "rewind.snapshots-count_other": "{{count}} yedekten beri", "search": "Ara", "settings": "Ayarlar", "settings.app-store-preferences.title": "Uygulama Mağazası Tercihleri", "settings.contact-support": "Yardım mı lazım? Destek ile iletişime geçin.", "settings.file-sharing": "Dosya paylaşımı", "settings.file-sharing.add-folder": "Ekle", "settings.file-sharing.add-folder-title": "Paylaşmak için bir klasör seçin", "settings.file-sharing.choice-entire-description": "Umbrel'inizdeki tüm dosyaları paylaşın", "settings.file-sharing.choice-entire-title": "Her şey", "settings.file-sharing.choice-heading": "Ne paylaşmak istersiniz?", "settings.file-sharing.choice-specific-description": "Hangi klasörleri paylaşmak istediğinizi seçin", "settings.file-sharing.choice-specific-title": "Belirli klasörler", "settings.file-sharing.choice-subtitle": "Bilgisayarınızda veya telefonunuzda dosya ve klasörlerinize Dropbox tarzında, ağ klasörleri olarak erişin", "settings.file-sharing.configure": "Yapılandır", "settings.file-sharing.description": "Diğer cihazlarda dosyalarınıza Dropbox tarzında bir ağ klasörü (SMB) olarak erişin", "settings.file-sharing.home-shared-note": "Tüm \"{{homeDirectoryName}}\" klasörünüz paylaşılıyor. Alt klasörleri ayrı ayrı paylaşmanıza gerek yok.", "settings.file-sharing.share-entire-home-dir": "Home klasörünüzün tamamını paylaşın", "settings.file-sharing.share-entire-home-dir-description": "Ağınızdaki diğer cihazlardan \"{{homeDirectoryName}}\" içindeki tüm dosya ve klasörlere erişin", "settings.file-sharing.shared-folders": "Paylaşılan klasörler", "show-details": "Ayrıntıları göster", "shut-down": "Kapat", "shut-down.complete": "Kapatma tamamlandı", "shut-down.complete-text": "Cihazınızı şimdi güçten çekebilirsiniz.", "shut-down.confirm.submit": "Kapat", "shut-down.confirm.title": "Umbrel'inizi kapatmak istediğinizden emin misiniz?", "shut-down.failed": "Kapatmayı başaramadık: {{message}}", "shut-down.shutting-down": "Kapatılıyor", "shut-down.shutting-down-message": "Kapatılırken bu sayfayı yenilemeyin veya Umbrel'inizi kapatmayın.", "software-update.callout": "Güncelleme sırasında bu sayfayı yenilemeyin veya Umbrel'inizi kapatmayın.", "software-update.check": "Güncellemeleri kontrol et", "software-update.checking": "Güncellemeler kontrol ediliyor...", "software-update.current-running": "Mevcut sürümünüz", "software-update.failed": "Güncelleme başarısız", "software-update.failed-to-check": "Güncellemeler kontrol edilemedi", "software-update.failed.retry": "Tekrar dene", "software-update.install-now": "Şimdi yükle", "software-update.new-version": "Yeni {{name}} indirilebilir", "software-update.on-latest": "En son umbrelOS sürümündesiniz", "software-update.see-whats-new": "Bak, neler yeni", "software-update.title": "Yazılım güncellemesi", "software-update.updating-to": "{{name}} sürümüne güncelleniyor", "software-update.view": "Görüntüle", "something-left": "{{left}} kaldı", "something-went-wrong": "⚠ Bir şeyler ters gitti", "start": "Başlat", "stop": "Durdur", "storage": "Depolama", "storage-manager": "Depolama Yöneticisi", "storage-manager.add": "Ekle", "storage-manager.add-to-raid.add-ssd": "SSD ekle", "storage-manager.add-to-raid.available": "Kullanılabilir:", "storage-manager.add-to-raid.description": "Yeni bir SSD algılandı ve eklemeye hazır.", "storage-manager.add-to-raid.enable-failsafe": "FailSafe'i Etkinleştir", "storage-manager.add-to-raid.failed-add": "SSD eklenemedi", "storage-manager.add-to-raid.failed-enable-failsafe": "FailSafe etkinleştirilemedi", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Yeni {{size}} SSD'niz kullanılabilir depolamaya eklenecek.", "storage-manager.add-to-raid.info-capacity-adds-available": "Yeni {{size}} SSD'niz kullanılabilir depolamaya {{available}} ekleyecek.", "storage-manager.add-to-raid.info-capacity-adds-both": "Yeni {{size}} SSD'niz kullanılabilir depolamaya {{available}} ve veri koruması için {{protection}} ekleyecek.", "storage-manager.add-to-raid.info-capacity-protection-only": "Yeni {{size}} SSD'niz veri koruması için {{protection}} sağlayacak.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Yeni {{size}} SSD tamamen veri koruması için kullanılacak.", "storage-manager.add-to-raid.info-data-safe": "Tek bir SSD arızalansa bile verilerin güvende olacak.", "storage-manager.add-to-raid.info-no-protection": "Bir SSD arızalanırsa verilerinizi kaybedebilirsiniz.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} farklı SSD boyutları nedeniyle toplam kullanılamaz.", "storage-manager.add-to-raid.info-wasted": "{{size}} farklı SSD boyutları nedeniyle kullanılamaz olacak.", "storage-manager.add-to-raid.recommended": "Önerilen", "storage-manager.add-to-raid.recommended-inline": "(önerilen)", "storage-manager.add-to-raid.restart-active-tasks": "Aktif görevlerin hepsi kesintiye uğrayacak", "storage-manager.add-to-raid.restart-after": "Yeniden başlatmadan sonra FailSafe kurulumu otomatik tamamlanacak ve normal kullanıma devam edebileceksin.", "storage-manager.add-to-raid.restart-during": "Yeniden başlatma sırasında:", "storage-manager.add-to-raid.restart-intro": "Bu işlem sırasında umbrelOS'u normal şekilde kullanmaya devam edebilirsin. Ancak %50 ilerlemede Umbrel otomatik olarak yeniden başlatılacak.", "storage-manager.add-to-raid.restart-required": "Yeniden başlatma gerekli", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS geçici olarak erişilemez olacak", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} boyutunda SSD Slot {{slot}}", "storage-manager.add-to-raid.title": "Depolamaya SSD Ekle", "storage-manager.add-to-raid.too-small": "SSD çok küçük", "storage-manager.add-to-raid.too-small-description": "Bu SSD ({{deviceSize}}), şu anda takılı en küçük SSD'den ({{minSize}}) daha küçük. FailSafe, tüm SSD'lerin en küçük kullanılan SSD ile aynı boyutta ya da daha büyük olmasını gerektirir.", "storage-manager.add-to-raid.understand-continue": "Anladım, devam et", "storage-manager.add-to-raid.warning-failsafe-now-only": "Birden fazla SSD olması, FailSafe'in yalnızca şimdi etkinleştirilebileceği anlamına gelir. Daha sonra etkinleştiremezsin.", "storage-manager.add-to-raid.wasted-label": "Kullanılamaz:", "storage-manager.available-storage": "Kullanılabilir depolama", "storage-manager.description": "SSD'lerinizin depolama alanını, sağlık durumunu ve ayarlarını görüntüleyin", "storage-manager.empty": "Boş", "storage-manager.failsafe-transition-failed": "FailSafe etkinleştirilemedi", "storage-manager.for-failsafe": "FailSafe için", "storage-manager.health.checksum-errors": "Checksum hataları: {{count}}", "storage-manager.health.critical": "Kritik", "storage-manager.health.critical-threshold": "Kritik eşik", "storage-manager.health.current-temperature": "Mevcut sıcaklık", "storage-manager.health.estimated-life": "Tahmini kalan ömür", "storage-manager.health.general": "Genel", "storage-manager.health.health-status": "Sağlık durumu", "storage-manager.health.low": "Düşük", "storage-manager.health.model-and-capacity": "Model ve boyut", "storage-manager.health.overheating": "Aşırı ısınma", "storage-manager.health.raid-failed-advice": "Bu SSD'de bir sorun var. Umbrel'inizi kapatıp SSD bağlantısını kontrol edin. Sorun devam ederse SSD'nin değiştirilmesi gerekebilir.", "storage-manager.health.read-errors": "Okuma hataları: {{count}}", "storage-manager.health.serial-number": "Seri numarası", "storage-manager.health.status-healthy": "Sağlıklı", "storage-manager.health.status-unhealthy": "Sağlıksız", "storage-manager.health.status-unknown": "Bilinmiyor", "storage-manager.health.temperature": "Sıcaklık", "storage-manager.health.title": "SSD Sağlığı", "storage-manager.health.warning-life-advice": "Bu SSD'yi yakında değiştirmeyi düşünün.", "storage-manager.health.warning-life-message": "Kalan ömür yalnızca %{{percent}}", "storage-manager.health.warning-temp-advice": "Umbrel Pro'nuzun iyi hava akışına sahip olduğundan ve SSD'nin düzgün oturduğundan emin olun.", "storage-manager.health.warning-temp-critical": "Sıcaklık kritik ({{temperature}})", "storage-manager.health.warning-temp-overheating": "Sürücü aşırı ısınıyor ({{temperature}})", "storage-manager.health.warning-threshold": "Uyarı eşiği", "storage-manager.health.warning-unhealthy-advice": "Bu SSD yakında arızalanabilir. Değiştirmeyi düşünün.", "storage-manager.health.warning-unhealthy-message": "Bu SSD'de sorun olabilir", "storage-manager.health.warnings": "Uyarılar", "storage-manager.health.wear": "Aşınma", "storage-manager.health.write-errors": "Yazma hataları: {{count}}", "storage-manager.install-ssd.description": "Depolamanızı genişletmek için daha fazla SSD ekleyin", "storage-manager.install-ssd.step-insert": "Yeni SSD'leri boş yuvalara tak", "storage-manager.install-ssd.step-power-on": "{{deviceName}}'ni aç", "storage-manager.install-ssd.step-remove-bottom-cover": "Manyetik alt kapağı çıkar", "storage-manager.install-ssd.step-replace-bottom-cover": "Alt kapağı yerine tak", "storage-manager.install-ssd.step-return": "Buraya dön ve SSD'leri depolamana ekle", "storage-manager.install-ssd.step-shut-down": "{{deviceName}}'ni kapat", "storage-manager.install-ssd.title": "SSD Ekleme", "storage-manager.install-tips.image-alt": "SSD kurulum talimatı", "storage-manager.install-tips.instructions": "Kurmak için başparmak vidasını çıkar ve SSD'yi eğik bir açıyla slota kaydır. SSD'yi vida ayağına oturana kadar bastır, sonra başparmak vidasıyla sabitle.", "storage-manager.install-tips.toggle": "SSD'yi nasıl takacağınızı mı unuttunuz?", "storage-manager.manage": "Yönet", "storage-manager.missing-ssd-warning": "Bir SSD eksik gibi görünüyor. Umbrel'inizi kapatıp tüm SSD'lerin bağlı olduğunu kontrol edin. Sorun devam ederse SSD'nin değiştirilmesi gerekebilir.", "storage-manager.mode": "Mod", "storage-manager.mode.failsafe": "Arıza Koruması", "storage-manager.mode.failsafe.description": "Bir SSD arızalanırsa verilerinizi güvende tutar. SSD'leriniz farklı boyutlardaysa, daha büyük olanlardaki ekstra alan kullanılmaz.", "storage-manager.mode.failsafe.info-description": "FailSafe, verilerinizin kopyalarını SSD'ler arasında tutarak korur. Tek bir SSD arızalanırsa verileriniz güvende kalır ve yerine yenisini eklediğinizde geri yüklenebilir.", "storage-manager.mode.failsafe.info-title": "Arıza Koruması Hakkında", "storage-manager.mode.full-storage": "Tam Depolama", "storage-manager.mode.full-storage.description": "Tüm SSD alanınızı birlikte kullanın. Bir SSD arızalanırsa verilerinizi kaybedebilirsiniz.", "storage-manager.mode.full-storage.info-description": "Full Storage tüm SSD'lerinizi tek bir geniş alanda birleştirir ve maksimum depolama sağlar. Ancak herhangi bir SSD arızalanırsa tüm verileriniz kaybolur.", "storage-manager.mode.full-storage.info-title": "Tam Depolama Hakkında", "storage-manager.mode.switch-from-failsafe-unavailable": "FailSafe'den Full Storage moduna geçmek için verilerini yedeklemen, cihazı fabrika ayarlarına sıfırlaman ve yedekten geri yüklemen gerekir.", "storage-manager.mode.switch-to-failsafe-unavailable": "Birden fazla SSD ile Full Storage modunda verilerin tüm sürücülere dağıtılır. FailSafe'e geçmek için verilerini yedeklemen, fabrika ayarlarına sıfırlaman ve geri yüklemen gerekir.", "storage-manager.mode.why-cant-switch": "Neden geçiş yapamıyorum?", "storage-manager.operation-in-progress.shutdown-description": "Kapatmak güvenli. İşlem duraklatılacak ve yeniden başlatma sonrası devam edecek; ancak başka değişiklikler yapabilmeniz için işlemin tamamlanması gerekiyor.", "storage-manager.operation-in-progress.shutdown-title": "Depolamanız güncelleniyor", "storage-manager.operation-in-progress.wait-description": "Lütfen daha fazla değişiklik yapmadan önce mevcut işlemin bitmesini bekleyin.", "storage-manager.operation-in-progress.wait-title": "Depolamanız güncelleniyor", "storage-manager.operation.adding-ssd": "SSD ekleniyor...", "storage-manager.operation.enabling-failsafe": "Arıza Koruması etkinleştiriliyor...", "storage-manager.operation.expanding": "Depolama genişletiliyor...", "storage-manager.operation.rebuilding": "Veriler yeniden oluşturuluyor...", "storage-manager.operation.replacing": "Sürücü değiştiriliyor...", "storage-manager.operation.restarting": "Yeniden başlatılıyor...", "storage-manager.operation.starting": "Başlatılıyor...", "storage-manager.operation.syncing-restarts": "Veriler senkronize ediliyor • %50'de yeniden başlatılacak", "storage-manager.raid-status.degraded": "Kısmi arızalı", "storage-manager.raid-status.failed": "Arızalı", "storage-manager.raid-status.offline": "Çevrimdışı", "storage-manager.raid-status.online": "Çevrimiçi", "storage-manager.raid-status.removed": "Kaldırıldı", "storage-manager.raid-status.unavailable": "Kullanılamıyor", "storage-manager.replace": "Değiştir", "storage-manager.replace-failed.degraded": "FailSafe koruması azaldı", "storage-manager.replace-failed.degraded-description": "FailSafe depolamanızdan bir SSD eksik. Tam korumayı geri yüklemek için onu değiştirin.", "storage-manager.replace-failed.description": "FailSafe korumanızı geri yüklemek için bu SSD'yi kullanın.", "storage-manager.replace-failed.error": "Değiştirme başlatılamadı", "storage-manager.replace-failed.replace-now": "Şimdi değiştir", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD, Yuva {{slot}}", "storage-manager.replace-failed.step-protected": "Tamamlandığında, verileriniz tekrar tamamen korunmuş olacak", "storage-manager.replace-failed.step-rebuild": "Veriler yeni SSD'ye yeniden oluşturulacak", "storage-manager.replace-failed.step-time": "Bu, sahip olduğunuz veri miktarına bağlı olarak biraz zaman alabilir", "storage-manager.replace-failed.title": "SSD'yi değiştir", "storage-manager.replace-failed.too-small": "SSD çok küçük", "storage-manager.replace-failed.too-small-description": "Bu SSD ({{deviceSize}}), FailSafe depolamanız için gerekli minimum ({{minSize}}) boyutundan daha küçük.", "storage-manager.replace-failed.what-happens": "Sonra ne olacak:", "storage-manager.ssd-failing": "Arızalanıyor", "storage-manager.swap": "Değiştir", "storage-manager.swap.data-erased-description": "Full Storage modunda veri koruması yok. Fabrika ayarlarına sıfırlama sırasında {{deviceName}} üzerindeki tüm veriler silinecek. Önce her şeyi yedeklediğinden emin ol.", "storage-manager.swap.data-protected": "Verilerin korunuyor", "storage-manager.swap.data-protected-description": "FailSafe etkinse, herhangi bir tek SSD'yi verilerini kaybetmeden değiştirebilirsin. Yedek gerekmez.", "storage-manager.swap.data-will-be-erased": "Veriler silinecek", "storage-manager.swap.description-failsafe": "FailSafe depolamada bir sürücüyü değiştir.", "storage-manager.swap.description-full-storage": "Full Storage kurulumunda bir sürücüyü değiştir.", "storage-manager.swap.description-no-free-slot": "Tüm yuvaların dolu olduğu Full Storage modunda, bir SSD'yi değiştirmek tam bir yedekleme ve geri yükleme gerektirir.", "storage-manager.swap.description-replace": "Verilerini yeni bir SSD'ye taşı, sonra eskisini çıkar.", "storage-manager.swap.failed-to-start": "Değiştirme işlemi başlatılamadı", "storage-manager.swap.no-data-loss": "Veri kaybı yok", "storage-manager.swap.no-data-loss-description": "Verilerin yeni SSD'ye kopyalanacak. İşlem tamamlandığında eskiyi güvenle çıkarabilirsin.", "storage-manager.swap.safe-swap-available": "Güvenli değiştirme mevcut", "storage-manager.swap.safe-swap-description": "Boş bir yuva olduğundan yeni SSD'yi önce ekleyip verilerini taşıyabilir, sonra eskisini çıkarabilirsin. Yedek gerekmez.", "storage-manager.swap.select-new-ssd": "Kullanılacak yeni SSD'yi seç:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD Slot {{slot}}'te", "storage-manager.swap.step-backup": "Verilerini yedekle", "storage-manager.swap.step-backup-description": "Ayarlar → Backups'a git ve tüm verilerinin yedeğini oluştur.", "storage-manager.swap.step-data-copied": "Veriler eski SSD'den yenisine kopyalanacak", "storage-manager.swap.step-factory-reset": "Fabrika ayarlarına sıfırla", "storage-manager.swap.step-factory-reset-description": "Ayarlar → Gelişmiş → Fabrika Ayarlarına Sıfırla'ya git ve {{deviceName}}'ni sil.", "storage-manager.swap.step-insert-new-ssd": "Yeni SSD'yi boş bir yuvaya tak", "storage-manager.swap.step-may-take-while": "Bu, sahip olduğunuz veri miktarına bağlı olarak biraz zaman alabilir", "storage-manager.swap.step-power-on": "{{deviceName}}'ni aç", "storage-manager.swap.step-remove-bottom-cover": "Manyetik alt kapağı çıkar", "storage-manager.swap.step-remove-old": "İşlem tamamlandığında, kapat ve {{ssd}}'yi çıkar", "storage-manager.swap.step-replace-bottom-cover": "Alt kapağı geri tak", "storage-manager.swap.step-restore": "Verilerini geri yükle", "storage-manager.swap.step-restore-description": "Ayarlar → Backups'a git ve yedeğinden geri yükle.", "storage-manager.swap.step-return-to-storage-manager": "Buraya dön, Depolama Yöneticisi'nde değişimi onayla ve yeni SSD'yi depolamana ekle.", "storage-manager.swap.step-return-to-swap": "Buraya dön, Depolama Yöneticisi'ne git ve değiştirmeyi başlatmak için tekrar \"Değiştir\"e tıkla.", "storage-manager.swap.step-setup-new-storage": "Yeni depolamanı kur", "storage-manager.swap.step-setup-new-storage-description": "{{deviceName}}'ni aç ve yeni SSD ile kurulum işlemini tamamla.", "storage-manager.swap.step-shut-down": "{{deviceName}}'ni kapat", "storage-manager.swap.step-shut-down-and-swap": "Kapat ve {{ssd}}'yi değiştir", "storage-manager.swap.step-shut-down-and-swap-description-other": "Kapat, cihazını aç, SSD'yi değiştir ve tekrar monte et.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Kapat, alt kapağı çıkar, SSD'yi değiştir ve kapağı kapat.", "storage-manager.swap.step-swap-ssd": "{{ssd}}'yi aynı boyutta yeni bir SSD ile değiştir", "storage-manager.swap.too-small": "Çok küçük (gereken: {{size}})", "storage-manager.swap.what-happens-next": "Sonrasında ne olacak:", "storage-manager.total-capacity-added": "Toplam eklenen kapasite", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Kullanılan", "storage-manager.wasted": "Kullanılamaz", "storage-manager.wasted-size": "{{size}} Kullanılamaz", "storage.full": "Depolama dolu", "storage.low": "Düşük depolama alanı", "temperature": "Sıcaklık", "temperature.dangerously-hot": "Çok sıcak", "temperature.nice": "Güzel", "temperature.normal": "Normal", "temperature.too-hot-suggestion": "Cihazınızın ortamını değiştirmeyi düşünün.", "temperature.warm": "Ilık", "terminal": "Terminal", "terminal-description": "umbrelOS'ta veya bir uygulama içinde özel komutlar çalıştırın", "terminal.app": "Uygulama", "terminal.app-description": "Belirli bir uygulama içinde özel komutlar çalıştırın", "terminal.umbrelos-description": "umbrelOS'ta özel komutlar çalıştırın", "tor-description": "Tor tarayıcı kullanarak Umbrel'inize her yerden erişin", "tor-enabled-description": "Aşağıdaki URL üzerinden bir Tor tarayıcısı kullanarak Umbrel'inize her yerden erişin:", "tor-error": "Tor ayarını güncelleyemedik: {{message}}", "tor.disable.description": "Bu birkaç dakika sürebilir", "tor.disable.progress": "Uzaktan Tor erişimi devre dışı bırakılıyor", "tor.enable.description": "Bu birkaç dakika sürebilir", "tor.enable.mobile.switch-label": "Uzaktan Tor erişimini etkinleştir", "tor.hidden-service": "Tor gizli servis URL'si", "troubleshoot": "Sorun giderme", "troubleshoot-description": "umbrelOS veya bir uygulama sorunlarını giderin", "troubleshoot-no-logs-yet": "Henüz günlük yok", "troubleshoot-pick-title": "Sorun giderme", "troubleshoot.app": "Uygulama", "troubleshoot.app-description": "Umbrel'inize yüklü bir uygulamanın günlüklerini görüntüleyin", "troubleshoot.app-download": "{{app}} günlüklerini indir", "troubleshoot.share-with-umbrel-support": "Umbrel Destek ile paylaş", "troubleshoot.system-download": "{{label}} indir", "troubleshoot.umbrelos-description": "umbrelOS günlüklerini görüntüleyin", "troubleshoot.umbrelos-logs": "umbrelOS günlükleri", "trpc.backend-unavailable": "Hata: Sistem API bağlantısı başarısız oldu", "trpc.checking-backend": "Yükleniyor...", "try-again": "Tekrar deneyin", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Bilinmeyen", "unknown-app": "Bilinmeyen uygulama", "unknown-error": "Bilinmeyen hata", "uptime": "Çalışma süresi", "url": "URL", "wallpaper": "Duvar kağıdı", "wallpaper-description": "Umbrel duvar kağıdınız ve temanız", "whats-new.continue": "Devam", "whats-new.feature-1.description": "Tüm Umbrel'inizin otomatik, şifreli yedeklerini harici bir USB sürücüsüne, bir NAS'a veya başka bir Umbrel'e ayarlayın.", "whats-new.feature-2.description": "Önceki yedeklerden belirli dosya ve klasörleri kurtarmak için zamanda geri gidin.", "whats-new.feature-3.description": "Veya tüm uygulamalarınız, dosyalarınız ve verileriniz dahil olmak üzere tüm Umbrel'inizi geri yükleyin.", "whats-new.feature-4.description": "Bir NAS veya başka bir Umbrel bağlayın ve depolamasına Files uygulamasından erişin.", "whats-new.feature-4.title": "Ağ cihazları", "whats-new.feature-5.description": "Harici USB sürücüler bağlayın (Umbrel Home'da veya herhangi bir Intel veya AMD cihazında) ve Files uygulamasından erişin.", "whats-new.feature-5.helper-text": "Raspberry Pi cihazlarında olası güç sorunları nedeniyle desteklenmez.", "whats-new.feature-5.title": "Harici Depolama", "whats-new.next": "İleri", "whats-new.title": "{{version}} sürümündeki yenilikler", "widget.progress.in-progress": "Devam ediyor", "widgets.edit.select-up-to-3-widgets": "En fazla 3 widget seçin", "widgets.install-an-app-before-using-widgets": "Ana ekranınızı widget'larla özelleştirmeye başlamak için bir uygulama yükleyin.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Açık ağlar güvensiz olabilir", "wifi-connection-failed": "Bağlanılamadı", "wifi-dangerous-change-confirmation-description": "Wi-Fi ağını değiştirmek, Umbrel'iniz ile olan bağlantınızı kesebilir. Yeniden bağlanmak için, Umbrel'inizin ve erişim sağladığınız cihazın aynı ağda olduğundan emin olun.", "wifi-dangerous-change-confirmation-title": "Wi-Fi ağını değiştirmek istediğinizden emin misiniz?", "wifi-dangerous-disable-confirmation-description": "Wi-Fi'yi devre dışı bırakmak, Umbrel'iniz ile olan bağlantınızı kesebilir. Yeniden bağlanmak için, Umbrel'inize bir Ethernet kablosu takın ve Umbrel'iniz ile erişim sağladığınız cihazın aynı ağda olduğundan emin olun.", "wifi-dangerous-disable-confirmation-title": "Wi-Fi'yi devre dışı bırakmak istediğinizden emin misiniz?", "wifi-description": "Cihazınızı bir Wi-Fi ağına bağlayın", "wifi-description-long": "Ethernet kablosu çıkarılsa bile cihazınız seçtiğiniz Wi-Fi'ye bağlı kalır ve başlatıldığında otomatik olarak Wi-Fi'ye yeniden bağlanır.", "wifi-no-networks-message": "Wi-Fi ağı bulunamadı", "wifi-searching": "Wi-Fi ağları aranıyor...", "wifi-unsupported-device-description": "Bu cihaz Wi-Fi'yi desteklemiyor. Bu, eksik veya uyumsuz bir kablosuz adaptörden kaynaklanabilir.", "wifi-view-networks": "Ağları görüntüle" } ================================================ FILE: packages/ui/public/locales/uk.json ================================================ { "2fa": "2FA", "2fa-description": "Другий рівень безпеки для вашого входу в Umbrel і програм", "2fa.disable.title": "Вимкнути двофакторну автентифікацію", "2fa.enable.or-paste": "Або вставте наступний код у вашу програму-аутентифікатор", "2fa.enable.scan-this": "Скануйте цей QR-код за допомогою програми-аутентифікатора, такого як Google Authenticator або Authy", "2fa.enable.title": "Увімкнути двофакторну автентифікацію", "2fa.enter-code": "Введіть код, показаний у вашій програмі-аутентифікаторі", "account": "Акаунт", "account-description": "Ваше ім'я та пароль", "advanced-settings": "Розширені налаштування", "advanced-settings-description": "Термінал, програма бета-тестування umbrelOS, Cloudflare DNS та інше", "app-not-found": "Програму не знайдено: {{app}}", "app-only-over-tor": "{{app}} можна використовувати лише через Tor. Будь ласка, відкрийте свій Umbrel у браузері Tor за URL-адресою віддаленого доступу (Налаштування > Розширені налаштування > Віддалений Tor-доступ), щоб відкрити цей додаток.", "app-page.section.about": "Про", "app-page.section.credentials.title": "Стандартні облікові дані", "app-page.section.dependencies.n-alternatives": "Переглянути {{count}} альтернатив", "app-page.section.info.compatibility": "Сумісність", "app-page.section.info.compatibility-compatible": "Сумісний", "app-page.section.info.compatibility-not-compatible": "Не сумісний", "app-page.section.info.developer": "Розробник", "app-page.section.info.source-code": "Вихідний код", "app-page.section.info.source-code.public": "Публічний", "app-page.section.info.submitted-by": "Подано", "app-page.section.info.support": "Отримати підтримку", "app-page.section.info.title": "Інформація", "app-page.section.info.version": "Версія", "app-page.section.recommendations.title": "Вам також може сподобатися", "app-page.section.release-notes.title": "Що нового", "app-page.section.release-notes.version": "Версія {{version}}", "app-page.section.requires": "Вимагає", "app-picker.search": "Пошук...", "app-picker.select-app": "Виберіть програму...", "app-settings.connected-to": "{{appName}} підключено до цих додатків", "app-settings.save-changes": "Зберегти зміни", "app-settings.title": "Налаштування", "app-store.browse-category-apps": "Перегляд програм у категорії {{category}}", "app-store.category.ai": "Штучний інтелект", "app-store.category.all": "Всі програми", "app-store.category.automation": "Дім і автоматизація", "app-store.category.bitcoin": "Біткойн", "app-store.category.crypto": "Крипто", "app-store.category.developer": "Інструменти розробника", "app-store.category.discover": "Відкривати", "app-store.category.files": "Файли та продуктивність", "app-store.category.finance": "Фінанси", "app-store.category.media": "Медіа", "app-store.category.networking": "Мережі", "app-store.category.social": "Соціальні мережі", "app-store.description": "Налаштування оновлення ваших програм", "app-store.discover.temporarily-unavailable-description": "Перегляньте категорії вище або скористайтеся пошуком, щоб знайти застосунки", "app-store.discover.temporarily-unavailable-title": "Рекомендований контент тимчасово недоступний", "app-store.menu.community-app-stores": "Спільнота магазинів програм", "app-store.search-apps": "Пошук програм", "app-store.search.no-results": "Немає результатів", "app-store.search.results-for": "Результати для", "app-store.title": "App Store", "app-store.updates": "Оновлення", "app-updates.less": "менше", "app-updates.more": "більше", "app-updates.no-updates": "Всі програми оновлені!", "app-updates.update": "Оновити", "app-updates.update-all": "Оновити все", "app-updates.updates-available-count_one": "Доступно {{count}} оновлення", "app-updates.updates-available-count_other": "Доступно {{count}} оновлень", "app-updates.updating": "Оновлення...", "app.install": "Встановити", "app.installed": "Встановлено", "app.installing": "Встановлення", "app.offline": "Не працює", "app.open": "Відкрити", "app.optimized-for-umbrel-home": "Оптимізовано для Umbrel Home", "app.os-update-required.confirm": "Перевірити оновлення umbrelOS", "app.os-update-required.description": "{{appName}} потребує umbrelOS версії {{version}} або новішої", "app.os-update-required.title": "Оновити umbrelOS", "app.restarting": "Перезапуск", "app.starting": "Запуск", "app.stopping": "Зупинка", "app.uninstall.confirm.description": "Всі дані, пов'язані з {{app}}, будуть безповоротно видалені. Ця дія не може бути скасована.", "app.uninstall.confirm.submit": "Видалити", "app.uninstall.confirm.title": "Видалити {{app}}?", "app.uninstall.deps.used-by.description_one": "Спочатку видаліть {{firstAppToUninstall}}, щоб видалити {{app}}.", "app.uninstall.deps.used-by.description_other": "Спочатку видаліть ці програми, щоб видалити {{app}}.", "app.uninstall.deps.used-by.title": "{{app}} використовується", "app.uninstalling": "Видалення", "app.updating": "Оновлення", "app.view": "Переглянути", "app_one": "програма", "app_other": "програми", "apps.uninstall.failed-to-get-required-apps": "Не вдалося отримати необхідні програми", "apps.uninstalled-all.success": "Всі програми видалено", "auth.checking-backend-for-user": "Завантаження...", "auth.failed-checking-if-user-logged-in": "Помилка: перевірка входу не вдалася", "auth.failed-to-check-if-user-exists": "Помилка: перевірка існування не вдалася", "back": "Назад", "backups": "Backups", "backups-configure": "Налаштувати", "backups-configure.add-backup-location": "Додати місце для резервних копій", "backups-configure.available": "Доступно", "backups-configure.awaiting-next-backup": "Очікування наступної автоматичної резервної копії", "backups-configure.back-up-now": "Створити резервну копію зараз", "backups-configure.backing-up-now": "Створюється резервна копія...", "backups-configure.connected": "Підключено", "backups-configure.connection": "Підключення", "backups-configure.in-progress": "Виконується", "backups-configure.last-backup": "Остання резервна копія", "backups-configure.locations": "Місця збереження", "backups-configure.no-backup-locations": "Додайте місце для резервних копій, щоб почати зберігати дані", "backups-configure.not-connected": "Не підключено", "backups-configure.path": "Шлях", "backups-configure.remove-backup-location": "Видалити місце для резервних копій", "backups-configure.remove-backup-location-confirmation": "Ви впевнені?", "backups-configure.remove-backup-location-confirmation-description": "Це видалить «{{device}}» зі списку місць для резервного копіювання. Існуючі резервні копії на цьому пристрої не будуть видалені, але автоматичне резервне копіювання припиниться.", "backups-configure.status": "Статус", "backups-configure.total-backups": "Всього Backups", "backups-configure.used": "Використано", "backups-configure.view": "Переглянути", "backups-description": "Зберігайте файли, програми та дані на іншому Umbrel, NAS або зовнішньому диску", "backups-error.backup-not-found": "Не вдалося знайти резервну копію.", "backups-error.generic": "Щось пішло не так: {{details}}", "backups-error.in-progress": "Вже виконується резервне копіювання. Будь ласка, зачекайте, поки воно завершиться.", "backups-error.invalid-exclusion-path": "Виключати з резервних копій можна лише файли та папки в домашньому каталозі.", "backups-error.invalid-password": "Невірний пароль шифрування.", "backups-error.invalid-path": "Обране місце не підходить для резервних копій.", "backups-error.mount-failed": "Не вдалося отримати доступ до знімка резервної копії.", "backups-error.mount-timeout": "Не вдалося отримати доступ до знімка резервної копії. Спробуйте ще раз або перевірте, чи пристрій правильно підключено.", "backups-error.not-enough-space": "На пристрої для резервного копіювання недостатньо місця.", "backups-error.not-found": "Не вдалося знайти резервну копію або місце її збереження.", "backups-error.repository-exists": "У цій папці вже існує місце для резервного копіювання.", "backups-error.repository-not-found": "Не вдалося знайти місце збереження резервної копії.", "backups-exclusions.add": "Додати", "backups-exclusions.app-paths-cannot-be-modified": "Ці файли/папки задає розробник програми і їх не можна змінити:", "backups-exclusions.app-paths-explanation": "Цей додаток виключає наступні дані з резервного копіювання. Ці шляхи зазвичай містять неважливі елементи (наприклад, кеші або логи, які можна відновити) або дані, відновлення яких може викликати проблеми (наприклад, застарілі стани додатків, що можуть призвести до конфліктів або невідповідностей).", "backups-exclusions.auto-excluded": "Автовиключено", "backups-exclusions.exclude-entire-app": "Виключити всю програму", "backups-exclusions.excluded-apps": "Виключені програми", "backups-exclusions.files-and-folders": "Виключені файли та папки", "backups-exclusions.no-excluded-apps": "Виключених програм немає", "backups-exclusions.no-excluded-files-or-folders": "Виключених файлів або папок немає", "backups-exclusions.select-item-to-exclude": "Виберіть елемент для виключення", "backups-exclusions.stop-excluding": "Прибрати з виключень", "backups-floating-island.backing-up": "Виконується резервне копіювання...", "backups-floating-island.backing-up-to": "Створюється резервна копія вашого Umbrel...", "backups-restore": "Restore", "backups-restore-full": "Повне відновлення", "backups-restore-full-description": "Відновити весь Umbrel із резервної копії", "backups-restore-header": "Відновити Umbrel", "backups-restore-pro.after-restore": "Після відновлення ваш тимчасовий обліковий запис буде замінено на обліковий запис і дані з резервної копії.", "backups-restore-pro.step1": "Завершіть початкове налаштування, натиснувши «Почати» нижче. Це буде ваш тимчасовий обліковий запис, поки ви не відновите свій обліковий запис із резервної копії.", "backups-restore-pro.step2": "Після завершення налаштування перейдіть у <0>Налаштування → Backups → Restore", "backups-restore-pro.step3": "Дотримуйтесь підказок у Restore Wizard.", "backups-restore-pro.subtitle": "Відновлення з резервної копії на Umbrel Pro потребує кількох додаткових кроків", "backups-restore.backup-date": "Дата резервної копії", "backups-restore.backup-location": "Розташування резервної копії", "backups-restore.browse-cloud-subtitle": "Відновити з Umbrel Private Cloud (незабаром)", "backups-restore.browse-cloud-title": "Umbrel Private Cloud", "backups-restore.browse-external-subtitle": "Відновити з зовнішнього USB-накопичувача", "backups-restore.browse-external-title": "Зовнішній диск", "backups-restore.browse-nas-or-external": "Перегляньте інший Umbrel, NAS або зовнішній диск, щоб відновити резервну копію", "backups-restore.browse-nas-subtitle": "Відновити з іншого пристрою Umbrel або NAS у вашій мережі", "backups-restore.browse-nas-title": "Інший Umbrel або NAS", "backups-restore.choose": "Вибрати", "backups-restore.choose-backup-location": "Оберіть місце збереження резервних копій", "backups-restore.connect-to-backup-location": "Підключитися до місця резервного копіювання", "backups-restore.encryption-password": "Пароль шифрування", "backups-restore.encryption-password-description": "Введіть пароль шифрування, який ви встановили, коли ввімкнули резервне копіювання", "backups-restore.enter-password-to-confirm": "Введіть свій пароль Umbrel, щоб підтвердити", "backups-restore.final-confirmation": "Ви впевнені?", "backups-restore.final-confirmation-description": "Відновлення з цієї резервної копії замінить ваші поточні додатки та дані umbrelOS вмістом обраної резервної копії. Будь-які файли, папки або програми, виключені з цієї резервної копії, будуть видалені з вашого Umbrel. Цю дію неможливо скасувати.", "backups-restore.invalid-password": "Невірний пароль", "backups-restore.last-backup": "Остання резервна копія: {{date}}", "backups-restore.latest": "Остання", "backups-restore.no-backups-found": "Резервні копії не знайдено", "backups-restore.no-backups-yet": "Поки що немає резервних копій", "backups-restore.please-select-backup": "Будь ласка, виберіть резервну копію", "backups-restore.please-select-repository": "Будь ласка, оберіть репозиторій", "backups-restore.restore-from-nas-or-external": "Відновіть Umbrel із резервної копії на іншому Umbrel, NAS або зовнішньому диску", "backups-restore.restore-from-unlisted": "Відновити з іншого місця", "backups-restore.restore-umbrel": "Відновити Umbrel", "backups-restore.restore-warning": "Відновлення з цієї резервної копії замінить ваші поточні додатки та дані umbrelOS вмістом обраної резервної копії. Будь-які файли, папки або програми, виключені з цієї резервної копії, будуть видалені з вашого Umbrel. Відкрийте <0>Rewind, якщо хочете відновити окремі файли чи папки замість цього.", "backups-restore.restoring-from": "Ви збираєтеся відновити з наступної резервної копії:", "backups-restore.review-description": "Відновлення налаштує ваш Umbrel з обліковим записом, файлами, додатками та налаштуваннями, які були включені на момент створення цієї резервної копії. Це може зайняти деякий час. Після завершення пароль для входу буде встановлено на той, який ви використовували під час створення резервної копії.", "backups-restore.select-backup": "Оберіть резервну копію", "backups-restore.select-backup-description": "Оберіть резервну копію, з якої хочете відновити", "backups-restore.select-backup-file": "Виберіть файл резервної копії", "backups-restore.select-backup-file-only": "Можна вибрати тільки {{backupFileName}}", "backups-restore.total-size": "Загальний розмір", "backups-restore.unknown-date": "Невідома дата", "backups-restore.unknown-repository": "Невідомий репозиторій", "backups-rewind": "Rewind", "backups-rewind-description": "Повернутися назад у часі, щоб відновити окремі файли та папки", "backups-rewind.start": "Розпочати Rewind", "backups-setup": "Налаштувати", "backups-setup-confirm": "Завершити налаштування", "backups-setup-external-description": "Резервне копіювання на зовнішній USB-накопичувач", "backups-setup-nas-or-umbrel-description": "Резервне копіювання на інший Umbrel або пристрій NAS у вашій мережі", "backups-setup-umbrel-or-nas": "Інший Umbrel або NAS", "backups-setup-umbrel-private-cloud": "Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-cta": "Продовжте спокій за межами дому з шифрованими «end-to-end» резервними копіями в Umbrel Private Cloud.", "backups-setup-umbrel-private-cloud-cta-link": "Отримати ранній доступ", "backups-setup-umbrel-private-cloud-description": "End-to-end зашифровані резервні копії в Umbrel Private Cloud", "backups-setup-umbrel-private-cloud-subtitle": "Скоро буде", "backups.add-umbrel-or-nas": "Додати Umbrel або NAS", "backups.all-apps-and-data-will-be-backed-up": "Усі програми та дані будуть збережені в резервних копіях", "backups.apps-and-data": "Apps & data", "backups.backup-location": "Місце збереження резервних копій", "backups.browse": "Огляд", "backups.choose-folder-within-device": "Оберіть папку в {{device}}, куди зберігати резервні копії", "backups.confirm-password": "Підтвердити пароль", "backups.copy": "Копіювати", "backups.encryption": "Шифрування", "backups.encryption-password-warning": "Переконайтеся, що пароль шифрування збережено у надійному місці, наприклад у менеджері паролів. Ви не зможете побачити його повторно, і він потрібен для відновлення резервних копій.", "backups.exclude-from-backups": "Виключити з Backups", "backups.exclude-from-backups-description": "Виключіть конкретні файли, папки та програми з ваших резервних копій.", "backups.hide": "Приховати", "backups.i-understand": "Я розумію", "backups.location": "Місце", "backups.modals.already-in-use.description": "Це розташування резервних копій вже використовується для резервного копіювання на цьому Umbrel.", "backups.modals.already-in-use.manage": "Керувати в Backups", "backups.modals.already-in-use.title": "Розташування резервних копій вже використовується", "backups.modals.connect-existing.description": "У цьому розташуванні вже є резервна копія Umbrel. Введіть пароль шифрування цієї копії, щоб додати її до цього Umbrel.", "backups.modals.connect-existing.title": "Підключити існуючу резервну копію Umbrel", "backups.no-external-drives-detected": "Зовнішні диски не виявлено", "backups.no-password-set": "Пароль не встановлено", "backups.password-is-set": "Пароль встановлено", "backups.password-minimum-length": "Пароль має містити щонайменше 8 символів", "backups.password-safety-warning": "Ваші резервні копії будуть зашифровані за допомогою цього пароля. Збережіть його в безпечному місці — ви не зможете побачити його знову, і він знадобиться для відновлення резервних копій.", "backups.passwords-do-not-match": "Паролі не збігаються", "backups.please-choose-folder": "Будь ласка, оберіть папку", "backups.restore-failed.message": "Під час відновлення Umbrel сталася помилка. Ваші поточні додатки та дані не були змінені.", "backups.restore-failed.retry": "Перейти до відновлення", "backups.restore-failed.title": "Не вдалося відновити", "backups.restoring": "Відновлення вашого Umbrel", "backups.restoring-completing": "Майже готово. Ваш Umbrel незабаром перезавантажиться...", "backups.restoring-progress": "Відновлено {{percent}}%", "backups.restoring-time-remaining": "Залишилось: {{time}}", "backups.restoring-warning": "Не вимикайте Umbrel і не відключайте місце резервного копіювання під час відновлення", "backups.review": "Переглянути та підтвердити", "backups.review-description": "Перегляньте деталі резервного копіювання та підтвердіть свій вибір", "backups.scanning-for-external-drives": "Пошук зовнішніх дисків...", "backups.schedule-description": "umbrelOS автоматично створює резервні копії даних щогодини. Він зберігає зашифровані щогодинні копії за останні 24 години, щоденні копії за минулий тиждень, щотижневі — за минулий місяць, і щомісячні — за минулий рік. Резервні копії старші одного року видаляються автоматично.", "backups.select-backup-folder": "Оберіть папку для резервних копій", "backups.select-backup-folder-description": "Виберіть папку, куди ви хочете зберігати резервні копії.", "backups.select-backup-location": "Оберіть місце резервного копіювання", "backups.set-encryption-password": "Встановити пароль шифрування", "backups.set-encryption-password-description": "Захистіть резервні копії паролем. Це гарантує приватність ваших даних і дозволить відновити їх лише з цим паролем.", "backups.show": "Показати", "backups.storage-capacity-warning": "На {{device}} має бути вільного місця принаймні вдвічі більше за розмір резервної копії", "backups.store-encryption-password-safely": "Збережіть пароль шифрування в надійному місці", "beta-program": "umbrelOS Beta Program", "beta-program-description": "Оптимізуйте отримання бета-оновлень umbrelOS, отримуйте ранній доступ до нових функцій та допомагайте нам удосконалювати їх, надаючи свій зворотній зв'язок. Бета-оновлення можуть бути нестабільними, а вирішення проблем може вимагати знайомства з терміналом.", "cancel": "Скасувати", "change": "Змінити", "change-name": "Змінити ім'я", "change-name.failed.name-required": "Ім'я обов'язкове", "change-name.input-placeholder": "Ваше ім'я", "change-password": "Змінити пароль", "change-password.callout": "Якщо ви забудете свій пароль, ви не зможете увійти до свого Umbrel. Переконайтеся, що ви надійно зберегли його.", "change-password.current-password": "Поточний пароль", "change-password.failed.current-required": "Поточний пароль обов'язковий", "change-password.failed.min-length": "Пароль повинен містити щонайменше {{characters}} символів", "change-password.failed.must-be-unique": "Новий пароль повинен відрізнятися від поточного пароля", "change-password.failed.new-required": "Новий пароль обов'язковий", "change-password.failed.no-match": "Паролі не співпадають", "change-password.failed.repeat-required": "Повторіть пароль обов'язково", "change-password.new-password": "Новий пароль", "change-password.repeat-password": "Повторіть пароль", "check-for-latest-version": "Перевірити останнє оновлення umbrelOS", "clipboard.copied": "Скопійовано", "close": "Закрити", "cmdk.change-wallpaper": "Змінити фон", "cmdk.frequent-apps": "Часто використовувані", "cmdk.input-placeholder": "Пошук програм, налаштувань або дій", "cmdk.live-usage": "Живий використання", "cmdk.restart-umbrel": "Перезапустити Umbrel", "cmdk.shutdown-umbrel": "Вимкнути Umbrel", "cmdk.update-all-apps": "Оновити всі програми", "cmdk.widgets": "Віджети", "community-app-store": "Community App Store", "community-app-store.add-error": "Не вдалося додати App Store: {{message}}", "community-app-store.back-to-umbrel-app-store": "Назад до Umbrel App Store", "community-app-store.open-button": "Відкрити", "community-app-store.remove-button": "Видалити", "community-app-store.remove-error": "Не вдалося видалити App Store: {{message}}", "community-app-stores.add-button": "Додати", "community-app-stores.description": "Community App Stores дозволяють встановлювати програми на ваш Umbrel, які можуть бути недоступні в офіційному Umbrel App Store. Вони також спрощують тестування бета-версій програм Umbrel перед їх випуском в офіційному Umbrel App Store.", "community-app-stores.learn-more": "Дізнатися більше", "community-app-stores.warning": "Community App Stores можуть бути створені будь-ким. Програми, опубліковані в них, не перевірені та не затверджені командою офіційного Umbrel App Store і можуть бути небезпечними або зловмисними. Використовуйте обережно та додавайте магазини програм тільки від розробників, яким ви довіряєте.", "confirm": "Підтвердити", "connect": "Підключити", "connecting": "Підключення...", "connection-lost": "З'єднання втрачено", "connection-lost-description": "Це може статися, коли вкладка вашого браузера була неактивною, мережеве з'єднання перервалося або пристрій не підключено до мережі.", "continue": "Продовжити", "continue-to-log-in": "Продовжити вхід", "cpu": "ЦП", "cpu-core-count": "{{cores}} потоки", "default-credentials.close": "Зрозуміло", "default-credentials.description": "Ось облікові дані, які вам знадобляться для входу в програму.", "default-credentials.dont-show-again": "Більше не показувати це", "default-credentials.dont-show-again-notice": "Ви можете отримати доступ до цих облікових даних у будь-який час, натиснувши правою кнопкою миші на значок програми.", "default-credentials.open": "Відкрити {{app}}", "default-credentials.password": "Пароль за замовчуванням", "default-credentials.title": "Облікові дані для {{app}}", "default-credentials.username": "Ім'я користувача за замовчуванням", "desktop.app.context.go-to-store-page": "Переглянути в App Store", "desktop.app.context.settings": "Налаштування", "desktop.app.context.show-default-credentials": "Показати облікові дані за замовчуванням", "desktop.app.context.uninstall": "Видалити", "desktop.context-menu.change-wallpaper": "Змінити фон", "desktop.context-menu.edit-widgets": "Редагувати віджети", "desktop.context-menu.logout": "Вийти", "desktop.greeting.afternoon": "Доброго дня, {{name}}", "desktop.greeting.evening": "Добрий вечір, {{name}}", "desktop.greeting.morning": "Доброго ранку, {{name}}", "desktop.install-first.for-the-ai-enthusiast": "Для Viber", "desktop.install-first.for-the-bitcoiner": "Для Біткойнера", "desktop.install-first.for-the-self-hoster": "Для власного хостингу", "desktop.install-first.for-the-streamer": "Для стрімера", "desktop.install-first.link-to-app-store": "Дізнатися більше в App Store", "desktop.not-enough-room": "Використовуйте більший екран для перегляду програм.", "device": "Пристрій", "device-info": "Інформація про пристрій", "device-info-description": "Інформація про ваш пристрій", "device-info.device": "Пристрій", "device-info.model-number": "Номер моделі", "device-info.serial-number": "Серійний номер", "device-info.view-info": "Переглянути інформацію", "device-name.home-or-pro": "Umbrel Home або Umbrel Pro", "disable": "Вимкнути", "done": "Готово", "download-logs": "Завантажити журнали", "enabling-tor": "Увімкнення віддаленого доступу через Tor", "external-dns": "Cloudflare DNS", "external-dns-description": "Cloudflare DNS пропонує кращу надійність мережі. Вимкніть, щоб використовувати налаштування DNS вашого маршрутизатора.", "external-dns-error": "Не вдалося оновити налаштування DNS: {{message}}", "external-drive": "Зовнішній диск", "factory-reset": "Скидання до заводських налаштувань", "factory-reset-description": "Стерти всі ваші дані та програми, відновити umbrelOS до стандартних налаштувань", "factory-reset-failed": "Не вдалося скинути пристрій до заводських налаштувань: {{message}}", "factory-reset.confirm.body": "Підтвердьте свій пароль для скидання", "factory-reset.confirm.ethernet-required-warning": "Переконайтеся, що ваш пристрій підключений до маршрутизатора через Ethernet (не Wi-Fi) і ви отримуєте до нього доступ з вашої локальної мережі (наприклад, http://umbrel.local або локальна IP-адреса вашого пристрою).", "factory-reset.confirm.submit": "Стерти все і скинути", "factory-reset.confirm.submit-callout": "Цю дію не можна скасувати.", "factory-reset.rebooting.message": "Ваш пристрій буде перезавантажено, і всі дані будуть видалені. Будь ласка, не закривайте цю сторінку.", "factory-reset.rebooting.status": "Виконується скидання...", "factory-reset.rebooting.title": "Виконується скидання до заводських налаштувань", "factory-reset.review.account-info": "Інформація про акаунт та пароль", "factory-reset.review.apps": "Програми", "factory-reset.review.following-will-be-removed": "Наступне буде видалено з вашого пристрою", "factory-reset.review.installed-apps_one": "{{count}} встановлена програма", "factory-reset.review.installed-apps_other": "{{count}} встановлених програм", "factory-reset.review.submit": "Продовжити", "factory-reset.review.total-data": "Загальний обсяг даних", "files": "Files", "files-action.add-favorite": "Додати у вибране", "files-action.add-network-device": "Додати пристрій", "files-action.cancel-upload": "Скасувати завантаження", "files-action.compress": "Стиснути", "files-action.copy": "Копіювати", "files-action.cut": "Вирізати", "files-action.delete": "Видалити назавжди", "files-action.download": "Завантажити", "files-action.download-items": "Завантажити {{count}} елементів", "files-action.drop-to-upload": "Перетягніть сюди, щоб завантажити", "files-action.eject-disk": "Вийняти", "files-action.empty-trash": "Очистити кошик", "files-action.format-drive": "Форматувати", "files-action.go-to-path": "Перейти до...", "files-action.new-folder": "Нова папка", "files-action.open": "Відкрити", "files-action.paste": "Вставити", "files-action.remove-favorite": "Вилучити з вибраного", "files-action.remove-network-host": "Від’єднати мережевий диск", "files-action.remove-network-share": "Від’єднати мережевий ресурс", "files-action.rename": "Перейменувати", "files-action.restore": "Відновити", "files-action.select": "Вибрати", "files-action.share": "Надати спільний доступ через мережу…", "files-action.sharing": "Надається спільний доступ…", "files-action.show-in-folder": "Показати в папці", "files-action.trash": "Кошик", "files-action.uncompress": "Розпакувати", "files-action.upload": "Завантажити", "files-add-network-share.add-manually": "Додати вручну", "files-add-network-share.add-share": "Додати ресурс", "files-add-network-share.back": "Назад", "files-add-network-share.continue": "Продовжити", "files-add-network-share.description": "Під’єднайтесь до NAS або іншого спільного диска у вашій мережі, щоб отримати до них доступ у Files.", "files-add-network-share.discovering": "Виявлення...", "files-add-network-share.enter-details-manually": "Введіть дані сервера", "files-add-network-share.host-label": "Адреса сервера", "files-add-network-share.host-required": "Потрібна адреса сервера", "files-add-network-share.manual-share-help": "Введіть точну назву мережевої папки так, як вона вказана на вашому сервері", "files-add-network-share.no-shares-found": "На цьому сервері не знайдено мережевих папок", "files-add-network-share.not-seeing-share": "Не бачите свою мережеву папку?", "files-add-network-share.password-label": "Пароль", "files-add-network-share.password-required": "Потрібен пароль", "files-add-network-share.retrieving-shares": "Отримання ресурсів…", "files-add-network-share.retry-discovery": "Пересканувати мережу", "files-add-network-share.select-share": "Виберіть ресурс для додавання", "files-add-network-share.share-placeholder": "shared-documents", "files-add-network-share.share-required": "Потрібна назва ресурсу", "files-add-network-share.title": "Додати мережевий ресурс", "files-add-network-share.username-label": "Ім’я користувача", "files-add-network-share.username-placeholder": "admin", "files-add-network-share.username-required": "Потрібне ім’я користувача", "files-audio-island.now-playing": "Зараз відтворюється", "files-audio-island.pause": "Пауза", "files-audio-island.play": "Відтворити", "files-backend-error.base-directory-not-found": "Не вдалося знайти базовий каталог", "files-backend-error.cant-find-root": "Не вдалося перевірити шлях до файлу", "files-backend-error.destination-already-exists": "У папці призначення вже існує елемент з такою назвою", "files-backend-error.destination-not-exist": "Папка призначення не існує", "files-backend-error.does-not-exist": "Файл або папка не існує", "files-backend-error.escapes-base": "Шлях виходить за межі дозволеного каталогу", "files-backend-error.invalid-base": "Шлях не належить до допустимого каталогу", "files-backend-error.invalid-filename": "Недопустиме ім'я файлу", "files-backend-error.invalid-path": "Недійсний шлях до файлу", "files-backend-error.mkdir-failed": "Не вдалося створити папку", "files-backend-error.move-failed": "Не вдалося перемістити елемент", "files-backend-error.not-enough-space": "Недостатньо вільного місця", "files-backend-error.operation-not-allowed": "Ця операція заборонена", "files-backend-error.parent-not-directory": "Батьківський шлях не є папкою", "files-backend-error.parent-not-exist": "Батьківська папка не існує", "files-backend-error.path-not-absolute": "Недійсний шлях до файлу", "files-backend-error.share-already-exists": "До цієї папки вже надано спільний доступ", "files-backend-error.share-name-generation-failed": "Не вдалося згенерувати унікальну назву для спільного доступу", "files-backend-error.source-not-exists": "Файл або папка-джерело не існує", "files-backend-error.subdir-of-self": "Папку неможливо перемістити або скопіювати всередину самої себе", "files-backend-error.trash-meta-not-exists": "Не вдалося знайти оригінальне розташування цього елемента", "files-backend-error.unique-name-index-exceeded": "Не вдалося згенерувати унікальне ім'я. Існує занадто багато елементів з подібними назвами", "files-backend-error.upload-failed": "Не вдалося завантажити", "files-collision.action.keep-both": "Зберегти обидва", "files-collision.action.replace": "Замінити", "files-collision.action.skip": "Пропустити", "files-collision.destination.original-location": "його початкове розташування", "files-collision.message": "Ви хочете замінити наявний елемент чи зберегти обидва?", "files-collision.title": "\"{{itemName}}\" уже існує в {{destinationName}}", "files-download.confirm": "Завантажити", "files-download.description": "Files не можуть відкрити цей тип файлу. Бажаєте замість цього завантажити його?", "files-download.title": "Завантажити {{name}}?", "files-empty-trash.confirm": "Очистити", "files-empty-trash.description": "Ви впевнені, що хочете назавжди видалити всі елементи з кошика? Ви не зможете скасувати цю дію.", "files-empty-trash.title": "Очистити кошик?", "files-empty.directory": "У цій папці немає елементів", "files-empty.network": "Немає мережевих пристроїв", "files-empty.network-host-offline": "Мережевий пристрій офлайн", "files-error.add-favorite": "Не вдалося додати до вибраного: {{message}}", "files-error.add-share": "Не вдалося надати спільний доступ до папки: {{message}}", "files-error.compress": "Не вдалося стиснути: {{message}}", "files-error.copy": "Не вдалося скопіювати: {{message}}", "files-error.create-folder": "Не вдалося створити папку: {{message}}", "files-error.delete": "Не вдалося видалити: {{message}}", "files-error.eject-disk": "Не вдалося від'єднати диск: {{message}}", "files-error.empty-trash": "Не вдалося очистити кошик: {{message}}", "files-error.extract": "Не вдалося розпакувати: {{message}}", "files-error.folder-already-exists": "Папка з такою назвою вже існує", "files-error.move": "Не вдалося перемістити: {{message}}", "files-error.remove-favorite": "Не вдалося видалити з вибраного: {{message}}", "files-error.remove-share": "Не вдалося видалити спільну папку: {{message}}", "files-error.rename": "Не вдалося перейменувати: {{message}}", "files-error.restore": "Не вдалося відновити: {{message}}", "files-error.trash": "Не вдалося перемістити в кошик: {{message}}", "files-error.upload": "Не вдалося завантажити: {{message}}", "files-error.upload-network-error": "Не вдалося завантажити {{name}}: сталася помилка мережі", "files-extension-change.confirm": "Продовжити", "files-extension-change.description-add": "Ви впевнені, що хочете змінити розширення для '{{fileName}}' на '{{extension}}'? Це може зробити файл нерозпізнаваним.", "files-extension-change.description-remove": "Ви впевнені, що хочете вилучити розширення у '{{fileName}}'?", "files-extension-change.title-add": "Змінити розширення на '{{extension}}'?", "files-extension-change.title-remove": "Вилучити розширення?", "files-external-storage.unsupported.description": "Ваш підключений зовнішній диск не можна використовувати на Raspberry Pi через проблеми з живленням. Зовнішнє сховище доступне на Umbrel Home, Umbrel Pro та на всіх пристроях x86 (Intel або AMD).", "files-external-storage.unsupported.description-general": "Зовнішнє сховище недоступне на Raspberry Pi через проблеми з живленням. Зовнішнє сховище доступне на Umbrel Home, Umbrel Pro та на всіх пристроях x86 (Intel або AMD).", "files-external-storage.unsupported.title": "Зовнішнє сховище не підтримується", "files-folder": "Папка", "files-format.confirm": "Форматувати", "files-format.description": "Форматування зітре всі дані на {{driveName}}. Цю дію неможливо скасувати.", "files-format.description-unreadable": "umbrelOS не може прочитати вміст {{driveName}}. Ви можете відформатувати його для використання з umbrelOS.", "files-format.drive-label": "Назва", "files-format.error": "Не вдалося відформатувати диск", "files-format.exfat-description": "Максимальна сумісність з Windows, macOS та Linux", "files-format.ext4-description": "Оптимізовано для umbrelOS та Linux", "files-format.filesystem": "Файлова система", "files-format.filesystem-label": "Форматувати як", "files-format.formatting": "Форматування...", "files-format.title": "Форматувати диск", "files-format.title-requires-format": "Потрібне форматування", "files-formatting-island.formatting": "Форматування...", "files-formatting-island.formatting-drives": "Форматування {{count}} дисків", "files-listing.empty": "Немає елементів", "files-listing.error": "Сталася помилка", "files-listing.item-count-truncated": "{{formattedCount}}+ елементів", "files-listing.item-count_one": "{{formattedCount}} елемент", "files-listing.item-count_other": "{{formattedCount}} елементів", "files-listing.loading": "Завантаження...", "files-listing.no-such-file": "Такого файлу чи папки не існує", "files-listing.selected-count": "{{selectedCount}} із {{totalCount}} вибрано", "files-listing.selected-count-truncated": "{{selectedCount}} з {{totalCount}}+ вибрано", "files-name-drawer.new-folder": "Нова папка", "files-name-drawer.new-folder-description": "Введіть назву для нової папки.", "files-name-drawer.new-folder-input": "Назва папки", "files-name-drawer.rename-file": "Перейменувати файл", "files-name-drawer.rename-file-description": "Введіть нову назву для цього файлу.", "files-name-drawer.rename-file-input": "Назва файлу", "files-name-drawer.rename-folder": "Перейменувати папку", "files-name-drawer.rename-folder-description": "Введіть нову назву для цієї папки.", "files-name-drawer.rename-folder-input": "Назва папки", "files-network-storage-error.add-share": "Не вдалося додати мережеву папку: {{message}}", "files-network-storage-error.discover-servers": "Не вдалося знайти мережеві пристрої: {{message}}", "files-network-storage-error.discover-shares": "Не вдалося знайти мережеві спільні папки: {{message}}", "files-network-storage-error.remove-share": "Не вдалося видалити мережеву папку: {{message}}", "files-operations-island.copying": "Копіювання \"{{from}}\" до \"{{to}}\"", "files-operations-island.moving": "Переміщення \"{{from}}\" до \"{{to}}\"", "files-operations-island.restoring": "Відновлюємо \"{{from}}\" до \"{{to}}\"", "files-path.input-group": "Введення шляху", "files-path.input-label": "Поточний шлях", "files-permanently-delete.confirm": "Видалити назавжди", "files-permanently-delete.description-multiple": "Ви впевнені, що хочете назавжди видалити ці {{count}} елементів? Ви не зможете скасувати цю дію.", "files-permanently-delete.description-single": "Ви впевнені, що хочете назавжди видалити \"{{fileName}}\"? Ви не зможете скасувати цю дію.", "files-permanently-delete.title-multiple": "Видалити {{count}} елементів назавжди?", "files-permanently-delete.title-single": "Видалити назавжди?", "files-search.default": "Пошук файлів і папок", "files-search.no-results": "Нічого не знайдено за запитом \"{{query}}\"", "files-search.placeholder": "Пошук", "files-search.searching-label": "Шукаємо Umbrel користувача {{name}}", "files-share.home-description": "Отримуйте доступ до всіх файлів у «{{homeDirectoryName}}» з інших пристроїв у вашій мережі", "files-share.home-title": "Надати спільний доступ до «{{homeDirectoryName}}» через мережу", "files-share.instructions.how-to-access": "Як отримати доступ", "files-share.instructions.ios.enter-password": "Введіть {{password}} як пароль.", "files-share.instructions.ios.enter-server": "Введіть {{smbUrl}} як адресу сервера.", "files-share.instructions.ios.enter-username": "Введіть {{username}} як ім'я користувача.", "files-share.instructions.ios.install-files": "Встановіть додаток «Files» з App Store, якщо ще не встановлений.", "files-share.instructions.ios.tap-connect": "Торкніться «Підключитися», щоб отримати доступ.", "files-share.instructions.ios.tap-dots": "Торкніться трьох крапок (…) у верхньому правому куті й виберіть «Connect to Server».", "files-share.instructions.macos.click-connect": "Натисніть «Підключитися», щоб отримати доступ.", "files-share.instructions.macos.enter-password": "Введіть {{password}} як пароль.", "files-share.instructions.macos.enter-url": "Введіть {{smbUrl}} і натисніть «Підключитися».", "files-share.instructions.macos.enter-username": "Введіть {{username}} як ім'я користувача.", "files-share.instructions.macos.open-finder": "Відкрийте «Finder», і натисніть ⌘ + K.", "files-share.instructions.macos.select-registered": "Виберіть «Зареєстрований користувач» за запитом.", "files-share.instructions.macos.time-machine": "Як використовувати як місце резервного копіювання для Time Machine", "files-share.instructions.macos.time-machine.choose-encryption": "Виберіть, чи шифрувати резервні копії, чи ні.", "files-share.instructions.macos.time-machine.disk-limit": "У полі «Ліміт використання диска» вкажіть максимальний обсяг простору, який ви хочете виділити на Umbrel для резервних копій Time Machine, а потім натисніть «Готово».", "files-share.instructions.macos.time-machine.follow-steps": "Виконайте наведені вище кроки й відкрийте «Параметри системи» на вашому Mac.", "files-share.instructions.macos.time-machine.go-settings": "Перейдіть до Time Machine і натисніть «Додати диск резервних копій…».", "files-share.instructions.macos.time-machine.select-disk": "Виберіть папку та натисніть \"Set Up Disk...\".", "files-share.instructions.umbrelos.backup.follow-onscreen": "Дотримуйтесь покрокових інструкцій, щоб налаштувати резервне копіювання.", "files-share.instructions.umbrelos.backup.follow-then-go-to": "Дотримуйтесь наведених вище кроків, а потім на іншому Umbrel перейдіть у \"{{settings}}\" > \"{{backups}}\".", "files-share.instructions.umbrelos.backup.select-add": "Виберіть опцію \"{{addUmbrelOrNas}}\".", "files-share.instructions.umbrelos.backup.select-connected": "Виберіть цей Umbrel у списку підключених пристроїв.", "files-share.instructions.umbrelos.backup.title": "Як використовувати як місце резервного копіювання для іншого Umbrel", "files-share.instructions.umbrelos.cant-find-note": "Не можете знайти? Спробуйте обрати \"Додати вручну\" та використайте наступні облікові дані. Якщо все ще не вдається додати, переконайтеся, що обидва ваші пристрої підключені до тієї самої мережі.", "files-share.instructions.umbrelos.enter-password": "Введіть {{password}} як пароль.", "files-share.instructions.umbrelos.enter-username": "Введіть {{username}} як ім'я користувача.", "files-share.instructions.umbrelos.open-and-click": "На іншому Umbrel відкрийте \"Files\" і натисніть поруч із \" {{deviceLabel}}\" у бічній панелі.", "files-share.instructions.umbrelos.select-device": "Виберіть цей пристрій Umbrel зі списку автоматично виявлених пристроїв у вашій мережі.", "files-share.instructions.umbrelos.select-sharename": "Виберіть \"{{sharename}}\" та натисніть, щоб додати шар.", "files-share.instructions.windows.enter-password": "Введіть {{password}} як пароль.", "files-share.instructions.windows.enter-url": "Введіть {{smbUrl}} і натисніть Enter.", "files-share.instructions.windows.enter-username": "Введіть {{username}} як ім'я користувача.", "files-share.instructions.windows.open-run": "Натисніть Windows + R, щоб відкрити вікно «Виконати».", "files-share.instructions.windows.remember-credentials": "Поставте прапорець «Запам’ятати мої облікові дані» і натисніть OK.", "files-share.regular-description": "Надати спільний доступ до цієї теки, щоб отримувати до неї доступ з інших пристроїв у вашій мережі", "files-share.regular-title": "Надати спільний доступ до теки через мережу", "files-share.toggle": "Надати спільний доступ до «{{name}}» через мережу", "files-sidebar.apps": "Програми", "files-sidebar.external-storage": "Зовнішнє сховище", "files-sidebar.favorites": "Вибране", "files-sidebar.home": "Головна", "files-sidebar.navigation": "Навігація файлами", "files-sidebar.network": "Мережа", "files-sidebar.network-pathbar": "Мережеві пристрої", "files-sidebar.network-sidebar": "Пристрої", "files-sidebar.recents": "Недавні", "files-sidebar.shared-folders": "Спільні теки", "files-sidebar.trash": "Кошик", "files-sidebar.trash.open": "Відкрити", "files-sort.created": "Додано", "files-sort.modified": "Змінено", "files-sort.name": "Назва", "files-sort.size": "Розмір", "files-sort.type": "Тип", "files-state.uploading": "Завантаження...", "files-state.waiting": "Очікування...", "files-type.3gp": "Відео 3GP", "files-type.3gp2": "Відео 3GP2", "files-type.7z": "Архів 7Z", "files-type.aac": "Аудіо AAC", "files-type.ai": "Файл Illustrator", "files-type.aiff": "Аудіо AIFF", "files-type.au": "Аудіо AU", "files-type.avi": "Відео AVI", "files-type.avif": "Зображення AVIF", "files-type.bmp": "Зображення BMP", "files-type.bzip2": "Архів BZIP2", "files-type.caf": "Аудіо CAF", "files-type.compressed": "Стиснутий архів", "files-type.csv": "Файл CSV", "files-type.directory": "Папка", "files-type.dmg": "Образ диска", "files-type.dv": "Відео DV", "files-type.epub": "Електронна книга EPUB", "files-type.excel": "Таблиця Excel", "files-type.exe": "Виконуваний файл Windows", "files-type.executable": "Виконуваний файл", "files-type.external-drive": "Диск", "files-type.flac": "Аудіо FLAC", "files-type.flv": "Відео FLV", "files-type.gif": "Зображення GIF", "files-type.gzip": "Архів GZIP", "files-type.heic": "Зображення HEIC", "files-type.ico": "Зображення ICO", "files-type.iso": "Образ ISO", "files-type.jpeg": "Зображення JPEG", "files-type.keynote": "Презентація Keynote", "files-type.lzip": "Архів LZIP", "files-type.lzma": "Архів LZMA", "files-type.lzop": "Архів LZOP", "files-type.m3u": "Плейліст M3U", "files-type.m4a": "Аудіо M4A", "files-type.m4v": "Відео M4V", "files-type.midi": "Аудіо MIDI", "files-type.mka": "Аудіо MKA", "files-type.mkv": "Відео MKV", "files-type.mng": "Відео MNG", "files-type.mobi": "Електронна книга MOBI", "files-type.mp3": "Аудіо MP3", "files-type.mp4": "Відео MP4", "files-type.mp4-audio": "Аудіо MP4", "files-type.mpeg": "Відео MPEG", "files-type.mpeg-ts": "Транспортний потік MPEG", "files-type.network-drive": "Мережевий диск", "files-type.numbers": "Таблиця Numbers", "files-type.ogg": "Аудіо OGG", "files-type.ogv": "Відео OGV", "files-type.pages": "Документ Pages", "files-type.pdf": "Документ PDF", "files-type.png": "Зображення PNG", "files-type.powerpoint": "Презентація PowerPoint", "files-type.psd": "Документ Photoshop", "files-type.quicktime": "Відео QuickTime", "files-type.rar": "Архів RAR", "files-type.sgi": "Відео SGI", "files-type.svg": "Зображення SVG", "files-type.tar": "Архів TAR", "files-type.tiff": "Зображення TIFF", "files-type.ts": "Відео TS", "files-type.txt": "Текстовий файл", "files-type.umbrel-backup": "Umbrel Backup", "files-type.wav": "Аудіо WAV", "files-type.webm": "Відео WebM", "files-type.webm-audio": "Аудіо WebM", "files-type.webp": "Зображення WebP", "files-type.wma": "Аудіо WMA", "files-type.wmv": "Відео WMV", "files-type.word": "Документ Word", "files-type.xz": "Архів XZ", "files-type.zip": "Архів ZIP", "files-upload-island.uploading-count": "Завантаження {{count}} елементів", "files-view.icons": "Значки", "files-view.list": "Список", "files-view.sort-by": "Сортувати за", "files-view.view-as": "Перегляд як", "files-widgets.favorites.no-items-text": "Додайте папку у Вибране, щоб побачити її тут", "files-widgets.recents.no-items-text": "Немає нещодавніх файлів", "generic-in": "в", "hide-details": "Приховати деталі", "install-first.install-app": "Встановити {{app}}", "install-first.title": "{{app}} вимагає ці додатки", "install-your-first-app": "Встановіть свою першу програму", "language": "Мова", "language-description": "Ваша бажана мова umbrelOS", "language.select-description": "Виберіть бажану мову umbrelOS", "live-usage": "Живе використання", "loading": "Завантаження", "local-ip": "Локальний IP", "login-2fa.subtitle": "Введіть код 2FA, відображений у вашій програмі-аутентифікаторі", "login-2fa.title": "Аутентифікація", "login-with-umbrel.description": "Введіть пароль Umbrel, щоб відкрити {{app}}", "login-with-umbrel.title": "Увійти з Umbrel", "login.password-label": "Пароль", "login.password.submit": "Увійти", "login.subtitle": "Введіть пароль Umbrel для входу", "login.title": "З поверненням", "logout": "Вийти", "logout-error-generic": "Помилка: вихід не вдався", "logout.confirm.submit": "Вийти", "logout.confirm.title": "Ви впевнені, що хочете вийти?", "memory": "Пам'ять", "memory.low": "Низький рівень пам'яті", "migrate": "Мігрувати", "migrate.callout": "Не вимикайте ваш Umbrel, доки міграція не завершиться", "migrate.failed.retry": "Спробувати знову", "migrate.failed.title": "Міграція не вдалася", "migrate.success.description": "Всі ваші програми, дані програм і деталі облікового запису були перенесені на ваш Umbrel Home.", "migrate.success.title": "Міграція успішна", "migration-assistant": "Помічник з міграції", "migration-assistant-description": "Перенесіть усі ваші додатки та дані з Raspberry Pi на {{deviceName}}", "migration-assistant-unsupported-device-description": "Наразі Migration Assistant підтримує перенесення всіх даних і додатків з Raspberry Pi з umbrelOS на Umbrel Home або Umbrel Pro. Відкрийте Migration Assistant на своєму Umbrel Home або Umbrel Pro, щоб почати.", "migration-assistant.continue-migration.ready.submit": "Почати міграцію", "migration-assistant.failed": "Щось не так...", "migration-assistant.failed.retrying-message": "Повторна спроба...", "migration-assistant.mobile.start-button": "Почати міграцію", "migration-assistant.prep.body": "Підготуйтеся до міграції", "migration-assistant.prep.button-continue": "Продовжити", "migration-assistant.prep.callout": "Дані на вашому {{deviceName}}, якщо такі є, будуть безповоротно видалені.", "migration-assistant.prep.connect-disk-to-home": "Підключіть зовнішній диск до будь-якого USB-порту на вашому {{deviceName}}.", "migration-assistant.prep.prep-done-continue-message": "Коли будете готові, натисніть '{{button}}' нижче.", "migration-assistant.prep.shut-down-rpi": "Вимкніть ваш Raspberry Pi Umbrel.", "migration-assistant.ready.description": "Усі ваші дані та додатки готові до перенесення на ваш {{deviceName}}", "migration-assistant.ready.hint-header": "Речі, які варто пам'ятати", "migration-assistant.ready.hint-keep-pi-off.description": "Це допомагає запобігти проблемам з програмами, такими як Lightning Node", "migration-assistant.ready.hint-keep-pi-off.title": "Тримайте ваш Raspberry Pi вимкненим після оновлення", "migration-assistant.ready.hint-use-same-password.description": "Не забудьте використовувати пароль Umbrel зі свого Raspberry Pi, щоб увійти на {{deviceName}}.", "migration-assistant.ready.hint-use-same-password.title": "Використовуйте той самий пароль", "migration-assistant.ready.title": "Ви готові до міграції!", "mini-browser.default-title": "Виберіть папку", "mini-browser.empty-external": "Підключіть зовнішній диск, щоб він з'явився тут.", "mini-browser.empty-network": "Додайте Umbrel або NAS, щоб вони з'явилися тут.", "mini-browser.load-more": "Завантажити більше", "mini-browser.load-more-in-folder": "Завантажити більше у {{name}}", "mini-browser.loading-more": "Завантаження додаткових…", "mini-browser.select": "Вибрати", "mini-browser.select-folder": "Виберіть папку", "name": "Ім'я", "nas": "NAS", "no-forgot-password-message": "Якщо ви забудете свій пароль, ви не зможете увійти в Umbrel. Переконайтеся, що ви надійно зберегли його.", "no-results-found": "Результатів не знайдено", "not-found-404": "Код помилки: 404", "not-found-404.back": "Назад", "not-found-404.home": "Перейти на головну", "notifications.backups-failing-location.description": "Автоматичні Backups на {{location}} не виконуються. Перевірте підключення та перегляньте налаштування Backups.", "notifications.backups-failing.description": "Автоматичне резервне копіювання не працює. Перевірте місце збереження та налаштування резервних копій.", "notifications.backups-failing.go-to-backups": "Перейти до Backups", "notifications.backups-failing.title": "За останні 24 години резервні копії не створювалися", "notifications.cpu.too-hot": "Висока температура ЦП", "notifications.memory.low": "Низький рівень пам'яті вашого пристрою", "notifications.new-version-available": "{{update}} доступна для встановлення", "notifications.raid.issue.description": "Виявлено проблему зі сховищем. Перегляньте Диспетчер сховища для деталей.", "notifications.raid.issue.title": "Потрібні термінові дії", "notifications.ssd.health.description": "Один або кілька SSD можуть потребувати уваги. Перегляньте Диспетчер сховища для деталей.", "notifications.ssd.health.title": "Попередження про стан SSD", "notifications.storage.full": "Пам'ять вашого пристрою заповнена", "notifications.view": "Переглянути", "ok": "OK", "onboarding.account-created.by-clicking-button-you-agree": "Натискаючи 'Далі', ви погоджуєтеся з Умовами обслуговування umbrelOS", "onboarding.account-created.youre-all-set-name": "Ви готові, {{name}}.", "onboarding.contact-support": "Підтримка", "onboarding.create-account": "Створити акаунт", "onboarding.create-account.confirm-password.input-label": "Підтвердити пароль", "onboarding.create-account.failed.name-required": "Ім'я обов'язкове", "onboarding.create-account.failed.passwords-dont-match": "Паролі не співпадають", "onboarding.create-account.name.input-placeholder": "Ваше ім'я", "onboarding.create-account.password.input-label": "Пароль", "onboarding.create-account.submit": "Створити", "onboarding.create-account.submitting": "Створення", "onboarding.create-account.subtitle": "Ваша інформація облікового запису зберігається лише на вашому Umbrel. Переконайтеся, що ви надійно зберегли свій пароль, оскільки його не можна скинути.", "onboarding.create-instead-long": "Створити новий обліковий запис", "onboarding.create-instead-short": "Новий обліковий запис", "onboarding.launch-umbrelos": "Запустити umbrelOS", "onboarding.raid.available-storage": "Доступне місце", "onboarding.raid.change-drives-link": "Потрібно додати або замінити накопичувачі?", "onboarding.raid.configuring.subtitle": "Це може зайняти кілька хвилин.", "onboarding.raid.configuring.title": "Налаштування вашого сховища", "onboarding.raid.configuring.warning": "Не оновлюйте цю сторінку та не вимикайте Umbrel під час налаштування сховища.", "onboarding.raid.continue": "Продовжити", "onboarding.raid.error.detection-instructions": "Вимкніть Umbrel Pro, перевірте, чи SSD правильно встановлені, і спробуйте ще раз.", "onboarding.raid.error.no-ssds-detected": "SSD не виявлено", "onboarding.raid.error.no-ssds-instructions": "Вимкніть Umbrel Pro і вставте щонайменше один SSD, щоб продовжити.", "onboarding.raid.failsafe": "FailSafe", "onboarding.raid.failsafe.cant-enable": "Поки що не можна увімкнути FailSafe", "onboarding.raid.failsafe.enable": "Увімкнути FailSafe", "onboarding.raid.failsafe.mixed-sizes": "FailSafe обмежений найменшим SSD ({{smallest}}). Додатковий простір на більших SSD не можна використати — {{wasted}} залишиться непридатним для використання.", "onboarding.raid.failsafe.protection-info-2ssds": "{{protection}} використовується для захисту даних. Додайте ще один SSD розміром {{smallest}}, щоб збільшити доступне сховище до {{futureWith3}}, або додайте ще два — до {{futureWith4}}. Ви можете додавати SSD будь-коли.", "onboarding.raid.failsafe.protection-info-3ssds": "{{protection}} використовується для захисту даних. Додайте ще один SSD розміром {{smallest}}, щоб збільшити доступне сховище до {{futureWith4}}. Ви можете додавати SSD будь-коли.", "onboarding.raid.failsafe.single-ssd-info": "У вас лише один SSD. Додайте щонайменше ще один {{size}} SSD, щоб увімкнути захист FailSafe для ваших даних. Ви можете додавати SSD будь-коли.", "onboarding.raid.failsafe.subtitle": "Ваші дані залишаться в безпеці, якщо вийде з ладу будь-який один SSD.", "onboarding.raid.failsafe.tip": "Використовуйте SSD одного розміру, щоб отримати максимум місця й нуль непридатного простору.", "onboarding.raid.failsafe.warning-now-only": "Якщо у вас більше одного SSD, FailSafe можна ввімкнути лише під час початкового налаштування. Потім ввімкнути його не вдасться.", "onboarding.raid.health-warning": "Цей диск повідомляє про проблеми зі станом", "onboarding.raid.launching": "Запускається...", "onboarding.raid.no-ssds-alt": "SSD не знайдено", "onboarding.raid.recommended": "Рекомендовано", "onboarding.raid.scanning": "Перевірка слотів SSD", "onboarding.raid.scanning-alt": "Сканування SSD", "onboarding.raid.setup-failed.description-no-retry": "Будь ласка, вимкніть пристрій і спробуйте ще раз.", "onboarding.raid.setup-failed.description-retry": "Спробуйте ще раз або вимкніть пристрій, щоб перевірити накопичувачі.", "onboarding.raid.setup-failed.title": "Не вдалося налаштувати сховище", "onboarding.raid.shutdown-dialog.description": "Щоб додати або замінити накопичувачі, вимкніть Umbrel Pro. Після цього можна знову ввімкнути і продовжити налаштування.", "onboarding.raid.shutdown-dialog.title": "Змінити накопичувачі?", "onboarding.raid.ssd-in-slot": "Один {{size}} SSD у слоті {{slot}}", "onboarding.raid.ssd-label": "SSD {{number}}", "onboarding.raid.ssd-tray-alt": "Лоток SSD", "onboarding.raid.ssds-found": "У вашому Umbrel Pro знайдено такі SSD", "onboarding.raid.storage": "Сховище", "onboarding.raid.storage-label": "Сховище", "onboarding.raid.success.storage-info": "Сховище {{available}}", "onboarding.raid.success.storage-info-failsafe": "Сховище {{available}} · FailSafe {{failsafe}}", "onboarding.raid.try-again": "Спробувати ще раз", "onboarding.raid.wasted": "Непридатне", "onboarding.restore-long": "Відновити мій Umbrel", "onboarding.restore-short": "Відновити", "onboarding.start.continue": "Почати", "onboarding.start.subtitle": "Ваш домашній хмарний сервер готовий до налаштування.", "onboarding.start.title": "Ласкаво просимо до umbrelOS", "open": "Відкрити", "open-live-usage": "Відкрити Живе використання", "password": "Пароль", "preferences": "Налаштування", "raid-error.description": "Ваша система зберігання не змогла запуститися належним чином. Перевірте стан ваших SSD нижче та виконайте кроки з усунення неполадок. Якщо проблема не зникне, деякі пошкоджені SSD може знадобитися замінити.", "raid-error.factory-reset-dialog.description": "Це видалить усі дані на вашому Umbrel Pro і відновить заводські налаштування. Цю дію неможливо скасувати.", "raid-error.factory-reset-dialog.title": "Скинути до заводських налаштувань?", "raid-error.factory-reset-failed": "Не вдалося скинути до заводських налаштувань", "raid-error.health-warning": "Попередження про стан", "raid-error.missing-ssd-multiple": "{{count}} SSD не відповідають", "raid-error.missing-ssd-one": "1 SSD не відповідає", "raid-error.shutdown-dialog.description": "Вимкніть Umbrel Pro, переконайтеся, що всі SSD правильно встановлені у своїх слотах, потім увімкніть пристрій знову.", "raid-error.shutdown-dialog.title": "Вимкнути для перевірки дисків?", "raid-error.ssd-in-slot": "Один {{size}} SSD у слоті {{slot}}", "raid-error.step-check-connections.button": "Вимкнути", "raid-error.step-check-connections.description": "Вимкніть живлення і перевірте, що всі SSD правильно встановлені у своїх слотах.", "raid-error.step-check-connections.title": "Перевірте підключення SSD", "raid-error.step-factory-reset.button": "Скинути до заводських налаштувань", "raid-error.step-factory-reset.description": "Крайній захід, якщо нічого іншого не допомагає. Це видалить усі дані.", "raid-error.step-factory-reset.title": "Скидання до заводських налаштувань", "raid-error.step-restart.button": "Перезавантажити", "raid-error.step-restart.description": "Швидкий перший крок, який часто допомагає", "raid-error.step-restart.title": "Спробуйте перезавантажити", "raid-error.title": "Виявлено проблему зі сховищем", "read-less": "Читати менше", "read-more": "Читати більше", "reconnect": "Підключитися знову", "redirect.to-home": "Завантаження...", "redirect.to-login": "Завантаження...", "redirect.to-onboarding": "Завантаження...", "redirect.to-raid-error": "Завантаження...", "reload": "Оновити", "remote-tor-access": "Віддалений доступ через Tor", "reset": "Скинути", "restart": "Перезапустити", "restart.confirm.submit": "Перезапустити", "restart.confirm.title": "Ви впевнені, що хочете перезапустити Umbrel?", "restart.restarting": "Перезапуск", "restart.restarting-message": "Будь ласка, не оновлюйте цю сторінку і не вимикайте ваш Umbrel, доки він перезапускається.", "rewind": "Rewind", "rewind.files-as-of": "Ваші файли станом на", "rewind.loading-snapshots": "Завантаження знімків...", "rewind.now": "Зараз", "rewind.preflight.description": "Знайдіть файли й папки з попередніх резервних копій та відновіть їх у теперішній стан.", "rewind.preflight.enable-backups": "Увімкніть Backups у Налаштуваннях, щоб почати використовувати Rewind", "rewind.restore-complete": "Відновлення завершено", "rewind.restore-error-description": "Спробуйте ще раз.", "rewind.restore-failed": "Не вдалося відновити", "rewind.restore-running-description": "Не закривайте й не оновлюйте цю сторінку, поки відновлення не завершиться", "rewind.restore-selected": "Відновити вибране", "rewind.restore-success-description": "Ваші файли відновлено", "rewind.restoring": "Відновлення", "rewind.snapshots-count_one": "{{count}} резервна копія з", "rewind.snapshots-count_other": "{{count}} резервних копій з", "search": "Пошук", "settings": "Налаштування", "settings.app-store-preferences.title": "Налаштування App Store", "settings.contact-support": "Потрібна допомога? Зв'яжіться з підтримкою.", "settings.file-sharing": "Спільний доступ до файлів", "settings.file-sharing.add-folder": "Додати", "settings.file-sharing.add-folder-title": "Виберіть папку для спільного доступу", "settings.file-sharing.choice-entire-description": "Надайте спільний доступ до всіх файлів на вашому Umbrel", "settings.file-sharing.choice-entire-title": "Усе", "settings.file-sharing.choice-heading": "Що ви хочете надати у спільний доступ?", "settings.file-sharing.choice-specific-description": "Оберіть папки для спільного доступу", "settings.file-sharing.choice-specific-title": "Окремі папки", "settings.file-sharing.choice-subtitle": "Отримуйте доступ до файлів і папок у стилі Dropbox — як мережеві папки на вашому комп'ютері чи телефоні", "settings.file-sharing.configure": "Налаштувати", "settings.file-sharing.description": "Отримуйте доступ до файлів у стилі Dropbox як мережеву папку (SMB) на інших пристроях", "settings.file-sharing.home-shared-note": "Вся папка \"{{homeDirectoryName}}\" надана у спільний доступ. Окремим папкам не потрібно окремого надання доступу.", "settings.file-sharing.share-entire-home-dir": "Надати спільний доступ до всієї папки Home", "settings.file-sharing.share-entire-home-dir-description": "Отримуйте доступ до всіх файлів і папок у \"{{homeDirectoryName}}\" з інших пристроїв у вашій мережі", "settings.file-sharing.shared-folders": "Спільні папки", "show-details": "Показати деталі", "shut-down": "Вимкнути", "shut-down.complete": "Вимкнення завершено", "shut-down.complete-text": "Тепер ви можете відключити пристрій від живлення.", "shut-down.confirm.submit": "Вимкнути", "shut-down.confirm.title": "Ви впевнені, що хочете вимкнути Umbrel?", "shut-down.failed": "Не вдалося вимкнути: {{message}}", "shut-down.shutting-down": "Вимкнення", "shut-down.shutting-down-message": "Будь ласка, не оновлюйте цю сторінку і не вимикайте ваш Umbrel, доки він вимикається.", "software-update.callout": "Будь ласка, не оновлюйте цю сторінку і не вимикайте ваш Umbrel під час оновлення.", "software-update.check": "Перевірити наявність оновлень", "software-update.checking": "Перевірка наявності оновлень...", "software-update.current-running": "Ви використовуєте", "software-update.failed": "Не вдалося оновити", "software-update.failed-to-check": "Не вдалося перевірити наявність оновлень", "software-update.failed.retry": "Спробувати ще раз", "software-update.install-now": "Встановити зараз", "software-update.new-version": "Доступна нова {{name}} для встановлення", "software-update.on-latest": "У вас найновіша версія umbrelOS", "software-update.see-whats-new": "Дивіться що нового", "software-update.title": "Оновлення програмного забезпечення", "software-update.updating-to": "Оновлення до {{name}}", "software-update.view": "Переглянути", "something-left": "Залишилося {{left}}", "something-went-wrong": "⚠ Щось пішло не так", "start": "Почати", "stop": "Зупинити", "storage": "Зберігання", "storage-manager": "Менеджер сховища", "storage-manager.add": "Додати", "storage-manager.add-to-raid.add-ssd": "Додати SSD", "storage-manager.add-to-raid.available": "Доступно:", "storage-manager.add-to-raid.description": "Виявлено новий SSD, готовий до додавання.", "storage-manager.add-to-raid.enable-failsafe": "Увімкнути FailSafe", "storage-manager.add-to-raid.failed-add": "Не вдалося додати SSD", "storage-manager.add-to-raid.failed-enable-failsafe": "Не вдалося ввімкнути FailSafe", "storage-manager.add-to-raid.failsafe-label": "FailSafe:", "storage-manager.add-to-raid.info-capacity-added": "Ваш новий {{size}} SSD буде додано до доступного простору.", "storage-manager.add-to-raid.info-capacity-adds-available": "Ваш новий {{size}} SSD додасть {{available}} доступного простору.", "storage-manager.add-to-raid.info-capacity-adds-both": "Ваш новий {{size}} SSD додасть {{available}} доступного простору та {{protection}} для захисту даних.", "storage-manager.add-to-raid.info-capacity-protection-only": "Ваш новий {{size}} SSD додасть {{protection}} для захисту даних.", "storage-manager.add-to-raid.info-capacity-protection-only-full": "Ваш новий {{size}} SSD буде використаний повністю для захисту даних.", "storage-manager.add-to-raid.info-data-safe": "Ваші дані будуть у безпеці, якщо вийде з ладу будь-який один SSD.", "storage-manager.add-to-raid.info-no-protection": "Якщо SSD відмовить, ви можете втратити свої дані.", "storage-manager.add-to-raid.info-total-wasted": "{{size}} загалом непридатно через різні розміри SSD.", "storage-manager.add-to-raid.info-wasted": "{{size}} буде непридатним через різні розміри SSD.", "storage-manager.add-to-raid.recommended": "Рекомендовано", "storage-manager.add-to-raid.recommended-inline": "(рекомендується)", "storage-manager.add-to-raid.restart-active-tasks": "Усі активні завдання будуть перервані", "storage-manager.add-to-raid.restart-after": "Після перезапуску налаштування FailSafe завершиться автоматично і ви зможете продовжити звичайне використання.", "storage-manager.add-to-raid.restart-during": "Під час перезапуску:", "storage-manager.add-to-raid.restart-intro": "Під час цього процесу ви можете продовжувати використовувати umbrelOS як зазвичай. Однак на 50% прогресу ваш Umbrel автоматично перезавантажиться.", "storage-manager.add-to-raid.restart-required": "Потрібне перезавантаження системи", "storage-manager.add-to-raid.restart-ui-inaccessible": "umbrelOS буде тимчасово недоступний", "storage-manager.add-to-raid.ssd-in-slot": "{{size}} SSD у слоті {{slot}}", "storage-manager.add-to-raid.title": "Додати SSD до сховища", "storage-manager.add-to-raid.too-small": "SSD занадто малий", "storage-manager.add-to-raid.too-small-description": "Цей SSD ({{deviceSize}}) менший за найменший SSD, що зараз встановлений ({{minSize}}). FailSafe вимагає, щоб усі SSD були щонайменше такого ж розміру, як найменший використовуваний SSD.", "storage-manager.add-to-raid.understand-continue": "Зрозуміло, продовжити", "storage-manager.add-to-raid.warning-failsafe-now-only": "Наявність більше ніж одного SSD означає, що FailSafe можна увімкнути лише зараз. Пізніше ви не зможете його увімкнути.", "storage-manager.add-to-raid.wasted-label": "Непридатне:", "storage-manager.available-storage": "Доступне сховище", "storage-manager.description": "Перегляньте сховище, стан і налаштування ваших SSD", "storage-manager.empty": "Порожньо", "storage-manager.failsafe-transition-failed": "Не вдалося ввімкнути FailSafe", "storage-manager.for-failsafe": "Для FailSafe", "storage-manager.health.checksum-errors": "Помилки контрольної суми: {{count}}", "storage-manager.health.critical": "Критично", "storage-manager.health.critical-threshold": "Критичний поріг", "storage-manager.health.current-temperature": "Поточна температура", "storage-manager.health.estimated-life": "Орієнтовний залишок ресурсу", "storage-manager.health.general": "Загальне", "storage-manager.health.health-status": "Стан", "storage-manager.health.low": "Низький", "storage-manager.health.model-and-capacity": "Модель і розмір", "storage-manager.health.overheating": "Перегрів", "storage-manager.health.raid-failed-advice": "Цей SSD має проблему. Вимкніть Umbrel і перевірте підключення SSD. Якщо проблема не зникне, можливо, SSD потрібно замінити.", "storage-manager.health.read-errors": "Помилки читання: {{count}}", "storage-manager.health.serial-number": "Серійний номер", "storage-manager.health.status-healthy": "Добрий стан", "storage-manager.health.status-unhealthy": "Поганий стан", "storage-manager.health.status-unknown": "Невідомо", "storage-manager.health.temperature": "Температура", "storage-manager.health.title": "Стан SSD", "storage-manager.health.warning-life-advice": "Розгляньте можливість заміни цього SSD найближчим часом.", "storage-manager.health.warning-life-message": "Залишилося лише {{percent}}% ресурсу", "storage-manager.health.warning-temp-advice": "Переконайтеся, що у вашого Umbrel Pro хороший обдув і SSD встановлено правильно.", "storage-manager.health.warning-temp-critical": "Температура критична ({{temperature}})", "storage-manager.health.warning-temp-overheating": "Диск перегрівається ({{temperature}})", "storage-manager.health.warning-threshold": "Поріг попередження", "storage-manager.health.warning-unhealthy-advice": "Цей SSD може скоро вийти з ладу. Розгляньте його заміну.", "storage-manager.health.warning-unhealthy-message": "У цьому SSD може бути проблема", "storage-manager.health.warnings": "Попередження", "storage-manager.health.wear": "Знос", "storage-manager.health.write-errors": "Помилки запису: {{count}}", "storage-manager.install-ssd.description": "Додайте ще SSD, щоб розширити сховище", "storage-manager.install-ssd.step-insert": "Вставте нові SSD у порожні слоти", "storage-manager.install-ssd.step-power-on": "Увімкніть ваш {{deviceName}}", "storage-manager.install-ssd.step-remove-bottom-cover": "Зніміть магнітну нижню кришку", "storage-manager.install-ssd.step-replace-bottom-cover": "Поверніть нижню кришку на місце", "storage-manager.install-ssd.step-return": "Поверніться сюди, щоб додати SSD до свого сховища", "storage-manager.install-ssd.step-shut-down": "Вимкніть ваш {{deviceName}}", "storage-manager.install-ssd.title": "Додавання SSD", "storage-manager.install-tips.image-alt": "Інструкція з встановлення SSD", "storage-manager.install-tips.instructions": "Щоб встановити, відкрутіть фіксуючий гвинт і вставте SSD під кутом у слот. Натисніть SSD униз, поки він не ляже на опору гвинта, після чого закріпіть його фіксуючим гвинтом.", "storage-manager.install-tips.toggle": "Забули, як вставити SSD?", "storage-manager.manage": "Керувати", "storage-manager.missing-ssd-warning": "Здається, один SSD відсутній. Вимкніть Umbrel і перевірте, чи всі SSD підключені. Якщо проблема триває, можливо, SSD потрібно замінити.", "storage-manager.mode": "Режим", "storage-manager.mode.failsafe": "FailSafe", "storage-manager.mode.failsafe.description": "Захищає ваші дані на випадок відмови SSD. Якщо SSD мають різний розмір, додатковий простір на більших буде невикористаним.", "storage-manager.mode.failsafe.info-description": "FailSafe захищає ваші дані, зберігаючи їх копії на різних SSD. Якщо якийсь SSD відмовить, ваші дані залишаться в безпеці і їх можна буде відновити після встановлення заміни.", "storage-manager.mode.failsafe.info-title": "Про FailSafe", "storage-manager.mode.full-storage": "Повне сховище", "storage-manager.mode.full-storage.description": "Використовує весь доступний простір SSD разом. Якщо SSD відмовить, ви можете втратити дані.", "storage-manager.mode.full-storage.info-description": "Full Storage об'єднує всі ваші SSD в один великий простір, даючи максимум сховища. Однак якщо якийсь SSD відмовить, усі ваші дані будуть втрачені.", "storage-manager.mode.full-storage.info-title": "Про Повне сховище", "storage-manager.mode.switch-from-failsafe-unavailable": "Перехід з FailSafe у режим Full Storage вимагає резервного копіювання даних, скидання пристрою до заводських налаштувань і відновлення з резервної копії.", "storage-manager.mode.switch-to-failsafe-unavailable": "Коли у режимі Full Storage використовується кілька SSD, ваші дані розподілені по всіх дисках. Перехід у режим FailSafe вимагає резервного копіювання, скидання до заводських налаштувань і відновлення.", "storage-manager.mode.why-cant-switch": "Чому я не можу переключитися?", "storage-manager.operation-in-progress.shutdown-description": "Можна безпечно вимкнути пристрій. Операція призупиниться і продовжиться після перезавантаження, але має завершитися, перш ніж Ви зможете вносити інші зміни.", "storage-manager.operation-in-progress.shutdown-title": "Ваше сховище оновлюється", "storage-manager.operation-in-progress.wait-description": "Зачекайте, поки поточна операція не завершиться, перш ніж вносити інші зміни.", "storage-manager.operation-in-progress.wait-title": "Ваше сховище оновлюється", "storage-manager.operation.adding-ssd": "Додавання SSD...", "storage-manager.operation.enabling-failsafe": "Увімкнення FailSafe...", "storage-manager.operation.expanding": "Розширення сховища...", "storage-manager.operation.rebuilding": "Відновлення даних...", "storage-manager.operation.replacing": "Заміна накопичувача...", "storage-manager.operation.restarting": "Перезапуск...", "storage-manager.operation.starting": "Запуск...", "storage-manager.operation.syncing-restarts": "Синхронізація даних • Перезавантаження на 50%", "storage-manager.raid-status.degraded": "У режимі деградації", "storage-manager.raid-status.failed": "Вийшов з ладу", "storage-manager.raid-status.offline": "Офлайн", "storage-manager.raid-status.online": "Онлайн", "storage-manager.raid-status.removed": "Вилучено", "storage-manager.raid-status.unavailable": "Недоступно", "storage-manager.replace": "Замінити", "storage-manager.replace-failed.degraded": "Захист FailSafe знижено", "storage-manager.replace-failed.degraded-description": "У сховищі FailSafe відсутній один SSD. Замініть його, щоб відновити повний захист.", "storage-manager.replace-failed.description": "Використайте цей SSD, щоб відновити захист FailSafe.", "storage-manager.replace-failed.error": "Не вдалося почати заміну", "storage-manager.replace-failed.replace-now": "Замінити зараз", "storage-manager.replace-failed.ssd-in-slot": "{{size}} SSD у слоті {{slot}}", "storage-manager.replace-failed.step-protected": "Після завершення ваші дані знову будуть повністю захищені", "storage-manager.replace-failed.step-rebuild": "Дані будуть відновлені на новому SSD", "storage-manager.replace-failed.step-time": "Це може зайняти деякий час залежно від обсягу ваших даних", "storage-manager.replace-failed.title": "Замінити SSD", "storage-manager.replace-failed.too-small": "SSD замалий", "storage-manager.replace-failed.too-small-description": "Цей SSD ({{deviceSize}}) має менший обсяг, ніж мінімально необхідний ({{minSize}}) для вашого сховища FailSafe.", "storage-manager.replace-failed.what-happens": "Що відбудеться далі:", "storage-manager.ssd-failing": "Виходить з ладу", "storage-manager.swap": "Заміна", "storage-manager.swap.data-erased-description": "Режим Full Storage не забезпечує захисту даних. Всі дані на вашому {{deviceName}} будуть видалені під час скидання до заводських налаштувань. Обов'язково зробіть резервну копію перед цим.", "storage-manager.swap.data-protected": "Ваші дані захищені", "storage-manager.swap.data-protected-description": "Якщо FailSafe увімкнено, ви можете замінити будь-який один SSD без втрати даних. Резервна копія не потрібна.", "storage-manager.swap.data-will-be-erased": "Дані будуть видалені", "storage-manager.swap.description-failsafe": "Замініть диск у вашому сховищі FailSafe.", "storage-manager.swap.description-full-storage": "Замініть диск у вашій конфігурації Full Storage.", "storage-manager.swap.description-no-free-slot": "У режимі Full Storage за наявності всіх зайнятих слотів заміна SSD вимагає повного резервного копіювання та відновлення.", "storage-manager.swap.description-replace": "Міграція ваших даних на новий SSD, а потім видалення старого.", "storage-manager.swap.failed-to-start": "Не вдалося запустити заміну", "storage-manager.swap.no-data-loss": "Без втрати даних", "storage-manager.swap.no-data-loss-description": "Ваші дані будуть скопійовані на новий SSD. Після завершення ви зможете безпечно вилучити старий.", "storage-manager.swap.safe-swap-available": "Доступна безпечна заміна", "storage-manager.swap.safe-swap-description": "Оскільки у вас є порожній слот, ви можете спочатку додати новий SSD і перенести дані перед видаленням старого. Резервна копія не потрібна.", "storage-manager.swap.select-new-ssd": "Виберіть новий SSD для використання:", "storage-manager.swap.ssd-in-slot": "{{size}} SSD у слоті {{slot}}", "storage-manager.swap.step-backup": "Зробіть резервну копію даних", "storage-manager.swap.step-backup-description": "Перейдіть у Налаштування → Backups і створіть резервну копію всіх даних.", "storage-manager.swap.step-data-copied": "Дані будуть скопійовані зі старого SSD на новий", "storage-manager.swap.step-factory-reset": "Скидання до заводських налаштувань", "storage-manager.swap.step-factory-reset-description": "Перейдіть у Налаштування → Додатково → Скидання до заводських налаштувань, щоб стерти ваш {{deviceName}}.", "storage-manager.swap.step-insert-new-ssd": "Вставте новий SSD у порожній слот", "storage-manager.swap.step-may-take-while": "Це може зайняти деякий час залежно від обсягу ваших даних", "storage-manager.swap.step-power-on": "Увімкніть ваш {{deviceName}}", "storage-manager.swap.step-remove-bottom-cover": "Зніміть магнітну нижню кришку", "storage-manager.swap.step-remove-old": "Після завершення вимкніть пристрій і витягніть {{ssd}}", "storage-manager.swap.step-replace-bottom-cover": "Поверніть нижню кришку на місце", "storage-manager.swap.step-restore": "Відновіть дані", "storage-manager.swap.step-restore-description": "Перейдіть у Налаштування → Backups і відновіть з резервної копії.", "storage-manager.swap.step-return-to-storage-manager": "Поверніться сюди в Керування сховищем, щоб підтвердити заміну та додати новий SSD до сховища", "storage-manager.swap.step-return-to-swap": "Поверніться сюди до Керування сховищем і натисніть «Заміна» ще раз, щоб почати процес заміни", "storage-manager.swap.step-setup-new-storage": "Налаштуйте нове сховище", "storage-manager.swap.step-setup-new-storage-description": "Увімкніть ваш {{deviceName}} і завершіть процес налаштування з новим SSD.", "storage-manager.swap.step-shut-down": "Вимкніть ваш {{deviceName}}", "storage-manager.swap.step-shut-down-and-swap": "Вимкніть і замініть {{ssd}}", "storage-manager.swap.step-shut-down-and-swap-description-other": "Вимкніть живлення, відкрийте пристрій, замініть SSD і зберіть назад.", "storage-manager.swap.step-shut-down-and-swap-description-pro": "Вимкніть живлення, зніміть нижню кришку, замініть SSD і закрийте кришку.", "storage-manager.swap.step-swap-ssd": "Замініть {{ssd}} на новий того ж розміру", "storage-manager.swap.too-small": "Занадто малий (потрібно {{size}})", "storage-manager.swap.what-happens-next": "Що буде далі:", "storage-manager.total-capacity-added": "Загальна додана ємність", "storage-manager.umbrel-pro": "Umbrel Pro", "storage-manager.used": "Використано", "storage-manager.wasted": "Непридатне для використання", "storage-manager.wasted-size": "{{size}} непридатне для використання", "storage.full": "Пам'ять заповнена", "storage.low": "Низький рівень зберігання", "temperature": "Температура", "temperature.dangerously-hot": "Дуже гаряче", "temperature.nice": "Приємно", "temperature.normal": "Нормально", "temperature.too-hot-suggestion": "Розгляньте можливість зміни середовища вашого пристрою.", "temperature.warm": "Тепло", "terminal": "Термінал", "terminal-description": "Виконуйте власні команди в umbrelOS або в межах програми", "terminal.app": "Програма", "terminal.app-description": "Виконуйте власні команди в межах певної програми", "terminal.umbrelos-description": "Виконуйте власні команди в umbrelOS", "tor-description": "Доступ до вашого Umbrel з будь-якого місця за допомогою браузера Tor", "tor-enabled-description": "Доступ до вашого Umbrel з будь-якого місця через браузер Tor за наступною URL-адресою:", "tor-error": "Не вдалося оновити налаштування Tor: {{message}}", "tor.disable.description": "Це може зайняти кілька хвилин", "tor.disable.progress": "Вимкнення віддаленого доступу через Tor", "tor.enable.description": "Це може зайняти кілька хвилин", "tor.enable.mobile.switch-label": "Увімкнути віддалений доступ Tor", "tor.hidden-service": "URL прихованої служби Tor", "troubleshoot": "Вирішення проблем", "troubleshoot-description": "Вирішити проблеми з umbrelOS або програмою", "troubleshoot-no-logs-yet": "Ще немає журналів", "troubleshoot-pick-title": "Вирішення проблем", "troubleshoot.app": "Програма", "troubleshoot.app-description": "Переглянути журнали програми, встановленої на вашому Umbrel", "troubleshoot.app-download": "Завантажити журнали {{app}}", "troubleshoot.share-with-umbrel-support": "Поділитися з підтримкою Umbrel", "troubleshoot.system-download": "Завантажити {{label}}", "troubleshoot.umbrelos-description": "Переглянути журнали umbrelOS", "troubleshoot.umbrelos-logs": "Журнали umbrelOS", "trpc.backend-unavailable": "Помилка: не вдалося підключитися до системного API", "trpc.checking-backend": "Завантаження...", "try-again": "Спробувати ще раз", "umbrel": "Umbrel", "umbrelos": "umbrelOS", "unknown": "Невідомо", "unknown-app": "Невідома програма", "unknown-error": "Невідома помилка", "uptime": "Час роботи", "url": "URL", "wallpaper": "Фон", "wallpaper-description": "Ваш фон та тема Umbrel", "whats-new.continue": "Продовжити", "whats-new.feature-1.description": "Налаштуйте автоматизовані, зашифровані Backups для всього вашого Umbrel на зовнішній USB-накопичувач, на NAS або на інший Umbrel.", "whats-new.feature-2.description": "Поверніться назад у часі, щоб відновити окремі файли та папки з попередніх Backups.", "whats-new.feature-3.description": "Або відновіть весь ваш Umbrel разом з усіма додатками, файлами та даними.", "whats-new.feature-4.description": "Підключіть NAS або інший Umbrel, і отримайте доступ до його сховища через Files.", "whats-new.feature-4.title": "Мережеві пристрої", "whats-new.feature-5.description": "Підключайте зовнішні USB-накопичувачі (на Umbrel Home або на будь-якому пристрої Intel чи AMD) та отримуйте до них доступ через Files.", "whats-new.feature-5.helper-text": "Не підтримується на пристроях Raspberry Pi через можливі проблеми з живленням.", "whats-new.feature-5.title": "Зовнішнє сховище", "whats-new.next": "Далі", "whats-new.title": "Що нового в {{version}}", "widget.progress.in-progress": "В процесі", "widgets.edit.select-up-to-3-widgets": "Виберіть до 3 віджетів", "widgets.install-an-app-before-using-widgets": "Встановіть програму, щоб почати налаштування головного екрану за допомогою віджетів.", "wifi": "Wi-Fi", "wifi-connect-insecure-message": "Відкриті мережі можуть бути небезпечними", "wifi-connection-failed": "Не вдалося підключитися", "wifi-dangerous-change-confirmation-description": "Зміна мережі Wi-Fi може відключити вас від вашого Umbrel. Для повторного підключення переконайтеся, що і ваш Umbrel, і пристрій, з якого ви отримуєте до нього доступ, знаходяться в одній мережі.", "wifi-dangerous-change-confirmation-title": "Ви впевнені, що хочете змінити мережу Wi-Fi?", "wifi-dangerous-disable-confirmation-description": "Вимкнення Wi-Fi може відключити вас від вашого Umbrel. Для повторного підключення підключіть Ethernet-кабель до вашого Umbrel і переконайтеся, що і ваш Umbrel, і пристрій, з якого ви отримуєте до нього доступ, знаходяться в одній мережі.", "wifi-dangerous-disable-confirmation-title": "Ви впевнені, що хочете вимкнути Wi-Fi?", "wifi-description": "Підключіть ваш пристрій до Wi-Fi мережі", "wifi-description-long": "Ваш пристрій залишатиметься підключеним до обраної Wi-Fi мережі, навіть якщо Ethernet-кабель буде відключено, і автоматично підключатиметься до Wi-Fi при запуску.", "wifi-no-networks-message": "Wi-Fi мережі не знайдено", "wifi-searching": "Пошук Wi-Fi мереж...", "wifi-unsupported-device-description": "Wi-Fi не підтримується на цьому пристрої. Це може бути через відсутність або несумісність бездротового адаптера.", "wifi-view-networks": "Переглянути мережі" } ================================================ FILE: packages/ui/public/site.webmanifest ================================================ { "name": "", "short_name": "", "icons": [ { "src": "/favicon/android-chrome-192x192.png", "sizes": "192x192", "type": "image/png" }, { "src": "/favicon/android-chrome-512x512.png", "sizes": "512x512", "type": "image/png" } ], "theme_color": "#000000", "background_color": "#000000", "display": "standalone" } ================================================ FILE: packages/ui/src/components/app-icon.tsx ================================================ import {HTMLProps, useEffect, useState} from 'react' import {cn} from '@/lib/utils' import {APP_ICON_PLACEHOLDER_SRC} from '@/modules/desktop/app-icon' type AppIconProps = {src?: string; size?: number; ref?: React.Ref} & HTMLProps export function AppIcon({src, style, size, className, ref, ...props}: AppIconProps) { // Keep a local copy of the image `src` so we can gracefully fall back to a // placeholder if the provided source fails to load. Because `src` can change // (for example, when navigating between different apps without remounting the // component), we need to update the local state whenever the prop changes. const [imgSrc, setImgSrc] = useState(src || APP_ICON_PLACEHOLDER_SRC) // If the `src` prop updates, refresh `imgSrc` so the new icon is displayed. useEffect(() => { setImgSrc(src || APP_ICON_PLACEHOLDER_SRC) }, [src]) // Not using `FadeImg` because we have a placeholder and `FadeImg` doesn't support placeholder images // Also not fading any other way because we want color-thief to work by picking up the color return ( setImgSrc(APP_ICON_PLACEHOLDER_SRC)} style={{ ...style, width: size, height: size, minWidth: size, minHeight: size, }} {...props} /> ) } ================================================ FILE: packages/ui/src/components/caret-right.tsx ================================================ const SvgComponent = ({className}: {className?: string}) => ( ) export default SvgComponent ================================================ FILE: packages/ui/src/components/chevron-down.tsx ================================================ /** * Most icons have a box around them. This one's bounding box matches the icon. */ export function ChevronDown() { return ( ) } ================================================ FILE: packages/ui/src/components/cmdk-providers.tsx ================================================ import React from 'react' // Backups import {BackupsCmdkSearchProvider} from '@/features/backups/cmdk-search-provider' // --------------------------------------------------------------------------- // Providers // --------------------------------------------------------------------------- // Files import {FilesCmdkSearchProvider} from '@/features/files/cmdk-search-provider' /** * --------------------------------------------------------------------------- * Command-K Search Providers * --------------------------------------------------------------------------- * * Each feature that wants to surface its own search results inside the global * command-k component should export a small React component that adheres to * the `CmdkSearchProvider` signature defined below. * * The component will be rendered inside the existing `` context so * it can directly return `CommandItem` elements. * * A very small, opinionated interface is intentionally chosen to keep things * straightforward: we just pass the current `query` and a helper to `close` * the palette once the provider performs its action (navigation, etc.). * * Providers are collected in the `cmdkSearchProviders` array (see bottom of * file). Currently only /features/files uses this, but new features should * add their provider to that array – in the future this could be automated via * code-generation or dynamic imports, but for now an explicit list keeps the * coupling minimal. */ export interface CmdkSearchProviderProps { // The current search query coming from the command-k input. query: string // Helper to close the command-k. Call it after executing the action close: () => void } export type CmdkSearchProvider = React.FC export const cmdkSearchProviders: CmdkSearchProvider[] = [FilesCmdkSearchProvider, BackupsCmdkSearchProvider] ================================================ FILE: packages/ui/src/components/cmdk.tsx ================================================ import {useCommandState} from 'cmdk' import {ComponentPropsWithoutRef, createContext, SetStateAction, useContext, useEffect, useRef, useState} from 'react' import {ErrorBoundary} from 'react-error-boundary' import {useNavigate} from 'react-router-dom' import {range} from 'remeda' // Pluggable search providers rendered inside the command palette // Currently only /features/files uses this import {cmdkSearchProviders} from '@/components/cmdk-providers' import {CommandDialog, CommandEmpty, CommandInput, CommandItem, CommandList} from '@/components/ui/command' import {ErrorBoundaryCardFallback} from '@/components/ui/error-boundary-card-fallback' import {Separator} from '@/components/ui/separator' import {LOADING_DASH} from '@/constants' import { APPS_PATH as FILES_APPS_PATH, RECENTS_PATH as FILES_RECENTS_PATH, TRASH_PATH as FILES_TRASH_PATH, } from '@/features/files/constants' import {useDebugInstallRandomApps} from '@/hooks/use-debug-install-random-apps' import {useIsMobile} from '@/hooks/use-is-mobile' import {useLaunchApp} from '@/hooks/use-launch-app' import {useQueryParams} from '@/hooks/use-query-params' import {cn} from '@/lib/utils' import {systemAppsKeyed, useApps} from '@/providers/apps' import {useAvailableApps} from '@/providers/available-apps' import {AppState, trpcReact} from '@/trpc/trpc' import {t} from '@/utils/i18n' import {AppIcon} from './app-icon' import {FadeScroller} from './fade-scroller' import {DebugOnlyBare} from './ui/debug-only' const CmdkOpenContext = createContext<{ open: boolean setOpen: (value: SetStateAction) => void } | null>(null) export function useCmdkOpen() { const ctx = useContext(CmdkOpenContext) if (!ctx) throw new Error('useCmdkOpen must be used within a CommandRoot') return ctx } export function CmdkProvider({children}: {children: React.ReactNode}) { const [open, setOpen] = useState(false) // Register Cmd+K listener once here, not in useCmdkOpen (which is called // by multiple components and would register duplicate listeners). useEffect(() => { const handler = (e: KeyboardEvent) => { if (e.key === 'k' && (e.metaKey || e.ctrlKey)) { e.preventDefault() setOpen((open) => !open) } } document.addEventListener('keydown', handler) return () => document.removeEventListener('keydown', handler) }, []) return {children} } export function CmdkMenu() { const {open, setOpen} = useCmdkOpen() return ( ) } function CmdkContent() { const {setOpen} = useCmdkOpen() const navigate = useNavigate() const {addLinkSearchParams} = useQueryParams() const userApps = useApps() const scrollRef = useRef(null) // The current search query from the command input. We pass this down to all // external search providers so they can surface their own results. const searchQuery = useCommandState((state) => state.search) const userQ = trpcReact.user.get.useQuery() const launchApp = useLaunchApp() const debugInstallRandomApps = useDebugInstallRandomApps() // We only show installed community apps here, effectively limiting available // apps to those present in the official app store const availableApps = useAvailableApps() const isLoading = userQ.isLoading || availableApps.isLoading || userApps.isLoading if (availableApps.isLoading) return null if (isLoading) return null if (userQ.isLoading) return null if (!userApps.userApps || !userApps.userAppsKeyed) return null const readyApps = userApps.userApps.filter((app) => app.state === 'ready') const unreadyApps = userApps.userApps.filter((app) => app.state !== 'ready') // Apps not installed yet const installableApps = availableApps.apps.filter((app) => !userApps.userAppsKeyed?.[app.id]) return ( setOpen(false)} /> {t('no-results-found')} { navigate({pathname: '/settings', search: addLinkSearchParams({dialog: 'restart'})}) setOpen(false) }} > {t('cmdk.restart-umbrel')} { navigate('/app-store?dialog=updates') setOpen(false) }} > {t('cmdk.update-all-apps')} { navigate('/settings/wallpaper') setOpen(false) }} > {t('cmdk.change-wallpaper')} { navigate(systemAppsKeyed['UMBREL_live-usage'].systemAppTo) setOpen(false) }} > {t('cmdk.live-usage')} { navigate('/edit-widgets') setOpen(false) }} > {t('cmdk.widgets')} { navigate(systemAppsKeyed['UMBREL_home'].systemAppTo) setOpen(false) }} > {systemAppsKeyed['UMBREL_home'].name} { navigate(systemAppsKeyed['UMBREL_app-store'].systemAppTo) setOpen(false) }} > {systemAppsKeyed['UMBREL_app-store'].name} { // TODO: THIS IS A HACK // We need a better approach to track the last visited path (possibly scroll position too?) // inside every page. We do this right now for the File app because it's has the most // UX-advantage (eg. user accidentally clicking close while they're in a deeply nested path) const lastFilesPath = sessionStorage.getItem('lastFilesPath') navigate(lastFilesPath || systemAppsKeyed['UMBREL_files'].systemAppTo) setOpen(false) }} > {systemAppsKeyed['UMBREL_files'].name} { navigate(`/files${FILES_RECENTS_PATH}`) setOpen(false) }} > {t('files-sidebar.recents')} { navigate(`/files${FILES_APPS_PATH}`) setOpen(false) }} > {t('files-sidebar.apps')} { navigate(`/files${FILES_TRASH_PATH}`) setOpen(false) }} > {t('files-sidebar.trash')} navigate(systemAppsKeyed['UMBREL_settings'].systemAppTo)} /> navigate({search: addLinkSearchParams({dialog: 'logout'})})} /> navigate({pathname: 'settings', search: addLinkSearchParams({dialog: 'shutdown'})})} /> {/* ---- */} {/* List rows */} navigate('settings/account/change-name')} /> navigate('settings/account/change-password')} /> navigate('/settings/wifi')}> {t('wifi')} navigate('/settings/2fa')}> {t('2fa')} navigate('/settings/advanced/tor')} /> navigate('/settings/migration-assistant')} /> navigate('/settings/language')} /> navigate('/settings/troubleshoot')} /> navigate('/settings/terminal')} /> navigate('/settings/device-info')} /> navigate('/settings/software-update')} /> navigate('/factory-reset')} /> navigate('/settings/advanced')} /> navigate('/settings/advanced/beta-program')} /> navigate('/settings/advanced/external-dns')} /> {readyApps.map((app) => ( { launchApp(app.id) setOpen(false) }} > {app.name} ))} {unreadyApps.map((app) => ( { navigate(`/app-store/${app.id}`) setOpen(false) }} > {app.name} – {appStateToString(app.state)} ))} {installableApps.map((app) => ( { navigate(`/app-store/${app.id}`) setOpen(false) }} > {app.name} {t('generic-in')} App Store ))} {/* Pluggable search providers */} {cmdkSearchProviders.map((Provider, idx) => ( setOpen(false)} /> ))} Install a bunch of random apps ) } function FrequentApps({onLaunchApp}: {onLaunchApp: () => void}) { const lastAppsQ = trpcReact.apps.recentlyOpened.useQuery(undefined, { retry: false, }) const lastApps = lastAppsQ.data ?? [] const {userAppsKeyed} = useApps() const search = useCommandState((state) => state.search) // If there's a search query, don't show frequent apps if (search) return null if (!userAppsKeyed) return null if (!lastApps) return null if (lastApps.length === 0) return null return (

{t('cmdk.frequent-apps')}

{/* Show skeleton by default to prevent layout shift */} {lastAppsQ.isLoading && range(0, 3).map((i) => )} {appsByFrequency(lastApps, 6).map((appId) => ( ))}
) } function appsByFrequency(lastOpenedApps: string[], count: number) { const openCounts = new Map() lastOpenedApps.map((appId) => { if (!openCounts.has(appId)) { openCounts.set(appId, 1) } else { openCounts.set(appId, openCounts.get(appId)! + 1) } }) const sortedAppIds = [...openCounts.entries()] .sort((a, b) => b[1] - a[1]) .slice(0, count) .map((a) => a[0]) return sortedAppIds } function FrequentApp({ appId, icon, name, onLaunch, }: { appId: string icon: string name: string onLaunch?: () => void }) { const launchApp = useLaunchApp() const isMobile = useIsMobile() return ( ) } const SettingsSearchItem = ({ onSelect, value, children, }: { onSelect: () => void value: string children?: React.ReactNode }) => { const {setOpen} = useCmdkOpen() return ( { onSelect() setOpen(false) }} > {children ?? value} ) } const SearchItem = (props: ComponentPropsWithoutRef) => { const search = useCommandState((state) => state.search) if (!search) return null return ( { props.onSelect?.(value) }} /> ) } export function appStateToString(appState: AppState) { return { 'not-installed': t('app.install'), installing: t('app.installing'), ready: t('app.open'), running: t('app.open'), starting: t('app.restarting'), restarting: t('app.starting'), stopping: t('app.stopping'), updating: t('app.updating'), uninstalling: t('app.uninstalling'), unknown: t('app.offline'), stopped: t('app.offline'), loading: t('loading'), }[appState] } ================================================ FILE: packages/ui/src/components/darken-layer.tsx ================================================ import {cn} from '@/lib/utils' /** * Put a darken layer over the page */ export function DarkenLayer({className}: {className?: string}) { return
} ================================================ FILE: packages/ui/src/components/fade-scroller.tsx ================================================ import {ComponentPropsWithoutRef, useLayoutEffect, useRef} from 'react' import {mergeRefs} from 'react-merge-refs' export type FadeScrollerProps = ComponentPropsWithoutRef<'div'> & { direction: 'x' | 'y' debug?: boolean ref?: React.Ref } const FADE_SCROLLER_CLASS_X = 'umbrel-fade-scroller-x' const FADE_SCROLLER_CLASS_Y = 'umbrel-fade-scroller-y' // eslint-disable-next-line @typescript-eslint/no-unused-vars export function useFadeScroller(direction: 'x' | 'y', debug?: boolean) { const ref = useRef(null) // TODO: consider re-running this effect when window is resized // NOTE: useLayoutEffect is used to avoid flicker when fading is rendered useLayoutEffect(() => { // Horizontal scroll in chrome adds fading via scroll-timeline even when it shouldn't. This happens in the 3-up section of the app store // Animating in the side fades also doesn't work because the positions of the gradient markers would be based on the scroll position const el = ref!.current if (!el) return // Throttle scroll updates to once per frame via rAF to avoid redundant // style recalculations — scroll events can fire 10+ times per frame. let rafId = 0 const updateFade = () => { if (!el) return // Round to avoid issues with sub-pixel scrolling // Using `<` and `>` to capture the edge case where the user scrolls past the end of the content (iOS bouncing) const atStart = direction === 'x' ? el.scrollLeft <= 0 : el.scrollTop <= 0 const atEnd = direction === 'x' ? Math.round(el.scrollLeft) + el.clientWidth >= el.scrollWidth : Math.round(el.scrollTop) + el.clientHeight >= el.scrollHeight if (atStart && atEnd) { el.style.setProperty('--distance1', `0px`) el.style.setProperty('--distance2', `0px`) } else if (atStart) { el.style.setProperty('--distance1', `0px`) el.style.setProperty('--distance2', `50px`) } else if (atEnd) { el.style.setProperty('--distance1', `50px`) el.style.setProperty('--distance2', `0px`) } else { el.style.setProperty('--distance1', `50px`) el.style.setProperty('--distance2', `50px`) } } const handleScroll = () => { cancelAnimationFrame(rafId) rafId = requestAnimationFrame(updateFade) } // Run on mount by default updateFade() el.addEventListener('scroll', handleScroll, {passive: true}) return () => { el.removeEventListener('scroll', handleScroll) cancelAnimationFrame(rafId) } }, [direction]) const scrollerClass = direction === 'x' ? FADE_SCROLLER_CLASS_X : direction === 'y' ? FADE_SCROLLER_CLASS_Y : undefined return {scrollerClass, ref} } export function FadeScroller({direction, debug, className, ref, ...props}: FadeScrollerProps) { const {scrollerClass, ref: scrollerRef} = useFadeScroller(direction, debug) return
} ================================================ FILE: packages/ui/src/components/iframe-checker.tsx ================================================ import React from 'react' export function IframeChecker({children}: {children: React.ReactNode}) { const isIframe = window.self !== window.top if (isIframe) { return
umbrelOS cannot be embedded in an iframe.
} return <>{children} } ================================================ FILE: packages/ui/src/components/install-button-connected.tsx ================================================ import prettyBytes from 'pretty-bytes' import {useImperativeHandle, useState} from 'react' import semver from 'semver' import {arrayIncludes} from 'ts-extras' import {useAppInstall} from '@/hooks/use-app-install' import {useLaunchApp} from '@/hooks/use-launch-app' import {useVersion} from '@/hooks/use-version' import {OSUpdateRequiredDialog} from '@/modules/app-store/os-update-required' import {SelectDependenciesDialog} from '@/modules/app-store/select-dependencies-dialog' import {useApps} from '@/providers/apps' import {useAllAvailableApps} from '@/providers/available-apps' import {installedStates, RegistryApp} from '@/trpc/trpc' import {InstallButton} from './install-button' export function InstallButtonConnected({app, ref}: {app: RegistryApp; ref?: React.Ref}) { const appInstall = useAppInstall(app.id) const {apps} = useAllAvailableApps() const [showDepsDialog, setShowDepsDialog] = useState(false) const [showOSUpdateRequiredDialog, setShowOSUpdateRequiredDialog] = useState(false) const {userAppsKeyed, isLoading} = useApps() const openApp = useLaunchApp() const [selections, setSelections] = useState({} as Record) const os = useVersion() const [highlightDependency, setHighlightDependency] = useState(undefined) useImperativeHandle(ref, () => ({ triggerInstall(highlightDependency?: string) { setHighlightDependency(highlightDependency) triggerInstall() }, })) if (isLoading || !userAppsKeyed || !apps || os.isLoading) { return ( ) } const isInstalled = (appId: string) => arrayIncludes(installedStates, userAppsKeyed[appId]?.state) const selectAlternative = (dependencyId: string, appId: string | undefined) => { if (appId) selections[dependencyId] = appId else delete selections[dependencyId] setSelections({...selections}) } const getAppsImplementing = (dependencyId: string) => apps // Filter out community apps that aren't installed .filter((registryApp) => { const isCommunityApp = registryApp.appStoreId !== 'umbrel-app-store' return !isCommunityApp || userAppsKeyed[registryApp.id] }) // Prefer installed app over registry app .map((registryApp) => userAppsKeyed[registryApp.id] ?? registryApp) .filter((applicableApp) => applicableApp.implements?.includes(dependencyId)) .map((implementingApp) => implementingApp.id) // Obtain possible alternatives for each dependency. Groups alternatives for // each dependency into a two dimensional array, where each item references // both the original dependency and the alterantive app. First item always is // the original dependency. // [ // [{dependencyId, appId: dependencyId}, {dependencyId, appId: implementingId}], // [{dependencyId, appId: dependencyId}], // ] const dependencies = (app.dependencies ?? []).map((dependencyId) => [dependencyId, ...getAppsImplementing(dependencyId)].map((appId) => ({ dependencyId, appId, })), ) // Auto-select the first installed alternative, naturally preferring the original // app when it is installed as well. dependencies.forEach((alternatives) => { alternatives.forEach(({dependencyId, appId}) => { if (!selections[dependencyId] && isInstalled(appId)) { selectAlternative(dependencyId, appId) } }) }) // TODO: Also check if app is ready? `&& userAppsKeyed[dep].state === 'ready'` // Will want to mark apps as in progress so we don't show that an app needs to be installed first const areAllAlternativesSelectedAndInstalled = dependencies.every((alternatives) => alternatives.some((app) => selections[app.dependencyId] === app.appId && isInstalled(app.appId)), ) const compatible = semver.lte(app.manifestVersion, os.version) const install = () => { if (!compatible) { setShowOSUpdateRequiredDialog(true) return } if (dependencies.length > 0) { return setShowDepsDialog(true) } appInstall.install() } function triggerInstall() { install() } const verifyInstall = (selectedDeps: Record) => { // Currently always the case because AppPermissionsDialog checks if (areAllAlternativesSelectedAndInstalled) { appInstall.install(selectedDeps) } } return ( <> openApp(app.id)} /> ) } ================================================ FILE: packages/ui/src/components/install-button.tsx ================================================ import {TbLoader} from 'react-icons/tb' import {arrayIncludes} from 'ts-extras' import {ProgressButton} from '@/components/progress-button' import {UNKNOWN} from '@/constants' import {cn} from '@/lib/utils' import {AppStateOrLoading} from '@/trpc/trpc' import {t} from '@/utils/i18n' import {assertUnreachable} from '@/utils/misc' // import {t} from '@/utils/i18n' import {tw} from '@/utils/tw' import {AnimatedNumber} from './ui/animated-number' type Props = { installSize?: string progress?: number state: AppStateOrLoading compatible?: boolean onInstallClick?: () => void onOpenClick?: () => void } export function InstallButton({installSize, progress, state, onInstallClick, onOpenClick, ...props}: Props) { return ( { if (state === 'not-installed') { onInstallClick?.() } else if (state === 'ready') { onOpenClick?.() } }} className='hover:bg-brand-lighter max-md:h-[30px] max-md:w-full max-md:text-13' style={{ ['--progress-button-bg' as string]: state === 'updating' ? 'hsl(0 0 30%)' : 'hsl(var(--color-brand))', }} disabled={!arrayIncludes(['not-installed', 'ready'], state)} initial={{borderRadius: 9999}} {...props} > ) } function ButtonContentForState({ state, installSize, progress, }: { state: AppStateOrLoading installSize?: string progress?: number }) { switch (state) { case 'not-installed': return ( <> {t('app.install')}{' '} {installSize} ) case 'installing': case 'updating': { const text = state === 'updating' ? t('app.updating') : t('app.installing') return ( <> {text} {/* */} {/* 4ch to fit text "100%" */} {progress === undefined ? UNKNOWN() : }% ) } case 'ready': case 'running': return t('app.open') case 'starting': return t('app.restarting') + '...' case 'restarting': return t('app.starting') + '...' case 'stopping': return t('app.stopping') + '...' case 'uninstalling': return t('app.uninstalling') + '...' case 'unknown': case 'stopped': return t('app.offline') case 'loading': case undefined: return // return t('loading') + '...' } return assertUnreachable(state) } export const installButtonClass = cn( tw`whitespace-nowrap disabled:bg-brand/60 disabled:opacity-100 bg-brand hover:bg-brand-lighter`, tw`max-md:h-[30px] max-md:w-full max-md:text-13`, ) ================================================ FILE: packages/ui/src/components/markdown.tsx ================================================ import MarkdownPrimitive from 'react-markdown' import {useLocation} from 'react-router-dom' import remarkBreaks from 'remark-breaks' import remarkGfm from 'remark-gfm' import {cn} from '@/lib/utils' import {tw} from '@/utils/tw' // IMPORTANT: Want to avoid any risk of tracking pixels, XSS, etc. // NEVER ALLOW HTML IN MARKDOWN // NEVER ALLOW IMAGES IN MARKDOWN export function Markdown({className, ...props}: React.ComponentProps) { const {pathname} = useLocation() const isInCommunityAppStore = pathname.startsWith('/community-app-store') if (isInCommunityAppStore) { return
} return ( ( ), }} allowedElements={[ 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'a', 'p', 'ul', 'ol', 'li', 'em', 'strong', // 'del', 'code', 'pre', 'br', ]} // `unwrapDisallowed` because **some text** should still render "some text" rather than nothing unwrapDisallowed // `skipHtml` still renders contents skipHtml className={cn(textClass, className)} {...props} /> ) } const textClass = tw`prose prose-sm prose-neutral prose-invert overflow-x-hidden` ================================================ FILE: packages/ui/src/components/onboarding-background.tsx ================================================ import {useDeviceInfo} from '@/hooks/use-device-info' import {cn} from '@/lib/utils' import {useOnboardingDevice} from '@/routes/onboarding/use-onboarding-device' const backgroundClass = 'pointer-events-none fixed inset-0 size-full object-cover object-center' export function OnboardingBackground({className}: {className?: string}) { const {isLoading} = useDeviceInfo() const {showDevice} = useOnboardingDevice() // Show black while loading to prevent wallpaper 18 flash on Pro/Home devices if (isLoading) { return
} // Pro/Home: Video (webm) with poster (jpg) fallback for older browsers // Uses pre-rendered ping-pong video (forward + reversed) for seamless infinite loop if (showDevice) { return (
) AlertDialogFooter.displayName = 'AlertDialogFooter' function AlertDialogTitle({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } function AlertDialogDescription({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } function AlertDialogAction({ variant, children, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } function AlertDialogCancel({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { const {onOpenChange} = useDialogState() return ( ) } function CarouselNext({ className, ref, variant = 'default', size = 'icon-only', ...props }: React.ComponentProps & {ref?: React.Ref}) { const {orientation, scrollNext, canScrollNext} = useCarousel() return ( ) } export {type CarouselApi, Carousel, CarouselContent, CarouselItem, CarouselPrevious, CarouselNext} ================================================ FILE: packages/ui/src/components/ui/checkbox.tsx ================================================ import * as CheckboxPrimitive from '@radix-ui/react-checkbox' import * as React from 'react' import {TbCheck, TbMinus} from 'react-icons/tb' import {cn} from '@/lib/utils' import {tw} from '@/utils/tw' function Checkbox({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } const checkboxContainerClass = tw`flex items-center space-x-2` // Removing `peer-disabled:cursor-not-allowed` because we want to disable the checkbox while it's going to the server without changing the cursor const checkboxLabelClass = tw`text-15 font-medium leading-none peer-disabled:opacity-50` export {Checkbox, checkboxContainerClass, checkboxLabelClass} ================================================ FILE: packages/ui/src/components/ui/command.tsx ================================================ import * as DialogPrimitive from '@radix-ui/react-dialog' import {DialogProps} from '@radix-ui/react-dialog' import {Command as CommandPrimitive} from 'cmdk' import * as React from 'react' import {RiCloseCircleFill} from 'react-icons/ri' import {mergeRefs} from 'react-merge-refs' import {AppIcon} from '@/components/app-icon' import {useFadeScroller} from '@/components/fade-scroller' import {Dialog} from '@/components/ui/dialog' import {useIsMobile} from '@/hooks/use-is-mobile' import {cn} from '@/lib/utils' import {dialogContentAnimationClass, dialogContentClass, dialogOverlayClass} from './shared/dialog' function Command({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } type CommandDialogProps = DialogProps const CommandDialog = ({children, ...props}: CommandDialogProps) => { return ( {children} ) } function CommandInput({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return (
) } function CommandList({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { const {scrollerClass, ref: localRef} = useFadeScroller('y') return ( ) } function CommandEmpty({ ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } function CommandGroup({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } function CommandSeparator({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } // Accept either a string (image source URL) or a React node for the icon type CommandItemIcon = string | React.ReactNode function CommandItem({ className, ref, icon, children, ...props }: React.ComponentPropsWithoutRef & { icon?: CommandItemIcon ref?: React.Ref> }) { const isMobile = useIsMobile() return ( {icon && (typeof icon === 'string' ? ( ) : ( // When a custom React node is provided, we still want to constrain its // dimensions so spacing stays consistent across command items. {icon} ))} {children} ) } const CommandShortcut = ({className, ...props}: React.HTMLAttributes) => { return } export { Command, CommandDialog, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut, } function BlurOverlay({ref}: {ref?: React.Ref}) { return ( ) } const CommandCloseButton = () => ( Close ) ================================================ FILE: packages/ui/src/components/ui/context-menu.tsx ================================================ import * as ContextMenuPrimitive from '@radix-ui/react-context-menu' import {Check, ChevronRight, Circle} from 'lucide-react' import * as React from 'react' import {cn} from '@/lib/utils' import {contextMenuClasses} from './shared/menu' const ContextMenu = ContextMenuPrimitive.Root const ContextMenuTrigger = ContextMenuPrimitive.Trigger const ContextMenuGroup = ContextMenuPrimitive.Group const ContextMenuPortal = ContextMenuPrimitive.Portal const ContextMenuSub = ContextMenuPrimitive.Sub const ContextMenuRadioGroup = ContextMenuPrimitive.RadioGroup function ContextMenuSubTrigger({ className, inset, children, ref, ...props }: React.ComponentPropsWithoutRef & { inset?: boolean ref?: React.Ref> }) { return ( {children} ) } function ContextMenuSubContent({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( { e.preventDefault() // Prevent default browser context menu e.stopPropagation() }} /> ) } function ContextMenuContent({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( { e.preventDefault() // Prevent default browser context menu e.stopPropagation() }} /> ) } function ContextMenuItem({ className, inset, ref, ...props }: React.ComponentPropsWithoutRef & { inset?: boolean ref?: React.Ref> }) { return ( ) } function ContextMenuCheckboxItem({ className, children, checked, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( {children} ) } function ContextMenuRadioItem({ className, children, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( {children} ) } function ContextMenuLabel({ className, inset, ref, ...props }: React.ComponentPropsWithoutRef & { inset?: boolean ref?: React.Ref> }) { return ( ) } function ContextMenuSeparator({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } const ContextMenuShortcut = ({className, ...props}: React.HTMLAttributes) => { return ( ) } export { ContextMenu, ContextMenuTrigger, ContextMenuContent, ContextMenuItem, ContextMenuCheckboxItem, ContextMenuRadioItem, ContextMenuLabel, ContextMenuSeparator, ContextMenuShortcut, ContextMenuGroup, ContextMenuPortal, ContextMenuSub, ContextMenuSubContent, ContextMenuSubTrigger, ContextMenuRadioGroup, } ================================================ FILE: packages/ui/src/components/ui/copy-button.tsx ================================================ import {useState} from 'react' import {TbCopy} from 'react-icons/tb' import {useCopyToClipboard} from 'react-use' import {Tooltip, TooltipContent, TooltipTrigger} from '@/components/ui/tooltip' import {t} from '@/utils/i18n' import {sleep} from '@/utils/misc' export function CopyButton({value}: {value: string}) { const [, copyToClipboard] = useCopyToClipboard() const [showCopied, setShowCopied] = useState(false) return ( {/* TODO: consider putting in portal to avoid inheriting parent's styling */} {t('clipboard.copied')} ) } ================================================ FILE: packages/ui/src/components/ui/copyable-field.tsx ================================================ import {useRef, useState, type RefObject} from 'react' import {MdContentCopy} from 'react-icons/md' import {useCopyToClipboard} from 'react-use' import {useIsFocused} from 'use-is-focused' import {Tooltip, TooltipContent, TooltipTrigger} from '@/components/ui/tooltip' import {cn} from '@/lib/utils' import {t} from '@/utils/i18n' import {sleep} from '@/utils/misc' export function CopyableField({ value, className, isPassword, narrow, }: { value: string className?: string isPassword?: boolean narrow?: boolean }) { const ref = useRef(null) const [, copyToClipboard] = useCopyToClipboard() const [showCopied, setShowCopied] = useState(false) const focused = useIsFocused(ref as RefObject) return (
setTimeout(() => ref.current?.select())} className={cn( 'block min-w-0 flex-1 appearance-none truncate bg-transparent py-1.5 pl-2.5 font-mono outline-hidden', narrow && 'py-0.5', )} type={isPassword && !focused ? 'password' : 'text'} value={value} /> {/* TODO: consider putting in portal to avoid inheriting parent's styling */} {t('clipboard.copied')}
) } ================================================ FILE: packages/ui/src/components/ui/cover-message.tsx ================================================ import {Portal} from '@radix-ui/react-portal' import {useEffect, useState} from 'react' import {cn} from '@/lib/utils' import {Wallpaper} from '@/providers/wallpaper' import {tw} from '@/utils/tw' import {DarkenLayer} from '../darken-layer' /** Compiler-safe replacement for react-use's useTimeout */ function useDelayedShow(ms: number) { const [show, setShow] = useState(false) useEffect(() => { const id = setTimeout(() => setShow(true), ms) return () => clearTimeout(id) }, [ms]) return show } /** Cover message without */ export function BareCoverMessage({ children, delayed, onClick, }: { children: React.ReactNode delayed?: boolean onClick?: () => void }) { const show = useDelayedShow(600) return (
{!delayed ? children : show && children}
) } /** Covers entire screen to show a message */ export function CoverMessage({ children, bodyClassName, onClick, delayed, }: { children: React.ReactNode bodyClassName?: string onClick?: () => void delayed?: boolean }) { const show = useDelayedShow(600) return ( {/*
*/}
{!delayed ? children : show && children}
{/*
*/}
) } // --- export const COVER_MESSAGE_TARGET_ID = 'cover-message-id' export function CoverMessageTarget() { return
} export function CoverMessageContent({children}: {children: React.ReactNode}) { // `?? undefined` to ensure we put portal in default place otherwise return {children} } export function CoverMessageParagraph({children, className}: {children: React.ReactNode; className?: string}) { return

{children}

} export const coverMessageBodyClass = tw`fixed inset-0 z-50 flex flex-col items-center justify-center gap-1 duration-700 animate-in fade-in fill-mode-both` ================================================ FILE: packages/ui/src/components/ui/debug-only.tsx ================================================ import {IS_DEV} from '@/utils/misc' export function DebugOnly({children}: {children: React.ReactNode}) { if (IS_DEV) { return (
{children}
development only
) } return null } export function DebugOnlyBare({children}: {children: React.ReactNode}) { if (IS_DEV) { return <>{children} } return null } ================================================ FILE: packages/ui/src/components/ui/dialog-close-button.tsx ================================================ import * as DialogPrimitive from '@radix-ui/react-dialog' import {RiCloseCircleFill} from 'react-icons/ri' import {cn} from '@/lib/utils' import {dialogHeaderCircleButtonClass} from '@/utils/element-classes' import {t} from '@/utils/i18n' export const DialogCloseButton = ({className}: {className?: React.ReactNode}) => ( {t('close')} ) ================================================ FILE: packages/ui/src/components/ui/dialog.tsx ================================================ import * as DialogPrimitive from '@radix-ui/react-dialog' import * as React from 'react' import {DialogCloseButton} from '@/components/ui/dialog-close-button' import {ScrollArea} from '@/components/ui/scroll-area' import {cn} from '@/lib/utils' import { dialogContentAnimationClass, dialogContentAnimationSlideClass, dialogContentClass, dialogFooterClass, dialogOverlayClass, } from './shared/dialog' const Dialog = DialogPrimitive.Root const DialogTrigger = DialogPrimitive.Trigger const DialogPortal = (props: DialogPrimitive.DialogPortalProps) => DialogPortal.displayName = DialogPrimitive.Portal.displayName function DialogOverlay({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } function DialogContent({ className, children, slide = true, ref, ...props }: React.ComponentPropsWithoutRef & {slide?: boolean} & { ref?: React.Ref> }) { return ( {children} {/* Close */} ) } const DialogScrollableContent = ({ children, showClose, onOpenAutoFocus, }: { children: React.ReactNode showClose?: boolean onOpenAutoFocus?: (e: Event) => void }) => { return ( {/* TODO: adjust dialog inset if `showClose` is true so close button isn't too close to scrollbar */} {children} {showClose && } ) } const DialogHeader = ({className, ...props}: React.HTMLAttributes) => (
) DialogHeader.displayName = 'DialogHeader' const DialogFooter = ({className, ...props}: React.HTMLAttributes) => (
) DialogFooter.displayName = 'DialogFooter' function DialogTitle({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } function DialogDescription({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } export { Dialog, DialogContent, DialogScrollableContent, DialogDescription, DialogFooter, DialogHeader, DialogPortal, DialogTitle, DialogTrigger, } ================================================ FILE: packages/ui/src/components/ui/drawer.tsx ================================================ import * as React from 'react' import {Drawer as DrawerPrimitive} from 'vaul' import {FadeScroller} from '@/components/fade-scroller' import {cn} from '@/lib/utils' const Drawer = ({shouldScaleBackground = false, ...props}: React.ComponentProps) => ( ) const DrawerTrigger = DrawerPrimitive.Trigger const DrawerPortal = DrawerPrimitive.Portal const DrawerClose = DrawerPrimitive.Close function DrawerOverlay({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } function DrawerContent({ className, ref, children, fullHeight, withScroll, ...props }: React.ComponentPropsWithoutRef & { fullHeight?: boolean withScroll?: boolean ref?: React.Ref> }) { return ( {/* -mb-[4px] so height is effectively zero */}
{!withScroll && children} {withScroll && {children}} ) } const DrawerHeader = ({className, ...props}: React.HTMLAttributes) => (
) const DrawerFooter = ({className, ...props}: React.HTMLAttributes) => (
) function DrawerTitle({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return } function DrawerDescription({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } // Put this in the content of a `Drawer` to make it scrollable. You might need to add `flex-1` to the parent. function DrawerScroller({children}: {children: React.ReactNode}) { return ( {children} ) } export { Drawer, DrawerPortal, DrawerOverlay, DrawerTrigger, DrawerClose, DrawerContent, DrawerHeader, DrawerFooter, DrawerTitle, DrawerDescription, DrawerScroller, } ================================================ FILE: packages/ui/src/components/ui/dropdown-menu.tsx ================================================ import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu' import {Check, ChevronRight, Circle} from 'lucide-react' import * as React from 'react' import {cn} from '@/lib/utils' import {dropdownClasses} from './shared/menu' const DropdownMenu = DropdownMenuPrimitive.Root const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger const DropdownMenuGroup = DropdownMenuPrimitive.Group const DropdownMenuPortal = DropdownMenuPrimitive.Portal const DropdownMenuSub = DropdownMenuPrimitive.Sub const DropdownMenuRadioGroup = DropdownMenuPrimitive.RadioGroup function DropdownMenuSubTrigger({ className, inset, children, ref, ...props }: React.ComponentPropsWithoutRef & { inset?: boolean ref?: React.Ref> }) { return ( {children} ) } function DropdownMenuSubContent({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( { e.preventDefault() // Prevent default browser context menu e.stopPropagation() }} /> ) } function DropdownMenuContent({ className, sideOffset = 4, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( { e.preventDefault() // Prevent default browser context menu e.stopPropagation() }} /> ) } function DropdownMenuItem({ className, inset, ref, ...props }: React.ComponentPropsWithoutRef & { inset?: boolean ref?: React.Ref> }) { return ( ) } function DropdownMenuCheckboxItem({ className, children, checked, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( {children} ) } function DropdownMenuRadioItem({ className, children, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( {children} ) } function DropdownMenuLabel({ className, inset, ref, ...props }: React.ComponentPropsWithoutRef & { inset?: boolean ref?: React.Ref> }) { return ( ) } function DropdownMenuSeparator({ className, ref, ...props }: React.ComponentPropsWithoutRef & { ref?: React.Ref> }) { return ( ) } const DropdownMenuShortcut = ({className, ...props}: React.HTMLAttributes) => { return } export { DropdownMenu, DropdownMenuTrigger, DropdownMenuContent, DropdownMenuItem, DropdownMenuCheckboxItem, DropdownMenuRadioItem, DropdownMenuLabel, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuGroup, DropdownMenuPortal, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuRadioGroup, } ================================================ FILE: packages/ui/src/components/ui/error-boundary-card-fallback.tsx ================================================ import type {FallbackProps} from 'react-error-boundary' import {useRouteError} from 'react-router-dom' import {Button} from '@/components/ui/button' import {Card} from '@/components/ui/card' import {GenericErrorDetails, GenericErrorText} from '@/components/ui/generic-error-text' import {t} from '@/utils/i18n' function useRouteErrorSafe() { try { return useRouteError() } catch { return null } } /** * Used for larger areas like the settings page, dialog content, etc. */ export function ErrorBoundaryCardFallback({error, resetErrorBoundary}: Partial) { const routeError = useRouteErrorSafe() const resolvedError = error ?? routeError return ( // Wrap div to prevent flex parent from sizing this element inappropriately
{resetErrorBoundary && ( )}
{resolvedError != null && }
) } ================================================ FILE: packages/ui/src/components/ui/error-boundary-page-fallback.tsx ================================================ import {ChevronDown, ChevronUp} from 'lucide-react' import {useState} from 'react' import type {FallbackProps} from 'react-error-boundary' import {useNavigate, useRouteError} from 'react-router-dom' import { AlertDialog, AlertDialogAction, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle, } from '@/components/ui/alert-dialog' import {Button} from '@/components/ui/button' import {Dock, DockBottomPositioner} from '@/modules/desktop/dock' import {AppsProvider} from '@/providers/apps' import {AvailableAppsProvider} from '@/providers/available-apps' import {Wallpaper} from '@/providers/wallpaper' import {t} from '@/utils/i18n' import {downloadLogs} from '@/utils/logs' function useRouteErrorSafe() { try { return useRouteError() } catch { return null } } function getErrorMessage(error: unknown): string { if (error instanceof Error) return error.message if (typeof error === 'string') return error return String(error) } /** * Used for when we can't reasonably replace the component with error text. EX: wallpaper or cmdk */ export function ErrorBoundaryPageFallback({error}: Partial = {}) { const navigate = useNavigate() const [showDetails, setShowDetails] = useState(false) const routeError = useRouteErrorSafe() const resolvedError = error ?? routeError return ( <> {t('something-went-wrong')} navigate('/')}>{t('not-found-404.home')} {resolvedError != null && (
{showDetails && (

{getErrorMessage(resolvedError)}

)}
)}
) } ================================================ FILE: packages/ui/src/components/ui/fade-in-img.tsx ================================================ import {useState} from 'react' import {cn} from '@/lib/utils' export function FadeInImg({src, alt, className, ...props}: React.ImgHTMLAttributes) { const [loaded, setLoaded] = useState(false) return ( {alt} { setLoaded(true) }} {...props} /> ) } ================================================ FILE: packages/ui/src/components/ui/form.tsx ================================================ import * as LabelPrimitive from '@radix-ui/react-label' import {Slot} from '@radix-ui/react-slot' import * as React from 'react' import { Controller, FormProvider, useFormContext, useFormState, type ControllerProps, type FieldPath, type FieldValues, } from 'react-hook-form' import {Label} from '@/components/ui/label' import {cn} from '@/lib/utils' const Form = FormProvider type FormFieldContextValue< TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, > = { name: TName } const FormFieldContext = React.createContext({} as FormFieldContextValue) const FormField = < TFieldValues extends FieldValues = FieldValues, TName extends FieldPath = FieldPath, >({ ...props }: ControllerProps) => { return ( ) } const useFormField = () => { const fieldContext = React.useContext(FormFieldContext) const itemContext = React.useContext(FormItemContext) const {getFieldState} = useFormContext() const formState = useFormState({name: fieldContext.name}) const fieldState = getFieldState(fieldContext.name, formState) if (!fieldContext) { throw new Error('useFormField should be used within ') } const {id} = itemContext return { id, name: fieldContext.name, formItemId: `${id}-form-item`, formDescriptionId: `${id}-form-item-description`, formMessageId: `${id}-form-item-message`, ...fieldState, } } type FormItemContextValue = { id: string } const FormItemContext = React.createContext({} as FormItemContextValue) function FormItem({className, ...props}: React.ComponentProps<'div'>) { const id = React.useId() return (
) } function FormLabel({className, ...props}: React.ComponentProps) { const {error, formItemId} = useFormField() return (