From fa54c9d6c9b804a44d29d0c90fe5a35dc087856f Mon Sep 17 00:00:00 2001 From: stinga11 Date: Tue, 21 Apr 2026 20:23:09 -0400 Subject: [PATCH 01/40] Change Budgie display server and update packages (#4450) Some changes consistent with other distros. --- archinstall/default_profiles/desktops/budgie.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/archinstall/default_profiles/desktops/budgie.py b/archinstall/default_profiles/desktops/budgie.py index e6680b7a..f156a53b 100644 --- a/archinstall/default_profiles/desktops/budgie.py +++ b/archinstall/default_profiles/desktops/budgie.py @@ -9,7 +9,7 @@ class BudgieProfile(Profile): 'Budgie', ProfileType.DesktopEnv, support_gfx_driver=True, - display_server=DisplayServerType.Xorg, + display_server=DisplayServerType.Wayland, ) @property @@ -18,12 +18,12 @@ class BudgieProfile(Profile): return [ 'materia-gtk-theme', 'budgie', - 'mate-terminal', - 'nemo', + 'konsole', + 'dolphin', 'papirus-icon-theme', ] @property @override def default_greeter_type(self) -> GreeterType: - return GreeterType.LightdmSlick + return GreeterType.Sddm From 094798b496896f7657be57a3ce62e0e35d31eae8 Mon Sep 17 00:00:00 2001 From: javier-anton-ordonez <93844376+javier-anton-ordonez@users.noreply.github.com> Date: Wed, 22 Apr 2026 02:34:41 +0200 Subject: [PATCH 02/40] ES Language updated (#4456) * ES langauje updated and added diferent translations * Update archinstall/locales/es/LC_MESSAGES/base.po Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Cerrar -> Ocultar Github copilot suggested * Apply suggestion from @Copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> * Fix Spanish translations and accents in base.po Github suggestions * ./locales_generator.sh generated * Accent updated and ./locales_generator.sh generated --------- Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- archinstall/locales/base.pot | 16 +++-- archinstall/locales/es/LC_MESSAGES/base.mo | Bin 63147 -> 65086 bytes archinstall/locales/es/LC_MESSAGES/base.po | 78 ++++++++++++--------- 3 files changed, 55 insertions(+), 39 deletions(-) diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index ac1728eb..f707ec7a 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -641,8 +641,8 @@ msgid "" msgstr "" msgid "" -"Provides a selection of desktop environments and tiling window managers, " -"e.g. gnome, kde, sway" +"Provides a selection of desktop environments and tiling window managers, e." +"g. gnome, kde, sway" msgstr "" msgid "Select your desired desktop environment" @@ -1331,8 +1331,8 @@ msgid "Disable Copy-on-Write" msgstr "" msgid "" -"Provides a selection of desktop environments and tiling window managers, " -"e.g. GNOME, KDE Plasma, Sway" +"Provides a selection of desktop environments and tiling window managers, e." +"g. GNOME, KDE Plasma, Sway" msgstr "" #, python-brace-format @@ -2251,3 +2251,11 @@ msgstr "" msgid "wide Unicode coverage, good fallback font" msgstr "" + +#, python-brace-format +msgid "Setting up U2F login: {u2f_config.u2f_login_method.value}" +msgstr "" + +#, python-brace-format +msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" +msgstr "" diff --git a/archinstall/locales/es/LC_MESSAGES/base.mo b/archinstall/locales/es/LC_MESSAGES/base.mo index 3c3993f7ee87559f7726ebb709f40d6dd7842c61..14e916ef66dffeec86c2631fab615c138248130d 100644 GIT binary patch delta 15362 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 Date: Wed, 22 Apr 2026 07:31:06 -0400 Subject: [PATCH 03/40] Use staticmethod for PasswordStrength methods (#4461) The methods don't need access to the class, so they don't need to be classmethods. This change reduces the number of 'bad return' warnings seen when running Pyright, Pyrefly, and ty. --- archinstall/lib/models/users.py | 45 ++++++++++++++++----------------- 1 file changed, 22 insertions(+), 23 deletions(-) diff --git a/archinstall/lib/models/users.py b/archinstall/lib/models/users.py index 8fda6888..92546076 100644 --- a/archinstall/lib/models/users.py +++ b/archinstall/lib/models/users.py @@ -36,67 +36,66 @@ class PasswordStrength(Enum): case PasswordStrength.STRONG: return 'green' - @classmethod - def strength(cls, password: str) -> Self: + @staticmethod + def strength(password: str) -> PasswordStrength: digit = any(character.isdigit() for character in password) upper = any(character.isupper() for character in password) lower = any(character.islower() for character in password) symbol = any(not character.isalnum() for character in password) - return cls._check_password_strength(digit, upper, lower, symbol, len(password)) + return PasswordStrength._check_password_strength(digit, upper, lower, symbol, len(password)) - @classmethod + @staticmethod def _check_password_strength( - cls, digit: bool, upper: bool, lower: bool, symbol: bool, length: int, - ) -> Self: + ) -> PasswordStrength: # suggested evaluation # https://github.com/archlinux/archinstall/issues/1304#issuecomment-1146768163 if digit and upper and lower and symbol: match length: case num if 13 <= num: - return cls.STRONG + return PasswordStrength.STRONG case num if 11 <= num <= 12: - return cls.MODERATE + return PasswordStrength.MODERATE case num if 7 <= num <= 10: - return cls.WEAK + return PasswordStrength.WEAK case num if num <= 6: - return cls.VERY_WEAK + return PasswordStrength.VERY_WEAK elif digit and upper and lower: match length: case num if 14 <= num: - return cls.STRONG + return PasswordStrength.STRONG case num if 11 <= num <= 13: - return cls.MODERATE + return PasswordStrength.MODERATE case num if 7 <= num <= 10: - return cls.WEAK + return PasswordStrength.WEAK case num if num <= 6: - return cls.VERY_WEAK + return PasswordStrength.VERY_WEAK elif upper and lower: match length: case num if 15 <= num: - return cls.STRONG + return PasswordStrength.STRONG case num if 12 <= num <= 14: - return cls.MODERATE + return PasswordStrength.MODERATE case num if 7 <= num <= 11: - return cls.WEAK + return PasswordStrength.WEAK case num if num <= 6: - return cls.VERY_WEAK + return PasswordStrength.VERY_WEAK elif lower or upper: match length: case num if 18 <= num: - return cls.STRONG + return PasswordStrength.STRONG case num if 14 <= num <= 17: - return cls.MODERATE + return PasswordStrength.MODERATE case num if 9 <= num <= 13: - return cls.WEAK + return PasswordStrength.WEAK case num if num <= 8: - return cls.VERY_WEAK + return PasswordStrength.VERY_WEAK - return cls.VERY_WEAK + return PasswordStrength.VERY_WEAK UserSerialization = TypedDict( From e7d38d0e8204c0baaf36b8baf37ed0cff9701ccb Mon Sep 17 00:00:00 2001 From: Softer Date: Wed, 22 Apr 2026 14:32:41 +0300 Subject: [PATCH 04/40] Fix Limine install with ESP mounted outside /boot (#4442) * Fix Limine install with ESP mounted outside /boot Place limine.conf next to the EFI binary on the ESP so it is found regardless of ESP mountpoint, and block unbootable layouts (non-UKI Limine with ESP not at /boot and no separate /boot partition) in GlobalMenu validation, guided.main() and _add_limine_bootloader(). Fixes #4333 * Extract bootloader layout validation into lib/bootloader/utils * Consolidate Limine layout validation in bootloader utils Move the boot-partition FAT check from GlobalMenu into validate_bootloader_layout so all three call sites (GlobalMenu, guided.py, Installer._add_limine_bootloader) share one function. Return a BootloaderValidationFailure dataclass (kind + description) instead of str | None, so callers can match on the failure kind and the description is built where partition context is in scope. * Encapsulate FAT filesystem detection in FilesystemType.is_fat() --- archinstall/lib/bootloader/utils.py | 63 ++++++++++++++++++++++++++ archinstall/lib/disk/device_handler.py | 2 +- archinstall/lib/global_menu.py | 15 +++--- archinstall/lib/installer.py | 17 ++++--- archinstall/lib/models/device.py | 3 ++ archinstall/scripts/guided.py | 10 ++++ 6 files changed, 95 insertions(+), 15 deletions(-) create mode 100644 archinstall/lib/bootloader/utils.py diff --git a/archinstall/lib/bootloader/utils.py b/archinstall/lib/bootloader/utils.py new file mode 100644 index 00000000..a732f4e1 --- /dev/null +++ b/archinstall/lib/bootloader/utils.py @@ -0,0 +1,63 @@ +from dataclasses import dataclass +from enum import Enum, auto +from pathlib import Path + +from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration +from archinstall.lib.models.device import DiskLayoutConfiguration + + +class BootloaderValidationFailureKind(Enum): + LimineNonFatBoot = auto() + LimineLayout = auto() + + +@dataclass(frozen=True) +class BootloaderValidationFailure: + kind: BootloaderValidationFailureKind + description: str + + +def validate_bootloader_layout( + bootloader_config: BootloaderConfiguration | None, + disk_config: DiskLayoutConfiguration | None, +) -> BootloaderValidationFailure | None: + """Validate bootloader configuration against disk layout. + + Returns a failure with a human-readable description if the configuration + would produce an unbootable system, or None if it is valid. + """ + if not (bootloader_config and disk_config): + return None + + if bootloader_config.bootloader == Bootloader.Limine: + boot_part = next( + (p for m in disk_config.device_modifications if (p := m.get_boot_partition())), + None, + ) + + # Limine reads its config and kernels from the boot partition, which + # must be FAT. + if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()): + return BootloaderValidationFailure( + kind=BootloaderValidationFailureKind.LimineNonFatBoot, + description='Limine does not support booting with a non-FAT boot partition.', + ) + + # When the ESP is the boot partition but mounted outside /boot and + # UKI is disabled, kernels end up on the root filesystem which + # Limine cannot access. + if not bootloader_config.uki: + efi_part = next( + (p for m in disk_config.device_modifications if (p := m.get_efi_partition())), + None, + ) + if efi_part and efi_part == boot_part and efi_part.mountpoint != Path('/boot'): + return BootloaderValidationFailure( + kind=BootloaderValidationFailureKind.LimineLayout, + description=( + f'Limine requires kernels on a FAT partition. The ESP is mounted at {efi_part.mountpoint}, ' + 'enable UKI or add a separate /boot partition to install Limine.' + ), + ) + + return None diff --git a/archinstall/lib/disk/device_handler.py b/archinstall/lib/disk/device_handler.py index 7ac05a31..2e51d3d2 100644 --- a/archinstall/lib/disk/device_handler.py +++ b/archinstall/lib/disk/device_handler.py @@ -250,7 +250,7 @@ class DeviceHandler: case FilesystemType.EXT2 | FilesystemType.EXT3 | FilesystemType.EXT4: # Force create options.append('-F') - case FilesystemType.FAT12 | FilesystemType.FAT16 | FilesystemType.FAT32: + case _ if fs_type.is_fat(): mkfs_type = 'fat' # Set FAT size options.extend(('-F', fs_type.value.removeprefix(mkfs_type))) diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index 2baef93d..3d94f31e 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -5,6 +5,7 @@ from archinstall.lib.applications.application_menu import ApplicationMenu from archinstall.lib.args import ArchConfig from archinstall.lib.authentication.authentication_menu import AuthenticationMenu from archinstall.lib.bootloader.bootloader_menu import BootloaderMenu +from archinstall.lib.bootloader.utils import validate_bootloader_layout from archinstall.lib.configuration import save_config from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu from archinstall.lib.general.general_menu import select_hostname, select_ntp, select_timezone @@ -17,7 +18,7 @@ from archinstall.lib.mirror.mirror_menu import MirrorMenu from archinstall.lib.models.application import ApplicationConfiguration, ZramConfiguration from archinstall.lib.models.authentication import AuthenticationConfiguration from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration -from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutType, FilesystemType, PartitionModification +from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutType, PartitionModification from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration from archinstall.lib.models.network import NetworkConfiguration, NicType @@ -486,16 +487,14 @@ class GlobalMenu(AbstractMenu[None]): if efi_partition is None: return 'EFI system partition (ESP) not found' - if efi_partition.fs_type not in [FilesystemType.FAT12, FilesystemType.FAT16, FilesystemType.FAT32]: + if efi_partition.fs_type is None or not efi_partition.fs_type.is_fat(): return 'ESP must be formatted as a FAT filesystem' - if bootloader == Bootloader.Limine: - if boot_partition.fs_type not in [FilesystemType.FAT12, FilesystemType.FAT16, FilesystemType.FAT32]: - return 'Limine does not support booting with a non-FAT boot partition' + if bootloader == Bootloader.Refind and not self._uefi: + return 'rEFInd can only be used on UEFI systems' - elif bootloader == Bootloader.Refind: - if not self._uefi: - return 'rEFInd can only be used on UEFI systems' + if failure := validate_bootloader_layout(bootloader_config, disk_config): + return failure.description return None diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 973e80ac..19560d75 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -12,6 +12,7 @@ from types import TracebackType from typing import Any, Self from archinstall.lib.boot import Boot +from archinstall.lib.bootloader.utils import validate_bootloader_layout from archinstall.lib.command import SysCommand, run from archinstall.lib.disk.fido import Fido2 from archinstall.lib.disk.luks import Luks2, unlock_luks2_dev @@ -30,7 +31,7 @@ from archinstall.lib.linux_path import LPath from archinstall.lib.locale.utils import verify_keyboard_layout, verify_x11_keyboard_layout from archinstall.lib.mirror.mirror_handler import MirrorListHandler from archinstall.lib.models.application import ZramAlgorithm -from archinstall.lib.models.bootloader import Bootloader +from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration from archinstall.lib.models.device import ( DiskEncryption, DiskLayoutConfiguration, @@ -1466,6 +1467,14 @@ class Installer: elif not efi_partition.mountpoint: raise ValueError('EFI partition is not mounted') + # Safety net for programmatic callers that bypass GlobalMenu and + # guided.py validation. + if failure := validate_bootloader_layout( + BootloaderConfiguration(bootloader=Bootloader.Limine, uki=uki_enabled), + self._disk_config, + ): + raise DiskError(failure.description) + info(f'Limine EFI partition: {efi_partition.dev_path}') parent_dev_path = get_parent_device_path(efi_partition.safe_dev_path) @@ -1476,15 +1485,11 @@ class Installer: if bootloader_removable: efi_dir_path = efi_dir_path / 'BOOT' efi_dir_path_target = efi_dir_path_target / 'BOOT' - - boot_limine_path = self.target / 'boot' / 'limine' - boot_limine_path.mkdir(parents=True, exist_ok=True) - config_path = boot_limine_path / 'limine.conf' else: efi_dir_path = efi_dir_path / 'arch-limine' efi_dir_path_target = efi_dir_path_target / 'arch-limine' - config_path = efi_dir_path / 'limine.conf' + config_path = efi_dir_path / 'limine.conf' efi_dir_path.mkdir(parents=True, exist_ok=True) diff --git a/archinstall/lib/models/device.py b/archinstall/lib/models/device.py index 3015833d..7fa05407 100644 --- a/archinstall/lib/models/device.py +++ b/archinstall/lib/models/device.py @@ -802,6 +802,9 @@ class FilesystemType(StrEnum): def is_crypto(self) -> bool: return self == FilesystemType.CRYPTO_LUKS + def is_fat(self) -> bool: + return self in (FilesystemType.FAT12, FilesystemType.FAT16, FilesystemType.FAT32) + @property def parted_value(self) -> str: return self.value + '(v1)' if self == FilesystemType.LINUX_SWAP else self.value diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 34133722..5cdcdad9 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -5,6 +5,7 @@ import time from archinstall.lib.applications.application_handler import ApplicationHandler from archinstall.lib.args import ArchConfig, ArchConfigHandler from archinstall.lib.authentication.authentication_handler import AuthenticationHandler +from archinstall.lib.bootloader.utils import validate_bootloader_layout from archinstall.lib.configuration import ConfigurationOutput from archinstall.lib.disk.filesystem import FilesystemHandler from archinstall.lib.disk.utils import disk_layouts @@ -211,6 +212,15 @@ def main(arch_config_handler: ArchConfigHandler | None = None) -> None: config.write_debug() config.save() + # Safety net for silent/config-file flow. The TUI menu blocks Install via + # GlobalMenu._validate_bootloader() before reaching this point. + if failure := validate_bootloader_layout( + arch_config_handler.config.bootloader_config, + arch_config_handler.config.disk_config, + ): + error(failure.description) + return + if arch_config_handler.args.dry_run: return From 00834f9c6ec034cbdd840ecfe9cfa40bdd4724df Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Wed, 22 Apr 2026 07:33:35 -0400 Subject: [PATCH 05/40] Use bools instead of time values for SysCommandWorker attributes (#4462) Only the truthiness of the time values was being evaluated. This also reduces the usage of time.time(), which makes the codebase more resilient against clock drift issues. --- archinstall/lib/command.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/archinstall/lib/command.py b/archinstall/lib/command.py index a9d65cb0..b99854d2 100644 --- a/archinstall/lib/command.py +++ b/archinstall/lib/command.py @@ -44,8 +44,8 @@ class SysCommandWorker: self._trace_log_pos = 0 self.poll_object = epoll() self.child_fd: int | None = None - self.started: float | None = None - self.ended: float | None = None + self.started = False + self.ended = False self.remove_vt100_escape_codes_from_lines: bool = remove_vt100_escape_codes_from_lines def __contains__(self, key: bytes) -> bool: @@ -117,7 +117,7 @@ class SysCommandWorker: def is_alive(self) -> bool: self.poll() - if self.started and self.ended is None: + if self.started and not self.ended: return True return False @@ -173,11 +173,11 @@ class SysCommandWorker: self.peak(output) self._trace_log += output except OSError: - self.ended = time.time() + self.ended = True break if self.ended or (not got_output and not _pid_exists(self.pid)): - self.ended = time.time() + self.ended = True try: wait_status = os.waitpid(self.pid, 0)[1] self.exit_code = os.waitstatus_to_exitcode(wait_status) @@ -215,7 +215,7 @@ class SysCommandWorker: # Only parent process moves back to the original working directory os.chdir(old_dir) - self.started = time.time() + self.started = True self.poll_object.register(self.child_fd, EPOLLIN | EPOLLHUP) return True From 80ae85cc8b74b23556b8f033894bb6a274c3d711 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 22 Apr 2026 21:41:09 +1000 Subject: [PATCH 06/40] Update dependency mypy to v1.20.2 (#4458) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 944d1294..e9c7285c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -34,7 +34,7 @@ Source = "https://github.com/archlinux/archinstall" [project.optional-dependencies] log = ["systemd_python==235"] dev = [ - "mypy==1.20.1", + "mypy==1.20.2", "flake8==7.3.0", "pre-commit==4.5.1", "ruff==0.15.11", From 6652197e3557d2024b15a230b6cbdef5eef66434 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:06:09 +1000 Subject: [PATCH 07/40] Update pre-commit hook pre-commit/mirrors-mypy to v1.20.2 (#4463) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 22adc703..a496557e 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -31,7 +31,7 @@ repos: args: [--config=.flake8] fail_fast: true - repo: https://github.com/pre-commit/mirrors-mypy - rev: v1.20.1 + rev: v1.20.2 hooks: - id: mypy args: [ From 6e222bcdd899e9b51aab00e9e08562d30246410d Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 23 Apr 2026 11:08:51 +1000 Subject: [PATCH 08/40] Update dependency pre-commit to v4.6.0 (#4459) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e9c7285c..dd42c642 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ log = ["systemd_python==235"] dev = [ "mypy==1.20.2", "flake8==7.3.0", - "pre-commit==4.5.1", + "pre-commit==4.6.0", "ruff==0.15.11", "pylint==4.0.5", "pytest==9.0.3", From de430190947549f3312e9d262e9ca55a34952896 Mon Sep 17 00:00:00 2001 From: Thierry M <52124613+roxfr@users.noreply.github.com> Date: Thu, 23 Apr 2026 12:07:54 +0200 Subject: [PATCH 09/40] Update base.po (#4467) --- archinstall/locales/fr/LC_MESSAGES/base.po | 1133 ++++++++++++-------- 1 file changed, 712 insertions(+), 421 deletions(-) diff --git a/archinstall/locales/fr/LC_MESSAGES/base.po b/archinstall/locales/fr/LC_MESSAGES/base.po index 042f5d69..d19a3938 100644 --- a/archinstall/locales/fr/LC_MESSAGES/base.po +++ b/archinstall/locales/fr/LC_MESSAGES/base.po @@ -2,20 +2,24 @@ msgid "" msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" -"PO-Revision-Date: 2025-04-11 23:02+0200\n" -"Last-Translator: Roxfr \n" +"PO-Revision-Date: 2026-04-23 11:28+0200\n" +"Last-Translator: Roxfr \n" "Language-Team: \n" "Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Generator: Poedit 3.6\n" +"X-Generator: Poedit 3.9\n" msgid "[!] A log file has been created here: {} {}" msgstr "[!] Un fichier journal a été créé ici : {} {}" -msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" -msgstr " Veuillez soumettre ce problème (et le fichier) à https://github.com/archlinux/archinstall/issues" +msgid "" +" Please submit this issue (and file) to https://github.com/archlinux/" +"archinstall/issues" +msgstr "" +" Veuillez soumettre ce problème (et le fichier) à https://github.com/" +"archlinux/archinstall/issues" msgid "Do you really want to abort?" msgstr "Voulez-vous vraiment abandonner ?" @@ -30,10 +34,13 @@ msgid "Desired hostname for the installation: " msgstr "Nom d'hôte souhaité pour l'installation : " msgid "Username for required superuser with sudo privileges: " -msgstr "Nom d'utilisateur pour le superutilisateur requis avec les privilèges sudo : " +msgstr "" +"Nom d'utilisateur pour le superutilisateur requis avec les privilèges sudo : " msgid "Any additional users to install (leave blank for no users): " -msgstr "Utilisateur supplémentaire à installer (laisser vide pour aucun utilisateur) : " +msgstr "" +"Utilisateur supplémentaire à installer (laisser vide pour aucun " +"utilisateur) : " msgid "Should this user be a superuser (sudoer)?" msgstr "Cet utilisateur doit-il être un superutilisateur (sudoer) ?" @@ -42,7 +49,9 @@ msgid "Select a timezone" msgstr "Sélectionner un fuseau horaire" msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" -msgstr "Souhaitez-vous utiliser GRUB comme chargeur de démarrage au lieu de systemd-boot ?" +msgstr "" +"Souhaitez-vous utiliser GRUB comme chargeur de démarrage au lieu de systemd-" +"boot ?" msgid "Choose a bootloader" msgstr "Choisir un chargeur de démarrage" @@ -50,42 +59,68 @@ msgstr "Choisir un chargeur de démarrage" msgid "Choose an audio server" msgstr "Choisir un serveur audio" -msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." -msgstr "Seuls les paquets tels que base, base-devel, linux, linux-firmware, efibootmgr et les paquets de profil optionnels sont installés." - -msgid "Note: base-devel is no longer installed by default. Add it here if you need build tools." +msgid "" +"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr " +"and optional profile packages are installed." msgstr "" +"Seuls les paquets tels que base, base-devel, linux, linux-firmware, " +"efibootmgr et les paquets de profil optionnels sont installés." -msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." -msgstr "Si vous désirez un navigateur Web, tel que firefox ou chrome, vous pouvez le spécifier dans l'invite suivante." +msgid "" +"Note: base-devel is no longer installed by default. Add it here if you need " +"build tools." +msgstr "" +"Remarque : base-devel n’est plus installé par défaut. Ajoutez-le ici si vous " +"avez besoin d’outils de compilation." -msgid "Write additional packages to install (space separated, leave blank to skip): " -msgstr "Saisir les paquets supplémentaires à installer (séparés par des espaces, vide pour ignorer) : " +msgid "" +"If you desire a web browser, such as firefox or chromium, you may specify it " +"in the following prompt." +msgstr "" +"Si vous désirez un navigateur Web, tel que firefox ou chrome, vous pouvez le " +"spécifier dans l'invite suivante." + +msgid "" +"Write additional packages to install (space separated, leave blank to skip): " +msgstr "" +"Saisir les paquets supplémentaires à installer (séparés par des espaces, " +"vide pour ignorer) : " msgid "Copy ISO network configuration to installation" msgstr "Copier la configuration réseau ISO dans l'installation" -msgid "Use NetworkManager (necessary for configuring internet graphically in GNOME and KDE)" -msgstr "Utiliser NetworkManager (nécessaire pour configurer graphiquement Internet dans GNOME et KDE)" +msgid "" +"Use NetworkManager (necessary for configuring internet graphically in GNOME " +"and KDE)" +msgstr "" +"Utiliser NetworkManager (nécessaire pour configurer graphiquement Internet " +"dans GNOME et KDE)" msgid "Select one network interface to configure" msgstr "Sélectionner une interface réseau à configurer" -msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" -msgstr "Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le mode par défaut \"{}\"" +msgid "" +"Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "" +"Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le " +"mode par défaut \"{}\"" #, python-brace-format msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " msgstr "Entrer l'IP et le sous-réseau pour {} (exemple : 192.168.0.5/24) : " msgid "Enter your gateway (router) IP address or leave blank for none: " -msgstr "Entrer l'adresse IP de votre passerelle (routeur) ou laisser vide pour aucune : " +msgstr "" +"Entrer l'adresse IP de votre passerelle (routeur) ou laisser vide pour " +"aucune : " msgid "Enter your DNS servers (space separated, blank for none): " msgstr "Entrer vos serveurs DNS (séparés par des espaces, vide pour aucun) : " msgid "Select which filesystem your main partition should use" -msgstr "Sélectionner le système de fichiers que votre partition principale doit utiliser" +msgstr "" +"Sélectionner le système de fichiers que votre partition principale doit " +"utiliser" msgid "Current partition layout" msgstr "Disposition actuelle des partitions" @@ -100,14 +135,21 @@ msgstr "" msgid "Enter a desired filesystem type for the partition" msgstr "Entrer un type de système de fichiers souhaité pour la partition" -msgid "Enter the start location (in parted units: s, GB, %, etc. ; default: {}): " -msgstr "Entrer l'emplacement de départ (en unités séparées : s, Go, %, etc. ; par défaut : {}) : " +msgid "" +"Enter the start location (in parted units: s, GB, %, etc. ; default: {}): " +msgstr "" +"Entrer l'emplacement de départ (en unités séparées : s, Go, %, etc. ; par " +"défaut : {}) : " msgid "Enter the end location (in parted units: s, GB, %, etc. ; ex: {}): " -msgstr "Entrer l'emplacement de fin (en unités séparées : s, Go, %, etc. ; ex : {}) : " +msgstr "" +"Entrer l'emplacement de fin (en unités séparées : s, Go, %, etc. ; ex : " +"{}) : " msgid "{} contains queued partitions, this will remove those, are you sure?" -msgstr "{} contient des partitions en file d'attente, cela les supprimera, êtes-vous sûr ?" +msgstr "" +"{} contient des partitions en file d'attente, cela les supprimera, êtes-vous " +"sûr ?" msgid "" "{}\n" @@ -127,11 +169,17 @@ msgstr "" "\n" "Sélectionner par index où et quelle partition montée" -msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." -msgstr " * Les points de montage de la partition sont relatifs à l'intérieur de l'installation, le démarrage serait /boot par exemple." +msgid "" +" * Partition mount-points are relative to inside the installation, the boot " +"would be /boot as an example." +msgstr "" +" * Les points de montage de la partition sont relatifs à l'intérieur de " +"l'installation, le démarrage serait /boot par exemple." msgid "Select where to mount partition (leave blank to remove mountpoint): " -msgstr "Sélectionner où monter la partition (laisser vide pour supprimer le point de montage) : " +msgstr "" +"Sélectionner où monter la partition (laisser vide pour supprimer le point de " +"montage) : " msgid "" "{}\n" @@ -176,34 +224,58 @@ msgid "Archinstall language" msgstr "Langue d'Archinstall" msgid "Wipe all selected drives and use a best-effort default partition layout" -msgstr "Effacer tous les lecteurs sélectionnés et utiliser une disposition de partition par défaut optimale" +msgstr "" +"Effacer tous les lecteurs sélectionnés et utiliser une disposition de " +"partition par défaut optimale" -msgid "Select what to do with each individual drive (followed by partition usage)" -msgstr "Sélectionner ce qu'il faut faire avec chaque lecteur individuel (suivi de l'utilisation de la partition)" +msgid "" +"Select what to do with each individual drive (followed by partition usage)" +msgstr "" +"Sélectionner ce qu'il faut faire avec chaque lecteur individuel (suivi de " +"l'utilisation de la partition)" msgid "Select what you wish to do with the selected block devices" -msgstr "Sélectionner ce que vous souhaitez faire avec les périphériques de bloc sélectionnés" +msgstr "" +"Sélectionner ce que vous souhaitez faire avec les périphériques de bloc " +"sélectionnés" -msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" -msgstr "Ceci est une liste préprogrammée de profiles, ils pourraient faciliter l'installation d'outils comme les environnements de bureau" +msgid "" +"This is a list of pre-programmed profiles, they might make it easier to " +"install things like desktop environments" +msgstr "" +"Ceci est une liste préprogrammée de profiles, ils pourraient faciliter " +"l'installation d'outils comme les environnements de bureau" msgid "Select keyboard layout" msgstr "Sélectionner la disposition du clavier" msgid "Select one of the regions to download packages from" -msgstr "Sélectionner l'une des régions depuis lesquelles télécharger les paquets" +msgstr "" +"Sélectionner l'une des régions depuis lesquelles télécharger les paquets" msgid "Select one or more hard drives to use and configure" msgstr "Sélectionner un ou plusieurs disques durs à utiliser et à configurer" -msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." -msgstr "Pour une meilleure compatibilité avec votre matériel AMD, vous pouvez utiliser les options entièrement open source ou AMD / ATI." +msgid "" +"For the best compatibility with your AMD hardware, you may want to use " +"either the all open-source or AMD / ATI options." +msgstr "" +"Pour une meilleure compatibilité avec votre matériel AMD, vous pouvez " +"utiliser les options entièrement open source ou AMD / ATI." -msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" -msgstr "Pour une compatibilité optimale avec votre matériel Intel, vous pouvez utiliser les options entièrement open source ou Intel.\n" +msgid "" +"For the best compatibility with your Intel hardware, you may want to use " +"either the all open-source or Intel options.\n" +msgstr "" +"Pour une compatibilité optimale avec votre matériel Intel, vous pouvez " +"utiliser les options entièrement open source ou Intel.\n" -msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" -msgstr "Pour une meilleure compatibilité avec votre matériel Nvidia, vous pouvez utiliser le pilote propriétaire Nvidia.\n" +msgid "" +"For the best compatibility with your Nvidia hardware, you may want to use " +"the Nvidia proprietary driver.\n" +msgstr "" +"Pour une meilleure compatibilité avec votre matériel Nvidia, vous pouvez " +"utiliser le pilote propriétaire Nvidia.\n" msgid "" "\n" @@ -212,7 +284,8 @@ msgid "" msgstr "" "\n" "\n" -"Sélectionner un pilote graphique ou laisser vide pour installer tous les pilotes open-source" +"Sélectionner un pilote graphique ou laisser vide pour installer tous les " +"pilotes open-source" msgid "All open-source (default)" msgstr "Tout open-source (par défaut)" @@ -235,8 +308,12 @@ msgstr "Sélectionner une ou plusieurs des options ci-dessous : " msgid "Adding partition...." msgstr "Ajout de la partition...." -msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." -msgstr "Vous devez entrer un type de fs valide pour continuer. Voir `man parted` pour les types de fs valides." +msgid "" +"You need to enter a valid fs-type in order to continue. See `man parted` for " +"valid fs-type's." +msgstr "" +"Vous devez entrer un type de fs valide pour continuer. Voir `man parted` " +"pour les types de fs valides." msgid "Error: Listing profiles on URL \"{}\" resulted in:" msgstr "Erreur : la liste des profils sur l'URL \"{}\" a entraîné :" @@ -309,7 +386,8 @@ msgid "" msgstr "" "Vous avez décidé d'ignorer la sélection du disque dur\n" "et vous utiliserez la configuration de disque montée sur {} (expérimental)\n" -"ATTENTION : Archinstall ne vérifiera pas l'adéquation de cette configuration\n" +"ATTENTION : Archinstall ne vérifiera pas l'adéquation de cette " +"configuration\n" "Souhaitez-vous continuer ?" msgid "Re-using partition instance: {}" @@ -334,7 +412,8 @@ msgid "Mark/Unmark a partition as encrypted" msgstr "Marquer/Démarquer une partition comme encrypté" msgid "Mark/Unmark a partition as bootable (automatic for /boot)" -msgstr "Marquer/Démarquer une partition comme amorçable (automatique pour /boot)" +msgstr "" +"Marquer/Démarquer une partition comme amorçable (automatique pour /boot)" msgid "Set desired filesystem for a partition" msgstr "Définir le système de fichiers souhaité pour une partition" @@ -374,7 +453,9 @@ msgid "Enter a encryption password for {}" msgstr "Entrer un mot de passe de chiffrement pour {}" msgid "Enter disk encryption password (leave blank for no encryption): " -msgstr "Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun chiffrement) : " +msgstr "" +"Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun " +"chiffrement) : " msgid "Create a required super-user with sudo privileges: " msgstr "Créer un super-utilisateur requis avec les privilèges sudo : " @@ -385,31 +466,44 @@ msgstr "Entrer le mot de passe root (laisser vide pour désactiver root) : " msgid "Password for user \"{}\": " msgstr "Mot de passe pour l'utilisateur \"{}\" : " -msgid "Verifying that additional packages exist (this might take a few seconds)" -msgstr "Vérifier que des paquets supplémentaires existent (cela peut prendre quelques secondes)" - -msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" -msgstr "Souhaitez-vous utiliser la synchronisation automatique de l'heure (NTP) avec les serveurs de temps par défaut ?\n" +msgid "" +"Verifying that additional packages exist (this might take a few seconds)" +msgstr "" +"Vérifier que des paquets supplémentaires existent (cela peut prendre " +"quelques secondes)" msgid "" -"Hardware time and other post-configuration steps might be required in order for NTP to work.\n" +"Would you like to use automatic time synchronization (NTP) with the default " +"time servers?\n" +msgstr "" +"Souhaitez-vous utiliser la synchronisation automatique de l'heure (NTP) avec " +"les serveurs de temps par défaut ?\n" + +msgid "" +"Hardware time and other post-configuration steps might be required in order " +"for NTP to work.\n" "For more information, please check the Arch wiki" msgstr "" -"Le temps matériel et d'autres étapes de post-configuration peuvent être nécessaires pour que NTP fonctionne.\n" +"Le temps matériel et d'autres étapes de post-configuration peuvent être " +"nécessaires pour que NTP fonctionne.\n" "Pour plus d'informations, veuillez consulter le wiki Arch" msgid "Enter a username to create an additional user (leave blank to skip): " -msgstr "Entrer un nom d'utilisateur pour créer un utilisateur supplémentaire (laisser vide pour ignorer) : " +msgstr "" +"Entrer un nom d'utilisateur pour créer un utilisateur supplémentaire " +"(laisser vide pour ignorer) : " msgid "Use ESC to skip\n" msgstr "Utiliser ESC pour ignorer\n" msgid "" "\n" -" Choose an object from the list, and select one of the available actions for it to execute" +" Choose an object from the list, and select one of the available actions for " +"it to execute" msgstr "" "\n" -"Choisir un objet dans la liste et sélectionner l'une des actions disponibles pour qu'il s'exécute" +"Choisir un objet dans la liste et sélectionner l'une des actions disponibles " +"pour qu'il s'exécute" msgid "Cancel" msgstr "Annuler" @@ -445,11 +539,18 @@ msgstr "" "\n" "Voici la configuration choisie :" -msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." -msgstr "Pacman est déjà en cours d'exécution, attendez au maximum 10 minutes pour qu'il se termine." +msgid "" +"Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "" +"Pacman est déjà en cours d'exécution, attendez au maximum 10 minutes pour " +"qu'il se termine." -msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." -msgstr "Le verrou pacman préexistant n'a jamais été fermé. Veuillez nettoyer toutes les sessions pacman existantes avant d'utiliser archinstall." +msgid "" +"Pre-existing pacman lock never exited. Please clean up any existing pacman " +"sessions before using archinstall." +msgstr "" +"Le verrou pacman préexistant n'a jamais été fermé. Veuillez nettoyer toutes " +"les sessions pacman existantes avant d'utiliser archinstall." msgid "Choose which optional additional repositories to enable" msgstr "Choisir les dépôts supplémentaires en option à activer" @@ -586,14 +687,17 @@ msgid "Select the desired subvolume options " msgstr "Sélectionner les options de sous-volume souhaitées " msgid "Define users with sudo privilege, by username: " -msgstr "Définir les utilisateurs avec le privilège sudo, par nom d'utilisateur : " +msgstr "" +"Définir les utilisateurs avec le privilège sudo, par nom d'utilisateur : " #, python-brace-format msgid "[!] A log file has been created here: {}" msgstr "[!] Un fichier journal a été créé ici : {}" msgid "Would you like to use BTRFS subvolumes with a default structure?" -msgstr "Souhaitez-vous utiliser des sous-volumes BTRFS avec une structure par défaut ?" +msgstr "" +"Souhaitez-vous utiliser des sous-volumes BTRFS avec une structure par " +"défaut ?" msgid "Would you like to use BTRFS compression?" msgstr "Souhaitez-vous utiliser la compression BTRFS ?" @@ -601,8 +705,12 @@ msgstr "Souhaitez-vous utiliser la compression BTRFS ?" msgid "Would you like to create a separate partition for /home?" msgstr "Souhaitez-vous créer une partition séparée pour /home ?" -msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" -msgstr "Les disques sélectionnés n'ont pas la capacité minimale requise pour une suggestion automatique\n" +msgid "" +"The selected drives do not have the minimum capacity required for an " +"automatic suggestion\n" +msgstr "" +"Les disques sélectionnés n'ont pas la capacité minimale requise pour une " +"suggestion automatique\n" msgid "Minimum capacity for /home partition: {}GB\n" msgstr "Capacité minimale pour la partition /home : {} Go\n" @@ -629,7 +737,9 @@ msgid "No iface specified for manual configuration" msgstr "Aucun iface spécifié pour la configuration manuelle" msgid "Manual nic configuration with no auto DHCP requires an IP address" -msgstr "La configuration manuelle de la carte réseau sans DHCP automatique nécessite une adresse IP" +msgstr "" +"La configuration manuelle de la carte réseau sans DHCP automatique nécessite " +"une adresse IP" msgid "Add interface" msgstr "Ajouter une interface" @@ -649,23 +759,42 @@ msgstr "Configuration manuelle" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "Marquer/Démarquer une partition comme compressée (btrfs uniquement)" -msgid "The password you are using seems to be weak, are you sure you want to use it?" -msgstr "Le mot de passe que vous utilisez semble faible, êtes-vous sûr de vouloir l'utiliser ?" +msgid "" +"The password you are using seems to be weak, are you sure you want to use it?" +msgstr "" +"Le mot de passe que vous utilisez semble faible, êtes-vous sûr de vouloir " +"l'utiliser ?" -msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" -msgstr "Fournit une sélection d'environnements de bureau et de gestionnaires de fenêtres en mosaïque, par ex. gnome, kde, sway" +msgid "" +"Provides a selection of desktop environments and tiling window managers, " +"e.g. gnome, kde, sway" +msgstr "" +"Fournit une sélection d'environnements de bureau et de gestionnaires de " +"fenêtres en mosaïque, par ex. gnome, kde, sway" msgid "Select your desired desktop environment" msgstr "Sélectionner l'environnement de bureau souhaité" -msgid "A very basic installation that allows you to customize Arch Linux as you see fit." -msgstr "Une installation très basique qui vous permet de personnaliser Arch Linux comme bon vous semble." +msgid "" +"A very basic installation that allows you to customize Arch Linux as you see " +"fit." +msgstr "" +"Une installation très basique qui vous permet de personnaliser Arch Linux " +"comme bon vous semble." -msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" -msgstr "Fournit une sélection de divers paquets de serveur à installer et à activer, par ex. httpd, nginx, mariadb" +msgid "" +"Provides a selection of various server packages to install and enable, e.g. " +"httpd, nginx, mariadb" +msgstr "" +"Fournit une sélection de divers paquets de serveur à installer et à activer, " +"par ex. httpd, nginx, mariadb" -msgid "Choose which servers to install, if none then a minimal installation will be done" -msgstr "Choisir les serveurs à installer, s'il n'y en a pas, alors une installation minimale sera effectuée" +msgid "" +"Choose which servers to install, if none then a minimal installation will be " +"done" +msgstr "" +"Choisir les serveurs à installer, s'il n'y en a pas, alors une installation " +"minimale sera effectuée" msgid "Installs a minimal system as well as xorg and graphics drivers." msgstr "Installe un système minimal ainsi que les pilotes graphiques et xorg." @@ -673,8 +802,12 @@ msgstr "Installe un système minimal ainsi que les pilotes graphiques et xorg." msgid "Press Enter to continue." msgstr "Appuyer sur Entrée pour continuer." -msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" -msgstr "Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer la configuration post-installation ?" +msgid "" +"Would you like to chroot into the newly created installation and perform " +"post-installation configuration?" +msgstr "" +"Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer " +"la configuration post-installation ?" msgid "Are you sure you want to reset this setting?" msgstr "Voulez-vous vraiment réinitialiser ce paramètre ?" @@ -683,10 +816,16 @@ msgid "Select one or more hard drives to use and configure\n" msgstr "Sélectionner un ou plusieurs disques durs à utiliser et à configurer\n" msgid "Any modifications to the existing setting will reset the disk layout!" -msgstr "Toute modification du paramètre existant réinitialisera la disposition du disque !" +msgstr "" +"Toute modification du paramètre existant réinitialisera la disposition du " +"disque !" -msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" -msgstr "Si vous réinitialisez la sélection du disque dur, cela réinitialisera également la disposition actuelle du disque. Êtes-vous sûr ?" +msgid "" +"If you reset the harddrive selection this will also reset the current disk " +"layout. Are you sure?" +msgstr "" +"Si vous réinitialisez la sélection du disque dur, cela réinitialisera " +"également la disposition actuelle du disque. Êtes-vous sûr ?" msgid "Save and exit" msgstr "Sauvegarder et quitter" @@ -696,7 +835,8 @@ msgid "" "contains queued partitions, this will remove those, are you sure?" msgstr "" "{}\n" -"contient des partitions en file d'attente, cela les supprimera, êtes-vous sûr ?" +"contient des partitions en file d'attente, cela les supprimera, êtes-vous " +"sûr ?" msgid "No audio server" msgstr "Pas de serveur audio" @@ -732,8 +872,13 @@ msgstr "Ajouter : " msgid "Value: " msgstr "Valeur : " -msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" -msgstr "Vous pouvez ignorer la sélection d'un lecteur et le partitionnement et utiliser n'importe quelle configuration de lecteur montée sur /mnt (expérimental)" +msgid "" +"You can skip selecting a drive and partitioning and use whatever drive-setup " +"is mounted at /mnt (experimental)" +msgstr "" +"Vous pouvez ignorer la sélection d'un lecteur et le partitionnement et " +"utiliser n'importe quelle configuration de lecteur montée sur /mnt " +"(expérimental)" msgid "Select one of the disks or skip and use /mnt as default" msgstr "Sélectionner l'un des disques ou ignorer et utiliser /mnt par défaut" @@ -756,8 +901,12 @@ msgstr "Espace libre" msgid "Bus-type" msgstr "Type de bus" -msgid "Either root-password or at least 1 user with sudo privileges must be specified" -msgstr "Le mot de passe root ou au moins 1 utilisateur avec des privilèges sudo doit être spécifié" +msgid "" +"Either root-password or at least 1 user with sudo privileges must be " +"specified" +msgstr "" +"Le mot de passe root ou au moins 1 utilisateur avec des privilèges sudo doit " +"être spécifié" msgid "Enter username (leave blank to skip): " msgstr "Entrer le nom d'utilisateur (laisser vide pour ignorer) : " @@ -795,8 +944,12 @@ msgstr "Supprimer le sous-volume" msgid "Configured {} interfaces" msgstr "Interfaces {} configurées" -msgid "This option enables the number of parallel downloads that can occur during installation" -msgstr "Cette option active le nombre de téléchargements parallèles qui peuvent se produire pendant l'installation" +msgid "" +"This option enables the number of parallel downloads that can occur during " +"installation" +msgstr "" +"Cette option active le nombre de téléchargements parallèles qui peuvent se " +"produire pendant l'installation" msgid "" "Enter the number of parallel downloads to be enabled.\n" @@ -807,37 +960,50 @@ msgstr "" " (Entrer une valeur comprise entre 1 et {})\n" "Note :" -msgid " - Maximum value : {} ( Allows {} parallel downloads, allows {} downloads at a time )" -msgstr " - Valeur maximale : {} (Autorise {} téléchargements parallèles, autorise {} téléchargements à la fois)" +msgid "" +" - Maximum value : {} ( Allows {} parallel downloads, allows {} downloads " +"at a time )" +msgstr "" +" - Valeur maximale : {} (Autorise {} téléchargements parallèles, autorise {} " +"téléchargements à la fois)" -msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" -msgstr " - Valeur minimale : 1 (Autorise 1 téléchargement parallèle, autorise 2 téléchargements à la fois)" +msgid "" +" - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a " +"time )" +msgstr "" +" - Valeur minimale : 1 (Autorise 1 téléchargement parallèle, autorise 2 " +"téléchargements à la fois)" -msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" -msgstr " - Désactiver/Défaut : 0 (Désactive le téléchargement parallèle, n'autorise qu'un seul téléchargement à la fois)" +msgid "" +" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 " +"download at a time )" +msgstr "" +" - Désactiver/Défaut : 0 (Désactive le téléchargement parallèle, n'autorise " +"qu'un seul téléchargement à la fois)" #, python-brace-format -msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" -msgstr "Entrée invalide ! Réessayer avec une entrée valide [1 pour {max_downloads}, ou 0 pour désactiver]" +msgid "" +"Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to " +"disable]" +msgstr "" +"Entrée invalide ! Réessayer avec une entrée valide [1 pour {max_downloads}, " +"ou 0 pour désactiver]" msgid "Parallel Downloads" msgstr "Téléchargements parallèles" msgid "Pacman" -msgstr "" +msgstr "Pacman" msgid "Color" -msgstr "" +msgstr "Couleur" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Enter the number of parallel downloads (1-{})" -msgstr "" -"Saisir le nombre de téléchargements parallèles à activer.\n" -"\n" -"Note :\n" +msgstr "Entrer le nombre de téléchargements simultanés (1–{})" msgid "Enable colored output for pacman" -msgstr "" +msgstr "Activer l’affichage en couleur pour pacman" msgid "ESC to skip" msgstr "ESC pour ignorer" @@ -851,14 +1017,20 @@ msgstr "TAB pour sélectionner" msgid "[Default value: 0] > " msgstr "[Valeur par défaut : 0] > " -msgid "To be able to use this translation, please install a font manually that supports the language." -msgstr "Pour pouvoir utiliser cette traduction, veuillez installer manuellement une police prenant en charge la langue." +msgid "" +"To be able to use this translation, please install a font manually that " +"supports the language." +msgstr "" +"Pour pouvoir utiliser cette traduction, veuillez installer manuellement une " +"police prenant en charge la langue." msgid "The font should be stored as {}" msgstr "La police d'écriture doit être stockée sous {}" msgid "Archinstall requires root privileges to run. See --help for more." -msgstr "Archinstall nécessite des privilèges root pour s'exécuter. Voir --help pour plus d'informations." +msgstr "" +"Archinstall nécessite des privilèges root pour s'exécuter. Voir --help pour " +"plus d'informations." msgid "Select an execution mode" msgstr "Sélectionner un mode d'exécution" @@ -868,14 +1040,22 @@ msgid "Unable to fetch profile from specified url: {}" msgstr "Impossible de récupérer le profil à partir de l'URL spécifiée : {}" #, python-brace-format -msgid "Profiles must have unique name, but profile definitions with duplicate name found: {}" -msgstr "Les profils doivent avoir un nom unique, mais des définitions de profil avec un nom en double ont été trouvées : {}" +msgid "" +"Profiles must have unique name, but profile definitions with duplicate name " +"found: {}" +msgstr "" +"Les profils doivent avoir un nom unique, mais des définitions de profil avec " +"un nom en double ont été trouvées : {}" msgid "Select one or more devices to use and configure" msgstr "Sélectionner un ou plusieurs périphériques à utiliser et à configurer" -msgid "If you reset the device selection this will also reset the current disk layout. Are you sure?" -msgstr "Si vous réinitialisez la sélection de périphérique, cela réinitialisera également la disposition actuelle du disque. Etes-vous sûr ?" +msgid "" +"If you reset the device selection this will also reset the current disk " +"layout. Are you sure?" +msgstr "" +"Si vous réinitialisez la sélection de périphérique, cela réinitialisera " +"également la disposition actuelle du disque. Etes-vous sûr ?" msgid "Existing Partitions" msgstr "Partitions existantes" @@ -894,8 +1074,12 @@ msgstr "Capacité minimale pour la partition /home : {} Gio\n" msgid "Minimum capacity for Arch Linux partition: {}GiB" msgstr "Capacité minimale pour la partition Arch Linux : {} Gio" -msgid "This is a list of pre-programmed profiles_bck, they might make it easier to install things like desktop environments" -msgstr "Ceci est une liste préprogrammée de profiles_bck, ils pourraient faciliter l'installation de choses comme les environnements de bureau" +msgid "" +"This is a list of pre-programmed profiles_bck, they might make it easier to " +"install things like desktop environments" +msgstr "" +"Ceci est une liste préprogrammée de profiles_bck, ils pourraient faciliter " +"l'installation de choses comme les environnements de bureau" msgid "Current profile selection" msgstr "Sélection du profil actuel" @@ -927,14 +1111,26 @@ msgstr "Supprimer la partition" msgid "Partition" msgstr "Partition" -msgid "This partition is currently encrypted, to format it a filesystem has to be specified" -msgstr "Cette partition est actuellement encrypté, pour la formater, un système de fichiers doit être spécifié" +msgid "" +"This partition is currently encrypted, to format it a filesystem has to be " +"specified" +msgstr "" +"Cette partition est actuellement encrypté, pour la formater, un système de " +"fichiers doit être spécifié" -msgid "Partition mount-points are relative to inside the installation, the boot would be /boot as an example." -msgstr "Les points de montage de partition sont relatifs à l'intérieur de l'installation, le démarrage serait /boot par exemple." +msgid "" +"Partition mount-points are relative to inside the installation, the boot " +"would be /boot as an example." +msgstr "" +"Les points de montage de partition sont relatifs à l'intérieur de " +"l'installation, le démarrage serait /boot par exemple." -msgid "If mountpoint /boot is set, then the partition will also be marked as bootable." -msgstr "Si le point de montage /boot est défini, la partition sera également marquée comme amorçable." +msgid "" +"If mountpoint /boot is set, then the partition will also be marked as " +"bootable." +msgstr "" +"Si le point de montage /boot est défini, la partition sera également marquée " +"comme amorçable." msgid "Mountpoint: " msgstr "Point de montage : " @@ -948,11 +1144,17 @@ msgstr "Total des secteurs : {}" msgid "Enter the start sector (default: {}): " msgstr "Saisir le secteur de début (par défaut : {}) : " -msgid "Enter the end sector of the partition (percentage or block number, default: {}): " -msgstr "Saisir le secteur de fin de la partition (pourcentage ou numéro de bloc, par défaut : {}) : " +msgid "" +"Enter the end sector of the partition (percentage or block number, default: " +"{}): " +msgstr "" +"Saisir le secteur de fin de la partition (pourcentage ou numéro de bloc, par " +"défaut : {}) : " msgid "This will remove all newly added partitions, continue?" -msgstr "Cela supprimera toutes les partitions nouvellement ajoutées, voulez-vous continuer ?" +msgstr "" +"Cela supprimera toutes les partitions nouvellement ajoutées, voulez-vous " +"continuer ?" #, python-brace-format msgid "Partition management: {}" @@ -966,13 +1168,16 @@ msgid "Encryption type" msgstr "Type de chiffrement" msgid "Iteration time" -msgstr "" +msgstr "Temps d’itération" msgid "Enter iteration time for LUKS encryption (in milliseconds)" msgstr "" +"Entrer le temps d’itération pour le chiffrement LUKS (en millisecondes)" msgid "Higher values increase security but slow down boot time" -msgstr "Des valeurs plus grandes peuvent agrandir la sécurité, mais peuvent ralentir le temps de démarrage" +msgstr "" +"Des valeurs plus grandes peuvent agrandir la sécurité, mais peuvent ralentir " +"le temps de démarrage" msgid "Default: 10000ms, Recommended range: 1000-60000" msgstr "Par défaut: 10000ms, range recommandé: 1000-60000" @@ -1042,14 +1247,20 @@ msgid "Back" msgstr "Retour" msgid "Please chose which greeter to install for the chosen profiles: {}" -msgstr "Veuillez choisir le greeter (interface de connexion) à installer pour les profils choisis : {}" +msgstr "" +"Veuillez choisir le greeter (interface de connexion) à installer pour les " +"profils choisis : {}" #, python-brace-format msgid "Environment type: {}" msgstr "Type d'environnement : {}" -msgid "The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues, are you okay with that?" -msgstr "Le pilote Nvidia propriétaire n'est pas pris en charge par Sway. Il est probable que vous rencontriez des problèmes, êtes-vous d'accord avec cela ?" +msgid "" +"The proprietary Nvidia driver is not supported by Sway. It is likely that " +"you will run into issues, are you okay with that?" +msgstr "" +"Le pilote Nvidia propriétaire n'est pas pris en charge par Sway. Il est " +"probable que vous rencontriez des problèmes, êtes-vous d'accord avec cela ?" msgid "Installed packages" msgstr "Paquets installés" @@ -1067,13 +1278,22 @@ msgid "Profile name: " msgstr "Nom de profil : " msgid "The profile name you entered is already in use. Try again" -msgstr "Le nom de profil que vous avez saisi est déjà utilisé. Essayer à nouveau" +msgstr "" +"Le nom de profil que vous avez saisi est déjà utilisé. Essayer à nouveau" -msgid "Packages to be install with this profile (space separated, leave blank to skip): " -msgstr "Saisir les paquets à installer avec ce profil (séparés par des espaces, vide pour ignorer) : " +msgid "" +"Packages to be install with this profile (space separated, leave blank to " +"skip): " +msgstr "" +"Saisir les paquets à installer avec ce profil (séparés par des espaces, vide " +"pour ignorer) : " -msgid "Services to be enabled with this profile (space separated, leave blank to skip): " -msgstr "Saisir les services à activer avec ce profil (séparés par des espaces, vide pour ignorer) : " +msgid "" +"Services to be enabled with this profile (space separated, leave blank to " +"skip): " +msgstr "" +"Saisir les services à activer avec ce profil (séparés par des espaces, vide " +"pour ignorer) : " msgid "Should this profile be enabled for installation?" msgstr "Ce profil doit-il être activé pour l'installation ?" @@ -1086,10 +1306,15 @@ msgid "" "Select a graphics driver or leave blank to install all open-source drivers" msgstr "" "\n" -"Sélectionner un pilote graphique ou laisser vide pour installer tous les pilotes open source" +"Sélectionner un pilote graphique ou laisser vide pour installer tous les " +"pilotes open source" -msgid "Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" -msgstr "Sway a besoin d'accéder à votre espace (ensemble de périphériques matériels : clavier, souris, etc.)" +msgid "" +"Sway needs access to your seat (collection of hardware devices i.e. " +"keyboard, mouse, etc)" +msgstr "" +"Sway a besoin d'accéder à votre espace (ensemble de périphériques " +"matériels : clavier, souris, etc.)" msgid "" "\n" @@ -1119,10 +1344,14 @@ msgid "Profiles" msgstr "Profils" msgid "Finding possible directories to save configuration files ..." -msgstr "Recherche des répertoires possibles pour enregistrer les fichiers de configuration..." +msgstr "" +"Recherche des répertoires possibles pour enregistrer les fichiers de " +"configuration..." msgid "Select directory (or directories) for saving configuration files" -msgstr "Sélectionner le répertoire (ou les répertoires) pour enregistrer les fichiers de configuration" +msgstr "" +"Sélectionner le répertoire (ou les répertoires) pour enregistrer les " +"fichiers de configuration" msgid "Add a custom mirror" msgstr "Ajouter un miroir personnalisé" @@ -1152,13 +1381,16 @@ msgid "Defined" msgstr "Défini" msgid "Save user configuration (including disk layout)" -msgstr "Enregistrer la configuration utilisateur (y compris la disposition du disque)" +msgstr "" +"Enregistrer la configuration utilisateur (y compris la disposition du disque)" msgid "" -"Enter a directory for the configuration(s) to be saved (tab completion enabled)\n" +"Enter a directory for the configuration(s) to be saved (tab completion " +"enabled)\n" "Save directory: " msgstr "" -"Saisir un répertoire pour la/les configuration(s) à enregistrer (complétion par tabulation activée)\n" +"Saisir un répertoire pour la/les configuration(s) à enregistrer (complétion " +"par tabulation activée)\n" "Entrer le nom du répertoire de sauvegarde : " msgid "" @@ -1166,7 +1398,8 @@ msgid "" "\n" "{}" msgstr "" -"Voulez-vous enregistrer {} fichier(s) de configuration à l'emplacement suivant ?\n" +"Voulez-vous enregistrer {} fichier(s) de configuration à l'emplacement " +"suivant ?\n" "\n" "{}" @@ -1179,26 +1412,39 @@ msgstr "Miroirs" msgid "Mirror regions" msgstr "Régions miroir" -msgid " - Maximum value : {} ( Allows {} parallel downloads, allows {max_downloads+1} downloads at a time )" -msgstr " - Valeur maximale : {} (Autorise {} téléchargements parallèles, autorise {max_downloads+1} téléchargements à la fois)" +msgid "" +" - Maximum value : {} ( Allows {} parallel downloads, allows " +"{max_downloads+1} downloads at a time )" +msgstr "" +" - Valeur maximale : {} (Autorise {} téléchargements parallèles, autorise " +"{max_downloads+1} téléchargements à la fois)" msgid "Invalid input! Try again with a valid input [1 to {}, or 0 to disable]" -msgstr "Entrée invalide ! Réessayer avec une entrée valide [1 pour {}, ou 0 pour désactiver]" +msgstr "" +"Entrée invalide ! Réessayer avec une entrée valide [1 pour {}, ou 0 pour " +"désactiver]" msgid "Locales" msgstr "Paramètres régionaux" -msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" -msgstr "Utiliser NetworkManager (nécessaire pour configurer graphiquement internet dans GNOME et KDE)" +msgid "" +"Use NetworkManager (necessary to configure internet graphically in GNOME and " +"KDE)" +msgstr "" +"Utiliser NetworkManager (nécessaire pour configurer graphiquement internet " +"dans GNOME et KDE)" msgid "Total: {} / {}" msgstr "Total (taille) : {} / {}" msgid "All entered values can be suffixed with a unit: B, KB, KiB, MB, MiB..." -msgstr "Toutes les valeurs saisies peuvent être saccompagnées par une unité : B, KB, KiB, MB, MiB..." +msgstr "" +"Toutes les valeurs saisies peuvent être saccompagnées par une unité : B, KB, " +"KiB, MB, MiB..." msgid "If no unit is provided, the value is interpreted as sectors" -msgstr "Si aucune unité n'est fournie, la valeur est interprétée comme des secteurs\"" +msgstr "" +"Si aucune unité n'est fournie, la valeur est interprétée comme des secteurs\"" msgid "Enter start (default: sector {}): " msgstr "Saisir le secteur de début (par défaut : secteur {}) : " @@ -1207,7 +1453,9 @@ msgid "Enter end (default: {}): " msgstr "Saisir le secteur de fin (par défaut : secteur {}) : " msgid "Unable to determine fido2 devices. Is libfido2 installed?" -msgstr "Impossible de déterminer les appareils fido2. Est-ce que libfido2 est installé ?" +msgstr "" +"Impossible de déterminer les appareils fido2. Est-ce que libfido2 est " +"installé ?" msgid "Path" msgstr "Chemin" @@ -1225,8 +1473,12 @@ msgstr "Configuration invalide : {error}" msgid "Type" msgstr "Type" -msgid "This option enables the number of parallel downloads that can occur during package downloads" -msgstr "Cette option active le nombre de téléchargements parallèles pouvant avoir lieu lors des téléchargements des paquets" +msgid "" +"This option enables the number of parallel downloads that can occur during " +"package downloads" +msgstr "" +"Cette option active le nombre de téléchargements parallèles pouvant avoir " +"lieu lors des téléchargements des paquets" msgid "" "Enter the number of parallel downloads to be enabled.\n" @@ -1238,17 +1490,29 @@ msgstr "" "Note :\n" #, python-brace-format -msgid " - Maximum recommended value : {} ( Allows {} parallel downloads at a time )" -msgstr " - Valeur maximale recommandée : {} (Autorise {} téléchargements parallèles à la fois)" +msgid "" +" - Maximum recommended value : {} ( Allows {} parallel downloads at a time )" +msgstr "" +" - Valeur maximale recommandée : {} (Autorise {} téléchargements parallèles " +"à la fois)" -msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\n" -msgstr " - Désactiver/Par défaut : 0 (Désactive le téléchargement parallèle, autorise un seul téléchargement à la fois)\n" +msgid "" +" - Disable/Default : 0 ( Disables parallel downloading, allows only 1 " +"download at a time )\n" +msgstr "" +" - Désactiver/Par défaut : 0 (Désactive le téléchargement parallèle, " +"autorise un seul téléchargement à la fois)\n" msgid "Invalid input! Try again with a valid input [or 0 to disable]" -msgstr "Entrée invalide ! Réessayer avec une entrée valide [ou 0 pour désactiver]" +msgstr "" +"Entrée invalide ! Réessayer avec une entrée valide [ou 0 pour désactiver]" -msgid "Hyprland needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" -msgstr "Hyprland a besoin d'accéder à votre espace (ensemble de périphériques matériels, par exemple clavier, souris, etc)" +msgid "" +"Hyprland needs access to your seat (collection of hardware devices i.e. " +"keyboard, mouse, etc)" +msgstr "" +"Hyprland a besoin d'accéder à votre espace (ensemble de périphériques " +"matériels, par exemple clavier, souris, etc)" msgid "" "\n" @@ -1259,8 +1523,11 @@ msgstr "" "\n" "Choisir une option pour donner à Hyprland l'accès à votre matériel" -msgid "All entered values can be suffixed with a unit: %, B, KB, KiB, MB, MiB..." -msgstr "Toutes les valeurs saisies peuvent être accompagnées par une unité : %, B, KB, KiB, MB, MiB..." +msgid "" +"All entered values can be suffixed with a unit: %, B, KB, KiB, MB, MiB..." +msgstr "" +"Toutes les valeurs saisies peuvent être accompagnées par une unité : %, B, " +"KB, KiB, MB, MiB..." msgid "Would you like to use unified kernel images?" msgstr "Souhaitez-vous utiliser des images de noyau unifiées ?" @@ -1269,28 +1536,50 @@ msgid "Unified kernel images" msgstr "Images du noyau unifiées" msgid "Waiting for time sync (timedatectl show) to complete." -msgstr "En attente de la fin de la synchronisation de l'heure (timedatectl show) de finir." +msgstr "" +"En attente de la fin de la synchronisation de l'heure (timedatectl show) de " +"finir." -msgid "Time syncronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" -msgstr "La synchronisation de l'heure ne se termine pas, veuillez consulter la documentation afin de trouver des solutions de contournement : https://archinstall.readthedocs.io/" +msgid "" +"Time syncronization not completing, while you wait - check the docs for " +"workarounds: https://archinstall.readthedocs.io/" +msgstr "" +"La synchronisation de l'heure ne se termine pas, veuillez consulter la " +"documentation afin de trouver des solutions de contournement : https://" +"archinstall.readthedocs.io/" -msgid "Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)" -msgstr "Ignorer l'attente de la synchronisation automatique de l'heure (cela peut entraîner des problèmes si l'heure n'est pas synchronisée lors de l'installation)" +msgid "" +"Skipping waiting for automatic time sync (this can cause issues if time is " +"out of sync during installation)" +msgstr "" +"Ignorer l'attente de la synchronisation automatique de l'heure (cela peut " +"entraîner des problèmes si l'heure n'est pas synchronisée lors de " +"l'installation)" -msgid "Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete." -msgstr "En attente de la fin de la synchronisation du trousseau de clés d'Arch Linux (archlinux-keyring-wkd-sync) de finir." +msgid "" +"Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete." +msgstr "" +"En attente de la fin de la synchronisation du trousseau de clés d'Arch Linux " +"(archlinux-keyring-wkd-sync) de finir." msgid "Selected profiles: " msgstr "Profils sélectionnés : " -msgid "Time synchronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" -msgstr "La synchronisation de l'heure ne se termine pas, veuillez consulter la documentation afin de trouver des solutions de contournement : https://archinstall.readthedocs.io/" +msgid "" +"Time synchronization not completing, while you wait - check the docs for " +"workarounds: https://archinstall.readthedocs.io/" +msgstr "" +"La synchronisation de l'heure ne se termine pas, veuillez consulter la " +"documentation afin de trouver des solutions de contournement : https://" +"archinstall.readthedocs.io/" msgid "Mark/Unmark as nodatacow" msgstr "Marquer/Démarquer comme nodatacow" msgid "Would you like to use compression or disable CoW?" -msgstr "Souhaitez-vous utiliser la compression ou désactiver la copie à l'écriture (CoW) ?" +msgstr "" +"Souhaitez-vous utiliser la compression ou désactiver la copie à l'écriture " +"(CoW) ?" msgid "Use compression" msgstr "Utiliser la compression" @@ -1298,8 +1587,12 @@ msgstr "Utiliser la compression" msgid "Disable Copy-on-Write" msgstr "Désactiver la copie à l'écriture (CoW)" -msgid "Provides a selection of desktop environments and tiling window managers, e.g. GNOME, KDE Plasma, Sway" -msgstr "Fournit une sélection d'environnements de bureau et de gestionnaires de fenêtres en mosaïque, par ex. GNOME, KDE Plasma, Sway" +msgid "" +"Provides a selection of desktop environments and tiling window managers, " +"e.g. GNOME, KDE Plasma, Sway" +msgstr "" +"Fournit une sélection d'environnements de bureau et de gestionnaires de " +"fenêtres en mosaïque, par ex. GNOME, KDE Plasma, Sway" #, python-brace-format msgid "Configuration type: {}" @@ -1308,11 +1601,18 @@ msgstr "Type de configuration : {}" msgid "LVM configuration type" msgstr "Type de configuration LVM" -msgid "LVM disk encryption with more than 2 partitions is currently not supported" -msgstr "Le chiffrement de disque LVM avec plus de 2 partitions n'est actuellement pas pris en charge" +msgid "" +"LVM disk encryption with more than 2 partitions is currently not supported" +msgstr "" +"Le chiffrement de disque LVM avec plus de 2 partitions n'est actuellement " +"pas pris en charge" -msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE Plasma)" -msgstr "Utiliser NetworkManager (nécessaire pour configurer internet graphiquement dans GNOME et KDE Plasma)" +msgid "" +"Use NetworkManager (necessary to configure internet graphically in GNOME and " +"KDE Plasma)" +msgstr "" +"Utiliser NetworkManager (nécessaire pour configurer internet graphiquement " +"dans GNOME et KDE Plasma)" msgid "Select a LVM option" msgstr "Sélectionner une option LVM" @@ -1381,7 +1681,9 @@ msgid "HSM" msgstr "Gestion hiérarchique du stockage (HSM)" msgid "Enter disk encryption password (leave blank for no encryption)" -msgstr "Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun chiffrement)" +msgstr "" +"Entrer le mot de passe de chiffrement du disque (laisser vide pour aucun " +"chiffrement)" msgid "Disk encryption password" msgstr "Mot de passe de chiffrement du disque" @@ -1413,8 +1715,11 @@ msgstr "Répertoire de montage racine" msgid "Select language" msgstr "Sélectionner la langue" -msgid "Write additional packages to install (space separated, leave blank to skip)" -msgstr "Écrire les paquets supplémentaires à installer (séparés par des espaces, laisser vide pour ignorer)" +msgid "" +"Write additional packages to install (space separated, leave blank to skip)" +msgstr "" +"Écrire les paquets supplémentaires à installer (séparés par des espaces, " +"laisser vide pour ignorer)" msgid "Invalid download number" msgstr "Numéro de téléchargement invalide" @@ -1445,13 +1750,15 @@ msgid "IP address" msgstr "Adresse IP" msgid "Enter your gateway (router) IP address (leave blank for none)" -msgstr "Entrer l'adresse IP de votre passerelle (routeur) (laisser vide pour aucun)" +msgstr "" +"Entrer l'adresse IP de votre passerelle (routeur) (laisser vide pour aucun)" msgid "Gateway address" msgstr "Adresse de passerelle" msgid "Enter your DNS servers with space separated (leave blank for none)" -msgstr "Entrer vos serveurs DNS séparés par des espaces (laisser vide pour aucun)" +msgstr "" +"Entrer vos serveurs DNS séparés par des espaces (laisser vide pour aucun)" msgid "DNS servers" msgstr "Serveurs DNS" @@ -1472,7 +1779,9 @@ msgid "The proprietary Nvidia driver is not supported by Sway." msgstr "Le pilote propriétaire Nvidia n'est pas supporté par Sway." msgid "It is likely that you will run into issues, are you okay with that?" -msgstr "Il est probable que vous rencontriez des problèmes, êtes-vous d'accord avec cela ?" +msgstr "" +"Il est probable que vous rencontriez des problèmes, êtes-vous d'accord avec " +"cela ?" msgid "Main profile" msgstr "Profil principal" @@ -1492,8 +1801,12 @@ msgstr "Voulez-vous continuer ?" msgid "Directory" msgstr "Répertoire" -msgid "Enter a directory for the configuration(s) to be saved (tab completion enabled)" -msgstr "Entrer un répertoire pour que la(les) configuration(s) soit(ent) enregistrée(s) (complétion par tabulation activée)" +msgid "" +"Enter a directory for the configuration(s) to be saved (tab completion " +"enabled)" +msgstr "" +"Entrer un répertoire pour que la(les) configuration(s) soit(ent) " +"enregistrée(s) (complétion par tabulation activée)" #, python-brace-format msgid "Do you want to save the configuration file(s) to {}?" @@ -1505,8 +1818,12 @@ msgstr "Activé" msgid "Disabled" msgstr "Désactivé" -msgid "Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" -msgstr "Veuillez soumettre ce problème (et fichier) à https://github.com/archlinux/archinstall/issues" +msgid "" +"Please submit this issue (and file) to https://github.com/archlinux/" +"archinstall/issues" +msgstr "" +"Veuillez soumettre ce problème (et fichier) à https://github.com/archlinux/" +"archinstall/issues" msgid "Mirror name" msgstr "Nom du miroir" @@ -1574,8 +1891,10 @@ msgstr "Marquer/Démarquer comme XBOOTLDR" msgid "Loading packages..." msgstr "Chargement des paquets..." -msgid "Select any packages from the below list that should be installed additionally" -msgstr "Sélectionner les paquets à installer en supplément dans la liste ci-dessous" +msgid "" +"Select any packages from the below list that should be installed additionally" +msgstr "" +"Sélectionner les paquets à installer en supplément dans la liste ci-dessous" msgid "Add a custom repository" msgstr "Ajouter un dépôt personnalisé" @@ -1629,7 +1948,7 @@ msgid "Only ASCII characters are supported" msgstr "Seuls les caractères ASCII sont pris en charge" msgid "Show help" -msgstr "Afficher de l'aide" +msgstr "Afficher l’aide" msgid "Exit help" msgstr "Quitter l’aide" @@ -1680,146 +1999,138 @@ msgid "Exit search mode" msgstr "Quitter le mode de recherche" msgid "General" -msgstr "" +msgstr "Général" -#, fuzzy msgid "Navigation" -msgstr "Enregistrer la configuration" +msgstr "Navigation" -#, fuzzy msgid "Selection" -msgstr "Sélectionner des régions" +msgstr "Sélection" msgid "Search" -msgstr "" +msgstr "Rechercher" msgid "Down" -msgstr "" +msgstr "Bas" msgid "Up" -msgstr "" +msgstr "Haut" -#, fuzzy msgid "Confirm" -msgstr "Confirmer et quitter" +msgstr "Confirmer" -#, fuzzy msgid "Focus right" -msgstr "Déplacer vers la droite" +msgstr "Focus à droite" -#, fuzzy msgid "Focus left" -msgstr "Déplacer vers la gauche" +msgstr "Focus à gauche" msgid "Toggle" -msgstr "" +msgstr "Basculer" -#, fuzzy msgid "Show/Hide help" -msgstr "Afficher de l'aide" +msgstr "Afficher/Masquer l’aide" msgid "Quit" -msgstr "" +msgstr "Quitter" msgid "First" -msgstr "" +msgstr "Premier" msgid "Last" -msgstr "" +msgstr "Dernier" -#, fuzzy msgid "Select" -msgstr "Sélectionner des régions" +msgstr "Sélectionner" msgid "Page Up" -msgstr "" +msgstr "Page précédente" msgid "Page Down" -msgstr "" +msgstr "Page suivante" -#, fuzzy msgid "Page up" -msgstr "Groupe de paquets :" +msgstr "Page précédente" -#, fuzzy msgid "Page down" -msgstr "Déplacer vers le bas" +msgstr "Page suivante" msgid "Page Left" -msgstr "" +msgstr "Page à gauche" -#, fuzzy msgid "Page Right" -msgstr "Déplacer vers la droite" +msgstr "Page à droite" msgid "Cursor up" -msgstr "" +msgstr "Curseur vers le haut" -#, fuzzy msgid "Cursor down" -msgstr "Déplacer vers le bas" +msgstr "Curseur vers le bas" -#, fuzzy msgid "Cursor right" -msgstr "Déplacer vers la droite" +msgstr "Curseur vers la droite" -#, fuzzy msgid "Cursor left" -msgstr "Déplacer vers la gauche" +msgstr "Curseur vers la gauche" msgid "Top" -msgstr "" +msgstr "Haut" msgid "Bottom" -msgstr "" +msgstr "Bas" msgid "Home" -msgstr "" +msgstr "Début" -#, fuzzy msgid "End" -msgstr "Activé" +msgstr "Fin" -#, fuzzy msgid "Toggle option" -msgstr "Options de sous-volume" +msgstr "Basculer l’option" msgid "Scroll Up" -msgstr "" +msgstr "Défilement vers le haut" -#, fuzzy msgid "Scroll Down" -msgstr "Faire défiler l’aperçu vers le bas" +msgstr "Défilement vers le bas" msgid "Scroll Left" -msgstr "" +msgstr "Défilement vers la gauche" msgid "Scroll Right" -msgstr "" +msgstr "Défilement vers la droite" msgid "Scroll Home" -msgstr "" +msgstr "Défilement au début" msgid "Scroll End" -msgstr "" +msgstr "Défilement à la fin" msgid "Focus Next" -msgstr "" +msgstr "Élément suivant (focus)" msgid "Focus Previous" -msgstr "" +msgstr "Élément précédent (focus)" msgid "Copy selected text" -msgstr "" +msgstr "Copier le texte sélectionné" -msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" -msgstr "labwc a besoin d’accéder à votre siège (ensemble d’appareils matériels, c’est-à-dire clavier, souris, etc.)" +msgid "" +"labwc needs access to your seat (collection of hardware devices i.e. " +"keyboard, mouse, etc)" +msgstr "" +"labwc a besoin d’accéder à votre siège (ensemble d’appareils matériels, " +"c’est-à-dire clavier, souris, etc.)" msgid "Choose an option to give labwc access to your hardware" msgstr "Choisir une option pour donner à labwc l’accès à votre matériel" -msgid "niri needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" -msgstr "niri a besoin d’accéder à vos périphériques (ensemble d’appareils matériels, c’est-à-dire clavier, souris, etc.)" +msgid "" +"niri needs access to your seat (collection of hardware devices i.e. " +"keyboard, mouse, etc)" +msgstr "" +"niri a besoin d’accéder à vos périphériques (ensemble d’appareils matériels, " +"c’est-à-dire clavier, souris, etc.)" msgid "Choose an option to give niri access to your hardware" msgstr "Choisir une option pour donner à niri l’accès à votre matériel" @@ -1830,58 +2141,49 @@ msgstr "Marquer/Démarquer comme ESP" msgid "Package group:" msgstr "Groupe de paquets :" -#, fuzzy msgid "Exit archinstall" -msgstr "Sortir d'Archinstall" +msgstr "Quitter archinstall" -#, fuzzy msgid "Reboot system" msgstr "Redémarrer le système" -#, fuzzy msgid "chroot into installation for post-installation configurations" -msgstr "Souhaitez-vous chrooter dans l'installation nouvellement créée et effectuer la configuration post-installation ?" +msgstr "" +"Entrer en chroot dans l’installation pour effectuer les configurations post-" +"installation" msgid "Installation completed" -msgstr "Installation complétée" +msgstr "Installation terminée" -#, fuzzy msgid "What would you like to do next?" -msgstr "Voulez-vous continuer ?" +msgstr "Quelle action souhaitez-vous effectuer ensuite ?" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Select which mode to configure for \"{}\"" -msgstr "Sélectionner le mode à configurer pour \"{}\" ou ignorer pour utiliser le mode par défaut \"{}\"" +msgstr "Sélectionner le mode à configurer pour \"{}\"" -#, fuzzy msgid "Incorrect credentials file decryption password" -msgstr "Mot de passe de déchiffrement du disque" +msgstr "Mot de passe de déchiffrement du fichier d’identifiants incorrect" -#, fuzzy msgid "Incorrect password" msgstr "Mot de passe incorrect" -#, fuzzy msgid "Credentials file decryption password" -msgstr "Mot de passe de déchiffrement du disque" +msgstr "Mot de passe de déchiffrement du fichier d’identifiants" -#, fuzzy msgid "Do you want to encrypt the user_credentials.json file?" -msgstr "Voulez-vous enregistrer le(s) fichier(s) de configuration dans {} ?" +msgstr "Voulez-vous chiffrer le fichier user_credentials.json ?" -#, fuzzy msgid "Credentials file encryption password" -msgstr "Mot de passe de l'encryption du disque" +msgstr "Mot de passe de chiffrement du fichier d’identifiants" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Repositories: {}" -msgstr "Nom du dépôt" +msgstr "Dépôts : {}" -#, fuzzy msgid "New version available" msgstr "Nouvelle version disponible" -#, fuzzy msgid "Passwordless login" msgstr "Connexion sans mot de passe" @@ -1891,20 +2193,17 @@ msgstr "Connexion à deux facteurs" msgid "Bluetooth" msgstr "Bluetooth" -#, fuzzy msgid "Would you like to configure Bluetooth?" -msgstr "Voulez-vous configurer le Bluetooth ?" +msgstr "Souhaitez-vous configurer le Bluetooth ?" msgid "Print service" -msgstr "" +msgstr "Service d’impression" -#, fuzzy msgid "Would you like to configure the print service?" -msgstr "Voulez-vous configurer le Bluetooth ?" +msgstr "Souhaitez-vous configurer le service d’impression ?" -#, fuzzy msgid "Power management" -msgstr "Gestion des partitions : {}" +msgstr "Gestion de l’alimentation" msgid "Authentication" msgstr "Authentification" @@ -1913,7 +2212,7 @@ msgid "Applications" msgstr "Applications" msgid "U2F login method: " -msgstr "Méthode\tde connexion U2F : " +msgstr "Méthode de connexion U2F : " msgid "Passwordless sudo: " msgstr "Sudo sans mot de passe : " @@ -1925,14 +2224,13 @@ msgstr "Type de\tsnapshot Btrfs : {}" msgid "Syncing the system..." msgstr "Synchronisation du système..." -#, fuzzy msgid "Value cannot be empty" msgstr "La valeur ne peut pas être vide" msgid "Snapshot type" msgstr "Type de snapshot" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Snapshot type: {}" msgstr "Type de snapshot : {}" @@ -1945,335 +2243,328 @@ msgstr "Pas de périphériques U2F trouvés" msgid "U2F Login Method" msgstr "Méthode de connexion U2F" -#, fuzzy msgid "Enable passwordless sudo?" msgstr "Activer sudo sans mot de passe ?" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Setting up U2F device for user: {}" -msgstr "Configuration du périphérique U2F pour l'utilisateur : {}" +msgstr "Configuration d’un périphérique U2F pour l’utilisateur : {}" -msgid "You may need to enter the PIN and then touch your U2F device to register it" -msgstr "Vous devez peut-être entrer le code PIN, puis toucher votre périphérique U2F pour l'enregistrer" +msgid "" +"You may need to enter the PIN and then touch your U2F device to register it" +msgstr "" +"Vous devez peut-être entrer le code PIN, puis toucher votre périphérique U2F " +"pour l'enregistrer" msgid "Starting device modifications in " -msgstr "" +msgstr "Démarrage des modifications du périphérique dans " -#, fuzzy msgid "No network connection found" -msgstr "Aucune configuration réseau" +msgstr "Aucune connexion réseau détectée" -#, fuzzy msgid "Would you like to connect to a Wifi?" -msgstr "Voulez-vous continuer ?" +msgstr "Souhaitez-vous vous connecter à un réseau Wi-Fi ?" -#, fuzzy msgid "No wifi interface found" -msgstr "Configurer les interfaces" +msgstr "Aucune interface Wi-Fi détectée" -#, fuzzy msgid "Select wifi network to connect to" -msgstr "Sélectionner une interface réseau à configurer" +msgstr "Sélectionner le réseau Wi-Fi auquel vous connecter" msgid "Scanning wifi networks..." -msgstr "" +msgstr "Recherche des réseaux Wi-Fi..." -#, fuzzy msgid "No wifi networks found" -msgstr "Aucune configuration réseau" +msgstr "Aucun réseau Wi-Fi trouvé" msgid "Failed setting up wifi" -msgstr "" +msgstr "Échec de la configuration du Wi-Fi" -#, fuzzy msgid "Enter wifi password" -msgstr "Entrer un mot de passe : " +msgstr "Entrer le mot de passe Wi-Fi" msgid "Ok" -msgstr "" +msgstr "Ok" msgid "Removable" -msgstr "" +msgstr "Amovible" msgid "Install to removable location" -msgstr "" +msgstr "Installer sur un support amovible" msgid "Will install to /EFI/BOOT/ (removable location)" -msgstr "" +msgstr "Installation dans /EFI/BOOT/ (emplacement amovible)" msgid "Will install to standard location with NVRAM entry" -msgstr "" +msgstr "Installation dans l’emplacement standard avec entrée NVRAM" -msgid "Would you like to install the bootloader to the default removable media search location?" +msgid "" +"Would you like to install the bootloader to the default removable media " +"search location?" msgstr "" +"Souhaitez-vous installer le chargeur d’amorçage dans l’emplacement de " +"recherche par défaut des supports amovibles ?" -msgid "This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is useful for:" +msgid "" +"This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is " +"useful for:" msgstr "" +"Cela installe le chargeur d’amorçage dans /EFI/BOOT/BOOTX64.EFI (ou " +"équivalent), ce qui est utile pour :" msgid "USB drives or other portable external media." -msgstr "" +msgstr "Clés USB ou autres supports externes portables." msgid "Systems where you want the disk to be bootable on any computer." msgstr "" +"Systèmes où vous souhaitez que le disque soit amorçable sur n’importe quel " +"ordinateur." msgid "Firmware that does not properly support NVRAM boot entries." msgstr "" +"Firmware ne prenant pas correctement en charge les entrées de démarrage " +"NVRAM." msgid "Will install to /EFI/BOOT/ (removable location, safe default)" msgstr "" +"Installation dans /EFI/BOOT/ (emplacement amovible, option sûre par défaut)" msgid "Will install to custom location with NVRAM entry" -msgstr "" +msgstr "Installation dans un emplacement personnalisé avec entrée NVRAM" -msgid "Firmware that does not properly support NVRAM boot entries like most MSI motherboards," +msgid "" +"Firmware that does not properly support NVRAM boot entries like most MSI " +"motherboards," msgstr "" +"Firmware ne prenant pas correctement en charge les entrées de démarrage " +"NVRAM, comme la plupart des cartes mères MSI, " msgid "most Apple Macs, many laptops..." -msgstr "" +msgstr "la plupart des Mac Apple, de nombreux ordinateurs portables…" -#, fuzzy msgid "Language" -msgstr "Langue locale" +msgstr "Langue" msgid "Compression algorithm" +msgstr "Algorithme de compression" + +msgid "" +"Only packages such as base, sudo, linux, linux-firmware, efibootmgr and " +"optional profile packages are installed." msgstr "" +"Seuls des paquets tels que base, sudo, linux, linux-firmware, efibootmgr et " +"les paquets de profil optionnels sont installés." -#, fuzzy -msgid "Only packages such as base, sudo, linux, linux-firmware, efibootmgr and optional profile packages are installed." -msgstr "Seuls les paquets tels que base, base-devel, linux, linux-firmware, efibootmgr et les paquets de profil optionnels sont installés." - -#, fuzzy msgid "Select zram compression algorithm:" -msgstr "Sélectionner un point de montage :" +msgstr "Sélectionner l’algorithme de compression zram :" msgid "Use Network Manager (default backend)" -msgstr "" +msgstr "Utiliser Network Manager (backend par défaut)" msgid "Use Network Manager (iwd backend)" -msgstr "" +msgstr "Utiliser Network Manager (backend iwd)" msgid "Firewall" -msgstr "" +msgstr "Pare-feu" -#, fuzzy msgid "Additional fonts" -msgstr "Dépôts supplémentaires" +msgstr "Polices supplémentaires" -#, fuzzy msgid "Select font packages to install" -msgstr "Veuillez choisir le greeter (interface de connexion) à installer" +msgstr "Sélectionner les paquets de polices à installer" msgid "Unicode font coverage for most languages" -msgstr "" +msgstr "Couverture Unicode des polices pour la plupart des langues" msgid "color emoji for browsers and apps" -msgstr "" +msgstr "émojis en couleur pour les navigateurs et les applications" msgid "Chinese, Japanese, Korean characters" -msgstr "" +msgstr "Caractères chinois, japonais et coréens" -#, fuzzy msgid "Select audio configuration" -msgstr "Enregistrer la configuration utilisateur" +msgstr "Sélectionner la configuration audio" -#, fuzzy msgid "Enter credentials file decryption password" -msgstr "Mot de passe de déchiffrement du disque" +msgstr "Entrer le mot de passe de déchiffrement du fichier d’identifiants" -#, fuzzy msgid "Enter root password" -msgstr "Entrer un mot de passe : " +msgstr "Entrer le mot de passe root" msgid "Select bootloader to install" -msgstr "" +msgstr "Sélectionner le chargeur d’amorçage à installer" -#, fuzzy msgid "Configuration preview" -msgstr "Configuration" +msgstr "Aperçu de la configuration" -#, fuzzy msgid "Enter a directory for the configuration(s) to be saved" -msgstr "Saisir un répertoire pour la ou les configuration(s) à enregistrer : " +msgstr "Entrer un répertoire pour enregistrer la ou les configurations" -#, fuzzy msgid "Select encryption type" -msgstr "Type de chiffrement" +msgstr "Sélectionner le type de chiffrement" -#, fuzzy msgid "Select disks for the installation" -msgstr "Nom d'hôte souhaité pour l'installation : " +msgstr "Sélectionner les disques pour l’installation" -#, fuzzy msgid "Enter a mountpoint" -msgstr "Sélectionner un point de montage :" +msgstr "Entrer un point de montage" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Enter a size (default: {}): " -msgstr "Saisir le secteur de fin (par défaut : secteur {}) : " +msgstr "Entrer une taille (par défaut : {}) : " -#, fuzzy msgid "Enter subvolume name" -msgstr "Nom du sous-volume" +msgstr "Entrer le nom du sous-volume" -#, fuzzy msgid "Enter subvolume mountpoint" -msgstr "Point de montage du sous-volume" +msgstr "Entrer le point de montage du sous-volume" -#, fuzzy msgid "Select a disk configuration" -msgstr "Configuration du disque" +msgstr "Sélectionner une configuration de disque" -#, fuzzy msgid "Enter root mount directory" -msgstr "Répertoire de montage racine" +msgstr "Entrer le répertoire de montage racine" msgid "You will use whatever drive-setup is mounted at the specified directory" msgstr "" +"Vous utiliserez toute configuration de disque montée dans le répertoire " +"spécifié" msgid "WARNING: Archinstall won't check the suitability of this setup" msgstr "" +"AVERTISSEMENT : Archinstall ne vérifiera pas la compatibilité de cette " +"configuration" -#, fuzzy msgid "Select main filesystem" -msgstr "Changer le système de fichiers" +msgstr "Sélectionner le système de fichiers principal" msgid "Enter a hostname" -msgstr "" +msgstr "Entrer un nom d’hôte" -#, fuzzy msgid "Select timezone" -msgstr "Sélectionner un fuseau horaire" +msgstr "Sélectionner le fuseau horaire" -#, fuzzy msgid "Enter the number of parallel downloads to be enabled" -msgstr "" -"Saisir le nombre de téléchargements parallèles à activer.\n" -"\n" -"Note :\n" +msgstr "Entrer le nombre de téléchargements simultanés à activer" #, python-brace-format msgid "Value must be between 1 and {}" -msgstr "" +msgstr "La valeur doit être comprise entre 1 et {}" -#, fuzzy msgid "Select which kernel(s) to install" -msgstr "Veuillez choisir le greeter (interface de connexion) à installer" +msgstr "Sélectionner le ou les noyaux à installer" -#, fuzzy msgid "Enter a respository name" -msgstr "Nom du dépôt" +msgstr "Entrer un nom de dépôt" -#, fuzzy msgid "Enter the repository url" -msgstr "Modifier le dépôt personnalisé" +msgstr "Entrer l’URL du dépôt" -#, fuzzy msgid "Enter server url" -msgstr "URL du serveur" +msgstr "Entrer l’URL du serveur" -#, fuzzy msgid "Select mirror regions to be enabled" -msgstr "Régions de miroirs sélectionnées" +msgstr "Sélectionner les régions de miroirs à activer" -#, fuzzy msgid "Select optional repositories to be enabled" -msgstr "Choisir les dépôts supplémentaires en option à activer" +msgstr "Sélectionner les dépôts optionnels à activer" -#, fuzzy msgid "Select an interface" -msgstr "Supprimer l'interface" +msgstr "Sélectionner une interface" -#, fuzzy msgid "Choose network configuration" -msgstr "Aucune configuration réseau" +msgstr "Choisir la configuration réseau" -#, fuzzy msgid "No packages found" -msgstr "Pas de périphériques U2F trouvés" +msgstr "Aucun paquet trouvé" -#, fuzzy msgid "Select which greeter to install" -msgstr "Veuillez choisir le greeter (interface de connexion) à installer" +msgstr "Sélectionner le gestionnaire d’accueil à installer" -#, fuzzy msgid "Select a profile type" -msgstr "Profils sélectionnés : " +msgstr "Sélectionner un type de profil" -#, fuzzy msgid "Enter new password" -msgstr "Entrer un mot de passe : " +msgstr "Entrer un nouveau mot de passe" msgid "Enter a username" -msgstr "" +msgstr "Entrer un nom d’utilisateur" -#, fuzzy msgid "Enter a password" -msgstr "Entrer un mot de passe : " +msgstr "Entrer un mot de passe" -#, fuzzy msgid "The password did not match, please try again" -msgstr "Le mot de passe de confirmation ne correspond pas, veuillez réessayer" +msgstr "Les mots de passe ne correspondent pas, veuillez réessayer" msgid "Password strength: Weak" -msgstr "" +msgstr "Force du mot de passe : Faible" msgid "Password strength: Moderate" -msgstr "" +msgstr "Force du mot de passe : Modéré" msgid "Password strength: Strong" -msgstr "" +msgstr "Force du mot de passe : Fort" -msgid "The selected desktop profile requires a regular user to log in via the greeter" +msgid "" +"The selected desktop profile requires a regular user to log in via the " +"greeter" msgstr "" +"Le profil de bureau sélectionné nécessite qu’un utilisateur standard se " +"connecte via le gestionnaire d’accueil" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment type: {} {}" -msgstr "Type d'environnement : {}" +msgstr "Type d’environnement : {} {}" -#, fuzzy msgid "Input cannot be empty" -msgstr "La valeur ne peut pas être vide" +msgstr "La saisie ne peut pas être vide" msgid "Recommended" -msgstr "" +msgstr "Recommandé" -#, fuzzy msgid "Package" -msgstr "Groupe de paquets :" +msgstr "Groupe de paquets" msgid "Curated selection of KDE Plasma packages" -msgstr "" +msgstr "Sélection de paquets KDE Plasma soigneusement choisie" msgid "Dependencies" -msgstr "" +msgstr "Dépendances" -#, fuzzy msgid "Package group" -msgstr "Groupe de paquets :" +msgstr "Groupe de paquets" msgid "Extensive KDE Plasma installation" -msgstr "" +msgstr "Installation complète de KDE Plasma" -#, fuzzy msgid "Packages in group" -msgstr "Groupe de paquets :" +msgstr "Paquets dans le groupe" msgid "Minimal KDE Plasma installation" -msgstr "" +msgstr "Installation minimale de KDE Plasma" -#, fuzzy msgid "Description" -msgstr "Chiffrement du disque" +msgstr "Description" -#, fuzzy msgid "Select a flavor of KDE Plasma to install" -msgstr "Veuillez choisir le greeter (interface de connexion) à installer" +msgstr "Sélectionner une variante de KDE Plasma à installer" msgid "Arial/Times/Courier replacement, Cyrillic support for Steam/games" msgstr "" +"Remplacement d’Arial/Times/Courier, prise en charge du cyrillique pour Steam/" +"jeux" msgid "wide Unicode coverage, good fallback font" +msgstr "large prise en charge Unicode, bonne police de secours" + +#, python-brace-format +msgid "Setting up U2F login: {u2f_config.u2f_login_method.value}" msgstr "" +"Mise en place de la connexion U2F : {u2f_config.u2f_login_method.value}" + +#, python-brace-format +msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" +msgstr "Par défaut : {DEFAULT_ITER_TIME} ms, plage recommandée : 1000–60000" #, python-brace-format #~ msgid "Edit {origkey} :" From bb46e295d1483060e36db3b0b50e9d3635c813f9 Mon Sep 17 00:00:00 2001 From: Softer Date: Fri, 24 Apr 2026 13:19:01 +0300 Subject: [PATCH 10/40] Fix OVMF paths in README QEMU examples (#4472) All three qemu-system-x86_64 examples in README pointed both -drive if=pflash entries at the same file (/usr/share/ovmf/x64/OVMF.4m.fd). OVMF needs CODE for the first pflash and VARS for the second; as written, EFI NVRAM is not initialized correctly. The path /usr/share/ovmf/x64/ is also stale - the ovmf package has been replaced by edk2-ovmf, which installs under /usr/share/edk2/x64/. Fix both in the three examples (testimage loop section, base Boot ISO block, espeakup variant). --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 1447c263..75631b6b 100644 --- a/README.md +++ b/README.md @@ -179,7 +179,7 @@ This can be done by installing `pacman -S arch-install-scripts util-linux` local # losetup --partscan --show ./testimage.img # pip install --upgrade archinstall # python -m archinstall --script guided - # qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host -m 4096 -boot order=d -drive file=./testimage.img,format=raw -drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd -drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd + # qemu-system-x86_64 -enable-kvm -machine q35,accel=kvm -device intel-iommu -cpu host -m 4096 -boot order=d -drive file=./testimage.img,format=raw -drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd -drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_VARS.4m.fd This will create a *20 GB* `testimage.img` and create a loop device which we can use to format and install to.
`archinstall` is installed and executed in [guided mode](#docs-todo). Once the installation is complete, ~~you can use qemu/kvm to boot the test media.~~
@@ -199,8 +199,8 @@ You may want to boot an ISO image in a VM to test `archinstall` in there. qemu-system-x86_64 -enable-kvm \ -machine q35,accel=kvm -device intel-iommu \ -cpu host -m 4096 -boot order=d \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ +-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \ +-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_VARS.4m.fd \ -drive file=./archlinux-2025.12.01-x86_64.iso,format=raw ``` @@ -209,8 +209,8 @@ HINT: For espeakup support qemu-system-x86_64 -enable-kvm \ -machine q35,accel=kvm -device intel-iommu \ -cpu host -m 4096 -boot order=d \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ --drive if=pflash,format=raw,readonly,file=/usr/share/ovmf/x64/OVMF.4m.fd \ +-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_CODE.4m.fd \ +-drive if=pflash,format=raw,readonly,file=/usr/share/edk2/x64/OVMF_VARS.4m.fd \ -drive file=./archlinux-2025.12.01-x86_64.iso,format=raw \ -device intel-hda -device hda-duplex,audiodev=snd0 \ -audiodev pa,id=snd0,server=/run/user/1000/pulse/native From c8e5c85e20db591617cee0fce173b259b213acd6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 18:35:31 +1000 Subject: [PATCH 11/40] Update dependency ruff to v0.15.12 (#4476) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dd42c642..5d34f793 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -37,7 +37,7 @@ dev = [ "mypy==1.20.2", "flake8==7.3.0", "pre-commit==4.6.0", - "ruff==0.15.11", + "ruff==0.15.12", "pylint==4.0.5", "pytest==9.0.3", ] From efda78cad5a076ac1a39695c82a8ab93ed7c9342 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 18:36:10 +1000 Subject: [PATCH 12/40] Update pre-commit hook astral-sh/ruff-pre-commit to v0.15.12 (#4477) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index a496557e..7ee79056 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ default_stages: ['pre-commit'] repos: - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.11 + rev: v0.15.12 hooks: # fix unused imports and sort them - id: ruff From 3c4c87bdd6e05d246da2762d91983d9fa1ff0bda Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Sun, 26 Apr 2026 19:03:16 +1000 Subject: [PATCH 13/40] Update dependency arch/python-cryptography to v47 (#4478) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5d34f793..95d85144 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ classifiers = [ dependencies = [ "pyparted==3.13.0", "pydantic==2.12.5", - "cryptography==46.0.7", + "cryptography==47.0.0", "textual==8.2.4", "markdown-it-py==4.0.0", "linkify-it-py==2.1.0", From d836ab0a6690c13a6d7a97f62e30837a2873b864 Mon Sep 17 00:00:00 2001 From: Softer Date: Sun, 26 Apr 2026 12:14:23 +0300 Subject: [PATCH 14/40] Extend validate_bootloader_layout with UEFI-dependent checks (#4474) * Extend validate_bootloader_layout with UEFI-dependent checks Add is_uefi parameter and three new validations: Systemd-boot, Efistub and rEFInd require UEFI; Efistub additionally requires a FAT boot partition. Move the rEFInd UEFI-only check out of GlobalMenu so guided.py and Installer silent-install paths get the same coverage. * Encapsulate UEFI-only flag in Bootloader enum Replace module-level _UEFI_ONLY_BOOTLOADERS tuple with an is_uefi_only() method on the Bootloader enum, mirroring the existing has_uki_support() / has_removable_support() pattern. * Drop is_uefi parameter from validate_bootloader_layout The UEFI flag is a constant system fact for the run, so the validator retrieves it via SysInfo.has_uefi() directly instead of having every caller pass it in. Updates all three call sites in global_menu.py, installer.py and guided.py, and removes the now-unused SysInfo import from guided.py. --- archinstall/lib/bootloader/utils.py | 31 ++++++++++++++++++++++++---- archinstall/lib/global_menu.py | 5 ----- archinstall/lib/models/bootloader.py | 7 +++++++ 3 files changed, 34 insertions(+), 9 deletions(-) diff --git a/archinstall/lib/bootloader/utils.py b/archinstall/lib/bootloader/utils.py index a732f4e1..ed761722 100644 --- a/archinstall/lib/bootloader/utils.py +++ b/archinstall/lib/bootloader/utils.py @@ -2,6 +2,7 @@ from dataclasses import dataclass from enum import Enum, auto from pathlib import Path +from archinstall.lib.hardware import SysInfo from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration from archinstall.lib.models.device import DiskLayoutConfiguration @@ -9,6 +10,8 @@ from archinstall.lib.models.device import DiskLayoutConfiguration class BootloaderValidationFailureKind(Enum): LimineNonFatBoot = auto() LimineLayout = auto() + BootloaderRequiresUefi = auto() + EfistubNonFatBoot = auto() @dataclass(frozen=True) @@ -29,12 +32,32 @@ def validate_bootloader_layout( if not (bootloader_config and disk_config): return None - if bootloader_config.bootloader == Bootloader.Limine: - boot_part = next( - (p for m in disk_config.device_modifications if (p := m.get_boot_partition())), - None, + bootloader = bootloader_config.bootloader + + if bootloader == Bootloader.NO_BOOTLOADER: + return None + + if bootloader.is_uefi_only() and not SysInfo.has_uefi(): + return BootloaderValidationFailure( + kind=BootloaderValidationFailureKind.BootloaderRequiresUefi, + description=f'{bootloader.value} requires a UEFI system.', ) + boot_part = next( + (p for m in disk_config.device_modifications if (p := m.get_boot_partition())), + None, + ) + + if bootloader == Bootloader.Efistub: + # The UEFI firmware reads the kernel directly from the boot partition, + # which must be FAT. + if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()): + return BootloaderValidationFailure( + kind=BootloaderValidationFailureKind.EfistubNonFatBoot, + description='Efistub does not support booting with a non-FAT boot partition.', + ) + + if bootloader == Bootloader.Limine: # Limine reads its config and kernels from the boot partition, which # must be FAT. if boot_part and (boot_part.fs_type is None or not boot_part.fs_type.is_fat()): diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index 3d94f31e..e327b388 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -461,8 +461,6 @@ class GlobalMenu(AbstractMenu[None]): if not bootloader_config or bootloader_config.bootloader == Bootloader.NO_BOOTLOADER: return None - bootloader = bootloader_config.bootloader - if disk_config := self._item_group.find_by_key('disk_config').value: for layout in disk_config.device_modifications: if root_partition := layout.get_root_partition(): @@ -490,9 +488,6 @@ class GlobalMenu(AbstractMenu[None]): if efi_partition.fs_type is None or not efi_partition.fs_type.is_fat(): return 'ESP must be formatted as a FAT filesystem' - if bootloader == Bootloader.Refind and not self._uefi: - return 'rEFInd can only be used on UEFI systems' - if failure := validate_bootloader_layout(bootloader_config, disk_config): return failure.description diff --git a/archinstall/lib/models/bootloader.py b/archinstall/lib/models/bootloader.py index 68c0bf98..5d8d0d80 100644 --- a/archinstall/lib/models/bootloader.py +++ b/archinstall/lib/models/bootloader.py @@ -25,6 +25,13 @@ class Bootloader(Enum): case _: return False + def is_uefi_only(self) -> bool: + match self: + case Bootloader.Systemd | Bootloader.Efistub | Bootloader.Refind: + return True + case _: + return False + def json(self) -> str: return self.value From 9e05260df55ed3a2ad3a3546521919317dda94c5 Mon Sep 17 00:00:00 2001 From: Softer Date: Mon, 27 Apr 2026 02:24:51 +0300 Subject: [PATCH 15/40] Fix argv injection in _create_user and gpasswd loop (#4473) * Fix argv injection in _create_user and gpasswd loop Use argv list with run() instead of f-string interpolation into SysCommand, add debug logging on failure. * Extract _chroot_argv helper and harden user/file ops Address svartkanin's review on #4473: factor the ['arch-chroot', '-S', str(self.target), ...] boilerplate into a private Installer._chroot_argv() helper, and migrate the seven existing argv-form call sites to it (useradd, gpasswd, chpasswd, chsh, chown, snapper-create-config, grub-install). Two related hardening tweaks while in the area: - Raise gpasswd failure log from debug() to warn(). The group-add loop has no return-False feedback channel for the caller, so a silent debug() means a half-configured user looks like a successful install. - Add `--` end-of-options separator for useradd and chown so a username or path starting with `-` cannot smuggle flags. The TUI validates usernames, but parse_arguments() in models/users.py does not, so config.json is the residual hole; this closes it for these two sites at zero cost. --- archinstall/lib/installer.py | 46 +++++++++++++++--------------------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 19560d75..e596f7fe 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -739,6 +739,9 @@ class Installer: return self.run_command(cmd, peek_output=peek_output) + def _chroot_argv(self, *args: str) -> list[str]: + return ['arch-chroot', '-S', str(self.target), *args] + def drop_to_shell(self) -> None: subprocess.check_call(f'arch-chroot {self.target}', shell=True) @@ -987,17 +990,7 @@ class Installer: } for config_name, mountpoint in snapper.items(): - command = [ - 'arch-chroot', - '-S', - str(self.target), - 'snapper', - '--no-dbus', - '-c', - config_name, - 'create-config', - mountpoint, - ] + command = self._chroot_argv('snapper', '--no-dbus', '-c', config_name, 'create-config', mountpoint) try: SysCommand(command, peek_output=True) @@ -1336,13 +1329,7 @@ class Installer: boot_dir = Path('/boot') - command = [ - 'arch-chroot', - '-S', - str(self.target), - 'grub-install', - '--debug', - ] + command = self._chroot_argv('grub-install', '--debug') if SysInfo.has_uefi(): if not efi_partition: @@ -1922,16 +1909,17 @@ class Installer: if not handled_by_plugin: info(f'Creating user {user.username}') - cmd = 'useradd -m' + cmd = self._chroot_argv('useradd', '-m') if user.sudo: - cmd += ' -G wheel' + cmd += ['-G', 'wheel'] - cmd += f' {user.username}' + cmd += ['--', user.username] try: - self.arch_chroot(cmd) - except SysCallError as err: + run(cmd) + except CalledProcessError as err: + debug(f'Error creating user {user.username}: {err}') raise SystemError(f'Could not create user inside installation: {err}') for plugin in plugins.values(): @@ -1942,7 +1930,11 @@ class Installer: self.set_user_password(user) for group in user.groups: - self.arch_chroot(f'gpasswd -a {user.username} {group}') + cmd = self._chroot_argv('gpasswd', '-a', user.username, group) + try: + run(cmd) + except CalledProcessError as err: + warn(f'Failed to add {user.username} to group {group}: {err}') if user.sudo: self.enable_sudo(user) @@ -1957,7 +1949,7 @@ class Installer: return False input_data = f'{user.username}:{enc_password}'.encode() - cmd = ['arch-chroot', '-S', str(self.target), 'chpasswd', '--encrypted'] + cmd = self._chroot_argv('chpasswd', '--encrypted') try: run(cmd, input_data=input_data) @@ -1969,7 +1961,7 @@ class Installer: def user_set_shell(self, user: str, shell: str) -> bool: info(f'Setting shell for {user} to {shell}') - cmd = ['arch-chroot', '-S', str(self.target), 'chsh', '-s', shell, user] + cmd = self._chroot_argv('chsh', '-s', shell, user) try: run(cmd) return True @@ -1979,7 +1971,7 @@ class Installer: def chown(self, owner: str, path: str, options: list[str] | None = None) -> bool: options = options or [] - cmd = ['arch-chroot', '-S', str(self.target), 'chown', *options, owner, path] + cmd = self._chroot_argv('chown', *options, '--', owner, path) try: run(cmd) return True From 210329ed808628cf11fa3a8543d8f5da33c5c4a5 Mon Sep 17 00:00:00 2001 From: Softer Date: Mon, 27 Apr 2026 02:30:20 +0300 Subject: [PATCH 16/40] Add console font selection to Locales menu (#4469) * Add console font selection to Locales menu Add a 4th menu item "Console font" to the Locales configuration, allowing users to select a console font for the target system. The selected font is written to /etc/vconsole.conf. If a terminus font (ter-*) is selected, the terminus-font package is automatically installed on the target system. * Switch list_console_fonts to pathlib and add @lru_cache Address svartkanin's review on #4469. Replace os.listdir + chained removesuffix with Path.glob('*.gz') + split('.')[0], and cache the result via lru_cache - the kbd consolefonts directory is static at runtime so re-scanning on every menu reopen was wasted I/O. --- archinstall/lib/installer.py | 8 +++--- archinstall/lib/locale/locale_menu.py | 31 +++++++++++++++++++++- archinstall/lib/locale/utils.py | 10 +++++++ archinstall/lib/models/locale.py | 11 +++++++- archinstall/locales/base.pot | 3 +++ archinstall/locales/uk/LC_MESSAGES/base.po | 3 +++ 6 files changed, 59 insertions(+), 7 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index e596f7fe..ff530df0 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -1982,12 +1982,10 @@ class Installer: def set_vconsole(self, locale_config: LocaleConfiguration) -> None: # use the already set kb layout kb_vconsole: str = locale_config.kb_layout - # this is the default used in ISO other option for hdpi screens TER16x32 - # can be checked using - # zgrep "CONFIG_FONT" /proc/config.gz - # https://wiki.archlinux.org/title/Linux_console#Fonts + font_vconsole = locale_config.console_font - font_vconsole = 'default8x16' + if font_vconsole.startswith('ter-'): + self.pacman.strap(['terminus-font']) # Ensure /etc exists vconsole_dir: Path = self.target / 'etc' diff --git a/archinstall/lib/locale/locale_menu.py b/archinstall/lib/locale/locale_menu.py index c03824a1..dc743fd3 100644 --- a/archinstall/lib/locale/locale_menu.py +++ b/archinstall/lib/locale/locale_menu.py @@ -1,6 +1,6 @@ from typing import override -from archinstall.lib.locale.utils import list_keyboard_languages, list_locales, set_kb_layout +from archinstall.lib.locale.utils import list_console_fonts, list_keyboard_languages, list_locales, set_kb_layout from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.helpers import Selection from archinstall.lib.models.locale import LocaleConfiguration @@ -47,6 +47,13 @@ class LocaleMenu(AbstractSubMenu[LocaleConfiguration]): preview_action=lambda item: item.get_value(), key='sys_enc', ), + MenuItem( + text=tr('Console font'), + action=select_console_font, + value=self._locale_conf.console_font, + preview_action=lambda item: item.get_value(), + key='console_font', + ), ] @override @@ -140,3 +147,25 @@ async def select_kb_layout(preset: str | None = None) -> str | None: return preset case _: raise ValueError('Unhandled return type') + + +async def select_console_font(preset: str | None = None) -> str | None: + fonts = list_console_fonts() + + items = [MenuItem(f, value=f) for f in fonts] + group = MenuItemGroup(items, sort_items=False) + group.set_focus_by_value(preset) + + result = await Selection[str]( + header=tr('Console font'), + group=group, + enable_filter=True, + ).show() + + match result.type_: + case ResultType.Selection: + return result.get_value() + case ResultType.Skip: + return preset + case _: + raise ValueError('Unhandled return type') diff --git a/archinstall/lib/locale/utils.py b/archinstall/lib/locale/utils.py index e7229160..497e1fcb 100644 --- a/archinstall/lib/locale/utils.py +++ b/archinstall/lib/locale/utils.py @@ -1,3 +1,6 @@ +from functools import lru_cache +from pathlib import Path + from archinstall.lib.command import SysCommand from archinstall.lib.exceptions import ServiceException, SysCallError from archinstall.lib.output import error @@ -26,6 +29,13 @@ def list_locales() -> list[str]: return locales +@lru_cache +def list_console_fonts() -> list[str]: + directory = Path('/usr/share/kbd/consolefonts') + fonts = {path.name.split('.')[0] for path in directory.glob('*.gz')} + return sorted(fonts) + + def list_x11_keyboard_languages() -> list[str]: return ( SysCommand( diff --git a/archinstall/lib/models/locale.py b/archinstall/lib/models/locale.py index 15dee2f6..8f580989 100644 --- a/archinstall/lib/models/locale.py +++ b/archinstall/lib/models/locale.py @@ -10,6 +10,11 @@ class LocaleConfiguration: kb_layout: str sys_lang: str sys_enc: str + # this is the default used in ISO other option for hdpi screens TER16x32 + # can be checked using + # zgrep "CONFIG_FONT" /proc/config.gz + # https://wiki.archlinux.org/title/Linux_console#Font + console_font: str = 'default8x16' @classmethod def default(cls) -> Self: @@ -23,12 +28,14 @@ class LocaleConfiguration: 'kb_layout': self.kb_layout, 'sys_lang': self.sys_lang, 'sys_enc': self.sys_enc, + 'console_font': self.console_font, } def preview(self) -> str: output = '{}: {}\n'.format(tr('Keyboard layout'), self.kb_layout) output += '{}: {}\n'.format(tr('Locale language'), self.sys_lang) - output += '{}: {}'.format(tr('Locale encoding'), self.sys_enc) + output += '{}: {}\n'.format(tr('Locale encoding'), self.sys_enc) + output += '{}: {}'.format(tr('Console font'), self.console_font) return output def _load_config(self, args: dict[str, str]) -> None: @@ -38,6 +45,8 @@ class LocaleConfiguration: self.sys_enc = args['sys_enc'] if 'kb_layout' in args: self.kb_layout = args['kb_layout'] + if 'console_font' in args: + self.console_font = args['console_font'] @classmethod def parse_arg(cls, args: dict[str, Any]) -> Self: diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index f707ec7a..a0c4c5b7 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -252,6 +252,9 @@ msgstr "" msgid "Locale encoding" msgstr "" +msgid "Console font" +msgstr "" + msgid "Drive(s)" msgstr "" diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index a178ac2d..ffab244f 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -256,6 +256,9 @@ msgstr "Мова локалізації" msgid "Locale encoding" msgstr "Кодування локалізації" +msgid "Console font" +msgstr "Шрифт консолі" + msgid "Drive(s)" msgstr "Диск(и)" From 3795bfc21a87224f9dd8e983a5a736b58cda06ad Mon Sep 17 00:00:00 2001 From: utuhiro78 <34818411+utuhiro78@users.noreply.github.com> Date: Mon, 27 Apr 2026 08:32:10 +0900 Subject: [PATCH 17/40] Update Japanese translation (#4482) --- archinstall/locales/ja/LC_MESSAGES/base.mo | Bin 68172 -> 72857 bytes archinstall/locales/ja/LC_MESSAGES/base.po | 230 ++++++++++++++++++++- 2 files changed, 219 insertions(+), 11 deletions(-) diff --git a/archinstall/locales/ja/LC_MESSAGES/base.mo b/archinstall/locales/ja/LC_MESSAGES/base.mo index 3ad3d1a276e7039db33fe23806d6b3fcdd109ba2..bfdce38d646ec876e4516067ceaba61ea4c87c39 100644 GIT binary patch delta 17972 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 delta 13924 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 wKg!_gll8y)=)_mI%?$HY3kpk5 Date: Mon, 27 Apr 2026 02:35:34 +0300 Subject: [PATCH 18/40] Remove disabled translation-check workflow (#4483) The workflow has been fully commented out since #2119 (2023-09-28) when translation handling was reworked. Because the file has no `on:` triggers, GitHub Actions creates a failed workflow run for every push, polluting the Actions tab without affecting PR check-runs. --- .github/workflows/translation-check.yaml | 28 ------------------------ 1 file changed, 28 deletions(-) delete mode 100644 .github/workflows/translation-check.yaml diff --git a/.github/workflows/translation-check.yaml b/.github/workflows/translation-check.yaml deleted file mode 100644 index 3cd4d14c..00000000 --- a/.github/workflows/translation-check.yaml +++ /dev/null @@ -1,28 +0,0 @@ -#on: -# push: -# paths: -# - 'archinstall/locales/**' -# pull_request: -# paths: -# - 'archinstall/locales/**' -#name: Verify local_generate script was run on translation changes -#jobs: -# translation-check: -# runs-on: ubuntu-latest -# container: -# image: archlinux/archlinux:latest -# steps: -# - uses: actions/checkout@v4 -# - run: pacman --noconfirm -Syu python git diffutils -# - name: Verify all translation scripts are up to date -# run: | -# cd .. -# cp -r archinstall archinstall_orig -# cd archinstall/archinstall/locales -# bash locales_generator.sh 1> /dev/null -# cd ../../.. -# git diff \ -# --quiet --no-index --name-only \ -# archinstall_orig/archinstall/locales \ -# archinstall/archinstall/locales \ -# || (echo "Translation files have not been updated after translation, please run ./locales_generator.sh once more and commit" && exit 1) From 074dfbb1784a374f6f2a548a2c027b1f942b153d Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Mon, 27 Apr 2026 08:44:14 +0200 Subject: [PATCH 19/40] Adding a reference to why AUR is not bundled as an option in archinstall (#4468) --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 75631b6b..95d15702 100644 --- a/README.md +++ b/README.md @@ -219,6 +219,10 @@ qemu-system-x86_64 -enable-kvm \ # FAQ +## AUR + +`archinstall` will not offer or bundle AUR helpers or AUR packages due to a current consensus. This is not any individual developers decision. The reasons and discussions for this stance on the topic can be found on our mailing list thread: [(optional) AUR helper in archinstall](https://lists.archlinux.org/archives/list/arch-dev-public@lists.archlinux.org/thread/VYOULH2GOJLFM2BXOFLWH3D754YXFPSL/). + ## Keyring out-of-date For a description of the problem see https://archinstall.archlinux.page/help/known_issues.html#keyring-is-out-of-date-2213 and discussion in issue https://github.com/archlinux/archinstall/issues/2213. From 9010ccf9eb3369f713d60cefc0b17e619f23c143 Mon Sep 17 00:00:00 2001 From: codefiles <11915375+codefiles@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:08:19 -0400 Subject: [PATCH 20/40] Add kernel enum (#4489) --- archinstall/lib/args.py | 3 ++- archinstall/lib/general/system_menu.py | 17 ++++++----------- archinstall/lib/global_menu.py | 3 ++- archinstall/lib/installer.py | 5 +++-- archinstall/lib/models/package_types.py | 12 ++++++++++++ archinstall/tui/ui/menu_item.py | 4 ++-- 6 files changed, 27 insertions(+), 17 deletions(-) create mode 100644 archinstall/lib/models/package_types.py diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index 79441a06..77545736 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -21,6 +21,7 @@ from archinstall.lib.models.device import DiskEncryption, DiskLayoutConfiguratio from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration from archinstall.lib.models.network import NetworkConfiguration +from archinstall.lib.models.package_types import DEFAULT_KERNEL from archinstall.lib.models.packages import Repository from archinstall.lib.models.pacman import PacmanConfiguration from archinstall.lib.models.profile import ProfileConfiguration @@ -71,7 +72,7 @@ class ArchConfig: auth_config: AuthenticationConfiguration | None = None swap: ZramConfiguration | None = None hostname: str = 'archlinux' - kernels: list[str] = field(default_factory=lambda: ['linux']) + kernels: list[str] = field(default_factory=lambda: [DEFAULT_KERNEL.value]) ntp: bool = True packages: list[str] = field(default_factory=list) pacman_config: PacmanConfiguration = field(default_factory=PacmanConfiguration.default) diff --git a/archinstall/lib/general/system_menu.py b/archinstall/lib/general/system_menu.py index 5c4d4634..7fa0d1f2 100644 --- a/archinstall/lib/general/system_menu.py +++ b/archinstall/lib/general/system_menu.py @@ -3,29 +3,24 @@ from typing import assert_never from archinstall.lib.hardware import GfxDriver, SysInfo from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.models.application import ZramAlgorithm, ZramConfiguration +from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.ui.result import ResultType -async def select_kernel(preset: list[str] = []) -> list[str]: +async def select_kernel(preset: list[Kernel] = []) -> list[Kernel]: """ Asks the user to select a kernel for system. :return: The string as a selected kernel :rtype: string """ - kernels = ['linux', 'linux-lts', 'linux-zen', 'linux-hardened'] - default_kernel = 'linux' + group = MenuItemGroup.from_enum(Kernel, sort_items=True, preset=preset) + group.set_default_by_value(DEFAULT_KERNEL) + group.set_focus_by_value(DEFAULT_KERNEL) - items = [MenuItem(k, value=k) for k in kernels] - - group = MenuItemGroup(items, sort_items=True) - group.set_default_by_value(default_kernel) - group.set_focus_by_value(default_kernel) - group.set_selected_by_value(preset) - - result = await Selection[str]( + result = await Selection[Kernel]( group, header=tr('Select which kernel(s) to install'), allow_skip=True, diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index e327b388..3bfefce7 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -22,6 +22,7 @@ from archinstall.lib.models.device import DiskLayoutConfiguration, DiskLayoutTyp from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration from archinstall.lib.models.network import NetworkConfiguration, NicType +from archinstall.lib.models.package_types import DEFAULT_KERNEL from archinstall.lib.models.packages import Repository from archinstall.lib.models.pacman import PacmanConfiguration from archinstall.lib.models.profile import ProfileConfiguration @@ -103,7 +104,7 @@ class GlobalMenu(AbstractMenu[None]): ), MenuItem( text=tr('Kernels'), - value=['linux'], + value=[DEFAULT_KERNEL], action=select_kernel, preview_action=self._prev_kernel, mandatory=True, diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index ff530df0..ca98fdb9 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -48,6 +48,7 @@ from archinstall.lib.models.device import ( from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.models.mirrors import MirrorConfiguration from archinstall.lib.models.network import Nic +from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel from archinstall.lib.models.packages import Repository from archinstall.lib.models.pacman import PacmanConfiguration from archinstall.lib.models.users import User @@ -60,7 +61,7 @@ from archinstall.lib.plugins import plugins from archinstall.lib.translationhandler import tr # Any package that the Installer() is responsible for (optional and the default ones) -__packages__ = ['base', 'sudo', 'linux-firmware', 'linux', 'linux-lts', 'linux-zen', 'linux-hardened'] +__packages__ = ['base', 'sudo', 'linux-firmware'] + [k.value for k in Kernel] # Additional packages that are installed if the user is running the Live ISO with accessibility tools enabled __accessibility_packages__ = ['brltty', 'espeakup', 'alsa-utils'] @@ -80,7 +81,7 @@ class Installer: It also wraps :py:func:`~archinstall.Installer.pacstrap` among other things. """ self._base_packages = base_packages or __packages__[:3] - self.kernels = kernels or ['linux'] + self.kernels = kernels or [DEFAULT_KERNEL.value] self._disk_config = disk_config self._disk_encryption = disk_config.disk_encryption or DiskEncryption(EncryptionType.NO_ENCRYPTION) diff --git a/archinstall/lib/models/package_types.py b/archinstall/lib/models/package_types.py new file mode 100644 index 00000000..e314c30a --- /dev/null +++ b/archinstall/lib/models/package_types.py @@ -0,0 +1,12 @@ +from enum import StrEnum, auto +from typing import Final + + +class Kernel(StrEnum): + LINUX = auto() + LINUX_LTS = 'linux-lts' + LINUX_ZEN = 'linux-zen' + LINUX_HARDENED = 'linux-hardened' + + +DEFAULT_KERNEL: Final = Kernel.LINUX diff --git a/archinstall/tui/ui/menu_item.py b/archinstall/tui/ui/menu_item.py index ed5a16ec..4c10e275 100644 --- a/archinstall/tui/ui/menu_item.py +++ b/archinstall/tui/ui/menu_item.py @@ -1,4 +1,4 @@ -from collections.abc import Awaitable, Callable +from collections.abc import Awaitable, Callable, Iterable from dataclasses import dataclass, field from enum import Enum from functools import cached_property @@ -148,7 +148,7 @@ class MenuItemGroup: cls, enum_cls: type[Enum], sort_items: bool = False, - preset: Enum | None = None, + preset: Iterable[Enum] | Enum | None = None, ) -> Self: items = [MenuItem(elem.value, value=elem) for elem in enum_cls] group = cls(items, sort_items=sort_items) From 8cc35f41d8da44b1665e3f8b41a10bb22bb0b1c7 Mon Sep 17 00:00:00 2001 From: Franco Castillo Date: Tue, 28 Apr 2026 04:08:39 -0300 Subject: [PATCH 21/40] Update Spanish translation (#4490) Signed-off-by: Franco Castillo --- archinstall/locales/es/LC_MESSAGES/base.mo | Bin 65086 -> 67046 bytes archinstall/locales/es/LC_MESSAGES/base.po | 200 +++++++++------------ 2 files changed, 88 insertions(+), 112 deletions(-) diff --git a/archinstall/locales/es/LC_MESSAGES/base.mo b/archinstall/locales/es/LC_MESSAGES/base.mo index 14e916ef66dffeec86c2631fab615c138248130d..5701d45472451d2476f3d5d88f44cf536839ce2b 100644 GIT binary patch delta 16896 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 roibA Date: Tue, 28 Apr 2026 12:22:01 +0300 Subject: [PATCH 22/40] Show install summary when configuration is valid (#4475) * Show install summary when configuration is valid Previously the Install menu preview was empty when everything was valid, leaving the user with no "ready" signal. Now show "Ready to install" plus a two-column summary of the current configuration. - New _install_summary() composes an aligned key/value table with rows for disks+FS+LUKS, bootloader, kernel, profile, greeter, package count, network, locale and timezone. Column width adapts to the longest translated label so translations keep the alignment. - Rows whose underlying config is not set are skipped rather than rendered as empty. - base.pot / uk base.po: add new msgids for summary labels. * Move install summary into ConfigurationOutput The summary helper that renders the install preview's two-column configuration overview lived in GlobalMenu. Move it to ConfigurationOutput.as_summary() so it sits alongside the JSON output methods that share the same role. The preview now syncs menu state to ArchConfig and delegates rendering. --- archinstall/lib/configuration.py | 66 ++++++++++++++++++++++ archinstall/lib/global_menu.py | 8 ++- archinstall/locales/base.pot | 15 +++++ archinstall/locales/uk/LC_MESSAGES/base.po | 15 +++++ 4 files changed, 102 insertions(+), 2 deletions(-) diff --git a/archinstall/lib/configuration.py b/archinstall/lib/configuration.py index 39d39511..0f22190e 100644 --- a/archinstall/lib/configuration.py +++ b/archinstall/lib/configuration.py @@ -10,6 +10,8 @@ from archinstall.lib.args import ArchConfig from archinstall.lib.crypt import encrypt from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.menu.util import get_password, prompt_dir +from archinstall.lib.models.bootloader import Bootloader +from archinstall.lib.models.network import NetworkConfiguration from archinstall.lib.output import debug, logger, warn from archinstall.lib.translationhandler import tr from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup @@ -58,6 +60,70 @@ class ConfigurationOutput: debug(' -- Chosen configuration --') debug(self.user_config_to_json()) + def as_summary(self) -> str: + """ + Render a concise two-column summary of the current configuration. + + The left column holds section labels, the right column holds values. + Column width adapts to the longest translated label so translations + do not break the alignment. Rows whose underlying config is not set + are skipped. + + Returns an empty string if nothing meaningful to show. + """ + rows: list[tuple[str, str]] = [] + + disk_config = self._config.disk_config + if disk_config and disk_config.device_modifications: + disk_parts: list[str] = [] + for mod in disk_config.device_modifications: + path = str(mod.device_path) + root_part = mod.get_root_partition() + flags: list[str] = [] + if root_part and root_part.fs_type: + flags.append(root_part.fs_type.value) + if disk_config.disk_encryption: + flags.append(tr('LUKS')) + disk_parts.append(f'{path} ({" + ".join(flags)})' if flags else path) + rows.append((tr('Disks'), ', '.join(disk_parts))) + + bl_config = self._config.bootloader_config + if bl_config and bl_config.bootloader != Bootloader.NO_BOOTLOADER: + rows.append((tr('Bootloader'), bl_config.bootloader.value)) + + kernels = self._config.kernels + if kernels: + rows.append((tr('Kernel'), ', '.join(kernels))) + + profile_config = self._config.profile_config + if profile_config and profile_config.profile: + names = profile_config.profile.current_selection_names() + rows.append((tr('Profile'), ', '.join(names) if names else profile_config.profile.name)) + if profile_config.greeter: + rows.append((tr('Greeter'), profile_config.greeter.value)) + + packages = self._config.packages + if packages: + rows.append((tr('Packages'), str(len(packages)))) + + net_config = self._config.network_config + if isinstance(net_config, NetworkConfiguration): + rows.append((tr('Network'), net_config.type.display_msg())) + + locale_config = self._config.locale_config + if locale_config: + rows.append((tr('Locale'), locale_config.sys_lang)) + + tz = self._config.timezone + if tz: + rows.append((tr('Timezone'), tz)) + + if not rows: + return '' + + label_width = max(len(label) for label, _ in rows) + 2 + return '\n'.join(f'{label:<{label_width}}{value}' for label, value in rows) + async def confirm_config(self) -> bool: header = f'{tr("The specified configuration will be applied")}. ' header += tr('Would you like to continue?') + '\n' diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index 3bfefce7..cdd820a9 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -6,7 +6,7 @@ from archinstall.lib.args import ArchConfig from archinstall.lib.authentication.authentication_menu import AuthenticationMenu from archinstall.lib.bootloader.bootloader_menu import BootloaderMenu from archinstall.lib.bootloader.utils import validate_bootloader_layout -from archinstall.lib.configuration import save_config +from archinstall.lib.configuration import ConfigurationOutput, save_config from archinstall.lib.disk.disk_menu import DiskLayoutConfigurationMenu from archinstall.lib.general.general_menu import select_hostname, select_ntp, select_timezone from archinstall.lib.general.system_menu import select_kernel, select_swap @@ -504,7 +504,11 @@ class GlobalMenu(AbstractMenu[None]): if error := self._validate_bootloader(): return tr(f'Invalid configuration: {error}') - return None + self.sync_all_to_config() + summary = ConfigurationOutput(self._arch_config).as_summary() + if summary: + return f'{tr("Ready to install")}\n\n{summary}' + return tr('Ready to install') def _prev_profile(self, item: MenuItem) -> str | None: profile_config: ProfileConfiguration | None = item.value diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index a0c4c5b7..b7e1184b 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -1248,6 +1248,21 @@ msgstr "" msgid "Invalid configuration: {error}" msgstr "" +msgid "Ready to install" +msgstr "" + +msgid "Disks" +msgstr "" + +msgid "Packages" +msgstr "" + +msgid "Network" +msgstr "" + +msgid "Locale" +msgstr "" + msgid "Type" msgstr "" diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index ffab244f..88bf9ede 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -1222,6 +1222,21 @@ msgstr "Модель" msgid "Invalid configuration: {error}" msgstr "Неправильна конфігурація: {error}" +msgid "Ready to install" +msgstr "Готово до встановлення" + +msgid "Disks" +msgstr "Диски" + +msgid "Packages" +msgstr "Пакети" + +msgid "Network" +msgstr "Мережа" + +msgid "Locale" +msgstr "Локаль" + msgid "Type" msgstr "Тип" From 1b7a32a3b36cefc06452e15db42283004ae9b38c Mon Sep 17 00:00:00 2001 From: Hassaan Amin <164820466+HASSAAN-AMIN@users.noreply.github.com> Date: Tue, 28 Apr 2026 03:03:49 -0700 Subject: [PATCH 23/40] Fix typos in known issues documentation (#4488) First Edit : - "effort" is singular so use has not have Second Edit : - we use "an" before vowel sounds (an old ) Third Edit : - use Sometimes because sometimes means occasionally and Some times means some period or era Fourth Edit : - Plural of ISO is ISOs not ISO's --- docs/help/known_issues.rst | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/help/known_issues.rst b/docs/help/known_issues.rst index bf039dcb..90945894 100644 --- a/docs/help/known_issues.rst +++ b/docs/help/known_issues.rst @@ -22,7 +22,7 @@ Restarting ``systemd-timesyncd.service`` might work but most often you need to c Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete. `#2679`_ ------------------------------ -The ``archlinux-keyring-wkd-sync.service`` or ``archlinux-keyring-wkd-sync.timer`` can hang "indefinitely" some times. +The ``archlinux-keyring-wkd-sync.service`` or ``archlinux-keyring-wkd-sync.timer`` can hang "indefinitely" sometimes. This is usually due to an inability to reach the key servers, or a slow connection towards key servers. The script ``/usr/bin/archlinux-keyring-wkd-sync`` can be run manually, to verify if it's executing slowly or not. @@ -65,7 +65,7 @@ ARM, 32bit and other CPU types error out `#1686`_, `#2185`_ This is a bit of a catch-all known issue. Officially `x86_64`_ is only supported by Arch Linux. -Hence little effort have been put into supporting other platforms. +Hence little effort has been put into supporting other platforms. In theory, other architectures should work but small quirks might arise. @@ -79,10 +79,10 @@ Missing key-issues tend to be that the `archlinux-keyring`_ package is out of da There is an attempt from upstream to fix this issue, and it's the `archlinux-keyring-wkd-sync.service`_ The service starts almost immediately during boot, and if network is not configured in time — the service will fail. -Subsequently the ``archinstall`` run might operate on a old keyring despite there being an update service for this. +Subsequently the ``archinstall`` run might operate on an old keyring despite there being an update service for this. There is really no way to reliably over time work around this issue in ``archinstall``. -Instead, efforts to the upstream service should be considered the way forward. And/or keys not expiring between a sane amount of ISO's. +Instead, efforts to the upstream service should be considered the way forward. And/or keys not expiring between a sane amount of ISOs. .. note:: From cb0f3a6eba4007fa2d84780451b34afa7d31dfa3 Mon Sep 17 00:00:00 2001 From: Softer Date: Tue, 28 Apr 2026 13:17:40 +0300 Subject: [PATCH 24/40] Warn when no network configuration is selected (#4408) * Make network configuration mandatory with explicit "No network" option * Add network configuration recommendation hint and disable sorting * Warn when network selection was skipped instead of making it mandatory Replace the mandatory network_config menu requirement with a yellow warning on the final confirmation screen, shown only when the user skipped the network menu entirely. Explicitly picking "No network configuration" is treated as a conscious choice and does not trigger the warning. - Drop mandatory=True from the network_config global menu item - Rename NicType.NONE menu label from "No network" to "No network configuration" (an installed system still has an NIC; only the install-time configuration is absent) - Add ConfigurationOutput.get_install_warnings() and render them in confirm_config when show_install_warnings=True - guided.py and minimal.py enable the warning on the confirm screen - Reuse the existing "No network configuration" msgid in .pot; add the warning string; update Ukrainian translations accordingly * Drop NicType.NONE from this PR The NONE option introduced earlier in this branch is being removed per review feedback (#4408). Whether to add explicit "None" options across multiple menus (greeter, gfx driver, network, bootloader) is now being discussed in #4464 and should land as a separate change there. This PR keeps only the warning-on-confirm behaviour: when the user skipped the network menu entirely (network_config is None), a yellow warning is shown on the final confirmation screen. --- archinstall/lib/configuration.py | 21 ++++++++++++++++++++- archinstall/lib/network/network_menu.py | 7 +++++-- archinstall/locales/base.pot | 8 ++++++++ archinstall/locales/uk/LC_MESSAGES/base.po | 6 ++++++ archinstall/scripts/guided.py | 2 +- archinstall/scripts/minimal.py | 2 +- 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/archinstall/lib/configuration.py b/archinstall/lib/configuration.py index 0f22190e..3e9135bf 100644 --- a/archinstall/lib/configuration.py +++ b/archinstall/lib/configuration.py @@ -124,10 +124,13 @@ class ConfigurationOutput: label_width = max(len(label) for label, _ in rows) + 2 return '\n'.join(f'{label:<{label_width}}{value}' for label, value in rows) - async def confirm_config(self) -> bool: + async def confirm_config(self, show_install_warnings: bool = False) -> bool: header = f'{tr("The specified configuration will be applied")}. ' header += tr('Would you like to continue?') + '\n' + if show_install_warnings: + header += self._render_install_warnings() + group = MenuItemGroup.yes_no() group.set_preview_for_all(lambda x: self.user_config_to_json()) @@ -145,6 +148,22 @@ class ConfigurationOutput: return True + def get_install_warnings(self) -> list[str]: + warnings: list[str] = [] + + if not isinstance(self._config.network_config, NetworkConfiguration): + warnings.append(tr('Warning: no network configuration selected. Network will need to be set up manually on the installed system.')) + + return warnings + + def _render_install_warnings(self) -> str: + warnings = self.get_install_warnings() + + if not warnings: + return '' + + return '\n' + '\n'.join(f'[yellow]{w}[/]' for w in warnings) + '\n' + def _is_valid_path(self, dest_path: Path) -> bool: dest_path_ok = dest_path.exists() and dest_path.is_dir() if not dest_path_ok: diff --git a/archinstall/lib/network/network_menu.py b/archinstall/lib/network/network_menu.py index bcf54698..2e95a82e 100644 --- a/archinstall/lib/network/network_menu.py +++ b/archinstall/lib/network/network_menu.py @@ -172,14 +172,17 @@ async def select_network(preset: NetworkConfiguration | None) -> NetworkConfigur """ items = [MenuItem(n.display_msg(), value=n) for n in NicType] - group = MenuItemGroup(items, sort_items=True) + group = MenuItemGroup(items, sort_items=False) if preset: group.set_selected_by_value(preset.type) + header = tr('Choose network configuration') + '\n' + header += tr('Recommended: Network Manager for desktop, Manual for server') + '\n' + result = await Selection[NicType]( group, - header=tr('Choose network configuration'), + header=header, allow_reset=True, allow_skip=True, ).show() diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index b7e1184b..f0b311d4 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -2192,6 +2192,14 @@ msgstr "" msgid "Choose network configuration" msgstr "" +msgid "Recommended: Network Manager for desktop, Manual for server" +msgstr "" + +msgid "" +"Warning: no network configuration selected. Network will need to be set up " +"manually on the installed system." +msgstr "" + msgid "No packages found" msgstr "" diff --git a/archinstall/locales/uk/LC_MESSAGES/base.po b/archinstall/locales/uk/LC_MESSAGES/base.po index 88bf9ede..a13d825c 100644 --- a/archinstall/locales/uk/LC_MESSAGES/base.po +++ b/archinstall/locales/uk/LC_MESSAGES/base.po @@ -2133,6 +2133,12 @@ msgstr "Оберіть інтерфейс" msgid "Choose network configuration" msgstr "Оберіть конфігурацію мережі" +msgid "Recommended: Network Manager for desktop, Manual for server" +msgstr "Рекомендовано: Network Manager для робочого столу, ручне налаштування для сервера" + +msgid "Warning: no network configuration selected. Network will need to be set up manually on the installed system." +msgstr "Попередження: конфігурацію мережі не обрано. Мережу доведеться налаштувати вручну на встановленій системі." + msgid "No packages found" msgstr "Пакети не знайдено" diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 5cdcdad9..21228480 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -226,7 +226,7 @@ def main(arch_config_handler: ArchConfigHandler | None = None) -> None: if not arch_config_handler.args.silent: aborted = False - res: bool = tui.run(config.confirm_config) + res: bool = tui.run(lambda: config.confirm_config(show_install_warnings=True)) if not res: debug('Installation aborted') diff --git a/archinstall/scripts/minimal.py b/archinstall/scripts/minimal.py index 4e897142..681d4266 100644 --- a/archinstall/scripts/minimal.py +++ b/archinstall/scripts/minimal.py @@ -77,7 +77,7 @@ async def main(arch_config_handler: ArchConfigHandler | None = None) -> None: if not arch_config_handler.args.silent: aborted = False - res: bool = tui.run(config.confirm_config) + res: bool = tui.run(lambda: config.confirm_config(show_install_warnings=True)) if not res: debug('Installation aborted') From e1efa34d8a009b52de4bce3eb37f28bdda3a239d Mon Sep 17 00:00:00 2001 From: Softer Date: Tue, 28 Apr 2026 14:01:05 +0300 Subject: [PATCH 25/40] Install mkinitcpio explicitly in base packages (#4484) Prevents pacstrap from picking a different initramfs provider (dracut, booster) when running from a non-Arch host. Fixes #4368 --- archinstall/lib/installer.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index ca98fdb9..c28f37c4 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -61,7 +61,12 @@ from archinstall.lib.plugins import plugins from archinstall.lib.translationhandler import tr # Any package that the Installer() is responsible for (optional and the default ones) -__packages__ = ['base', 'sudo', 'linux-firmware'] + [k.value for k in Kernel] +# https://github.com/archlinux/archinstall/issues/4368 +# mkinitcpio is listed explicitly so pacstrap installs it deterministically. Otherwise +# pacman picks the first initramfs provider from the host's pacman.conf, which on non-Arch +# hosts (EndeavourOS prefers dracut, etc.) breaks the installer's mkinitcpio() and +# _config_uki() methods that assume mkinitcpio is present in the chroot. +__packages__ = ['base', 'sudo', 'linux-firmware', 'mkinitcpio'] + [k.value for k in Kernel] # Additional packages that are installed if the user is running the Live ISO with accessibility tools enabled __accessibility_packages__ = ['brltty', 'espeakup', 'alsa-utils'] @@ -80,7 +85,7 @@ class Installer: `Installer()` is the wrapper for most basic installation steps. It also wraps :py:func:`~archinstall.Installer.pacstrap` among other things. """ - self._base_packages = base_packages or __packages__[:3] + self._base_packages = base_packages or __packages__[:4] self.kernels = kernels or [DEFAULT_KERNEL.value] self._disk_config = disk_config From 8a929f603fc5c99f8fd59e9e150c1a702e9a4165 Mon Sep 17 00:00:00 2001 From: Softer Date: Tue, 28 Apr 2026 14:02:32 +0300 Subject: [PATCH 26/40] Fix sway+nvidia confirmation dialog (#4481) (#4485) * Fix sway+nvidia confirmation dialog (#4481) Two bugs in the Sway+Nvidia driver confirmation: 1. The boolean was inverted - confirming "yes, I'm okay with issues" reverted the driver to the previous choice instead of keeping it. 2. The warning triggered for any Nvidia driver, including the open-source nouveau driver which is officially supported by Sway. Add GfxDriver.is_nvidia_proprietary() and is_nvidia_nouveau() methods so the warning fires only for nvidia-open-dkms (proprietary userspace). * Address review feedback (#4485) - Drop is_nvidia_nouveau() helper. It is not called anywhere yet; can be re-added when a consumer lands. - Collapse the Sway+Nvidia confirmation result handling into a single expression now that allow_skip=False guarantees a boolean answer. --- archinstall/lib/hardware.py | 13 +++++++++++++ archinstall/lib/profile/profile_menu.py | 5 ++--- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/archinstall/lib/hardware.py b/archinstall/lib/hardware.py index 09b3eb5f..2cfdb706 100644 --- a/archinstall/lib/hardware.py +++ b/archinstall/lib/hardware.py @@ -68,6 +68,19 @@ class GfxDriver(Enum): case _: return False + def is_nvidia_proprietary(self) -> bool: + """ + True for Nvidia drivers that ship proprietary userspace components. + Currently only NvidiaOpenKernel (nvidia-open-dkms): open kernel module + paired with proprietary userspace. NvidiaOpenSource (nouveau) is fully + open and works with Sway, so it is excluded. + """ + match self: + case GfxDriver.NvidiaOpenKernel: + return True + case _: + return False + def packages_text(self) -> str: pkg_names = [p.value for p in self.gfx_packages()] text = tr('Installed packages') + ':\n' diff --git a/archinstall/lib/profile/profile_menu.py b/archinstall/lib/profile/profile_menu.py index cb560c27..115c9fc0 100644 --- a/archinstall/lib/profile/profile_menu.py +++ b/archinstall/lib/profile/profile_menu.py @@ -95,7 +95,7 @@ class ProfileMenu(AbstractSubMenu[ProfileConfiguration]): driver = await select_driver(preset=preset) if driver and 'Sway' in profile.current_selection_names(): - if driver.is_nvidia(): + if driver.is_nvidia_proprietary(): header = tr('The proprietary Nvidia driver is not supported by Sway.') + '\n' header += tr('It is likely that you will run into issues, are you okay with that?') + '\n' @@ -105,8 +105,7 @@ class ProfileMenu(AbstractSubMenu[ProfileConfiguration]): preset=False, ).show() - if result.get_value(): - return preset + return driver if result.get_value() else preset return driver From c4d68855cb6d95e370d05c806200f4ea23362116 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Tue, 28 Apr 2026 07:34:33 -0400 Subject: [PATCH 27/40] Replace time.time with time.monotonic to avoid clock drift issues (#4492) Using time.time() can be inaccurate if the system clock gets updated in between calls. --- archinstall/lib/installer.py | 4 ++-- archinstall/lib/networking.py | 10 +++++----- archinstall/lib/pacman/pacman.py | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index c28f37c4..7bbfbae5 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -189,10 +189,10 @@ class Installer: if not skip_ntp: info(tr('Waiting for time sync (timedatectl show) to complete.')) - started_wait = time.time() + started_wait = time.monotonic() notified = False while True: - if not notified and time.time() - started_wait > 5: + if not notified and time.monotonic() - started_wait > 5: notified = True warn(tr('Time synchronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/')) diff --git a/archinstall/lib/networking.py b/archinstall/lib/networking.py index ebf59990..e950a697 100644 --- a/archinstall/lib/networking.py +++ b/archinstall/lib/networking.py @@ -46,12 +46,12 @@ class DownloadTimer: self.previous_handler = signal.signal(signal.SIGALRM, self.raise_timeout) # type: ignore[assignment] self.previous_timer = signal.alarm(self.timeout) - self.start_time = time.time() + self.start_time = time.monotonic() return self def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None: if self.start_time: - time_delta = time.time() - self.start_time + time_delta = time.monotonic() - self.start_time signal.alarm(0) self.time = time_delta if self.timeout > 0: @@ -165,7 +165,7 @@ def build_icmp(payload: bytes) -> bytes: def ping(hostname: str, timeout: int = 5) -> int: watchdog = select.epoll() - started = time.time() + started = time.monotonic() random_identifier = f'archinstall-{random.randint(1000, 9999)}'.encode() # Create a raw socket (requires root, which should be fine on archiso) @@ -180,7 +180,7 @@ def ping(hostname: str, timeout: int = 5) -> int: # Gracefully wait for X amount of time # for a ICMP response or exit with no latency - while latency == -1 and time.time() - started < timeout: + while latency == -1 and time.monotonic() - started < timeout: try: for _fileno, _event in watchdog.poll(0.1): response, _ = icmp_socket.recvfrom(1024) @@ -188,7 +188,7 @@ def ping(hostname: str, timeout: int = 5) -> int: # Check if it's an Echo Reply (ICMP type 0) if icmp_type == 0 and response[-len(random_identifier) :] == random_identifier: - latency = round((time.time() - started) * 1000) + latency = round((time.monotonic() - started) * 1000) break except OSError as e: debug(f'Error: {e}') diff --git a/archinstall/lib/pacman/pacman.py b/archinstall/lib/pacman/pacman.py index 5427214c..83f8b40d 100644 --- a/archinstall/lib/pacman/pacman.py +++ b/archinstall/lib/pacman/pacman.py @@ -29,11 +29,11 @@ class Pacman: if pacman_db_lock.exists(): warn(tr('Pacman is already running, waiting maximum 10 minutes for it to terminate.')) - started = time.time() + started = time.monotonic() while pacman_db_lock.exists(): time.sleep(0.25) - if time.time() - started > (60 * 10): + if time.monotonic() - started > (60 * 10): error(tr('Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall.')) sys.exit(1) From ccbc53d5763e502a8b513338542eaf1e3ad08403 Mon Sep 17 00:00:00 2001 From: utuhiro78 <34818411+utuhiro78@users.noreply.github.com> Date: Wed, 29 Apr 2026 12:44:11 +0900 Subject: [PATCH 28/40] Update Japanese translation (#4498) --- archinstall/locales/ja/LC_MESSAGES/base.mo | Bin 72857 -> 73655 bytes archinstall/locales/ja/LC_MESSAGES/base.po | 24 +++++++++++++++++++++ 2 files changed, 24 insertions(+) diff --git a/archinstall/locales/ja/LC_MESSAGES/base.mo b/archinstall/locales/ja/LC_MESSAGES/base.mo index bfdce38d646ec876e4516067ceaba61ea4c87c39..043a6f2b917c747b6be6e64d592ac7d5e9d89d70 100644 GIT binary patch delta 15284 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

;rAE8qI#J2nQ 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 Date: Wed, 29 Apr 2026 08:06:10 +0200 Subject: [PATCH 29/40] Danish translation (#4493) * Danish translation * updated base.po and created base.mo --------- Co-authored-by: Steen Rabol --- archinstall/locales/base.pot | 8 +- archinstall/locales/da/LC_MESSAGES/base.mo | Bin 0 -> 64584 bytes archinstall/locales/da/LC_MESSAGES/base.po | 2224 ++++++++++++++++++++ 3 files changed, 2228 insertions(+), 4 deletions(-) create mode 100644 archinstall/locales/da/LC_MESSAGES/base.mo create mode 100644 archinstall/locales/da/LC_MESSAGES/base.po diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index f0b311d4..4e9e0e9f 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -644,8 +644,8 @@ msgid "" msgstr "" msgid "" -"Provides a selection of desktop environments and tiling window managers, e." -"g. gnome, kde, sway" +"Provides a selection of desktop environments and tiling window managers, " +"e.g. gnome, kde, sway" msgstr "" msgid "Select your desired desktop environment" @@ -1349,8 +1349,8 @@ msgid "Disable Copy-on-Write" msgstr "" msgid "" -"Provides a selection of desktop environments and tiling window managers, e." -"g. GNOME, KDE Plasma, Sway" +"Provides a selection of desktop environments and tiling window managers, " +"e.g. GNOME, KDE Plasma, Sway" msgstr "" #, python-brace-format diff --git a/archinstall/locales/da/LC_MESSAGES/base.mo b/archinstall/locales/da/LC_MESSAGES/base.mo new file mode 100644 index 0000000000000000000000000000000000000000..b0cb0718a097bd1fbad1dd0bff026305ea0f7018 GIT binary patch literal 64584 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 literal 0 HcmV?d00001 diff --git a/archinstall/locales/da/LC_MESSAGES/base.po b/archinstall/locales/da/LC_MESSAGES/base.po new file mode 100644 index 00000000..cc54891d --- /dev/null +++ b/archinstall/locales/da/LC_MESSAGES/base.po @@ -0,0 +1,2224 @@ +msgid "" +msgstr "" +"Project-Id-Version: \n" +"POT-Creation-Date: \n" +"PO-Revision-Date: \n" +"Last-Translator: \n" +"Language-Team: \n" +"Language: de\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +msgid "[!] A log file has been created here: {} {}" +msgstr "[!] En logfil er blevet oprettet her: {} {}" + +msgid " Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr " Indsend venligst denne fejl (og filen) til https://github.com/archlinux/archinstall/issues" + +msgid "Do you really want to abort?" +msgstr "Vil du virkelig afbryde?" + +msgid "And one more time for verification: " +msgstr "Og én gang til for bekræftelse: " + +msgid "Would you like to use swap on zram?" +msgstr "Vil du bruge swap på zram?" + +msgid "Desired hostname for the installation: " +msgstr "Ønsket værtsnavn for installationen: " + +msgid "Username for required superuser with sudo privileges: " +msgstr "Brugernavn til den påkrævede superbruger med sudo-rettigheder: " + +msgid "Any additional users to install (leave blank for no users): " +msgstr "Eventuelle yderligere brugere der skal oprettes (lad feltet være tomt for ingen): " + +msgid "Should this user be a superuser (sudoer)?" +msgstr "Skal denne bruger være superbruger (sudoer)?" + +msgid "Select a timezone" +msgstr "Vælg en tidszone" + +msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?" +msgstr "Vil du bruge GRUB som bootloader i stedet for systemd-boot?" + +msgid "Choose a bootloader" +msgstr "Vælg en bootloader" + +msgid "Choose an audio server" +msgstr "Vælg en lydserver" + +msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Kun pakker som base, base-devel, linux, linux-firmware, efibootmgr og valgfrie profilpakker installeres." + +msgid "Note: base-devel is no longer installed by default. Add it here if you need build tools." +msgstr "Bemærk: base-devel installeres ikke længere som standard. Tilføj den her, hvis du har brug for byggeværktøjer." + +msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." +msgstr "Hvis du ønsker en webbrowser, f.eks. firefox eller chromium, kan du angive den i næste prompt." + +msgid "Write additional packages to install (space separated, leave blank to skip): " +msgstr "Skriv yderligere pakker der skal installeres (adskilt med mellemrum, lad feltet være tomt for at springe over): " + +msgid "Copy ISO network configuration to installation" +msgstr "Kopiér ISO-netværkskonfigurationen til installationen" + +msgid "Use NetworkManager (necessary for configuring internet graphically in GNOME and KDE)" +msgstr "Brug NetworkManager (nødvendigt for grafisk internetkonfiguration i GNOME og KDE)" + +msgid "Select one network interface to configure" +msgstr "Vælg én netværksgrænseflade der skal konfigureres" + +msgid "Select which mode to configure for \"{}\" or skip to use default mode \"{}\"" +msgstr "Vælg hvilken tilstand der skal konfigureres for \"{}\", eller spring over for at bruge standardtilstanden \"{}\"" + +#, python-brace-format +msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): " +msgstr "Indtast IP og subnet for {} (eksempel: 192.168.0.5/24): " + +msgid "Enter your gateway (router) IP address or leave blank for none: " +msgstr "Indtast IP-adressen på din gateway (router), eller lad feltet være tomt for ingen: " + +msgid "Enter your DNS servers (space separated, blank for none): " +msgstr "Indtast dine DNS-servere (adskilt med mellemrum, tomt for ingen): " + +msgid "Select which filesystem your main partition should use" +msgstr "Vælg hvilket filsystem din hovedpartition skal bruge" + +msgid "Current partition layout" +msgstr "Nuværende partitionslayout" + +msgid "" +"Select what to do with\n" +"{}" +msgstr "" +"Vælg hvad der skal gøres med\n" +"{}" + +msgid "Enter a desired filesystem type for the partition" +msgstr "Indtast den ønskede filsystemtype for partitionen" + +msgid "Enter the start location (in parted units: s, GB, %, etc. ; default: {}): " +msgstr "Indtast startplaceringen (i parted-enheder: s, GB, %, osv.; standard: {}): " + +msgid "Enter the end location (in parted units: s, GB, %, etc. ; ex: {}): " +msgstr "Indtast slutplaceringen (i parted-enheder: s, GB, %, osv.; f.eks.: {}): " + +msgid "{} contains queued partitions, this will remove those, are you sure?" +msgstr "{} indeholder planlagte partitioner. Dette vil fjerne dem. Er du sikker?" + +msgid "" +"{}\n" +"\n" +"Select by index which partitions to delete" +msgstr "" +"{}\n" +"\n" +"Vælg efter indeks hvilke partitioner der skal slettes" + +msgid "" +"{}\n" +"\n" +"Select by index which partition to mount where" +msgstr "" +"{}\n" +"\n" +"Vælg efter indeks hvilken partition der skal monteres hveller" + +msgid " * Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr " * Partitionens monteringspunkter er relative inde i installationen; boot vil f.eks. være /boot." + +msgid "Select where to mount partition (leave blank to remove mountpoint): " +msgstr "Vælg hvor partitionen skal monteres (lad feltet være tomt for at fjerne monteringspunktet): " + +msgid "" +"{}\n" +"\n" +"Select which partition to mask for formatting" +msgstr "" +"{}\n" +"\n" +"Vælg hvilken partition der skal markeres til formatering" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as encrypted" +msgstr "" +"{}\n" +"\n" +"Vælg hvilken partition der skal mark som krypteret" + +msgid "" +"{}\n" +"\n" +"Select which partition to mark as bootable" +msgstr "" +"{}\n" +"\n" +"Vælg hvilken partition der skal mark som bootbar" + +msgid "" +"{}\n" +"\n" +"Select which partition to set a filesystem on" +msgstr "" +"{}\n" +"\n" +"Vælg hvilken partition der skal set en filsystem on" + +msgid "Enter a desired filesystem type for the partition: " +msgstr "Indtast den ønskede filsystemtype for partitionen: " + +msgid "Archinstall language" +msgstr "Archinstall-sprog" + +msgid "Wipe all selected drives and use a best-effort default partition layout" +msgstr "Slet alle valgte drev og brug et bedst muligt standardpartitionslayout" + +msgid "Select what to do with each individual drive (followed by partition usage)" +msgstr "Vælg hvad der skal gøres med hvert enkelt drev (efterfulgt af partitionsbrug)" + +msgid "Select what you wish to do with the selected block devices" +msgstr "Vælg hvad du vil gøre med de valgte blokenheder" + +msgid "This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments" +msgstr "Dette er en liste over forudprogrammerede profiler, som kan gøre det lettere at installere ting som skrivebordsmiljøer" + +msgid "Select keyboard layout" +msgstr "Vælg tastaturlayout" + +msgid "Select one of the regions to download packages from" +msgstr "Vælg en af regionerne som pakker skal hentes fra" + +msgid "Select one or more hard drives to use and configure" +msgstr "Vælg en eller flere harddiske der skal bruges og konfigureres" + +msgid "For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options." +msgstr "For bedst kompatibilitet med din AMD-hardware kan du bruge enten alle open source-drivere eller AMD/ATI-valgene." + +msgid "For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n" +msgstr "For bedst kompatibilitet med din Intel-hardware kan du bruge enten alle open source-drivere eller Intel-valgene.\n" + +msgid "For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n" +msgstr "For bedst kompatibilitet med din Nvidia-hardware kan du bruge Nvidias proprietære driver.\n" + +msgid "" +"\n" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" +"\n" +"\n" +"Vælg en grafikdriver, eller lad feltet være tomt for at installere alle open source-drivere" + +msgid "All open-source (default)" +msgstr "Alle open source-drivere (standard)" + +msgid "Choose which kernels to use or leave blank for default \"{}\"" +msgstr "Vælg hvilke kerner der skal bruges, eller lad feltet være tomt for standard \"{}\"" + +msgid "Choose which locale language to use" +msgstr "Vælg hvilket lokaliseringssprog der skal bruges" + +msgid "Choose which locale encoding to use" +msgstr "Vælg hvilken lokaliseringskodning der skal bruges" + +msgid "Select one of the values shown below: " +msgstr "Vælg en af værdierne nedenfor: " + +msgid "Select one or more of the options below: " +msgstr "Vælg en eller flere af mulighederne nedenfor: " + +msgid "Adding partition...." +msgstr "Tilføjer partition...." + +msgid "You need to enter a valid fs-type in order to continue. See `man parted` for valid fs-type's." +msgstr "Du skal indtaste en gyldig fs-type for at fortsætte. Se `man parted` for gyldige fs-typer." + +msgid "Error: Listing profiles on URL \"{}\" resulted in:" +msgstr "Fejl: Liste over profiler fra URL \"{}\" gav:" + +msgid "Error: Could not decode \"{}\" result as JSON:" +msgstr "Fejl: Kunne ikke afkode resultatet \"{}\" som JSON:" + +msgid "Keyboard layout" +msgstr "Tastaturlayout" + +msgid "Mirror region" +msgstr "Spejlregion" + +msgid "Locale language" +msgstr "Lokaliseringssprog" + +msgid "Locale encoding" +msgstr "Lokaliseringskodning" + +msgid "Console font" +msgstr "Konsolskrifttype" + +msgid "Drive(s)" +msgstr "Drev" + +msgid "Disk layout" +msgstr "Disklayout" + +msgid "Encryption password" +msgstr "Krypteringsadgangskode" + +msgid "Swap" +msgstr "Swap" + +msgid "Bootloader" +msgstr "Bootloader" + +msgid "Root password" +msgstr "Root-adgangskode" + +msgid "Superuser account" +msgstr "Superbrugerkonto" + +msgid "User account" +msgstr "Brugerkonto" + +msgid "Profile" +msgstr "Profil" + +msgid "Audio" +msgstr "Lyd" + +msgid "Kernels" +msgstr "Kerner" + +msgid "Additional packages" +msgstr "Yderligere pakker" + +msgid "Network configuration" +msgstr "Netværkskonfiguration" + +msgid "Automatic time sync (NTP)" +msgstr "Automatisk tidssynkronisering (NTP)" + +msgid "Install ({} config(s) missing)" +msgstr "Installer ({} konfiguration(er) mangler)" + +msgid "" +"You decided to skip harddrive selection\n" +"and will use whatever drive-setup is mounted at {} (experimental)\n" +"WARNING: Archinstall won't check the suitability of this setup\n" +"Do you wish to continue?" +msgstr "" +"Du valgte at springe harddiskvalg over\n" +"og vil bruge den drevopsætning der er monteret på {} (eksperimentelt)\n" +"ADVARSEL: Archinstall kontrollerer ikke om denne opsætning er egnet\n" +"Vil du fortsætte?" + +msgid "Re-using partition instance: {}" +msgstr "Genbruger partitionsinstans: {}" + +msgid "Create a new partition" +msgstr "Create en new partition" + +msgid "Delete a partition" +msgstr "Slet en partition" + +msgid "Clear/Delete all partitions" +msgstr "Clear/Slet all partitioner" + +msgid "Assign mount-point for a partition" +msgstr "Tildel monteringspunkt til en partition" + +msgid "Mark/Unmark a partition to be formatted (wipes data)" +msgstr "Markér/fjern markering en partition skal være fellermateret (wipes data)" + +msgid "Mark/Unmark a partition as encrypted" +msgstr "Markér/fjern markering en partition som krypteret" + +msgid "Mark/Unmark a partition as bootable (automatic for /boot)" +msgstr "Markér/fjern markering af en partition som bootbar (automatisk for /boot)" + +msgid "Set desired filesystem for a partition" +msgstr "Angiv ønsket filsystem for en partition" + +msgid "Abort" +msgstr "Afbryd" + +msgid "Hostname" +msgstr "Værtsnavn" + +msgid "Not configured, unavailable unless setup manually" +msgstr "Ikke konfigureret, utilgængelig medmindre det sættes op manuelt" + +msgid "Timezone" +msgstr "Tidszone" + +msgid "Set/Modify the below options" +msgstr "Angiv/ændr indstillingerne nedenfor" + +msgid "Install" +msgstr "Installer" + +msgid "" +"Use ESC to skip\n" +"\n" +msgstr "" +"Brug ESC for at springe over\n" +"\n" + +msgid "Suggest partition layout" +msgstr "Foreslå partitionslayout" + +msgid "Enter a password: " +msgstr "Indtast en adgangskode: " + +msgid "Enter a encryption password for {}" +msgstr "Indtast en krypteringsadgangskode for {}" + +msgid "Enter disk encryption password (leave blank for no encryption): " +msgstr "Indtast adgangskode til diskkryptering (lad feltet være tomt for ingen kryptering): " + +msgid "Create a required super-user with sudo privileges: " +msgstr "Create en required super-bruger med sudo-rettigheder: " + +msgid "Enter root password (leave blank to disable root): " +msgstr "Indtast root-adgangskode (lad feltet være tomt for at deaktivere root): " + +msgid "Password for user \"{}\": " +msgstr "Adgangskode for brugeren \"{}\": " + +msgid "Verifying that additional packages exist (this might take a few seconds)" +msgstr "Kontrollerer at de yderligere pakker findes (det kan tage et par sekunder)" + +msgid "Would you like to use automatic time synchronization (NTP) with the default time servers?\n" +msgstr "Vil du bruge automatisk tidssynkronisering (NTP) med standardtidserverne?\n" + +msgid "" +"Hardware time and other post-configuration steps might be required in order for NTP to work.\n" +"For more information, please check the Arch wiki" +msgstr "" +"Hardwaretid og andre efterkonfigurationstrin kan være nødvendige for at NTP virker.\n" +"Se Arch-wikien for mere information" + +msgid "Enter a username to create an additional user (leave blank to skip): " +msgstr "Indtast et brugernavn for at oprette en ekstra bruger (lad feltet være tomt for at springe over): " + +msgid "Use ESC to skip\n" +msgstr "Brug ESC for at springe over\n" + +msgid "" +"\n" +" Choose an object from the list, and select one of the available actions for it to execute" +msgstr "" +"\n" +" Vælg et objekt fra listen, og vælg en af de tilgængelige handlinger der skal udføres" + +msgid "Cancel" +msgstr "Annuller" + +msgid "Confirm and exit" +msgstr "Bekræft og afslut" + +msgid "Add" +msgstr "Tilføj" + +msgid "Copy" +msgstr "Kopiér" + +msgid "Edit" +msgstr "Redigér" + +msgid "Delete" +msgstr "Slet" + +msgid "Select an action for '{}'" +msgstr "Vælg en handling for '{}'" + +msgid "Copy to new key:" +msgstr "Kopiér til ny nøgle:" + +msgid "Unknown nic type: {}. Possible values are {}" +msgstr "Ukendt NIC-type: {}. Mulige værdier er {}" + +msgid "" +"\n" +"This is your chosen configuration:" +msgstr "" +"\n" +"Dette er din valgte konfiguration:" + +msgid "Pacman is already running, waiting maximum 10 minutes for it to terminate." +msgstr "Pacman kører allerede. Venter højst 10 minutter på at den afsluttes." + +msgid "Pre-existing pacman lock never exited. Please clean up any existing pacman sessions before using archinstall." +msgstr "En eksisterende pacman-lås blev aldrig afsluttet. Ryd op i eventuelle eksisterende pacman-sessioner før du bruger archinstall." + +msgid "Choose which optional additional repositories to enable" +msgstr "Vælg hvilke valgfrie ekstra pakkearkiver der skal aktiveres" + +msgid "Add a user" +msgstr "Tilføj en bruger" + +msgid "Change password" +msgstr "Skift adgangskode" + +msgid "Promote/Demote user" +msgstr "Forfrem/degrader bruger" + +msgid "Delete User" +msgstr "Slet bruger" + +msgid "" +"\n" +"Define a new user\n" +msgstr "" +"\n" +"Definér en ny bruger\n" + +msgid "User Name : " +msgstr "Brugernavn: " + +msgid "Should {} be a superuser (sudoer)?" +msgstr "Skal {} være superbruger (sudoer)?" + +msgid "Define users with sudo privilege: " +msgstr "Definér brugere med sudo-rettigheder: " + +msgid "No network configuration" +msgstr "Ingen netværkskonfiguration" + +msgid "Set desired subvolumes on a btrfs partition" +msgstr "Set desired underenheds on en btrfs partition" + +msgid "" +"{}\n" +"\n" +"Select which partition to set subvolumes on" +msgstr "" +"{}\n" +"\n" +"Vælg hvilken partition der skal set underenheds on" + +msgid "Manage btrfs subvolumes for current partition" +msgstr "Administrér btrfs-underenheder for den aktuelle partition" + +msgid "No configuration" +msgstr "Ingen konfiguration" + +msgid "Save user configuration" +msgstr "Gem brugerkonfiguration" + +msgid "Save user credentials" +msgstr "Gem brugerlegitimationsoplysninger" + +msgid "Save disk layout" +msgstr "Gem disklayout" + +msgid "Save all" +msgstr "Gem alt" + +msgid "Choose which configuration to save" +msgstr "Vælg hvilken konfiguration der skal gemmes" + +msgid "Enter a directory for the configuration(s) to be saved: " +msgstr "Indtast en mappe hvor konfigurationen/konfigurationerne skal gemmes: " + +msgid "Not a valid directory: {}" +msgstr "Ikke en gyldig mappe: {}" + +msgid "The password you are using seems to be weak," +msgstr "Adgangskoden du bruger ser ud til at være svag," + +msgid "are you sure you want to use it?" +msgstr "er du sikker på at du vil bruge den?" + +msgid "Optional repositories" +msgstr "Valgfrie pakkearkiver" + +msgid "Save configuration" +msgstr "Gem konfiguration" + +msgid "Missing configurations:\n" +msgstr "Manglende konfigurationer:\n" + +msgid "Either root-password or at least 1 superuser must be specified" +msgstr "Enten root-adgangskode eller mindst 1 superbruger skal angives" + +msgid "Manage superuser accounts: " +msgstr "Administrér superbrugerkonti: " + +msgid "Manage ordinary user accounts: " +msgstr "Administrér almindelige brugerkonti: " + +msgid " Subvolume :{:16}" +msgstr " Underenhed :{:16}" + +msgid " mounted at {:16}" +msgstr " montereed at {:16}" + +msgid " with option {}" +msgstr " med mulighed {}" + +msgid "" +"\n" +" Fill the desired values for a new subvolume \n" +msgstr "" +"\n" +" Udfyld de ønskede værdier for en ny underenhed \n" + +msgid "Subvolume name " +msgstr "Subvolume navn " + +msgid "Subvolume mountpoint" +msgstr "Subvolume monteringspunkt" + +msgid "Subvolume options" +msgstr "Subvolume muligheds" + +msgid "Save" +msgstr "Gem" + +msgid "Subvolume name :" +msgstr "Subvolume navn :" + +msgid "Select a mount point :" +msgstr "Vælg en montere point :" + +msgid "Select the desired subvolume options " +msgstr "Vælg desired underenhed muligheds " + +msgid "Define users with sudo privilege, by username: " +msgstr "Define brugers med sudo privilege, by brugernavn: " + +#, python-brace-format +msgid "[!] A log file has been created here: {}" +msgstr "[!] A log fil has been created here: {}" + +msgid "Would you like to use BTRFS subvolumes with a default structure?" +msgstr "Vil du bruge BTRFS-underenheder med en standardstruktur?" + +msgid "Would you like to use BTRFS compression?" +msgstr "Vil du bruge BTRFS-komprimering?" + +msgid "Would you like to create a separate partition for /home?" +msgstr "Vil du oprette en separat partition til /home?" + +msgid "The selected drives do not have the minimum capacity required for an automatic suggestion\n" +msgstr "De valgte drev har ikke den minimumskapacitet der kræves for et automatisk forslag\n" + +msgid "Minimum capacity for /home partition: {}GB\n" +msgstr "Minimumskapacitet for /home-partition: {} GB\n" + +msgid "Minimum capacity for Arch Linux partition: {}GB" +msgstr "Minimumskapacitet for Arch Linux-partition: {} GB" + +msgid "Continue" +msgstr "Fortsæt" + +msgid "yes" +msgstr "ja" + +msgid "no" +msgstr "nej" + +msgid "set: {}" +msgstr "angivet: {}" + +msgid "Manual configuration setting must be a list" +msgstr "Manuel konfigurationsindstilling skal være en liste" + +msgid "No iface specified for manual configuration" +msgstr "Ingen grænseflade angivet til manuel konfiguration" + +msgid "Manual nic configuration with no auto DHCP requires an IP address" +msgstr "Manuel NIC-konfiguration uden automatisk DHCP kræver en IP-adresse" + +msgid "Add interface" +msgstr "Tilføj grænseflade" + +msgid "Edit interface" +msgstr "Redigér grænseflade" + +msgid "Delete interface" +msgstr "Slet grænseflade" + +msgid "Select interface to add" +msgstr "Vælg grænseflade der skal tilføjes" + +msgid "Manual configuration" +msgstr "Manuel konfiguration" + +msgid "Mark/Unmark a partition as compressed (btrfs only)" +msgstr "Markér/fjern markering en partition som komprimeret (btrfs only)" + +msgid "The password you are using seems to be weak, are you sure you want to use it?" +msgstr "Adgangskoden du bruger ser ud til at være svag. Er du sikker på at du vil bruge den?" + +msgid "Provides a selection of desktop environments and tiling window managers, e.g. gnome, kde, sway" +msgstr "Giver et udvalg af skrivebordsmiljøer og flisebaserede vindueshåndterere, f.eks. gnome, kde, sway" + +msgid "Select your desired desktop environment" +msgstr "Vælg dit ønskede skrivebordsmiljø" + +msgid "A very basic installation that allows you to customize Arch Linux as you see fit." +msgstr "En meget grundlæggende installation, der lader dig tilpasse Arch Linux som du ønsker." + +msgid "Provides a selection of various server packages to install and enable, e.g. httpd, nginx, mariadb" +msgstr "Giver et udvalg af forskellige serverpakker der kan installeres og aktiveres, f.eks. httpd, nginx, mariadb" + +msgid "Choose which servers to install, if none then a minimal installation will be done" +msgstr "Vælg hvilke servere der skal installeres. Hvis ingen vælges, udføres en minimal installation" + +msgid "Installs a minimal system as well as xorg and graphics drivers." +msgstr "Installerer et minimalt system samt xorg og grafikdrivere." + +msgid "Press Enter to continue." +msgstr "Tryk Enter for at fortsætte." + +msgid "Would you like to chroot into the newly created installation and perform post-installation configuration?" +msgstr "Vil du chroote ind i den nyoprettede installation og udføre efterkonfiguration?" + +msgid "Are you sure you want to reset this setting?" +msgstr "Er du sikker på at du vil nulstille denne indstilling?" + +msgid "Select one or more hard drives to use and configure\n" +msgstr "Vælg en eller flere harddiske der skal bruges og konfigureres\n" + +msgid "Any modifications to the existing setting will reset the disk layout!" +msgstr "Enhver ændring af den eksisterende indstilling vil nulstille disklayoutet!" + +msgid "If you reset the harddrive selection this will also reset the current disk layout. Are you sure?" +msgstr "Hvis du nulstiller harddiskvalget, nulstilles det nuværende disklayout også. Er du sikker?" + +msgid "Save and exit" +msgstr "Gem og afslut" + +msgid "" +"{}\n" +"contains queued partitions, this will remove those, are you sure?" +msgstr "" +"{}\n" +"indeholder planlagte partitioner. Dette vil fjerne dem. Er du sikker?" + +msgid "No audio server" +msgstr "Ingen lydserver" + +msgid "(default)" +msgstr "(standard)" + +msgid "Use ESC to skip" +msgstr "Brug ESC for at springe over" + +msgid "" +"Use CTRL+C to reset current selection\n" +"\n" +msgstr "" +"Brug CTRL+C for at nulstille det aktuelle valg\n" +"\n" + +msgid "Copy to: " +msgstr "Kopiér til: " + +msgid "Edit: " +msgstr "Redigér: " + +msgid "Key: " +msgstr "Nøgle: " + +msgid "Edit {}: " +msgstr "Redigér {}: " + +msgid "Add: " +msgstr "Tilføj: " + +msgid "Value: " +msgstr "Værdi: " + +msgid "You can skip selecting a drive and partitioning and use whatever drive-setup is mounted at /mnt (experimental)" +msgstr "You can springe over selecting en drev og partitioning og use whatever drev-setup is montereed at /mnt (experimental)" + +msgid "Select one of the disks or skip and use /mnt as default" +msgstr "Vælg en af diskene, eller spring over og brug /mnt som standard" + +msgid "Select which partitions to mark for formatting:" +msgstr "Vælg hvilke partitioner der skal markeres til formatering:" + +msgid "Use HSM to unlock encrypted drive" +msgstr "Brug HSM til at låse krypteret drev op" + +msgid "Device" +msgstr "Enhed" + +msgid "Size" +msgstr "Størrelse" + +msgid "Free space" +msgstr "Ledig plads" + +msgid "Bus-type" +msgstr "Bustype" + +msgid "Either root-password or at least 1 user with sudo privileges must be specified" +msgstr "Enten root-adgangskode eller mindst 1 bruger med sudo-rettigheder skal angives" + +msgid "Enter username (leave blank to skip): " +msgstr "Indtast brugernavn (lad feltet være tomt for at springe over): " + +msgid "The username you entered is invalid. Try again" +msgstr "The brugernavn you entered is ingyldig. Try again" + +msgid "Should \"{}\" be a superuser (sudo)?" +msgstr "Skal \"{}\" være superbruger (sudo)?" + +msgid "Select which partitions to encrypt" +msgstr "Vælg hvilke partitioner der skal krypteres" + +msgid "very weak" +msgstr "meget svag" + +msgid "weak" +msgstr "svag" + +msgid "moderate" +msgstr "moderat" + +msgid "strong" +msgstr "stærk" + +msgid "Add subvolume" +msgstr "Tilføj underenhed" + +msgid "Edit subvolume" +msgstr "Redigér underenhed" + +msgid "Delete subvolume" +msgstr "Slet underenhed" + +msgid "Configured {} interfaces" +msgstr "Configured {} grænseflades" + +msgid "This option enables the number of parallel downloads that can occur during installation" +msgstr "Denne indstilling aktiverer antallet af parallelle downloads under installationen" + +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +" (Enter a value between 1 to {})\n" +"Note:" +msgstr "" +"Indtast antallet af parallelle downloads der skal aktiveres.\n" +" (Indtast en værdi mellem 1 og {})\n" +"Bemærk:" + +msgid " - Maximum value : {} ( Allows {} parallel downloads, allows {} downloads at a time )" +msgstr " - Maksimumsværdi : {} (tillader {} parallelle downloads, {} downloads ad gangen)" + +msgid " - Minimum value : 1 ( Allows 1 parallel download, allows 2 downloads at a time )" +msgstr " - Minimumsværdi : 1 (tillader 1 parallel download, 2 downloads ad gangen)" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )" +msgstr " - Deaktiver/standard : 0 (deaktiverer parallel download og tillader kun 1 download ad gangen)" + +#, python-brace-format +msgid "Invalid input! Try again with a valid input [1 to {max_downloads}, or 0 to disable]" +msgstr "Ugyldigt input! Prøv igen med et gyldigt input [1 til {max_downloads}, eller 0 for at deaktivere]" + +msgid "Parallel Downloads" +msgstr "Parallelle downloads" + +msgid "Pacman" +msgstr "Pacman" + +msgid "Color" +msgstr "Farve" + +#, python-brace-format +msgid "Enter the number of parallel downloads (1-{})" +msgstr "Indtast antallet af parallelle downloads (1-{})" + +msgid "Enable colored output for pacman" +msgstr "Aktivér farvet output for pacman" + +msgid "ESC to skip" +msgstr "ESC for at springe over" + +msgid "CTRL+C to reset" +msgstr "CTRL+C for at nulstille" + +msgid "TAB to select" +msgstr "TAB for at vælge" + +msgid "[Default value: 0] > " +msgstr "[Standard værdi: 0] > " + +msgid "To be able to use this translation, please install a font manually that supports the language." +msgstr "For at kunne bruge denne oversættelse skal du manuelt installere en skrifttype der understøtter sproget." + +msgid "The font should be stored as {}" +msgstr "Skrifttypen skal gemmes som {}" + +msgid "Archinstall requires root privileges to run. See --help for more." +msgstr "Archinstall kræver root-rettigheder for at køre. Se --help for mere information." + +msgid "Select an execution mode" +msgstr "Vælg en execution tilstand" + +#, python-brace-format +msgid "Unable to fetch profile from specified url: {}" +msgstr "Kan ikke hente profil fra den angivne URL: {}" + +#, python-brace-format +msgid "Profiles must have unique name, but profile definitions with duplicate name found: {}" +msgstr "Profils must have unique navn, but profil definitions med duplicate navn found: {}" + +msgid "Select one or more devices to use and configure" +msgstr "Vælg en eller flere enheder der skal bruges og konfigureres" + +msgid "If you reset the device selection this will also reset the current disk layout. Are you sure?" +msgstr "Hvis du nulstiller enhedsvalget, nulstilles det aktuelle disklayout også. Er du sikker?" + +msgid "Existing Partitions" +msgstr "Existing Partitioner" + +msgid "Select a partitioning option" +msgstr "Vælg en partitioning mulighed" + +msgid "Enter the root directory of the mounted devices: " +msgstr "Indtast root-mappen for de monterede enheder: " + +#, python-brace-format +msgid "Minimum capacity for /home partition: {}GiB\n" +msgstr "Minimumskapacitet for /home-partition: {} GiB\n" + +#, python-brace-format +msgid "Minimum capacity for Arch Linux partition: {}GiB" +msgstr "Minimumskapacitet for Arch Linux-partition: {} GiB" + +msgid "This is a list of pre-programmed profiles_bck, they might make it easier to install things like desktop environments" +msgstr "Dette er en liste over forudprogrammerede profiles_bck, som kan gøre det lettere at installere ting som skrivebordsmiljøer" + +msgid "Current profile selection" +msgstr "Nuværende profil selection" + +msgid "Remove all newly added partitions" +msgstr "Remove all newly tilføjed partitioner" + +msgid "Assign mountpoint" +msgstr "Assign monteringspunkt" + +msgid "Mark/Unmark to be formatted (wipes data)" +msgstr "Markér/fjern markering skal være fellermateret (wipes data)" + +msgid "Mark/Unmark as bootable" +msgstr "Markér/fjern markering som bootbar" + +msgid "Change filesystem" +msgstr "Ændr filsystem" + +msgid "Mark/Unmark as compressed" +msgstr "Markér/fjern markering som komprimeret" + +msgid "Set subvolumes" +msgstr "Set underenheds" + +msgid "Delete partition" +msgstr "Slet partition" + +msgid "Partition" +msgstr "Partition" + +msgid "This partition is currently encrypted, to format it a filesystem has to be specified" +msgstr "Denne partition er i øjeblikket krypteret. For at formatere den skal der angives et filsystem." + +msgid "Partition mount-points are relative to inside the installation, the boot would be /boot as an example." +msgstr "Partitionens monteringspunkter er relative inde i installationen; boot vil f.eks. være /boot." + +msgid "If mountpoint /boot is set, then the partition will also be marked as bootable." +msgstr "Hvis monteringspunktet /boot angives, markeres partitionen også som bootbar." + +msgid "Mountpoint: " +msgstr "Monteringspunkt: " + +msgid "Current free sectors on device {}:" +msgstr "Nuværende free sectellers on enhed {}:" + +msgid "Total sectors: {}" +msgstr "Total sectellers: {}" + +msgid "Enter the start sector (default: {}): " +msgstr "Indtast start secteller (standard: {}): " + +msgid "Enter the end sector of the partition (percentage or block number, default: {}): " +msgstr "Indtast partitionens slutsektor (procent eller bloknummer, standard: {}): " + +msgid "This will remove all newly added partitions, continue?" +msgstr "Dette vil fjerne alle nyligt tilføjede partitioner. Fortsæt?" + +#, python-brace-format +msgid "Partition management: {}" +msgstr "Partitionshåndtering: {}" + +#, python-brace-format +msgid "Total length: {}" +msgstr "Samlet længde: {}" + +msgid "Encryption type" +msgstr "Krypteringstype" + +msgid "Iteration time" +msgstr "Iterationstid" + +msgid "Enter iteration time for LUKS encryption (in milliseconds)" +msgstr "Indtast iterationstid for LUKS-kryptering (i millisekunder)" + +msgid "Higher values increase security but slow down boot time" +msgstr "Higher værdis increase security but slow down boot time" + +msgid "Default: 10000ms, Recommended range: 1000-60000" +msgstr "Standard: 10000 ms, anbefalet område: 1000-60000" + +msgid "Iteration time cannot be empty" +msgstr "Iterationstid må ikke være tom" + +msgid "Iteration time must be at least 100ms" +msgstr "Iterationstid skal være mindst 100 ms" + +msgid "Iteration time must be at most 120000ms" +msgstr "Iterationstid må højst være 120000 ms" + +msgid "Please enter a valid number" +msgstr "Indtast venligst et gyldigt tal" + +msgid "Partitions" +msgstr "Partitioner" + +msgid "No HSM devices available" +msgstr "No HSM enheds available" + +msgid "Partitions to be encrypted" +msgstr "Partitioner skal være krypteret" + +msgid "Select disk encryption option" +msgstr "Vælg disk kryptering mulighed" + +msgid "Select a FIDO2 device to use for HSM" +msgstr "Vælg en FIDO2-enhed der skal bruges til HSM" + +msgid "Use a best-effort default partition layout" +msgstr "Use en best-effellert standard partition layout" + +msgid "Manual Partitioning" +msgstr "Manuel partitionering" + +msgid "Pre-mounted configuration" +msgstr "Pre-montereed konfiguration" + +msgid "Unknown" +msgstr "Ukendt" + +msgid "Partition encryption" +msgstr "Partition kryptering" + +#, python-brace-format +msgid " ! Formatting {} in " +msgstr " ! Fellermatting {} in " + +#, fuzzy +msgid "← Back" +msgstr " Tilbage" + +msgid "Disk encryption" +msgstr "Disk kryptering" + +msgid "Configuration" +msgstr "Konfiguration" + +msgid "Password" +msgstr "Adgangskode" + +msgid "All settings will be reset, are you sure?" +msgstr "Alle indstillinger nulstilles. Er du sikker?" + +msgid "Back" +msgstr "Tilbage" + +msgid "Please chose which greeter to install for the chosen profiles: {}" +msgstr "Vælg hvilken login-skærm der skal installeres for de valgte profiler: {}" + +#, python-brace-format +msgid "Environment type: {}" +msgstr "Miljøtype: {}" + +msgid "The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues, are you okay with that?" +msgstr "Den proprietære Nvidia-driver understøttes ikke af Sway. Du vil sandsynligvis støde på problemer. Er det i orden?" + +msgid "Installed packages" +msgstr "Installered pakker" + +msgid "Add profile" +msgstr "Tilføj profil" + +msgid "Edit profile" +msgstr "Redigér profil" + +msgid "Delete profile" +msgstr "Slet profil" + +msgid "Profile name: " +msgstr "Profil navn: " + +msgid "The profile name you entered is already in use. Try again" +msgstr "The profil navn you entered is already in use. Try again" + +msgid "Packages to be install with this profile (space separated, leave blank to skip): " +msgstr "Pakker der skal installeres med denne profil (adskilt med mellemrum, lad feltet være tomt for at springe over): " + +msgid "Services to be enabled with this profile (space separated, leave blank to skip): " +msgstr "Tjenester der skal aktiveres med denne profil (adskilt med mellemrum, lad feltet være tomt for at springe over): " + +msgid "Should this profile be enabled for installation?" +msgstr "Skal denne profil aktiveres til installation?" + +msgid "Create your own" +msgstr "Opret din egen" + +msgid "" +"\n" +"Select a graphics driver or leave blank to install all open-source drivers" +msgstr "" +"\n" +"Vælg en grafikdriver, eller lad feltet være tomt for at installere alle open source-drivere" + +msgid "Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "Sway skal have adgang til dit seat (samling af hardwareenheder, dvs. tastatur, mus osv.)" + +msgid "" +"\n" +"\n" +"Choose an option to give Sway access to your hardware" +msgstr "" +"\n" +"\n" +"Vælg en mulighed for at give Sway adgang til din hardware" + +msgid "Graphics driver" +msgstr "Grafikdriver" + +msgid "Greeter" +msgstr "Login-skærm" + +msgid "Please chose which greeter to install" +msgstr "Vælg hvilken login-skærm der skal installeres" + +msgid "This is a list of pre-programmed default_profiles" +msgstr "Dette er en liste over forudprogrammerede default_profiles" + +msgid "Disk configuration" +msgstr "Diskkonfiguration" + +msgid "Profiles" +msgstr "Profiler" + +msgid "Finding possible directories to save configuration files ..." +msgstr "Finder mulige mapper til at gemme konfigurationsfiler ..." + +msgid "Select directory (or directories) for saving configuration files" +msgstr "Vælg mappe (eller mapper) til lagring af konfigurationsfiler" + +msgid "Add a custom mirror" +msgstr "Tilføj en brugerdefineret spejl" + +msgid "Change custom mirror" +msgstr "Ændr brugerdefineret spejl" + +msgid "Delete custom mirror" +msgstr "Slet brugerdefineret spejl" + +msgid "Enter name (leave blank to skip): " +msgstr "Indtast navn (lad feltet være tomt for at springe over): " + +msgid "Enter url (leave blank to skip): " +msgstr "Indtast URL (lad feltet være tomt for at springe over): " + +msgid "Select signature check option" +msgstr "Vælg signatur kontrol mulighed" + +msgid "Select signature option" +msgstr "Vælg signatur mulighed" + +msgid "Custom mirrors" +msgstr "Brugerdefinerede spejle" + +msgid "Defined" +msgstr "Defineret" + +msgid "Save user configuration (including disk layout)" +msgstr "Gem bruger konfiguration (including disk layout)" + +msgid "" +"Enter a directory for the configuration(s) to be saved (tab completion enabled)\n" +"Save directory: " +msgstr "" +"Indtast en mappe hvor konfigurationen/konfigurationerne skal gemmes (tab-fuldførelse aktiveret)\n" +"Gemmemappe: " + +msgid "" +"Do you want to save {} configuration file(s) in the following location?\n" +"\n" +"{}" +msgstr "" +"Vil du gemme {} konfigurationsfil(er) på følgende placering?\n" +"\n" +"{}" + +msgid "Saving {} configuration files to {}" +msgstr "Gemmer {} konfigurationsfiler til {}" + +msgid "Mirrors" +msgstr "Spejle" + +msgid "Mirror regions" +msgstr "Mirreller regioner" + +msgid " - Maximum value : {} ( Allows {} parallel downloads, allows {max_downloads+1} downloads at a time )" +msgstr " - Maksimumsværdi : {} (tillader {} parallelle downloads, {max_downloads+1} downloads ad gangen)" + +msgid "Invalid input! Try again with a valid input [1 to {}, or 0 to disable]" +msgstr "Ugyldigt input! Prøv igen med et gyldigt input [1 til {}, eller 0 for at deaktivere]" + +msgid "Locales" +msgstr "Lokaliseringer" + +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" +msgstr "Brug NetworkManager (nødvendigt for at konfigurere internet grafisk i GNOME og KDE)" + +msgid "Total: {} / {}" +msgstr "I alt: {} / {}" + +msgid "All entered values can be suffixed with a unit: B, KB, KiB, MB, MiB..." +msgstr "Alle indtastede værdier kan afsluttes med en enhed: B, KB, KiB, MB, MiB..." + +msgid "If no unit is provided, the value is interpreted as sectors" +msgstr "If no unit is provided, værdi is interpreted som sectellers" + +msgid "Enter start (default: sector {}): " +msgstr "Indtast start (standard: secteller {}): " + +msgid "Enter end (default: {}): " +msgstr "Indtast end (standard: {}): " + +msgid "Unable to determine fido2 devices. Is libfido2 installed?" +msgstr "Kan ikke registrere fido2-enheder. Er libfido2 installeret?" + +msgid "Path" +msgstr "Sti" + +msgid "Manufacturer" +msgstr "Producent" + +msgid "Product" +msgstr "Produkt" + +#, python-brace-format +msgid "Invalid configuration: {error}" +msgstr "Ugyldig konfiguration: {error}" + +msgid "Ready to install" +msgstr "Klar til installation" + +msgid "Disks" +msgstr "Diske" + +msgid "Packages" +msgstr "Pakker" + +msgid "Network" +msgstr "Netværk" + +msgid "Locale" +msgstr "Lokalisering" + +msgid "Type" +msgstr "Type" + +msgid "This option enables the number of parallel downloads that can occur during package downloads" +msgstr "Denne indstilling aktiverer antallet af parallelle downloads under pakkehentning" + +msgid "" +"Enter the number of parallel downloads to be enabled.\n" +"\n" +"Note:\n" +msgstr "" +"Indtast antallet af parallelle downloads der skal aktiveres.\n" +"\n" +"Bemærk:\n" + +#, python-brace-format +msgid " - Maximum recommended value : {} ( Allows {} parallel downloads at a time )" +msgstr " - Maksimal anbefalet værdi : {} (tillader {} parallelle downloads ad gangen)" + +msgid " - Disable/Default : 0 ( Disables parallel downloading, allows only 1 download at a time )\n" +msgstr " - Deaktiver/standard : 0 (deaktiverer parallel download og tillader kun 1 download ad gangen)\n" + +msgid "Invalid input! Try again with a valid input [or 0 to disable]" +msgstr "Ugyldigt input! Prøv igen med et gyldigt input [eller 0 for at deaktivere]" + +msgid "Hyprland needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "Hyprland skal have adgang til dit seat (samling af hardwareenheder, dvs. tastatur, mus osv.)" + +msgid "" +"\n" +"\n" +"Choose an option to give Hyprland access to your hardware" +msgstr "" +"\n" +"\n" +"Vælg en mulighed for at give Hyprland adgang til din hardware" + +msgid "All entered values can be suffixed with a unit: %, B, KB, KiB, MB, MiB..." +msgstr "Alle indtastede værdier kan afsluttes med en enhed: %, B, KB, KiB, MB, MiB..." + +msgid "Would you like to use unified kernel images?" +msgstr "Vil du use unified kerne images?" + +msgid "Unified kernel images" +msgstr "Unified kerne images" + +msgid "Waiting for time sync (timedatectl show) to complete." +msgstr "Venter på at tidssynkronisering (timedatectl show) bliver fuldført." + +msgid "Time syncronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" +msgstr "Tidssynkronisering fuldføres ikke. Mens du venter, kan du se dokumentationen for løsninger: https://archinstall.readthedocs.io/" + +msgid "Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)" +msgstr "Springer ventetid på automatisk tidssynkronisering over (det kan give problemer, hvis tiden ikke er synkroniseret under installationen)" + +msgid "Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete." +msgstr "Venter på at Arch Linux-nøgleringssynkronisering (archlinux-keyring-wkd-sync) bliver fuldført." + +msgid "Selected profiles: " +msgstr "Vælged profils: " + +msgid "Time synchronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" +msgstr "Tidssynkronisering fuldføres ikke. Mens du venter, kan du se dokumentationen for løsninger: https://archinstall.readthedocs.io/" + +msgid "Mark/Unmark as nodatacow" +msgstr "Markér/fjern markering som nodatacow" + +msgid "Would you like to use compression or disable CoW?" +msgstr "Vil du use komprimering eller deaktivere CoW?" + +msgid "Use compression" +msgstr "Use komprimering" + +msgid "Disable Copy-on-Write" +msgstr "Deaktiver Copy-on-Write" + +msgid "Provides a selection of desktop environments and tiling window managers, e.g. GNOME, KDE Plasma, Sway" +msgstr "Giver et udvalg af skrivebordsmiljøer og flisebaserede vindueshåndterere, f.eks. GNOME, KDE Plasma, Sway" + +#, python-brace-format +msgid "Configuration type: {}" +msgstr "Konfiguration type: {}" + +msgid "LVM configuration type" +msgstr "LVM konfiguration type" + +msgid "LVM disk encryption with more than 2 partitions is currently not supported" +msgstr "LVM disk kryptering med mellere than 2 partitioner is aktuellely not suppellerted" + +msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE Plasma)" +msgstr "Brug NetworkManager (nødvendigt for at konfigurere internet grafisk i GNOME og KDE Plasma)" + +msgid "Select a LVM option" +msgstr "Vælg en LVM mulighed" + +msgid "Partitioning" +msgstr "Partitionering" + +msgid "Logical Volume Management (LVM)" +msgstr "Logisk diskenhedshåndtering (LVM)" + +msgid "Physical volumes" +msgstr "Fysiske diskenheder" + +msgid "Volumes" +msgstr "Diskenheder" + +msgid "LVM volumes" +msgstr "LVM-diskenheder" + +msgid "LVM volumes to be encrypted" +msgstr "LVM volumes skal være krypteret" + +msgid "Select which LVM volumes to encrypt" +msgstr "Vælg hvilke LVM-diskenheder der skal krypteres" + +msgid "Default layout" +msgstr "Standard layout" + +msgid "No Encryption" +msgstr "Ingen kryptering" + +msgid "LUKS" +msgstr "LUKS" + +msgid "LVM on LUKS" +msgstr "LVM på LUKS" + +msgid "LUKS on LVM" +msgstr "LUKS på LVM" + +msgid "Yes" +msgstr "Ja" + +msgid "No" +msgstr "Nej" + +msgid "Archinstall help" +msgstr "Archinstallere help" + +msgid " (default)" +msgstr " (standard)" + +msgid "Press Ctrl+h for help" +msgstr "Tryk Ctrl+h for hjælp" + +msgid "Choose an option to give Sway access to your hardware" +msgstr "Vælg en mulighed for at give Sway adgang til din hardware" + +msgid "Seat access" +msgstr "Seat-adgang" + +msgid "Mountpoint" +msgstr "Monteringspunkt" + +msgid "HSM" +msgstr "HSM" + +msgid "Enter disk encryption password (leave blank for no encryption)" +msgstr "Indtast adgangskode til diskkryptering (lad feltet være tomt for ingen kryptering)" + +msgid "Disk encryption password" +msgstr "Disk kryptering adgangskode" + +msgid "Partition - New" +msgstr "Partition - ny" + +msgid "Filesystem" +msgstr "Filsystem" + +msgid "Invalid size" +msgstr "Ugyldig størrelse" + +msgid "Start (default: sector {}): " +msgstr "Start (standard: secteller {}): " + +msgid "End (default: {}): " +msgstr "End (standard: {}): " + +msgid "Subvolume name" +msgstr "Subvolume navn" + +msgid "Disk configuration type" +msgstr "Disk konfiguration type" + +msgid "Root mount directory" +msgstr "Root-monteringsmappe" + +msgid "Select language" +msgstr "Vælg sprog" + +msgid "Write additional packages to install (space separated, leave blank to skip)" +msgstr "Skriv yderligere pakker der skal installeres (adskilt med mellemrum, lad feltet være tomt for at springe over)" + +msgid "Invalid download number" +msgstr "Ugyldigt downloadantal" + +msgid "Number downloads" +msgstr "Antal downloads" + +msgid "The username you entered is invalid" +msgstr "The brugernavn you entered is ingyldig" + +msgid "Username" +msgstr "Brugernavn" + +#, python-brace-format +msgid "Should \"{}\" be a superuser (sudo)?\n" +msgstr "Skal \"{}\" være superbruger (sudo)?\n" + +msgid "Interfaces" +msgstr "Grænseflader" + +msgid "You need to enter a valid IP in IP-config mode" +msgstr "Du skal indtaste en gyldig IP i IP-konfigurationstilstand" + +msgid "Modes" +msgstr "Tilstande" + +msgid "IP address" +msgstr "IP-adresse" + +msgid "Enter your gateway (router) IP address (leave blank for none)" +msgstr "Indtast IP-adressen på din gateway (router) (lad feltet være tomt for ingen)" + +msgid "Gateway address" +msgstr "Gateway-adresse" + +msgid "Enter your DNS servers with space separated (leave blank for none)" +msgstr "Indtast dine DNS-servere adskilt med mellemrum (lad feltet være tomt for ingen)" + +msgid "DNS servers" +msgstr "DNS-servere" + +msgid "Configure interfaces" +msgstr "Configure grænseflades" + +msgid "Kernel" +msgstr "Kerne" + +msgid "UEFI is not detected and some options are disabled" +msgstr "UEFI is not detected og some muligheds are deaktiveret" + +msgid "Info" +msgstr "Info" + +msgid "The proprietary Nvidia driver is not supported by Sway." +msgstr "The proprietary Nvidia drevr is not suppellerted by Sway." + +msgid "It is likely that you will run into issues, are you okay with that?" +msgstr "Du vil sandsynligvis støde på problemer. Er det i orden?" + +msgid "Main profile" +msgstr "Main profil" + +msgid "Confirm password" +msgstr "Confirm adgangskode" + +msgid "The confirmation password did not match, please try again" +msgstr "The confirmation adgangskode did not match, please try again" + +msgid "Not a valid directory" +msgstr "Not en gyldig mappe" + +msgid "Would you like to continue?" +msgstr "Vil du fellertsætte?" + +msgid "Directory" +msgstr "Mappe" + +msgid "Enter a directory for the configuration(s) to be saved (tab completion enabled)" +msgstr "Indtast en mappe hvor konfigurationen/konfigurationerne skal gemmes (tab-fuldførelse aktiveret)" + +#, python-brace-format +msgid "Do you want to save the configuration file(s) to {}?" +msgstr "Vil du gem konfiguration fil(s) to {}?" + +msgid "Enabled" +msgstr "Aktiveret" + +msgid "Disabled" +msgstr "Deaktiveret" + +msgid "Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" +msgstr "Indsend venligst denne fejl (og filen) til https://github.com/archlinux/archinstall/issues" + +msgid "Mirror name" +msgstr "Spejlnavn" + +msgid "Url" +msgstr "URL" + +msgid "Select signature check" +msgstr "Vælg signatur kontrol" + +msgid "Select execution mode" +msgstr "Vælg execution tilstand" + +msgid "Press ? for help" +msgstr "Tryk ? for hjælp" + +msgid "Choose an option to give Hyprland access to your hardware" +msgstr "Vælg en mulighed for at give Hyprland adgang til din hardware" + +msgid "Additional repositories" +msgstr "Yderligere pakkearkiver" + +msgid "NTP" +msgstr "NTP" + +msgid "Swap on zram" +msgstr "Swap på zram" + +msgid "Name" +msgstr "Navn" + +msgid "Signature check" +msgstr "Signaturkontrol" + +#, python-brace-format +msgid "Selected free space segment on device {}:" +msgstr "Vælged ledig plads segment on enhed {}:" + +#, python-brace-format +msgid "Size: {} / {}" +msgstr "Størrelse: {} / {}" + +#, python-brace-format +msgid "Size (default: {}): " +msgstr "Størrelse (standard: {}): " + +msgid "HSM device" +msgstr "HSM-enhed" + +msgid "Some packages could not be found in the repository" +msgstr "Nogle pakker kunne ikke findes i pakkearkivet" + +msgid "User" +msgstr "Bruger" + +msgid "The specified configuration will be applied" +msgstr "Den angivne konfiguration vil blive anvendt" + +msgid "Wipe" +msgstr "Slet" + +msgid "Mark/Unmark as XBOOTLDR" +msgstr "Markér/fjern markering som XBOOTLDR" + +msgid "Loading packages..." +msgstr "Indlæser pakker..." + +msgid "Select any packages from the below list that should be installed additionally" +msgstr "Vælg eventuelle pakker fra listen nedenfor som også skal installeres" + +msgid "Add a custom repository" +msgstr "Tilføj en brugerdefineret pakkearkiv" + +msgid "Change custom repository" +msgstr "Ændr brugerdefineret pakkearkiv" + +msgid "Delete custom repository" +msgstr "Slet brugerdefineret pakkearkiv" + +msgid "Repository name" +msgstr "Arkivnavn" + +msgid "Add a custom server" +msgstr "Tilføj en brugerdefineret server" + +msgid "Change custom server" +msgstr "Ændr brugerdefineret server" + +msgid "Delete custom server" +msgstr "Slet brugerdefineret server" + +msgid "Server url" +msgstr "Server-URL" + +msgid "Select regions" +msgstr "Vælg regioner" + +msgid "Add custom servers" +msgstr "Tilføj brugerdefineret servers" + +msgid "Add custom repository" +msgstr "Tilføj brugerdefineret pakkearkiv" + +msgid "Loading mirror regions..." +msgstr "Loading spejl regioner..." + +msgid "Mirrors and repositories" +msgstr "Mirrellers og pakkearkiver" + +msgid "Selected mirror regions" +msgstr "Vælged spejl regioner" + +msgid "Custom servers" +msgstr "Brugerdefinerede servere" + +msgid "Custom repositories" +msgstr "Brugerdefinerede pakkearkiver" + +msgid "Only ASCII characters are supported" +msgstr "Only ASCII characters are suppellerted" + +msgid "Show help" +msgstr "Vis hjælp" + +msgid "Exit help" +msgstr "Afslut hjælp" + +msgid "Preview scroll up" +msgstr "Forhåndsvisning rul op" + +msgid "Preview scroll down" +msgstr "Forhåndsvisning rul ned" + +msgid "Move up" +msgstr "Flyt op" + +msgid "Move down" +msgstr "Flyt ned" + +msgid "Move right" +msgstr "Flyt til højre" + +msgid "Move left" +msgstr "Flyt til venstre" + +msgid "Jump to entry" +msgstr "Hop til post" + +msgid "Skip selection (if available)" +msgstr "Spring over selection (if available)" + +msgid "Reset selection (if available)" +msgstr "Nulstil valg (hvis tilgængeligt)" + +msgid "Select on single select" +msgstr "Vælg on single select" + +msgid "Select on multi select" +msgstr "Vælg on multi select" + +msgid "Reset" +msgstr "Nulstil" + +msgid "Skip selection menu" +msgstr "Spring over selection menu" + +msgid "Start search mode" +msgstr "Start search tilstand" + +msgid "Exit search mode" +msgstr "Exit search tilstand" + +msgid "General" +msgstr "Generelt" + +msgid "Navigation" +msgstr "Navigation" + +msgid "Selection" +msgstr "Valg" + +msgid "Search" +msgstr "Søg" + +msgid "Down" +msgstr "Ned" + +msgid "Up" +msgstr "Op" + +msgid "Confirm" +msgstr "Bekræft" + +msgid "Focus right" +msgstr "Fokus til højre" + +msgid "Focus left" +msgstr "Fokus til venstre" + +msgid "Toggle" +msgstr "Slå til/fra" + +msgid "Show/Hide help" +msgstr "Vis/skjul hjælp" + +msgid "Quit" +msgstr "Afslut" + +msgid "First" +msgstr "Første" + +msgid "Last" +msgstr "Sidste" + +msgid "Select" +msgstr "Vælg" + +msgid "Page Up" +msgstr "Side op" + +msgid "Page Down" +msgstr "Side ned" + +msgid "Page up" +msgstr "Side op" + +msgid "Page down" +msgstr "Side ned" + +msgid "Page Left" +msgstr "Side venstre" + +msgid "Page Right" +msgstr "Side højre" + +msgid "Cursor up" +msgstr "Markør op" + +msgid "Cursor down" +msgstr "Markør ned" + +msgid "Cursor right" +msgstr "Markør højre" + +msgid "Cursor left" +msgstr "Markør venstre" + +msgid "Top" +msgstr "Top" + +msgid "Bottom" +msgstr "Bund" + +msgid "Home" +msgstr "Hjem" + +msgid "End" +msgstr "Slut" + +msgid "Toggle option" +msgstr "Toggle mulighed" + +msgid "Scroll Up" +msgstr "Rul op" + +msgid "Scroll Down" +msgstr "Rul ned" + +msgid "Scroll Left" +msgstr "Rul til venstre" + +msgid "Scroll Right" +msgstr "Rul til højre" + +msgid "Scroll Home" +msgstr "Rul til start" + +msgid "Scroll End" +msgstr "Rul til slut" + +msgid "Focus Next" +msgstr "Fokusér næste" + +msgid "Focus Previous" +msgstr "Fokusér forrige" + +msgid "Copy selected text" +msgstr "Kopiér markeret tekst" + +msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "labwc skal have adgang til dit seat (samling af hardwareenheder, dvs. tastatur, mus osv.)" + +msgid "Choose an option to give labwc access to your hardware" +msgstr "Vælg en mulighed for at give labwc adgang til din hardware" + +msgid "niri needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" +msgstr "niri skal have adgang til dit seat (samling af hardwareenheder, dvs. tastatur, mus osv.)" + +msgid "Choose an option to give niri access to your hardware" +msgstr "Vælg en mulighed for at give niri adgang til din hardware" + +msgid "Mark/Unmark as ESP" +msgstr "Markér/fjern markering som ESP" + +msgid "Package group:" +msgstr "Pakkegruppe:" + +msgid "Exit archinstall" +msgstr "Afslut archinstall" + +msgid "Reboot system" +msgstr "Genstart systemet" + +msgid "chroot into installation for post-installation configurations" +msgstr "chroot ind i installationen for efterinstallationskonfiguration" + +msgid "Installation completed" +msgstr "Installationen er fuldført" + +msgid "What would you like to do next?" +msgstr "Hvad vil du gøre nu?" + +#, python-brace-format +msgid "Select which mode to configure for \"{}\"" +msgstr "Vælg hvilken tilstand der skal konfigureres for \"{}\"" + +msgid "Incorrect credentials file decryption password" +msgstr "Incellerrect credentials fil decryption adgangskode" + +msgid "Incorrect password" +msgstr "Incellerrect adgangskode" + +msgid "Credentials file decryption password" +msgstr "Credentials fil decryption adgangskode" + +msgid "Do you want to encrypt the user_credentials.json file?" +msgstr "Vil du encrypt bruger_credentials.json fil?" + +msgid "Credentials file encryption password" +msgstr "Credentials fil kryptering adgangskode" + +#, python-brace-format +msgid "Repositories: {}" +msgstr "Repositelleries: {}" + +msgid "New version available" +msgstr "Ny version tilgængelig" + +msgid "Passwordless login" +msgstr "Adgangskodeless login" + +msgid "Second factor login" +msgstr "Second facteller login" + +msgid "Bluetooth" +msgstr "Bluetooth" + +msgid "Would you like to configure Bluetooth?" +msgstr "Vil du configure Bluetooth?" + +msgid "Print service" +msgstr "Udskriftstjeneste" + +msgid "Would you like to configure the print service?" +msgstr "Vil du configure udskriftstjeneste?" + +msgid "Power management" +msgstr "Strømstyring" + +msgid "Authentication" +msgstr "Godkendelse" + +msgid "Applications" +msgstr "Programmer" + +msgid "U2F login method: " +msgstr "U2F-loginmetode: " + +msgid "Passwordless sudo: " +msgstr "Adgangskodeless sudo: " + +#, python-brace-format +msgid "Btrfs snapshot type: {}" +msgstr "Btrfs-snapshot-type: {}" + +msgid "Syncing the system..." +msgstr "Syncing system..." + +msgid "Value cannot be empty" +msgstr "Værdien må ikke være tom" + +msgid "Snapshot type" +msgstr "Snapshot-type" + +#, python-brace-format +msgid "Snapshot type: {}" +msgstr "Snapshot-type: {}" + +msgid "U2F login setup" +msgstr "Opsætning af U2F-login" + +msgid "No U2F devices found" +msgstr "No U2F enheds found" + +msgid "U2F Login Method" +msgstr "U2F-loginmetode" + +msgid "Enable passwordless sudo?" +msgstr "Enable adgangskodeless sudo?" + +#, python-brace-format +msgid "Setting up U2F device for user: {}" +msgstr "Sætter U2F-enhed op for bruger: {}" + +msgid "You may need to enter the PIN and then touch your U2F device to register it" +msgstr "Du skal muligvis indtaste PIN-koden og derefter røre ved din U2F-enhed for at registrere den" + +msgid "Starting device modifications in " +msgstr "Starting enhed modifications in " + +msgid "No network connection found" +msgstr "No netværk connection found" + +msgid "Would you like to connect to a Wifi?" +msgstr "Vil du oprette forbindelse til Wi-Fi?" + +msgid "No wifi interface found" +msgstr "No wifi grænseflade found" + +msgid "Select wifi network to connect to" +msgstr "Vælg det Wi-Fi-netværk der skal oprettes forbindelse til" + +msgid "Scanning wifi networks..." +msgstr "Scanning wifi netværks..." + +msgid "No wifi networks found" +msgstr "No wifi netværks found" + +msgid "Failed setting up wifi" +msgstr "Kunne ikke sætte wifi op" + +msgid "Enter wifi password" +msgstr "Indtast wifi adgangskode" + +msgid "Ok" +msgstr "OK" + +msgid "Removable" +msgstr "Flytbar" + +msgid "Install to removable location" +msgstr "Installer til flytbar placering" + +msgid "Will install to /EFI/BOOT/ (removable location)" +msgstr "Installerer til /EFI/BOOT/ (flytbar placering)" + +msgid "Will install to standard location with NVRAM entry" +msgstr "Installerer til standardplacering med NVRAM-post" + +msgid "Would you like to install the bootloader to the default removable media search location?" +msgstr "Vil du installere bootloaderen på standardplaceringen for søgning efter flytbare medier?" + +msgid "This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is useful for:" +msgstr "Dette installerer bootloaderen til /EFI/BOOT/BOOTX64.EFI (eller tilsvarende), hvilket er nyttigt for:" + +msgid "USB drives or other portable external media." +msgstr "USB drevs eller other pellertable external media." + +msgid "Systems where you want the disk to be bootable on any computer." +msgstr "Systems where you want disk skal være bootbar on any computer." + +msgid "Firmware that does not properly support NVRAM boot entries." +msgstr "Firmware der ikke korrekt understøtter NVRAM-bootposter." + +msgid "Will install to /EFI/BOOT/ (removable location, safe default)" +msgstr "Installerer til /EFI/BOOT/ (flytbar placering, sikker standard)" + +msgid "Will install to custom location with NVRAM entry" +msgstr "Installerer til brugerdefineret placering med NVRAM-post" + +msgid "Firmware that does not properly support NVRAM boot entries like most MSI motherboards," +msgstr "Firmware der ikke korrekt understøtter NVRAM-bootposter, som de fleste MSI-bundkort," + +msgid "most Apple Macs, many laptops..." +msgstr "de fleste Apple Mac-computere, mange bærbare..." + +msgid "Language" +msgstr "Sprog" + +msgid "Compression algorithm" +msgstr "Komprimeringsalgoritme" + +msgid "Only packages such as base, sudo, linux, linux-firmware, efibootmgr and optional profile packages are installed." +msgstr "Only pakker such som base, sudo, linux, linux-firmware, efibootmgr og mulighedal profil pakker are installereed." + +msgid "Select zram compression algorithm:" +msgstr "Vælg zram komprimering algellerithm:" + +msgid "Use Network Manager (default backend)" +msgstr "Use Netværk Manager (standard backend)" + +msgid "Use Network Manager (iwd backend)" +msgstr "Use Netværk Manager (iwd backend)" + +msgid "Firewall" +msgstr "Firewall" + +msgid "Additional fonts" +msgstr "Yderligere skrifttyper" + +msgid "Select font packages to install" +msgstr "Vælg skrifttypepakker der skal installeres" + +msgid "Unicode font coverage for most languages" +msgstr "Unicode-skrifttypedækning for de fleste sprog" + +msgid "color emoji for browsers and apps" +msgstr "farveemoji til browsere og apps" + +msgid "Chinese, Japanese, Korean characters" +msgstr "Chinese, Japanese, Kellerean characters" + +msgid "Select audio configuration" +msgstr "Vælg lyd konfiguration" + +msgid "Enter credentials file decryption password" +msgstr "Indtast credentials fil decryption adgangskode" + +msgid "Enter root password" +msgstr "Indtast root-adgangskode" + +msgid "Select bootloader to install" +msgstr "Vælg bootloader der skal installeres" + +msgid "Configuration preview" +msgstr "Konfigurationsforhåndsvisning" + +msgid "Enter a directory for the configuration(s) to be saved" +msgstr "Indtast en mappe hvor konfigurationen/konfigurationerne skal gemmes" + +msgid "Select encryption type" +msgstr "Vælg kryptering type" + +msgid "Select disks for the installation" +msgstr "Vælg diske til installationen" + +msgid "Enter a mountpoint" +msgstr "Indtast en monteringspunkt" + +#, python-brace-format +msgid "Enter a size (default: {}): " +msgstr "Indtast en størrelse (standard: {}): " + +msgid "Enter subvolume name" +msgstr "Indtast underenhed navn" + +msgid "Enter subvolume mountpoint" +msgstr "Indtast underenhed monteringspunkt" + +msgid "Select a disk configuration" +msgstr "Vælg en disk konfiguration" + +msgid "Enter root mount directory" +msgstr "Indtast root montere mappe" + +msgid "You will use whatever drive-setup is mounted at the specified directory" +msgstr "You will use whatever drev-setup is montereed at specified mappe" + +msgid "WARNING: Archinstall won't check the suitability of this setup" +msgstr "ADVARSEL: Archinstall kontrollerer ikke om denne opsætning er egnet" + +msgid "Select main filesystem" +msgstr "Vælg main filsystem" + +msgid "Enter a hostname" +msgstr "Indtast en hostnavn" + +msgid "Select timezone" +msgstr "Vælg timezone" + +msgid "Enter the number of parallel downloads to be enabled" +msgstr "Indtast antallet af parallelle downloads der skal aktiveres" + +#, python-brace-format +msgid "Value must be between 1 and {}" +msgstr "Værdien skal være mellem 1 og {}" + +msgid "Select which kernel(s) to install" +msgstr "Vælg hvilke kerner der skal installeres" + +msgid "Enter a respository name" +msgstr "Indtast en respositellery navn" + +msgid "Enter the repository url" +msgstr "Indtast pakkearkiv url" + +msgid "Enter server url" +msgstr "Indtast server url" + +msgid "Select mirror regions to be enabled" +msgstr "Vælg spejl regioner skal være aktiveret" + +msgid "Select optional repositories to be enabled" +msgstr "Vælg mulighedal pakkearkiver skal være aktiveret" + +msgid "Select an interface" +msgstr "Vælg en grænseflade" + +msgid "Choose network configuration" +msgstr "Vælg netværk konfiguration" + +msgid "Recommended: Network Manager for desktop, Manual for server" +msgstr "Anbefalet: Network Manager til desktop, manuel til server" + +msgid "Warning: no network configuration selected. Network will need to be set up manually on the installed system." +msgstr "Advarsel: ingen netværkskonfiguration valgt. Netværket skal sættes op manuelt på det installerede system." + +msgid "No packages found" +msgstr "Ingen pakker fundet" + +msgid "Select which greeter to install" +msgstr "Vælg hvilken login-skærm der skal installeres" + +msgid "Select a profile type" +msgstr "Vælg en profil type" + +msgid "Enter new password" +msgstr "Indtast ny adgangskode" + +msgid "Enter a username" +msgstr "Indtast et brugernavn" + +msgid "Enter a password" +msgstr "Indtast en adgangskode" + +msgid "The password did not match, please try again" +msgstr "The adgangskode did not match, please try again" + +msgid "Password strength: Weak" +msgstr "Adgangskodestyrke: Svag" + +msgid "Password strength: Moderate" +msgstr "Adgangskodestyrke: Moderat" + +msgid "Password strength: Strong" +msgstr "Adgangskodestyrke: Stærk" + +msgid "The selected desktop profile requires a regular user to log in via the greeter" +msgstr "Den valgte skrivebordsprofil kræver en almindelig bruger for at logge ind via login-skærmen" + +#, python-brace-format +msgid "Environment type: {} {}" +msgstr "Miljøtype: {} {}" + +msgid "Input cannot be empty" +msgstr "Input må ikke være tomt" + +msgid "Recommended" +msgstr "Anbefalet" + +msgid "Package" +msgstr "Pakke" + +msgid "Curated selection of KDE Plasma packages" +msgstr "Kurateret udvalg af KDE Plasma-pakker" + +msgid "Dependencies" +msgstr "Afhængigheder" + +msgid "Package group" +msgstr "Pakkegruppe" + +msgid "Extensive KDE Plasma installation" +msgstr "Extensive KDE Plasma installereation" + +msgid "Packages in group" +msgstr "Pakker i gruppen" + +msgid "Minimal KDE Plasma installation" +msgstr "Minimal KDE Plasma installereation" + +msgid "Description" +msgstr "Beskrivelse" + +msgid "Select a flavor of KDE Plasma to install" +msgstr "Vælg hvilken variant af KDE Plasma der skal installeres" + +msgid "Arial/Times/Courier replacement, Cyrillic support for Steam/games" +msgstr "Erstatning for Arial/Times/Courier, kyrillisk understøttelse til Steam/spil" + +msgid "wide Unicode coverage, good fallback font" +msgstr "wide Unicode coverage, good fallback skrifttype" + +#, python-brace-format +msgid "Setting up U2F login: {u2f_config.u2f_login_method.value}" +msgstr "Sætter U2F-login op: {u2f_config.u2f_login_method.value}" + +#, python-brace-format +msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" +msgstr "Standard: {DEFAULT_ITER_TIME} ms, anbefalet område: 1000-60000" From 3223ae421249277d341beaecc4150a51f9db9258 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Wed, 29 Apr 2026 03:08:24 -0400 Subject: [PATCH 30/40] Remove the old curses-based TUI code (#4497) The new Textual-based TUI shipped in the April .iso. --- archinstall/lib/menu/abstract_menu.py | 3 +- archinstall/tui/curses_menu.py | 1369 ------------------------- archinstall/tui/help.py | 109 -- archinstall/tui/menu_item.py | 515 ---------- archinstall/tui/result.py | 37 - archinstall/tui/types.py | 144 --- 6 files changed, 1 insertion(+), 2176 deletions(-) delete mode 100644 archinstall/tui/curses_menu.py delete mode 100644 archinstall/tui/help.py delete mode 100644 archinstall/tui/menu_item.py delete mode 100644 archinstall/tui/result.py delete mode 100644 archinstall/tui/types.py diff --git a/archinstall/lib/menu/abstract_menu.py b/archinstall/lib/menu/abstract_menu.py index 084c6e4f..8e9cbed7 100644 --- a/archinstall/lib/menu/abstract_menu.py +++ b/archinstall/lib/menu/abstract_menu.py @@ -5,7 +5,6 @@ from typing import Any, Self, override from archinstall.lib.menu.helpers import Selection from archinstall.lib.output import error from archinstall.lib.translationhandler import tr -from archinstall.tui.types import Chars from archinstall.tui.ui.components import InstanceRunnable from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup from archinstall.tui.ui.result import ResultType @@ -154,7 +153,7 @@ class AbstractSubMenu[ValueT](AbstractMenu[ValueT]): auto_cursor: bool = True, allow_reset: bool = False, ): - back_text = f'{Chars.Right_arrow} ' + tr('Back') + back_text = '← ' + tr('Back') item_group.add_item(MenuItem(text=back_text)) super().__init__( diff --git a/archinstall/tui/curses_menu.py b/archinstall/tui/curses_menu.py deleted file mode 100644 index b64a800c..00000000 --- a/archinstall/tui/curses_menu.py +++ /dev/null @@ -1,1369 +0,0 @@ -import curses -import os -import signal -import sys -from abc import ABCMeta, abstractmethod -from collections.abc import Callable -from curses.ascii import isprint -from curses.textpad import Textbox -from types import FrameType, TracebackType -from typing import ClassVar, Literal, Self, override - -from archinstall.lib.translationhandler import tr -from archinstall.tui.help import Help -from archinstall.tui.menu_item import MenuItem, MenuItemGroup, MenuItemsState -from archinstall.tui.result import Result, ResultType -from archinstall.tui.types import ( - SCROLL_INTERVAL, - STYLE, - Alignment, - Chars, - FrameDim, - FrameProperties, - FrameStyle, - MenuKeys, - Orientation, - PreviewStyle, - ViewportEntry, -) - - -class AbstractCurses[ValueT](metaclass=ABCMeta): - def __init__(self) -> None: - self._help_window = self._set_help_viewport() - - @abstractmethod - def resize_win(self) -> None: - pass - - @abstractmethod - def kickoff(self, win: curses.window) -> Result[ValueT]: - pass - - def clear_all(self) -> None: - Tui.t().screen.clear() - Tui.t().screen.refresh() - - def clear_help_win(self) -> None: - self._help_window.erase() - - def _set_help_viewport(self) -> Viewport: - max_height, max_width = Tui.t().max_yx - height = max_height - 10 - - max_help_width = max([len(line) for line in Help.get_help_text().split('\n')]) - x_start = int((max_width / 2) - (max_help_width / 2)) - - return Viewport( - max_help_width + 10, - height, - x_start, - int((max_height / 2) - height / 2), - frame=FrameProperties.min(tr('Archinstall help')), - ) - - def _confirm_interrupt(self, warning: str) -> bool: - while True: - result = SelectMenu[bool]( - MenuItemGroup.yes_no(), - header=warning, - alignment=Alignment.CENTER, - columns=2, - orientation=Orientation.HORIZONTAL, - ).run() - - match result.type_: - case ResultType.Selection: - if result.item() == MenuItem.yes(): - return True - - return False - - def help_text(self) -> str: - return tr('Press Ctrl+h for help') - - def _show_help(self) -> None: - help_text = Help.get_help_text() - lines = help_text.split('\n') - - entries = [ViewportEntry('', 0, 0, STYLE.NORMAL)] - entries += [ViewportEntry(f' {e} ', idx + 1, 0, STYLE.NORMAL) for idx, e in enumerate(lines)] - self._help_window.update(entries, 0) - - def get_header_entries(self, header: str) -> list[ViewportEntry]: - full_header = [] - rows = header.split('\n') - - for cur_row, line in enumerate(rows): - full_header += [ViewportEntry(line, cur_row, 0, STYLE.NORMAL)] - - return full_header - - -class AbstractViewport: - def __init__(self) -> None: - pass - - def add_str(self, screen: curses.window, row: int, col: int, text: str, color: STYLE) -> None: - try: - screen.addstr(row, col, text, Tui.t().get_color(color)) - except curses.error: - # debug(f'Curses error while adding string to viewport: {text}') - pass - - def add_frame( - self, - entries: list[ViewportEntry], - max_width: int, - max_height: int, - frame: FrameProperties, - scroll_pct: int | None = None, - ) -> list[ViewportEntry]: - if not entries: - return [] - - dim = self._get_frame_dim(entries, max_width, max_height, frame) - - h_bar = Chars.Horizontal * (dim.x_delta() - 2) - top_ve = self._get_top(dim, h_bar, frame, scroll_pct) - bottom_ve = self._get_bottom(dim, h_bar, scroll_pct) - - frame_border = [] - - for i in range(1, dim.height): - frame_border += [ViewportEntry(Chars.Vertical, i, dim.x_start, STYLE.NORMAL)] - - frame_border += self._get_right_frame(dim, scroll_pct) - - # adjust the original rows and cols of the entries as - # they need to be shrunk by 1 to make space for the frame - entries = self._adjust_entries(entries) - - framed_entries = [ - top_ve, - bottom_ve, - *frame_border, - *entries, - ] - - return framed_entries - - def align_center(self, lines: list[ViewportEntry], width: int) -> int: - max_col = self._max_col(lines) - x_offset = int((width / 2) - (max_col / 2)) - return x_offset - - def _get_right_frame( - self, - dim: FrameDim, - scroll_percentage: int | None = None, - ) -> list[ViewportEntry]: - right_frame = {} - scroll_height = int(dim.height * scroll_percentage // 100) if scroll_percentage else 0 - - if scroll_height <= 0: - scroll_height = 1 - elif scroll_height >= dim.height: - scroll_height = dim.height - 1 - - for i in range(1, dim.height): - right_frame[i] = ViewportEntry(Chars.Vertical, i, dim.x_end - 1, STYLE.NORMAL) - - if scroll_percentage is not None: - right_frame[0] = ViewportEntry(Chars.Triangle_up, 0, dim.x_end - 1, STYLE.NORMAL) - right_frame[scroll_height] = ViewportEntry(Chars.Block, scroll_height, dim.x_end - 1, STYLE.NORMAL) - right_frame[dim.height] = ViewportEntry(Chars.Triangle_down, dim.height, dim.x_end - 1, STYLE.NORMAL) - - return list(right_frame.values()) - - def _get_top( - self, - dim: FrameDim, - h_bar: str, - frame: FrameProperties, - scroll_percentage: int | None = None, - ) -> ViewportEntry: - top = self._replace_str(h_bar, 1, f' {frame.header} ') if frame.header else h_bar - - if scroll_percentage is None: - top = Chars.Upper_left + top + Chars.Upper_right - else: - top = Chars.Upper_left + top[:-1] - - return ViewportEntry(top, 0, dim.x_start, STYLE.NORMAL) - - def _get_bottom( - self, - dim: FrameDim, - h_bar: str, - scroll_pct: int | None = None, - ) -> ViewportEntry: - if scroll_pct is None: - bottom = Chars.Lower_left + h_bar + Chars.Lower_right - else: - bottom = Chars.Lower_left + h_bar[:-1] - - return ViewportEntry(bottom, dim.height, dim.x_start, STYLE.NORMAL) - - def _get_frame_dim( - self, - entries: list[ViewportEntry], - max_width: int, - max_height: int, - frame: FrameProperties, - ) -> FrameDim: - rows = self._assemble_entries(entries).split('\n') - header_len = len(frame.header) if frame.header else 0 - header_len += 3 # for header padding - - if frame.w_frame_style == FrameStyle.MIN: - frame_start = min([e.col for e in entries]) - max_row_cols = [(e.col + len(e.text) + 1) for e in entries] - max_row_cols.append(header_len) - frame_end = max(max_row_cols) - - # 2 for frames, 1 for extra space start away from frame - # must align with def _adjust_entries - # 2 for frame - frame_end += 3 - - frame_height = len(rows) + 1 - if frame_height > max_height: - frame_height = max_height - else: - frame_start = 0 - frame_end = max_width - frame_height = max_height - 1 - - return FrameDim(frame_start, frame_end, frame_height) - - def _adjust_entries( - self, - entries: list[ViewportEntry], - ) -> list[ViewportEntry]: - for entry in entries: - # top row frame offset - entry.row += 1 - # left side frame offset + extra space from frame to start from - entry.col += 2 - - return entries - - def _num_unique_rows(self, entries: list[ViewportEntry]) -> int: - return len(set([e.row for e in entries])) - - def _max_col(self, entries: list[ViewportEntry]) -> int: - values = [len(e.text) + e.col for e in entries] - if not values: - return 0 - return max(values) - - def _replace_str(self, text: str, index: int = 0, replacement: str = '') -> str: - len_replace = len(replacement) - return f'{text[:index]}{replacement}{text[index + len_replace :]}' - - def _assemble_entries(self, entries: list[ViewportEntry]) -> str: - if not entries: - return '' - - max_col = self._max_col(entries) - view = [max_col * ' '] * self._num_unique_rows(entries) - - for e in entries: - view[e.row] = self._replace_str(view[e.row], e.col, e.text) - - view = [v.rstrip() for v in view] - - return '\n'.join(view) - - -class EditViewport(AbstractViewport): - def __init__( - self, - width: int, - edit_width: int, - edit_height: int, - x_start: int, - y_start: int, - process_key: Callable[[int], int], - frame: FrameProperties, - alignment: Alignment = Alignment.CENTER, - hide_input: bool = False, - ) -> None: - super().__init__() - - self._max_height, self._max_width = Tui.t().max_yx - - self._width = width - self._edit_width = edit_width - self._edit_height = edit_height - self.x_start = x_start - self.y_start = y_start - self._process_key_cb = process_key - self._frame = frame - self._alignment = alignment - self._hide_input = hide_input - - self._main_win: curses.window | None = None - self._edit_win: curses.window | None = None - self._textbox: Textbox | None = None - - self._init_wins() - - def _init_wins(self) -> None: - self._main_win = curses.newwin(self._edit_height, self._width, self.y_start, 0) - self._main_win.nodelay(False) - - x_offset = 0 - if self._alignment == Alignment.CENTER: - x_offset = int((self._width / 2) - (self._edit_width / 2)) - - self._edit_win = self._main_win.subwin( - 1, - self._edit_width - 2, - self.y_start + 1, - self.x_start + x_offset + 1, - ) - - def update(self) -> None: - if not self._main_win: - return - - self._main_win.erase() - - framed = self.add_frame( - [ViewportEntry('', 0, 0, STYLE.NORMAL)], - self._edit_width, - 3, - frame=self._frame, - ) - - x_offset = 0 - if self._alignment == Alignment.CENTER: - x_offset = self.align_center(framed, self._width) - - for row in framed: - self.add_str( - self._main_win, - row.row, - row.col + x_offset, - row.text, - row.style, - ) - - self._main_win.refresh() - - def textbox_value(self) -> str: - if not self._textbox: - return '' - return self._textbox.gather().strip() - - def erase(self) -> None: - if self._main_win: - self._main_win.erase() - self._main_win.refresh() - - def edit(self, default_text: str | None = None) -> None: - assert self._edit_win and self._main_win - - self._edit_win.erase() - - if default_text is not None and len(default_text) > 0: - self._edit_win.addstr(0, 0, default_text) - - # if this gets initialized multiple times it will be an overlay - # and ENTER has to be pressed multiple times to accept - if not self._textbox: - self._textbox = Textbox(self._edit_win) - self._main_win.refresh() - - self._textbox.edit(self._process_key_cb) - - -class Viewport(AbstractViewport): - def __init__( - self, - width: int, - height: int, - x_start: int, - y_start: int, - frame: FrameProperties | None = None, - alignment: Alignment = Alignment.LEFT, - ): - super().__init__() - - self.width = width - self.height = height - self.x_start = x_start - self.y_start = y_start - self._frame = frame - self._alignment = alignment - - self._main_win = curses.newwin(self.height, self.width, self.y_start, self.x_start) - self._main_win.nodelay(False) - self._main_win.standout() - - def getch(self) -> int: - return self._main_win.getch() - - def erase(self) -> None: - self._main_win.erase() - self._main_win.refresh() - - def update( - self, - entries: list[ViewportEntry], - cur_pos: int = 0, - scroll_pos: int | None = None, - ) -> None: - # self._state = self._get_viewport_state(lines, cur_pos, scroll_pos) - # visible_entries = self._adjust_entries_row(self._state.displayed_entries) - visible_entries = entries - - if self._frame: - visible_entries = self.add_frame( - visible_entries, - self.width, - self.height, - frame=self._frame, - scroll_pct=scroll_pos, - ) - - x_offset = 0 - if self._alignment == Alignment.CENTER: - x_offset = self.align_center(visible_entries, self.width) - - self._main_win.erase() - - for entry in visible_entries: - self.add_str( - self._main_win, - entry.row, - entry.col + x_offset, - entry.text, - entry.style, - ) - - self._main_win.refresh() - - -class EditMenu(AbstractCurses[str]): - def __init__( - self, - title: str, - edit_width: int = 50, - header: str | None = None, - validator: Callable[[str | None], str | None] | None = None, - allow_skip: bool = False, - allow_reset: bool = False, - reset_warning_msg: str | None = None, - alignment: Alignment = Alignment.CENTER, - default_text: str | None = None, - hide_input: bool = False, - ): - super().__init__() - - self._max_height, self._max_width = Tui.t().max_yx - - self._header = header - - self._header_entries = [] - if header: - self._header_entries = self.get_header_entries(header) - - self._validator = validator - self._allow_skip = allow_skip - self._allow_reset = allow_reset - self._interrupt_warning = reset_warning_msg - self._alignment = alignment - self._edit_width = edit_width - self._default_text = default_text - self._hide_input = hide_input - - if self._interrupt_warning is None: - self._interrupt_warning = tr('Are you sure you want to reset this setting?') + '\n' - - title = f'* {title}' if not self._allow_skip else title - self._frame = FrameProperties(title, FrameStyle.MAX) - - self._title_vp: Viewport | None = None - self._header_vp: Viewport | None = None - self._input_vp: EditViewport | None = None - self._info_vp: Viewport | None = None - - self._set_default_info = True - self._only_ascii_text = ViewportEntry(tr('Only ASCII characters are supported'), 0, 0, STYLE.NORMAL) - - self._init_viewports() - - self._last_state: Result[str] | None = None - self._help_active = False - - self._current_text = default_text or '' - self._real_input = default_text or '' - - def _init_viewports(self) -> None: - y_offset = 0 - - self._title_vp = Viewport(self._max_width, 2, 0, y_offset) - y_offset += 2 - - if self._header_entries: - header_height = len(self._header_entries) - self._header_vp = Viewport(self._max_width, header_height, 0, y_offset, alignment=self._alignment) - y_offset += header_height - - self._input_vp = EditViewport( - self._max_width, - self._edit_width, - 3, - 0, - y_offset, - self._process_edit_key, - frame=self._frame, - alignment=self._alignment, - hide_input=self._hide_input, - ) - - y_offset += 3 - self._info_vp = Viewport(self._max_width, 1, 0, y_offset, alignment=self._alignment) - - def input(self) -> Result[str]: - result = Tui.run(self) - - assert not result.has_item() or isinstance(result.text(), str) - - self._clear_all() - return result - - @override - def resize_win(self) -> None: - self._draw() - - def _clear_all(self) -> None: - if self._title_vp: - self._title_vp.erase() - if self._header_vp: - self._header_vp.erase() - if self._input_vp: - self._input_vp.erase() - if self._info_vp: - self._info_vp.erase() - - def _get_input_text(self) -> str | None: - assert self._input_vp - assert self._info_vp - - text = self._real_input - - self.clear_all() - - if self._validator: - if (err := self._validator(text)) is not None: - self.clear_all() - entry = ViewportEntry(err, 0, 0, STYLE.ERROR) - self._info_vp.update([entry], 0) - self._set_default_info = False - - if self._hide_input: - self._real_input = '' - - return None - - return text - - def _draw(self) -> None: - if self._title_vp: - help_text = self.help_text() - help_entry = ViewportEntry(help_text, 0, 0, STYLE.NORMAL) - self._title_vp.update([help_entry], 0) - - if self._header_entries and self._header_vp: - self._header_vp.update(self._header_entries, 0) - - if self._input_vp: - self._input_vp.update() - - if self._set_default_info and self._info_vp: - self._info_vp.update([self._only_ascii_text], 0) - - self._input_vp.edit(default_text=self._real_input) - - @override - def kickoff(self, win: curses.window) -> Result[str]: - try: - self._draw() - except KeyboardInterrupt: - if not self._handle_interrupt(): - return self.kickoff(win) - else: - self._last_state = Result(ResultType.Reset, None) - - if self._last_state is None: - return self.kickoff(win) - - if self._last_state.type_ == ResultType.Selection: - text = self._get_input_text() - - if text is None: - return self.kickoff(win) - else: - if not text and not self._allow_skip: - return self.kickoff(win) - - return Result(ResultType.Selection, text) - - return self._last_state - - def _process_edit_key(self, key: int) -> int: - key_handles = MenuKeys.from_ord(key) - - if self._help_active: - if MenuKeys.ESC in key_handles: - self._help_active = False - self.clear_help_win() - return 7 - return 0 - - # remove standard keys from the list of key handles - key_handles = [key for key in key_handles if key != MenuKeys.STD_KEYS] - - # regular key stroke should be passed to the editor - if key_handles: - special_key = key_handles[0] - - match special_key: - case MenuKeys.HELP: - assert self._input_vp - self._current_text = self._input_vp.textbox_value() - self._clear_all() - self._help_active = True - self._show_help() - return 0 - case MenuKeys.ESC: - if self._allow_skip: - self._last_state = Result(ResultType.Skip, None) - key = 7 - case MenuKeys.ACCEPT: - self._last_state = Result(ResultType.Selection, None) - key = 7 - case MenuKeys.BACKSPACE: - if len(self._real_input) > 0: - self._real_input = self._real_input[:-1] - case _: - if isprint(key): - self._real_input += chr(key) - if self._hide_input: - key = 42 - else: - try: - if isprint(key): - self._real_input += chr(key) - if self._hide_input: - key = 42 - except Exception: - pass - - return key - - def _handle_interrupt(self) -> bool: - if self._allow_reset: - if self._interrupt_warning: - return self._confirm_interrupt(self._interrupt_warning) - else: - return False - - return True - - -class SelectMenu[ValueT](AbstractCurses[ValueT]): - def __init__( - self, - group: MenuItemGroup, - multi: bool = False, - orientation: Orientation = Orientation.VERTICAL, - alignment: Alignment = Alignment.LEFT, - columns: int = 1, - column_spacing: int = 10, - header: str | None = None, - frame: FrameProperties | None = None, - cursor_char: str = '>', - search_enabled: bool = True, - allow_skip: bool = False, - allow_reset: bool = False, - reset_warning_msg: str | None = None, - preview_style: PreviewStyle = PreviewStyle.NONE, - preview_size: float | Literal['auto'] = 0.2, - preview_frame: FrameProperties | None = None, - additional_title: str | None = None, - ): - super().__init__() - - self._multi = multi - self._cursor_char = f'{cursor_char} ' - self._search_enabled = search_enabled - self._allow_skip = allow_skip - self._allow_reset = allow_reset - self._active_search = False - self._help_active = False - self._item_group = group - self._preview_style = preview_style - self._preview_frame = preview_frame - self._orientation = orientation - self._column_spacing = column_spacing - self._alignment = alignment - self._footers = self._footer_entries() - self._frame = frame - self._interrupt_warning = reset_warning_msg - self._header = header - self._additional_title = additional_title - - self._header_entries = [] - if header: - self._header_entries = self.get_header_entries(header) - - if self._interrupt_warning is None: - self._interrupt_warning = tr('Are you sure you want to reset this setting?') + '\n' - - if self._orientation == Orientation.HORIZONTAL: - self._horizontal_cols = columns - else: - self._horizontal_cols = 1 - - self._prev_scroll_pos: int = 0 - - self._visible_entries: list[ViewportEntry] = [] - self._max_height, self._max_width = Tui.t().max_yx - - self._title_vp: Viewport | None = None - self._header_vp: Viewport | None = None - self._footer_vp: Viewport | None = None - self._menu_vp: Viewport | None = None - self._preview_vp: Viewport | None = None - - self._init_viewports(preview_size) - - assert self._menu_vp is not None - self._items_state: MenuItemsState = MenuItemsState( # type: ignore[unreachable] - self._item_group, - total_cols=self._horizontal_cols, - total_rows=self._menu_vp.height, - with_frame=self._frame is not None, - ) - - def run(self) -> Result[ValueT]: - result = Tui.run(self) - self._clear_all() - return result - - @override - def kickoff(self, win: curses.window) -> Result[ValueT]: - self._draw() - - while True: - try: - if not self._help_active: - self._draw() - - key = win.getch() - - ret = self._process_input_key(key) - - if ret is not None: - return ret - except KeyboardInterrupt: - if self._handle_interrupt(): - return Result(ResultType.Reset, None) - else: - return self.kickoff(win) - - @override - def resize_win(self) -> None: - self._draw() - - def _clear_all(self) -> None: - self.clear_help_win() - - if self._header_vp: - self._header_vp.erase() - if self._menu_vp: - self._menu_vp.erase() - if self._preview_vp: - self._preview_vp.erase() - if self._footer_vp: - self._footer_vp.erase() - if self._title_vp: - self._title_vp.erase() - - def _footer_entries(self) -> list[ViewportEntry]: - if self._active_search: - filter_pattern = self._item_group.filter_pattern - return [ViewportEntry(f'/{filter_pattern}', 0, 0, STYLE.NORMAL)] - - return [] - - def _init_viewports(self, arg_prev_size: float | Literal['auto']) -> None: - footer_height = 2 # possible filter at the bottom - y_offset = 0 - - self._title_vp = Viewport(self._max_width, 2, 0, y_offset) - y_offset += 2 - - if self._header_entries: - header_height = len(self._header_entries) - self._header_vp = Viewport( - self._max_width, - header_height, - 0, - y_offset, - alignment=self._alignment, - ) - y_offset += header_height - - prev_offset = y_offset + footer_height - prev_size = self._determine_prev_size(arg_prev_size, offset=prev_offset) - available_height = self._max_height - y_offset - footer_height - - match self._preview_style: - case PreviewStyle.BOTTOM: - menu_height = available_height - prev_size - - self._menu_vp = Viewport( - self._max_width, - menu_height, - 0, - y_offset, - frame=self._frame, - alignment=self._alignment, - ) - self._preview_vp = Viewport( - self._max_width, - prev_size, - 0, - menu_height + y_offset, - frame=self._preview_frame, - ) - case PreviewStyle.RIGHT: - menu_width = self._max_width - prev_size - - self._menu_vp = Viewport( - menu_width, - available_height, - 0, - y_offset, - frame=self._frame, - alignment=self._alignment, - ) - self._preview_vp = Viewport( - prev_size, - available_height, - menu_width, - y_offset, - frame=self._preview_frame, - alignment=self._alignment, - ) - case PreviewStyle.TOP: - menu_height = available_height - prev_size - - self._menu_vp = Viewport( - self._max_width, - menu_height, - 0, - prev_size + y_offset, - frame=self._frame, - alignment=self._alignment, - ) - self._preview_vp = Viewport( - self._max_width, - prev_size, - 0, - y_offset, - frame=self._preview_frame, - alignment=self._alignment, - ) - case PreviewStyle.NONE: - self._menu_vp = Viewport( - self._max_width, - available_height, - 0, - y_offset, - frame=self._frame, - alignment=self._alignment, - ) - - self._footer_vp = Viewport( - self._max_width, - footer_height, - 0, - self._max_height - footer_height, - ) - - def _determine_prev_size( - self, - preview_size: float | Literal['auto'], - offset: int = 0, - ) -> int: - if not isinstance(preview_size, float) and preview_size != 'auto': - raise ValueError('preview size must be a float or "auto"') - - prev_size: int = 0 - - if preview_size == 'auto': - match self._preview_style: - case PreviewStyle.RIGHT: - menu_width = self._item_group.get_max_width() + 5 - if self._multi: - menu_width += 5 - prev_size = self._max_width - menu_width - case PreviewStyle.BOTTOM: - menu_height = len(self._item_group.items) + 1 # leave empty line between menu and preview - prev_size = self._max_height - offset - menu_height - case PreviewStyle.TOP: - menu_height = len(self._item_group.items) - prev_size = self._max_height - offset - menu_height - else: - match self._preview_style: - case PreviewStyle.RIGHT: - prev_size = int(self._max_width * preview_size) - case PreviewStyle.BOTTOM: - prev_size = int((self._max_height - offset) * preview_size) - case PreviewStyle.TOP: - prev_size = int((self._max_height - offset) * preview_size) - - return prev_size - - def _draw(self) -> None: - footer_entries = self._footer_entries() - - items = self._items_state.get_view_items() - vp_entries = self._item_to_vp_entry(items) - - if self._title_vp: - title_text = self.help_text() - - if self._additional_title is not None: - title_text += f' {self._additional_title}' - - title_vp_entry = ViewportEntry(title_text, 0, 0, STYLE.NORMAL) - - self._update_viewport(self._title_vp, [title_vp_entry]) - - if self._header_vp: - self._update_viewport(self._header_vp, self._header_entries) - - if self._menu_vp: - self._update_viewport(self._menu_vp, vp_entries) - - if vp_entries: - self._update_preview() - elif self._preview_vp: - self._update_viewport(self._preview_vp, []) - - if self._footer_vp: - self._update_viewport(self._footer_vp, footer_entries, 0) - - def _update_viewport( - self, - viewport: Viewport, - entries: list[ViewportEntry], - cur_pos: int = 0, - ) -> None: - if entries: - viewport.update(entries, cur_pos=cur_pos) - else: - viewport.update([]) - - def _get_col_widths(self, items: list[list[MenuItem]]) -> list[int]: - cols_widths = self._calc_col_widths(items, self._horizontal_cols) - return [col_width + len(self._cursor_char) + self._item_distance() for col_width in cols_widths] - - def _item_distance(self) -> int: - if self._horizontal_cols == 1: - return 0 - else: - return self._column_spacing - - def _item_to_vp_entry(self, items: list[list[MenuItem]]) -> list[ViewportEntry]: - entries = [] - cols_widths = self._get_col_widths(items) - - for row_idx, row in enumerate(items): - cur_pos = len(self._cursor_char) - - for col_idx, cell in enumerate(row): - cur_text = '' - style = STYLE.NORMAL - - if cell == self._item_group.focus_item: - cur_text = self._cursor_char - style = STYLE.MENU_STYLE - - entries += [ViewportEntry(cur_text, row_idx, cur_pos - len(self._cursor_char), STYLE.CURSOR_STYLE)] - - menu_item_text = self._menu_item_text(cell) - entries += [ViewportEntry(menu_item_text, row_idx, cur_pos, style)] - cur_pos += len(menu_item_text) - - if col_idx < len(row) - 1: - spacer_len = cols_widths[col_idx] - len(menu_item_text) - entries += [ViewportEntry(' ' * spacer_len, row_idx, cur_pos, STYLE.NORMAL)] - cur_pos += spacer_len - - return entries - - def _calc_col_widths(self, rows: list[list[MenuItem]], columns: int) -> list[int]: - col_widths = [] - - for row in rows: - col_entries = [] - for column in range(columns): - if column < len(row): - col_entries += [len(row[column].text)] - - if col_entries: - col_widths += [max(col_entries)] - - return col_widths - - def _menu_item_text(self, item: MenuItem) -> str: - item_text = '' - - if self._multi and not item.is_empty(): - item_text += self._multi_prefix(item) - - item_text += self._item_group.get_item_text(item) - return item_text - - def _update_preview(self) -> None: - if not self._preview_vp: - return - - focus_item = self._item_group.focus_item - - if not focus_item or focus_item.preview_action is None: - self._preview_vp.update([]) - return - - action_text = focus_item.preview_action(focus_item) - - if not action_text: - self._preview_vp.update([]) - return - - preview_text = action_text.split('\n') - entries = [ViewportEntry(e, idx, 0, STYLE.NORMAL) for idx, e in enumerate(preview_text)] - - total_prev_rows = max([e.row for e in entries]) + 1 # rows start with 0 and we need the count - available_rows = self._preview_vp.height - 2 # for the preview frame - - self._calc_prev_scroll_pos(entries, total_prev_rows) - prev_entries = self._get_scroll_win_prev_entries(entries, total_prev_rows, available_rows) - scroll_pct = self._get_scroll_pct(total_prev_rows, available_rows) - - self._preview_vp.update(prev_entries, scroll_pos=scroll_pct) - - def _get_scroll_pct( - self, - total_prev_rows: int, - available_rows: int, - ) -> int | None: - assert self._preview_vp is not None - - if total_prev_rows <= available_rows: - return None - - pct = int(self._prev_scroll_pos / total_prev_rows * 100) - - if pct + SCROLL_INTERVAL > 100: - pct = 100 - - if pct < 0: - pct = 0 - - return pct - - def _get_scroll_win_prev_entries( - self, - entries: list[ViewportEntry], - total_prev_rows: int, - available_rows: int, - ) -> list[ViewportEntry]: - assert self._preview_vp is not None - - if total_prev_rows <= available_rows: - start_row = 0 - else: - start_row = self._prev_scroll_pos - - end_row = start_row + available_rows - - if end_row > total_prev_rows: - end_row = total_prev_rows - - prev_entries = [e for e in entries if start_row <= e.row < end_row] - - # normalize the rows - for e in prev_entries: - e.row -= start_row - - return prev_entries - - def _calc_prev_scroll_pos( - self, - entries: list[ViewportEntry], - total_prev_rows: int, - ) -> None: - if self._prev_scroll_pos >= total_prev_rows: - self._prev_scroll_pos = total_prev_rows - 2 - elif self._prev_scroll_pos < 0: - self._prev_scroll_pos = 0 - - def _multi_prefix(self, item: MenuItem) -> str: - if item.read_only: - return ' ' - elif self._item_group.is_item_selected(item): - return '[x] ' - else: - return '[ ] ' - - def _handle_interrupt(self) -> bool: - if self._allow_reset and self._interrupt_warning: - return self._confirm_interrupt(self._interrupt_warning) - else: - return False - - def _process_input_key(self, key: int) -> Result[ValueT] | None: - key_handles = MenuKeys.from_ord(key) - - if self._help_active: - if MenuKeys.ESC in key_handles: - self._help_active = False - self.clear_help_win() - self._draw() - return None - - # special case when search is currently active - if self._active_search: - if MenuKeys.STD_KEYS in key_handles: - self._item_group.append_filter(chr(key)) - self._draw() - return None - elif MenuKeys.BACKSPACE in key_handles: - self._item_group.reduce_filter() - self._draw() - return None - - # remove standard keys from the list of key handles - key_handles = [key for key in key_handles if key != MenuKeys.STD_KEYS] - - if len(key_handles) > 1: - decoded = MenuKeys.decode(key) - handles = ', '.join(k.name for k in key_handles) - raise ValueError(f'Multiple key matches for key {decoded}: {handles}') - elif len(key_handles) == 0: - return None - - handle = key_handles[0] - - match handle: - case MenuKeys.HELP: - self._help_active = True - self._clear_all() - self._show_help() - return None - case MenuKeys.ACCEPT: - if self._multi: - if self._item_group.is_mandatory_fulfilled(): - if self._item_group.focus_item is not None: - if self._item_group.focus_item not in self._item_group.selected_items: - self._item_group.selected_items.append(self._item_group.focus_item) - return Result(ResultType.Selection, self._item_group.selected_items) - else: - item = self._item_group.focus_item - if item: - if item.action: - item.value = item.action(item.value) - - if self._item_group.is_mandatory_fulfilled(): - return Result(ResultType.Selection, self._item_group.focus_item) - - return None - case MenuKeys.MENU_DOWN | MenuKeys.MENU_RIGHT: - self._focus_item('next') - case MenuKeys.MENU_UP | MenuKeys.MENU_LEFT: - self._focus_item('prev') - case MenuKeys.MENU_START: - self._focus_item('first') - case MenuKeys.MENU_END: - self._focus_item('last') - case MenuKeys.MULTI_SELECT: - if self._multi: - self._item_group.select_current_item() - case MenuKeys.ENABLE_SEARCH: - if self._search_enabled and not self._active_search: - self._active_search = True - self._item_group.set_filter_pattern('') - case MenuKeys.ESC: - if self._active_search: - self._active_search = False - self._item_group.set_filter_pattern('') - else: - if self._allow_skip: - return Result(ResultType.Skip, None) - case MenuKeys.NUM_KEYS: - self._item_group.focus_index(key - 49) - case MenuKeys.SCROLL_DOWN: - self._prev_scroll_pos += SCROLL_INTERVAL - case MenuKeys.SCROLL_UP: - self._prev_scroll_pos -= SCROLL_INTERVAL - case _: - pass - - return None - - def _focus_item(self, direction: Literal['next', 'prev', 'first', 'last']) -> None: - # reset the preview scroll as the newly focused item - # may have a different preview row count and it'll blow up - self._prev_scroll_pos = 0 - - match direction: - case 'next': - self._item_group.focus_next() - case 'prev': - self._item_group.focus_prev() - case 'first': - self._item_group.focus_first() - case 'last': - self._item_group.focus_last() - - -class Tui: - _t: ClassVar[Self | None] = None - - def __enter__(self) -> None: - if Tui._t is None: - tui = self.init() - Tui._t = tui - - def __exit__(self, exc_type: type[BaseException] | None, exc_value: BaseException | None, traceback: TracebackType | None) -> None: - self.stop() - - @property - def screen(self) -> curses.window: - return self._screen - - @classmethod - def t(cls) -> Self: - assert cls._t is not None - return cls._t - - @staticmethod - def shutdown() -> None: - if Tui._t is None: - return - - Tui.t().stop() - - def init(self) -> Self: - self._screen = curses.initscr() - curses.noecho() - curses.cbreak() - curses.curs_set(0) - curses.set_escdelay(25) - - self._screen.keypad(True) - self._screen.scrollok(True) - - if curses.has_colors(): - curses.start_color() - self._set_up_colors() - - signal.signal(signal.SIGWINCH, self._sig_win_resize) - self._screen.refresh() - - return self - - def stop(self) -> None: - try: - curses.nocbreak() - - try: - self.screen.keypad(False) - except Exception: - pass - - curses.echo() - curses.curs_set(True) - curses.endwin() - except Exception: - # this may happen when curses has not been initialized - pass - - Tui._t = None - - @staticmethod - def print( - text: str, - row: int = 0, - col: int = 0, - endl: str = '\n', - clear_screen: bool = False, - ) -> None: - if clear_screen: - os.system('clear') # type: ignore[deprecated] - - if Tui._t is None: - print(text, end=endl) - sys.stdout.flush() - - return - - # will append the row at the very bottom of the screen - # and also scroll the existing text up by 1 line - if row == -1: - last_row = Tui.t().max_yx[0] - 1 - Tui.t().screen.scroll(1) - Tui.t().screen.addstr(last_row, col, text) - else: - Tui.t().screen.addstr(row, col, text) - - Tui.t().screen.refresh() - - @property - def max_yx(self) -> tuple[int, int]: - return self._screen.getmaxyx() - - @staticmethod - def run[ValueT](component: AbstractCurses[ValueT]) -> Result[ValueT]: - if Tui._t is None: - tui = Tui().init() - tui.screen.clear() - results = tui._main_loop(component) - Tui().stop() - return results - else: - tui = Tui._t - tui.screen.clear() - return Tui.t()._main_loop(component) - - def _sig_win_resize(self, signum: int, frame: FrameType | None) -> None: - if hasattr(self, '_component') and self._component is not None: # pylint: disable=no-member - self._component.resize_win() # pylint: disable=no-member - - def _main_loop[ValueT](self, component: AbstractCurses[ValueT]) -> Result[ValueT]: - self._screen.refresh() - return component.kickoff(self._screen) - - def _reset_terminal(self) -> None: - os.system('reset') # type: ignore[deprecated] - - def _set_up_colors(self) -> None: - curses.init_pair(STYLE.NORMAL.value, curses.COLOR_WHITE, curses.COLOR_BLACK) - curses.init_pair(STYLE.CURSOR_STYLE.value, curses.COLOR_CYAN, curses.COLOR_BLACK) - curses.init_pair(STYLE.MENU_STYLE.value, curses.COLOR_WHITE, curses.COLOR_BLUE) - curses.init_pair(STYLE.MENU_STYLE.value, curses.COLOR_WHITE, curses.COLOR_BLUE) - curses.init_pair(STYLE.HELP.value, curses.COLOR_GREEN, curses.COLOR_BLACK) - curses.init_pair(STYLE.ERROR.value, curses.COLOR_RED, curses.COLOR_BLACK) - - def get_color(self, color: STYLE) -> int: - return curses.color_pair(color.value) diff --git a/archinstall/tui/help.py b/archinstall/tui/help.py deleted file mode 100644 index 2a1ab106..00000000 --- a/archinstall/tui/help.py +++ /dev/null @@ -1,109 +0,0 @@ -from dataclasses import dataclass, field -from enum import Enum - -from archinstall.lib.translationhandler import tr - - -class HelpTextGroupId(Enum): - GENERAL = 'General' - NAVIGATION = 'Navigation' - SELECTION = 'Selection' - SEARCH = 'Search' - - -@dataclass -class HelpText: - description: str - keys: list[str] = field(default_factory=list) - - -@dataclass -class HelpGroup: - group_id: HelpTextGroupId - group_entries: list[HelpText] - - def get_desc_width(self) -> int: - return max([len(e.description) for e in self.group_entries]) - - def get_key_width(self) -> int: - return max([len(', '.join(e.keys)) for e in self.group_entries]) - - -class Help: - # the groups needs to be classmethods not static methods - # because they rely on the DeferredTranslation setup first; - # if they are static methods, they will be called before the - # translation setup is done - - @staticmethod - def general() -> HelpGroup: - return HelpGroup( - group_id=HelpTextGroupId.GENERAL, - group_entries=[ - HelpText(tr('Show help'), ['Ctrl+h']), - HelpText(tr('Exit help'), ['Esc']), - ], - ) - - @staticmethod - def navigation() -> HelpGroup: - return HelpGroup( - group_id=HelpTextGroupId.NAVIGATION, - group_entries=[ - HelpText(tr('Preview scroll up'), ['PgUp']), - HelpText(tr('Preview scroll down'), ['PgDown']), - HelpText(tr('Move up'), ['k', '↑']), - HelpText(tr('Move down'), ['j', '↓']), - HelpText(tr('Move right'), ['l', '→']), - HelpText(tr('Move left'), ['h', '←']), - HelpText(tr('Jump to entry'), ['1..9']), - ], - ) - - @staticmethod - def selection() -> HelpGroup: - return HelpGroup( - group_id=HelpTextGroupId.SELECTION, - group_entries=[ - HelpText(tr('Skip selection (if available)'), ['Esc']), - HelpText(tr('Reset selection (if available)'), ['Ctrl+c']), - HelpText(tr('Select on single select'), ['Enter']), - HelpText(tr('Select on multi select'), ['Space', 'Tab']), - HelpText(tr('Reset'), ['Ctrl-C']), - HelpText(tr('Skip selection menu'), ['Esc']), - ], - ) - - @staticmethod - def search() -> HelpGroup: - return HelpGroup( - group_id=HelpTextGroupId.SEARCH, - group_entries=[ - HelpText(tr('Start search mode'), ['/']), - HelpText(tr('Exit search mode'), ['Esc']), - ], - ) - - @staticmethod - def get_help_text() -> str: - help_output = '' - help_texts = [ - Help.general(), - Help.navigation(), - Help.selection(), - Help.search(), - ] - max_desc_width = max([help.get_desc_width() for help in help_texts]) + 2 - max_key_width = max([help.get_key_width() for help in help_texts]) - - for help_group in help_texts: - help_output += f'{help_group.group_id.value}\n' - divider_len = max_desc_width + max_key_width - help_output += '-' * divider_len + '\n' - - for entry in help_group.group_entries: - help_output += entry.description.ljust(max_desc_width, ' ') + ', '.join(entry.keys) + '\n' - - help_output += '\n' - - return help_output diff --git a/archinstall/tui/menu_item.py b/archinstall/tui/menu_item.py deleted file mode 100644 index 418a4409..00000000 --- a/archinstall/tui/menu_item.py +++ /dev/null @@ -1,515 +0,0 @@ -from collections.abc import Callable -from dataclasses import dataclass, field -from enum import Enum -from functools import cached_property -from typing import Any, ClassVar, Self, override - -from archinstall.lib.translationhandler import tr -from archinstall.lib.utils.encoding import unicode_ljust - - -@dataclass -class MenuItem: - text: str - value: Any | None = None - action: Callable[[Any], Any] | None = None - enabled: bool = True - read_only: bool = False - mandatory: bool = False - dependencies: list[str | Callable[[], bool]] = field(default_factory=list) - dependencies_not: list[str] = field(default_factory=list) - display_action: Callable[[Any], str] | None = None - preview_action: Callable[[Self], str | None] | None = None - key: str | None = None - - _id: str = '' - _yes: ClassVar[Self | None] = None - _no: ClassVar[Self | None] = None - - def __post_init__(self) -> None: - if self.key is not None: - self._id = self.key - else: - self._id = str(id(self)) - - @override - def __hash__(self) -> int: - return hash(self._id) - - def get_id(self) -> str: - return self._id - - def get_value(self) -> Any: - assert self.value is not None - return self.value - - @classmethod - def yes(cls, action: Callable[[Any], Any] | None = None) -> Self: - if cls._yes is None: - cls._yes = cls(tr('Yes'), value=True, key='yes', action=action) - - return cls._yes - - @classmethod - def no(cls, action: Callable[[Any], Any] | None = None) -> Self: - if cls._no is None: - cls._no = cls(tr('No'), value=False, key='no', action=action) - - return cls._no - - def is_empty(self) -> bool: - return self.text == '' or self.text is None - - def has_value(self) -> bool: - if self.value is None: - return False - elif isinstance(self.value, list) and len(self.value) == 0: - return False - elif isinstance(self.value, dict) and len(self.value) == 0: - return False - else: - return True - - def get_display_value(self) -> str | None: - if self.display_action is not None: - return self.display_action(self.value) - - return None - - -class MenuItemGroup: - def __init__( - self, - menu_items: list[MenuItem], - focus_item: MenuItem | None = None, - default_item: MenuItem | None = None, - sort_items: bool = False, - sort_case_sensitive: bool = True, - checkmarks: bool = False, - ) -> None: - if len(menu_items) < 1: - raise ValueError('Menu must have at least one item') - - if sort_items: - if sort_case_sensitive: - menu_items = sorted(menu_items, key=lambda x: x.text) - else: - menu_items = sorted(menu_items, key=lambda x: x.text.lower()) - - self._filter_pattern: str = '' - self._checkmarks: bool = checkmarks - - self._menu_items: list[MenuItem] = menu_items - self.focus_item: MenuItem | None = focus_item - self.selected_items: list[MenuItem] = [] - self.default_item: MenuItem | None = default_item - - if not focus_item: - self.focus_first() - - if self.focus_item not in self.items: - raise ValueError(f'Selected item not in menu: {self.focus_item}') - - def add_item(self, item: MenuItem) -> None: - self._menu_items.append(item) - del self.items # resetting the cache - - def find_by_id(self, item_id: str) -> MenuItem: - for item in self._menu_items: - if item.get_id() == item_id: - return item - - raise ValueError(f'No item found for id: {item_id}') - - def find_by_key(self, key: str) -> MenuItem: - for item in self._menu_items: - if item.key == key: - return item - - raise ValueError(f'No item found for key: {key}') - - def get_enabled_items(self) -> list[MenuItem]: - return [it for it in self.items if self.is_enabled(it)] - - @classmethod - def yes_no(cls) -> Self: - return cls( - [MenuItem.yes(), MenuItem.no()], - sort_items=True, - ) - - @classmethod - def from_enum( - cls, - enum_cls: type[Enum], - sort_items: bool = False, - preset: Enum | None = None, - ) -> Self: - items = [MenuItem(elem.value, value=elem) for elem in enum_cls] - group = cls(items, sort_items=sort_items) - - if preset is not None: - group.set_selected_by_value(preset) - - return group - - def set_preview_for_all(self, action: Callable[[Any], str | None]) -> None: - for item in self.items: - item.preview_action = action - - def set_focus_by_value(self, value: Any) -> None: - for item in self._menu_items: - if item.value == value: - self.focus_item = item - break - - def set_default_by_value(self, value: Any) -> None: - for item in self._menu_items: - if item.value == value: - self.default_item = item - break - - def set_selected_by_value(self, values: Any | list[Any] | None) -> None: - if values is None: - return - - if not isinstance(values, list): - values = [values] - - for item in self._menu_items: - if item.value in values: - self.selected_items.append(item) - - if values: - self.set_focus_by_value(values[0]) - - def get_focused_index(self) -> int | None: - items = self.get_enabled_items() - - if self.focus_item and items: - try: - return items.index(self.focus_item) - except ValueError: - # on large menus (15k+) when filtering very quickly - # the index search is too slow while the items are reduced - # by the filter and it will blow up as it cannot find the - # focus item - pass - - return None - - def index_focus(self) -> int | None: - if self.focus_item and self.items: - try: - return self.items.index(self.focus_item) - except ValueError: - # on large menus (15k+) when filtering very quickly - # the index search is too slow while the items are reduced - # by the filter and it will blow up as it cannot find the - # focus item - pass - - return None - - @property - def size(self) -> int: - return len(self.items) - - def get_max_width(self) -> int: - # use the menu_items not the items here otherwise the preview - # will get resized all the time when a filter is applied - return max([len(self.get_item_text(item)) for item in self._menu_items]) - - @cached_property - def _max_items_text_width(self) -> int: - return max([len(item.text) for item in self._menu_items]) - - def get_item_text(self, item: MenuItem) -> str: - if item.is_empty(): - return '' - - max_width = self._max_items_text_width - display_text = item.get_display_value() - - default_text = self._default_suffix(item) - - text = unicode_ljust(str(item.text), max_width, ' ') - spacing = ' ' * 4 - - if display_text: - text = f'{text}{spacing}{display_text}' - elif self._checkmarks: - from archinstall.tui.types import Chars - - if item.has_value(): - if item.get_value() is not False: - text = f'{text}{spacing}{Chars.Check}' - else: - text = item.text - - if default_text: - text = f'{text} {default_text}' - - return text.rstrip(' ') - - def _default_suffix(self, item: MenuItem) -> str: - if self.default_item == item: - return tr(' (default)') - return '' - - def set_action_for_all(self, action: Callable[[Any], Any]) -> None: - for item in self.items: - item.action = action - - @cached_property - def items(self) -> list[MenuItem]: - pattern = self._filter_pattern.lower() - items = filter(lambda item: item.is_empty() or pattern in item.text.lower(), self._menu_items) - l_items = sorted(items, key=self._items_score) - return l_items - - def _items_score(self, item: MenuItem) -> int: - pattern = self._filter_pattern.lower() - if item.text.lower().startswith(pattern): - return 0 - return 1 - - @property - def filter_pattern(self) -> str: - return self._filter_pattern - - def has_filter(self) -> bool: - return self._filter_pattern != '' - - def set_filter_pattern(self, pattern: str) -> None: - self._filter_pattern = pattern - del self.items # resetting the cache - self.focus_first() - - def append_filter(self, pattern: str) -> None: - self._filter_pattern += pattern - del self.items # resetting the cache - self.focus_first() - - def reduce_filter(self) -> None: - self._filter_pattern = self._filter_pattern[:-1] - del self.items # resetting the cache - self.focus_first() - - def _reload_focus_item(self) -> None: - if len(self.items) > 0: - if self.focus_item not in self.items: - self.focus_first() - else: - self.focus_item = None - - def is_item_selected(self, item: MenuItem) -> bool: - return item in self.selected_items - - def select_current_item(self) -> None: - if self.focus_item: - if self.focus_item in self.selected_items: - self.selected_items.remove(self.focus_item) - else: - self.selected_items.append(self.focus_item) - - def focus_index(self, index: int) -> None: - enabled = self.get_enabled_items() - self.focus_item = enabled[index] - - def focus_first(self) -> None: - if len(self.items) == 0: - return - - first_item: MenuItem | None = self.items[0] - - if first_item and not self._is_selectable(first_item): - first_item = self._find_next_selectable_item(self.items, first_item, 1) - - if first_item is not None: - self.focus_item = first_item - - def focus_last(self) -> None: - if len(self.items) == 0: - return - - last_item: MenuItem | None = self.items[-1] - - if last_item and not self._is_selectable(last_item): - last_item = self._find_next_selectable_item(self.items, last_item, -1) - - if last_item is not None: - self.focus_item = last_item - - def focus_prev(self, skip_empty: bool = True) -> None: - # e.g. when filter shows no items - if self.focus_item is None: - return - - item = self._find_next_selectable_item(self.items, self.focus_item, -1) - - if item is not None: - self.focus_item = item - - def focus_next(self, skip_not_enabled: bool = True) -> None: - # e.g. when filter shows no items - if self.focus_item is None: - return - - item = self._find_next_selectable_item(self.items, self.focus_item, 1) - - if item is not None: - self.focus_item = item - - def _find_next_selectable_item( - self, - items: list[MenuItem], - start_item: MenuItem, - direction: int, - ) -> MenuItem | None: - start_index = self.items.index(start_item) - n = len(items) - - current_index = start_index - for _ in range(n): - current_index = (current_index + direction) % n - - if self._is_selectable(items[current_index]): - return items[current_index] - - return None - - def is_mandatory_fulfilled(self) -> bool: - for item in self._menu_items: - if item.mandatory and not item.value: - return False - return True - - def max_item_width(self) -> int: - spaces = [len(str(it.text)) for it in self.items] - if spaces: - return max(spaces) - return 0 - - def _is_selectable(self, item: MenuItem) -> bool: - if item.is_empty(): - return False - elif item.read_only: - return False - - return self.is_enabled(item) - - def is_enabled(self, item: MenuItem) -> bool: - if not item.enabled: - return False - - for dep in item.dependencies: - if isinstance(dep, str): - item = self.find_by_key(dep) - if not item.value or not self.is_enabled(item): - return False - else: - return dep() - - for dep_not in item.dependencies_not: - item = self.find_by_key(dep_not) - if item.value is not None: - return False - - return True - - -class MenuItemsState: - def __init__( - self, - item_group: MenuItemGroup, - total_cols: int, - total_rows: int, - with_frame: bool, - ) -> None: - self._item_group = item_group - self._total_cols = total_cols - self._total_rows = total_rows - 2 if with_frame else total_rows - - self._prev_row_idx: int = -1 - self._prev_visible_rows: list[int] = [] - self._view_items: list[list[MenuItem]] = [] - - def _determine_focus_row(self) -> int | None: - focus_index = self._item_group.index_focus() - - if focus_index is None: - return None - - row_index = focus_index // self._total_cols - return row_index - - def get_view_items(self) -> list[list[MenuItem]]: - enabled_items = self._item_group.get_enabled_items() - focus_row_idx = self._determine_focus_row() - - if focus_row_idx is None: - return [] - - start, end = 0, 0 - - if len(self._view_items) == 0 or self._prev_row_idx == -1 or focus_row_idx == 0: # initial setup - if focus_row_idx < self._total_rows: - start = 0 - end = self._total_rows - elif focus_row_idx > len(enabled_items) - self._total_rows: - start = len(enabled_items) - self._total_rows - end = len(enabled_items) - else: - start = focus_row_idx - end = focus_row_idx + self._total_rows - elif len(enabled_items) <= self._total_rows: # the view can handle all items - start = 0 - end = self._total_rows - elif not self._item_group.has_filter() and focus_row_idx in self._prev_visible_rows: # focus is in the same view - self._prev_row_idx = focus_row_idx - return self._view_items - else: - if self._item_group.has_filter(): - start = focus_row_idx - end = focus_row_idx + self._total_rows - else: - delta = focus_row_idx - self._prev_row_idx - - if delta > 0: # cursor is on the bottom most row - start = focus_row_idx - self._total_rows + 1 - end = focus_row_idx + 1 - else: # focus is on the top most row - start = focus_row_idx - end = focus_row_idx + self._total_rows - - self._view_items = self._get_view_items(enabled_items, start, end) - self._prev_visible_rows = list(range(start, end)) - self._prev_row_idx = focus_row_idx - - return self._view_items - - def _get_view_items( - self, - items: list[MenuItem], - start_row: int, - total_rows: int, - ) -> list[list[MenuItem]]: - groups: list[list[MenuItem]] = [] - nr_items = self._total_cols * min(total_rows, len(items)) - - for x in range(start_row, nr_items, self._total_cols): - groups.append( - items[x : x + self._total_cols], - ) - - return groups - - def _max_visible_items(self) -> int: - return self._total_cols * self._total_rows - - def _remaining_next_spots(self) -> int: - return self._max_visible_items() - self._prev_row_idx - - def _remaining_prev_spots(self) -> int: - return self._max_visible_items() - self._remaining_next_spots() diff --git a/archinstall/tui/result.py b/archinstall/tui/result.py deleted file mode 100644 index 13f12794..00000000 --- a/archinstall/tui/result.py +++ /dev/null @@ -1,37 +0,0 @@ -from dataclasses import dataclass -from enum import Enum, auto - -from archinstall.tui.menu_item import MenuItem - - -class ResultType(Enum): - Selection = auto() - Skip = auto() - Reset = auto() - - -@dataclass -class Result[ValueT]: - type_: ResultType - _item: MenuItem | list[MenuItem] | str | None - - def has_item(self) -> bool: - return self._item is not None - - def get_value(self) -> ValueT: - return self.item().get_value() # type: ignore[no-any-return] - - def get_values(self) -> list[ValueT]: - return [i.get_value() for i in self.items()] - - def item(self) -> MenuItem: - assert self._item is not None and isinstance(self._item, MenuItem) - return self._item - - def items(self) -> list[MenuItem]: - assert self._item is not None and isinstance(self._item, list) - return self._item - - def text(self) -> str: - assert self._item is not None and isinstance(self._item, str) - return self._item diff --git a/archinstall/tui/types.py b/archinstall/tui/types.py deleted file mode 100644 index d57123ae..00000000 --- a/archinstall/tui/types.py +++ /dev/null @@ -1,144 +0,0 @@ -import curses -from dataclasses import dataclass -from enum import Enum, auto -from typing import Self - -SCROLL_INTERVAL = 10 - - -class STYLE(Enum): - NORMAL = 1 - CURSOR_STYLE = 2 - MENU_STYLE = 3 - HELP = 4 - ERROR = 5 - - -class MenuKeys(Enum): - # latin keys - STD_KEYS = frozenset(range(32, 127)) - # numbers - NUM_KEYS = frozenset(range(49, 58)) - # Menu up: up, k - MENU_UP = frozenset({259, 107}) - # Menu down: down, j - MENU_DOWN = frozenset({258, 106}) - # Menu left: left, h - MENU_LEFT = frozenset({260, 104}) - # Menu right: right, l - MENU_RIGHT = frozenset({261, 108}) - # Menu start: home CTRL-a - MENU_START = frozenset({262, 1}) - # Menu end: end CTRL-e - MENU_END = frozenset({360, 5}) - # Enter - ACCEPT = frozenset({10}) - # Selection: space, tab - MULTI_SELECT = frozenset({32, 9}) - # Search: / - ENABLE_SEARCH = frozenset({47}) - # ESC - ESC = frozenset({27}) - # BACKSPACE (search) - BACKSPACE = frozenset({127, 263}) - # Help view: ctrl+h - HELP = frozenset({8}) - # Scroll up: PGUP - SCROLL_UP = frozenset({339}) - # Scroll down: PGDOWN - SCROLL_DOWN = frozenset({338}) - - @classmethod - def from_ord(cls, key: int) -> list[Self]: - matches: list[Self] = [] - - for group in cls: - if key in group.value: - matches.append(group) - - return matches - - @classmethod - def decode(cls, key: int) -> str: - byte_str = curses.keyname(key) - return byte_str.decode('utf-8') - - -class FrameStyle(Enum): - MAX = auto() - MIN = auto() - - -@dataclass -class FrameProperties: - header: str - w_frame_style: FrameStyle = FrameStyle.MAX - h_frame_style: FrameStyle = FrameStyle.MAX - - @classmethod - def max(cls, header: str) -> Self: - return cls( - header, - FrameStyle.MAX, - FrameStyle.MAX, - ) - - @classmethod - def min(cls, header: str) -> Self: - return cls( - header, - FrameStyle.MIN, - FrameStyle.MIN, - ) - - -class Orientation(Enum): - VERTICAL = auto() - HORIZONTAL = auto() - - -class PreviewStyle(Enum): - NONE = auto() - BOTTOM = auto() - RIGHT = auto() - TOP = auto() - - -# https://www.compart.com/en/unicode/search?q=box+drawings#characters -# https://en.wikipedia.org/wiki/Box-drawing_characters -class Chars: - Horizontal = '─' - Vertical = '│' - Upper_left = '┌' - Upper_right = '┐' - Lower_left = '└' - Lower_right = '┘' - Block = '█' - Triangle_up = '▲' - Triangle_down = '▼' - Check = '+' - Cross = 'x' - Right_arrow = '←' - - -@dataclass -class ViewportEntry: - text: str - row: int - col: int - style: STYLE - - -class Alignment(Enum): - LEFT = auto() - CENTER = auto() - - -@dataclass -class FrameDim: - x_start: int - x_end: int - height: int - - def x_delta(self) -> int: - return self.x_end - self.x_start From 05560d29af9852899d95878b1026e7ffbd2ae760 Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Wed, 29 Apr 2026 07:54:59 -0400 Subject: [PATCH 31/40] Add basic Pyrefly configuration to pyproject.toml (#4494) This makes it easier to use the Pyrefly type checker with various IDEs. --- pyproject.toml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index 95d85144..1add6027 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -172,6 +172,23 @@ score = false [tool.pylint.variables] init-import = true +[tool.pyrefly] +python-version = "3.14" + +replace-imports-with-any = [ + "parted", # pyparted doesn't have type hints +] + +[tool.pyrefly.errors] +# Enable some additional rules that are disabled by default +implicit-abstract-class = true +missing-override-decorator = true +missing-source = true +not-required-key-access = true +open-unpacking = true +unannotated-parameter = true +unused-ignore = true + [tool.ruff] target-version = "py314" line-length = 160 From 3b026cb603b3e53000a9a84b0d2682b95d458fa0 Mon Sep 17 00:00:00 2001 From: Softer Date: Thu, 30 Apr 2026 00:33:21 +0300 Subject: [PATCH 32/40] Fix broken localization in U2F, LUKS, and gfx driver preview (#4500) --- archinstall/lib/authentication/authentication_handler.py | 2 +- archinstall/lib/disk/encryption_menu.py | 2 +- archinstall/lib/profile/profile_menu.py | 2 +- archinstall/locales/base.pot | 8 ++++++++ 4 files changed, 11 insertions(+), 3 deletions(-) diff --git a/archinstall/lib/authentication/authentication_handler.py b/archinstall/lib/authentication/authentication_handler.py index a0b8e132..9a99ba02 100644 --- a/archinstall/lib/authentication/authentication_handler.py +++ b/archinstall/lib/authentication/authentication_handler.py @@ -81,7 +81,7 @@ class AuthenticationHandler: install_session.pacman.strap('pam-u2f') - print(tr(f'Setting up U2F login: {u2f_config.u2f_login_method.value}')) + print(tr('Setting up U2F login: {}').format(u2f_config.u2f_login_method.value)) # https://developers.yubico.com/pam-u2f/ u2f_auth_file = install_session.target / 'etc/u2f_mappings' diff --git a/archinstall/lib/disk/encryption_menu.py b/archinstall/lib/disk/encryption_menu.py index 39c631cd..d66ccf92 100644 --- a/archinstall/lib/disk/encryption_menu.py +++ b/archinstall/lib/disk/encryption_menu.py @@ -375,7 +375,7 @@ async def select_lvm_vols_to_encrypt( async def select_iteration_time(preset: int | None = None) -> int | None: header = tr('Enter iteration time for LUKS encryption (in milliseconds)') + '\n' header += tr('Higher values increase security but slow down boot time') + '\n' - header += tr(f'Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000') + '\n' + header += tr('Default: {}ms, Recommended range: 1000-60000').format(DEFAULT_ITER_TIME) + '\n' def validate_iter_time(value: str) -> str | None: try: diff --git a/archinstall/lib/profile/profile_menu.py b/archinstall/lib/profile/profile_menu.py index 115c9fc0..0bdc9b0b 100644 --- a/archinstall/lib/profile/profile_menu.py +++ b/archinstall/lib/profile/profile_menu.py @@ -113,7 +113,7 @@ class ProfileMenu(AbstractSubMenu[ProfileConfiguration]): if item.value: driver = item.get_value().value packages = item.get_value().packages_text() - return f'Driver: {driver}\n{packages}' + return f'{tr("Graphics driver")}: {driver}\n{packages}' return None def _prev_greeter(self, item: MenuItem) -> str | None: diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot index 4e9e0e9f..31f5e196 100644 --- a/archinstall/locales/base.pot +++ b/archinstall/locales/base.pot @@ -2285,3 +2285,11 @@ msgstr "" #, python-brace-format msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" msgstr "" + +#, python-brace-format +msgid "Setting up U2F login: {}" +msgstr "" + +#, python-brace-format +msgid "Default: {}ms, Recommended range: 1000-60000" +msgstr "" From 6fefa3b6f54a16832249605bfb5d1d4cb444d06c Mon Sep 17 00:00:00 2001 From: aronmr-1 Date: Wed, 29 Apr 2026 21:43:01 +0000 Subject: [PATCH 33/40] Improved Finnish language (#4501) --- archinstall/locales/fi/LC_MESSAGES/base.mo | Bin 40494 -> 51470 bytes archinstall/locales/fi/LC_MESSAGES/base.po | 379 +++++++++++---------- archinstall/locales/languages.json | 2 +- 3 files changed, 206 insertions(+), 175 deletions(-) diff --git a/archinstall/locales/fi/LC_MESSAGES/base.mo b/archinstall/locales/fi/LC_MESSAGES/base.mo index f6edf647b6322606d65af4662c1a27b16e8a6eee..43b527d57e25ff1c6ff6397f4403d58f5721cdc1 100644 GIT binary patch delta 19895 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 M?6&#aD@r^3Kd8N9ltEbzc90p2gd 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 N^_wkxU%nX|@E_nwMkoLP diff --git a/archinstall/locales/fi/LC_MESSAGES/base.po b/archinstall/locales/fi/LC_MESSAGES/base.po index 7651bb13..2580f222 100644 --- a/archinstall/locales/fi/LC_MESSAGES/base.po +++ b/archinstall/locales/fi/LC_MESSAGES/base.po @@ -3,7 +3,7 @@ msgstr "" "Project-Id-Version: \n" "POT-Creation-Date: \n" "PO-Revision-Date: \n" -"Last-Translator: Aleksi Puhakainen \n" +"Last-Translator: Aron R, Github aronmr-1\n" "Language-Team: \n" "Language: fi\n" "MIME-Version: 1.0\n" @@ -55,7 +55,7 @@ msgid "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr msgstr "Vain paketit, kuten base, base-devel, linux, linux-firmware, efibootmgr ja valinnaiset profiili-paketit, asennetaan." msgid "Note: base-devel is no longer installed by default. Add it here if you need build tools." -msgstr "" +msgstr "Huomio: base-devel ei enään asenneta oletuksena. Lisää se tähän jos tarvitset työkaluja pakettejen rakentamiseen" msgid "If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt." msgstr "Jos haluat selaimen, kuten firefox tai chromium, voit valita sen seuraavassa kohdassa." @@ -257,6 +257,9 @@ msgstr "Kieli" msgid "Locale encoding" msgstr "Kieli-koodaus" +msgid "Console font" +msgstr "Päätteen kirjaintyyli" + msgid "Drive(s)" msgstr "Levyasemat" @@ -645,7 +648,7 @@ msgid "Select interface to add" msgstr "Valitse lisättävä liitäntä" msgid "Manual configuration" -msgstr "Käsin määrittely" +msgstr "Manuaalinen konfiguraatio" msgid "Mark/Unmark a partition as compressed (btrfs only)" msgstr "Merkitse/poista osio pakatuksi (vain btrfs)" @@ -828,7 +831,7 @@ msgid "Pacman" msgstr "" msgid "Color" -msgstr "" +msgstr "Väri" #, fuzzy, python-brace-format msgid "Enter the number of parallel downloads (1-{})" @@ -967,28 +970,28 @@ msgid "Encryption type" msgstr "Salaustyyppi" msgid "Iteration time" -msgstr "" +msgstr "Iteraatioaika" msgid "Enter iteration time for LUKS encryption (in milliseconds)" -msgstr "" +msgstr "Anna iteraatioaika LUKS salaukselle (millisekunneissa)" msgid "Higher values increase security but slow down boot time" -msgstr "" +msgstr "Suuremmat arvot parantavat tietosuojaa mutta hidastavat käynnistysaikaa" msgid "Default: 10000ms, Recommended range: 1000-60000" -msgstr "" +msgstr "Oletusarvo: 10000ms, suositeltu 1000-60000ms" msgid "Iteration time cannot be empty" -msgstr "" +msgstr "Iteraatioaika ei voi olla tyhjä" msgid "Iteration time must be at least 100ms" -msgstr "" +msgstr "Iteraatioajan on oltava ainakin 100ms" msgid "Iteration time must be at most 120000ms" -msgstr "" +msgstr "Iteraatioaika saa olla enintään 120000ms" msgid "Please enter a valid number" -msgstr "" +msgstr "Ole hyvä ja syötä kelpaava numero" msgid "Partitions" msgstr "Osiot" @@ -1223,6 +1226,23 @@ msgstr "Tuote" msgid "Invalid configuration: {error}" msgstr "Virheellinen määritys: {error}" +msgid "Ready to install" +msgstr "Valmis asentamaan" + +msgid "Disks" +msgstr "Levyasemat" + +#, fuzzy +msgid "Packages" +msgstr "Määritetty {} liittymää" + +msgid "Network" +msgstr "Verkko" + +#, fuzzy +msgid "Locale" +msgstr "Alueet" + msgid "Type" msgstr "Tyyppi" @@ -1312,7 +1332,7 @@ msgid "LVM configuration type" msgstr "Ei määritystä" msgid "LVM disk encryption with more than 2 partitions is currently not supported" -msgstr "" +msgstr "LVM levyaseman salaus enemmällä kuin kahdella osiolla ei ole tällä hetkellä tuettu" #, fuzzy msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE Plasma)" @@ -1327,13 +1347,13 @@ msgid "Partitioning" msgstr "Osio" msgid "Logical Volume Management (LVM)" -msgstr "" +msgstr "Looginen taltiohallinta (engl. 'Logical Volume Management', LVM)" msgid "Physical volumes" -msgstr "" +msgstr "Fyysiset taltiot" msgid "Volumes" -msgstr "" +msgstr "Taltiot" #, fuzzy msgid "LVM volumes" @@ -1366,10 +1386,10 @@ msgstr "" #, fuzzy msgid "Yes" -msgstr "kyllä" +msgstr "Kyllä" msgid "No" -msgstr "" +msgstr "Ei" #, fuzzy msgid "Archinstall help" @@ -1380,7 +1400,7 @@ msgid " (default)" msgstr "(oletus)" msgid "Press Ctrl+h for help" -msgstr "" +msgstr "Paina Ctrl+h saadaksesi apua" #, fuzzy msgid "Choose an option to give Sway access to your hardware" @@ -1390,7 +1410,7 @@ msgstr "" "Valitse asetus antaaksesi Swaylle pääsyn laitteistoosi" msgid "Seat access" -msgstr "" +msgstr "Istunnon pääsy (seat)" #, fuzzy msgid "Mountpoint" @@ -1416,7 +1436,7 @@ msgid "Filesystem" msgstr "Vaihda tiedostojärjestelmä" msgid "Invalid size" -msgstr "" +msgstr "Epäkelpo koko" #, fuzzy msgid "Start (default: sector {}): " @@ -1435,7 +1455,7 @@ msgid "Disk configuration type" msgstr "Kiintolevyn määritys" msgid "Root mount directory" -msgstr "" +msgstr "Juuren (Root) liittämishakemisto (mount directory)" #, fuzzy msgid "Select language" @@ -1446,10 +1466,10 @@ msgid "Write additional packages to install (space separated, leave blank to ski msgstr "Kirjoita asennettavat lisäpaketit (välilyönnillä erotettuna, ohita vaihe jättämällä tyhjäksi): " msgid "Invalid download number" -msgstr "" +msgstr "Epäkelpo numero lataukseen" msgid "Number downloads" -msgstr "" +msgstr "Numero latauksia" #, fuzzy msgid "The username you entered is invalid" @@ -1515,14 +1535,14 @@ msgstr "Sway ei tue patentoitua Nvidia-ohjainta. Todennäköistä, että kohtaat #, fuzzy msgid "Main profile" -msgstr "Muokkaa profiilia" +msgstr "Pääprofiili" #, fuzzy msgid "Confirm password" -msgstr "Vaihda salasana" +msgstr "Vahvista salasana" msgid "The confirmation password did not match, please try again" -msgstr "" +msgstr "Salasanat eivät vastannet, ole hyvä ja koita uudestaan" #, fuzzy msgid "Not a valid directory" @@ -1533,7 +1553,7 @@ msgid "Would you like to continue?" msgstr "Haluatko käyttää BTRFS-pakkausta?" msgid "Directory" -msgstr "" +msgstr "Hakemisto" #, fuzzy msgid "Enter a directory for the configuration(s) to be saved (tab completion enabled)" @@ -1574,7 +1594,7 @@ msgid "Select execution mode" msgstr "Valitse suoritustila" msgid "Press ? for help" -msgstr "" +msgstr "Paina ? saadaksesi apua" #, fuzzy msgid "Choose an option to give Hyprland access to your hardware" @@ -1591,7 +1611,7 @@ msgid "NTP" msgstr "" msgid "Swap on zram" -msgstr "" +msgstr "Swap zram:illa (Swap on zram)" msgid "Name" msgstr "Nimi" @@ -1617,17 +1637,17 @@ msgid "HSM device" msgstr "Laite" msgid "Some packages could not be found in the repository" -msgstr "" +msgstr "Jotkut paketit eivät löytyneet repositoriosta" #, fuzzy msgid "User" msgstr "Käyttäjänimi : " msgid "The specified configuration will be applied" -msgstr "" +msgstr "Käytetään valittua konfiguraatiota" msgid "Wipe" -msgstr "" +msgstr "Pyyhi" #, fuzzy msgid "Mark/Unmark as XBOOTLDR" @@ -1638,7 +1658,7 @@ msgid "Loading packages..." msgstr "Lisäpaketit" msgid "Select any packages from the below list that should be installed additionally" -msgstr "" +msgstr "Valitse alla olevalta listalta asennettavat lisäpaketit" #, fuzzy msgid "Add a custom repository" @@ -1669,7 +1689,7 @@ msgid "Delete custom server" msgstr "Poista mukautettu peilipaikka" msgid "Server url" -msgstr "" +msgstr "Palvelimen url" #, fuzzy msgid "Select regions" @@ -1704,19 +1724,19 @@ msgid "Custom repositories" msgstr "Valinnaiset arkistot" msgid "Only ASCII characters are supported" -msgstr "" +msgstr "Ainoastaan ASCII hahmot tuetaan" msgid "Show help" msgstr "Näytä apua" msgid "Exit help" -msgstr "" +msgstr "Poistu avusta" msgid "Preview scroll up" -msgstr "" +msgstr "Esikatsele ylöspäin scrollaamista" msgid "Preview scroll down" -msgstr "" +msgstr "Esikatsele alaspäin scrollaamista" msgid "Move up" msgstr "Liikku ylös" @@ -1731,13 +1751,13 @@ msgid "Move left" msgstr "Liiku vasemmalle" msgid "Jump to entry" -msgstr "" +msgstr "Hyppää kohtaan" msgid "Skip selection (if available)" -msgstr "" +msgstr "Hyppää valinnan yli (jos saatavilla)" msgid "Reset selection (if available)" -msgstr "" +msgstr "Nollaa valinta (jos saatavilla)" #, fuzzy msgid "Select on single select" @@ -1748,20 +1768,20 @@ msgid "Select on multi select" msgstr "Valitse aikavyöhyke" msgid "Reset" -msgstr "" +msgstr "Nollaa" #, fuzzy msgid "Skip selection menu" msgstr "Valitse suoritustila" msgid "Start search mode" -msgstr "" +msgstr "Aloita hakutila" msgid "Exit search mode" -msgstr "" +msgstr "Poistu hakutilasta" msgid "General" -msgstr "" +msgstr "Yleinen" #, fuzzy msgid "Navigation" @@ -1772,13 +1792,13 @@ msgid "Selection" msgstr "Valitse allekirjoituksen asetus" msgid "Search" -msgstr "" +msgstr "Haku" msgid "Down" -msgstr "" +msgstr "Alas" msgid "Up" -msgstr "" +msgstr "Ylös" #, fuzzy msgid "Confirm" @@ -1793,47 +1813,47 @@ msgid "Focus left" msgstr "Liiku vasemmalle" msgid "Toggle" -msgstr "" +msgstr "Vaihda" #, fuzzy msgid "Show/Hide help" msgstr "Näytä apua" msgid "Quit" -msgstr "" +msgstr "Poistu" msgid "First" -msgstr "" +msgstr "Ensimmäinen" msgid "Last" -msgstr "" +msgstr "Viimeinen" #, fuzzy msgid "Select" msgstr "Valitse allekirjoituksen asetus" msgid "Page Up" -msgstr "" +msgstr "Liiku ylös" msgid "Page Down" -msgstr "" +msgstr "Liiku alas" msgid "Page up" -msgstr "" +msgstr "Liiku ylös" #, fuzzy msgid "Page down" -msgstr "Liikku alas" +msgstr "Liiku alas" msgid "Page Left" -msgstr "" +msgstr "Liiku vasemalle" #, fuzzy msgid "Page Right" msgstr "Liiku oikealle" msgid "Cursor up" -msgstr "" +msgstr "Kursori ylös" #, fuzzy msgid "Cursor down" @@ -1848,48 +1868,48 @@ msgid "Cursor left" msgstr "Liiku vasemmalle" msgid "Top" -msgstr "" +msgstr "Yläosa" msgid "Bottom" -msgstr "" +msgstr "Pohja" msgid "Home" -msgstr "" +msgstr "Rivin alku" #, fuzzy msgid "End" -msgstr "Käytössä" +msgstr "Rivin loppu" #, fuzzy msgid "Toggle option" msgstr "Alitaltion valinnat" msgid "Scroll Up" -msgstr "" +msgstr "Scrollaa ylös" msgid "Scroll Down" -msgstr "" +msgstr "Scrollaa alas" msgid "Scroll Left" -msgstr "" +msgstr "Scrollaa vasemmalle" msgid "Scroll Right" -msgstr "" +msgstr "Scrollaa oikealle" msgid "Scroll Home" -msgstr "" +msgstr "Scrollaa rivin alkuun" msgid "Scroll End" -msgstr "" +msgstr "Scrollaa rivin loppuun" msgid "Focus Next" -msgstr "" +msgstr "Kohdista seuraava" msgid "Focus Previous" -msgstr "" +msgstr "Kohdista edeltävä" msgid "Copy selected text" -msgstr "" +msgstr "Kopioi valittu teksti" #, fuzzy msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" @@ -1900,33 +1920,33 @@ msgid "Choose an option to give labwc access to your hardware" msgstr "" "\n" "\n" -"Valitse asetus antaaksesi Swaylle pääsyn laitteistoosi" +"Valitse asetus antaaksesi labwc:lle pääsyn laitteistoosi" #, fuzzy msgid "niri needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" -msgstr "Sway tarvitsee pääsyn istuntoon (kokoelma laitteistoja, kuten näppäimistö, hiiri jne.)" +msgstr "niri tarvitsee pääsyn istuntoon (kokoelma laitteistoja, kuten näppäimistö, hiiri jne.)" #, fuzzy msgid "Choose an option to give niri access to your hardware" msgstr "" "\n" "\n" -"Valitse asetus antaaksesi Swaylle pääsyn laitteistoosi" +"Valitse asetus antaaksesi nirin pääsyn laitteistoosi" #, fuzzy msgid "Mark/Unmark as ESP" msgstr "Merkitse/poista käynnistyvä" msgid "Package group:" -msgstr "" +msgstr "Pakettiryhmä:" #, fuzzy msgid "Exit archinstall" -msgstr "Archinstall kieli" +msgstr "Poistu archinstall:ista" #, fuzzy msgid "Reboot system" -msgstr "Vaihda tiedostojärjestelmä" +msgstr "Käynnistä järjestelmä uudelleen" #, fuzzy msgid "chroot into installation for post-installation configurations" @@ -1937,7 +1957,7 @@ msgstr "Lataus valmis" #, fuzzy msgid "What would you like to do next?" -msgstr "Haluatko käyttää BTRFS-pakkausta?" +msgstr "Mitä haluaisit tehdä seuraavaksi?" #, fuzzy, python-brace-format msgid "Select which mode to configure for \"{}\"" @@ -1945,11 +1965,11 @@ msgstr "Valitse, mikä tila määritetään \"{}\", tai ohita ja käytä \"{}\" #, fuzzy msgid "Incorrect credentials file decryption password" -msgstr "Salauksen salasana" +msgstr "Väärä salasana salausta varten" #, fuzzy msgid "Incorrect password" -msgstr "Root salasana" +msgstr "Väärä salasana" #, fuzzy msgid "Credentials file decryption password" @@ -1957,10 +1977,7 @@ msgstr "Salauksen salasana" #, fuzzy msgid "Do you want to encrypt the user_credentials.json file?" -msgstr "" -"Haluatko tallentaa {} asetustiedostoa seuraavaan paikkaan?\n" -"\n" -"{}" +msgstr "Haluatko salata user_crendentials.json tiedoston?" #, fuzzy msgid "Credentials file encryption password" @@ -1976,10 +1993,10 @@ msgstr "Ei HSM-laitteita saatavilla" #, fuzzy msgid "Passwordless login" -msgstr "Salasana" +msgstr "Salasanaton kirjautuminen" msgid "Second factor login" -msgstr "" +msgstr "Toisen faktorin kirjautuminen" msgid "Bluetooth" msgstr "" @@ -1989,67 +2006,67 @@ msgid "Would you like to configure Bluetooth?" msgstr "Haluatko käyttää BTRFS-pakkausta?" msgid "Print service" -msgstr "" +msgstr "Printtauspalvelu" #, fuzzy msgid "Would you like to configure the print service?" -msgstr "Haluatko käyttää BTRFS-pakkausta?" +msgstr "Haluatko konfiguroida printtauspalvelun" #, fuzzy msgid "Power management" -msgstr "Osioiden hallinta: {}" +msgstr "Tehohallinta" msgid "Authentication" msgstr "Todennus" msgid "Applications" -msgstr "" +msgstr "Applikaatiot" msgid "U2F login method: " -msgstr "" +msgstr "U2F kirjautumismenetelmä" msgid "Passwordless sudo: " msgstr "Salasanaton sudo" #, python-brace-format msgid "Btrfs snapshot type: {}" -msgstr "" +msgstr "Btrfs tilankuvien tyyppi: {}" msgid "Syncing the system..." -msgstr "" +msgstr "Järjestelmän synkronointi" msgid "Value cannot be empty" -msgstr "" +msgstr "Arvo ei voi olla tyhjä" msgid "Snapshot type" -msgstr "" +msgstr "Tilannekuvan tyyppi" #, fuzzy, python-brace-format msgid "Snapshot type: {}" -msgstr "Ympäristötyyppi: {}" +msgstr "Tilannekuvan tyyppi: {}" msgid "U2F login setup" -msgstr "" +msgstr "U2F kirjautumisen konfigurointi" msgid "No U2F devices found" -msgstr "" +msgstr "U2F laitteita ei löydetty" msgid "U2F Login Method" -msgstr "" +msgstr "U2F kirjautumisen menetelmä" #, fuzzy msgid "Enable passwordless sudo?" -msgstr "Anna salasana: " +msgstr "Aktivoi salasanaton sudo?" #, fuzzy, python-brace-format msgid "Setting up U2F device for user: {}" msgstr "Valitse HSM:ään käytettävä FIDO2-laite" msgid "You may need to enter the PIN and then touch your U2F device to register it" -msgstr "" +msgstr "Voit joutua syöttämään PIN:in ja koskettaa U2F laitettasi rekisteröidäksesi sen" msgid "Starting device modifications in " -msgstr "" +msgstr "Aloitetaan laitteen muokkausta " #, fuzzy msgid "No network connection found" @@ -2057,116 +2074,116 @@ msgstr "Ei verkkoasetuksia" #, fuzzy msgid "Would you like to connect to a Wifi?" -msgstr "Haluatko käyttää BTRFS-pakkausta?" +msgstr "Haluaisitko liittyä langattomaan verkkoon?" #, fuzzy msgid "No wifi interface found" -msgstr "Määritetty {} liittymää" +msgstr "Langattomia liittymiä ei löydetty" #, fuzzy msgid "Select wifi network to connect to" -msgstr "Valitse yksi määritettävä verkkoliitäntä" +msgstr "Valitse wifi verkko johon yhdistää" msgid "Scanning wifi networks..." -msgstr "" +msgstr "Etsitään wifiyhteyksiä..." #, fuzzy msgid "No wifi networks found" msgstr "Ei verkkoasetuksia" msgid "Failed setting up wifi" -msgstr "" +msgstr "Langattoman verkon määrittäminen epäonnistui" #, fuzzy msgid "Enter wifi password" -msgstr "Anna salasana: " +msgstr "Anna wifi salasana: " msgid "Ok" msgstr "" msgid "Removable" -msgstr "" +msgstr "Irrotettava" msgid "Install to removable location" -msgstr "" +msgstr "Asenna irrotettavaan sijaintiin" msgid "Will install to /EFI/BOOT/ (removable location)" -msgstr "" +msgstr "Asennetaan sijaintiin /EFI/BOOT (irrotettava sijainti)" msgid "Will install to standard location with NVRAM entry" -msgstr "" +msgstr "Asennetaan oletuskohteeseen NVRAM kohteella" msgid "Would you like to install the bootloader to the default removable media search location?" -msgstr "" +msgstr "Haluatko asentaa käynnistyslataajan (bootloader) irrotettavan median oletushakukohteeseen?" msgid "This installs the bootloader to /EFI/BOOT/BOOTX64.EFI (or similar) which is useful for:" -msgstr "" +msgstr "Tämä asentaa käynnistyslataajan sijaintiin /EFI/BOOT/BOOTX64.EFI (tai vastaava) joka on hyödyllistä seuraaville:" msgid "USB drives or other portable external media." -msgstr "" +msgstr "USB levyt ja muu kannettava ulkoinen media." msgid "Systems where you want the disk to be bootable on any computer." -msgstr "" +msgstr "Järjestelmät joissa haluat että levy käynnistyvä millä tahansa koneella." msgid "Firmware that does not properly support NVRAM boot entries." -msgstr "" +msgstr "Firmware joka ei kunnolla tue NVRAM käynnistyskohteita." msgid "Will install to /EFI/BOOT/ (removable location, safe default)" -msgstr "" +msgstr "Asennetaan sijaintiin /EFI/BOOT (irrotettava sijainti, varma oletusarvo)" msgid "Will install to custom location with NVRAM entry" -msgstr "" +msgstr "Asennetaan omaan sijaintiin NVRAM kohteella" msgid "Firmware that does not properly support NVRAM boot entries like most MSI motherboards," -msgstr "" +msgstr "Firmware joka ei kunnolla tue NVRAM käynnistyskohteita kuten useimmat MSI emolevyt," msgid "most Apple Macs, many laptops..." -msgstr "" +msgstr "useimmat Apple Macit, monet kannettavat tietokoneet..." #, fuzzy msgid "Language" msgstr "Kieli" msgid "Compression algorithm" -msgstr "" +msgstr "Kompressioalgoritmi" #, fuzzy msgid "Only packages such as base, sudo, linux, linux-firmware, efibootmgr and optional profile packages are installed." -msgstr "Vain paketit, kuten base, base-devel, linux, linux-firmware, efibootmgr ja valinnaiset profiili-paketit, asennetaan." +msgstr "Vain paketit, kuten base, sudo, linux, linux-firmware, efibootmgr ja valinnaiset profiili-paketit ovat asennettu." #, fuzzy msgid "Select zram compression algorithm:" -msgstr "Valitse liitoskohta :" +msgstr "Valitse zram kompression algoritmi:" msgid "Use Network Manager (default backend)" -msgstr "" +msgstr "Käytä Network Manager (oletus backendi)" msgid "Use Network Manager (iwd backend)" -msgstr "" +msgstr "Käytä Network Manager (iwd backendi)" msgid "Firewall" -msgstr "" +msgstr "Palomuuri" #, fuzzy msgid "Additional fonts" -msgstr "Valinnaiset arkistot" +msgstr "Lisäfontit" #, fuzzy msgid "Select font packages to install" -msgstr "Valitse asennettava käyttöliittymä" +msgstr "Valitse asennettavat fonttipaketit" msgid "Unicode font coverage for most languages" -msgstr "" +msgstr "Unicode fontin kattavuus useimmille kielille" msgid "color emoji for browsers and apps" -msgstr "" +msgstr "väri emojit selaimille ja sovelluksille" msgid "Chinese, Japanese, Korean characters" -msgstr "" +msgstr "Kiinalaiset, japanilaiset, korealaiset kirjaimet" #, fuzzy msgid "Select audio configuration" -msgstr "Tallenna käyttäjän määritykset" +msgstr "Valitse äänen konfiguraatio" #, fuzzy msgid "Enter credentials file decryption password" @@ -2174,14 +2191,14 @@ msgstr "Salauksen salasana" #, fuzzy msgid "Enter root password" -msgstr "Anna salasana: " +msgstr "Anna juuren (root) salasana: " msgid "Select bootloader to install" -msgstr "" +msgstr "Valitse asennettava käynnistyslataaja" #, fuzzy msgid "Configuration preview" -msgstr "Asetukset" +msgstr "Konfiguraation esikatselu" #, fuzzy msgid "Enter a directory for the configuration(s) to be saved" @@ -2193,7 +2210,7 @@ msgstr "Salaustyyppi" #, fuzzy msgid "Select disks for the installation" -msgstr "Valitse hostname asennukselle: " +msgstr "Valitse levyasemat asennukselle" #, fuzzy msgid "Enter a mountpoint" @@ -2201,7 +2218,7 @@ msgstr "Valitse liitoskohta :" #, fuzzy, python-brace-format msgid "Enter a size (default: {}): " -msgstr "Anna loppu (oletus: {}): " +msgstr "Anna koko (oletus: {}): " #, fuzzy msgid "Enter subvolume name" @@ -2216,20 +2233,20 @@ msgid "Select a disk configuration" msgstr "Kiintolevyn määritys" msgid "Enter root mount directory" -msgstr "" +msgstr "Syötä juuren (root) liitoshakemisto" msgid "You will use whatever drive-setup is mounted at the specified directory" -msgstr "" +msgstr "Käytät mitä tahansa levykonfiguraatiota joka on liitetty valittuun hakemistoon" msgid "WARNING: Archinstall won't check the suitability of this setup" -msgstr "" +msgstr "VAROITUS: Archinstall ei tarkista konfiguraation soveltuvuutta" #, fuzzy msgid "Select main filesystem" -msgstr "Vaihda tiedostojärjestelmä" +msgstr "Vaihda päätiedostojärjestelmä" msgid "Enter a hostname" -msgstr "" +msgstr "Syötä isäntänimi (hostname)" #, fuzzy msgid "Select timezone" @@ -2244,22 +2261,22 @@ msgstr "" #, python-brace-format msgid "Value must be between 1 and {}" -msgstr "" +msgstr "Arvon on oltava yhden ja {} välillä" #, fuzzy msgid "Select which kernel(s) to install" -msgstr "Valitse asennettava käyttöliittymä" +msgstr "Valitse asennettavat ytimet (kernel)" #, fuzzy msgid "Enter a respository name" -msgstr "Pakettivarasto" +msgstr "Syötä pakettivaraston nimi" #, fuzzy msgid "Enter the repository url" -msgstr "Vaihda mukautettu peilipaikka" +msgstr "Syötä pakettivarason url" msgid "Enter server url" -msgstr "" +msgstr "Syötä palvelimen url" #, fuzzy msgid "Select mirror regions to be enabled" @@ -2271,92 +2288,106 @@ msgstr "Valitse, valinnaiset lisävarastot jotka otetaan käyttöön" #, fuzzy msgid "Select an interface" -msgstr "Poista liitäntä" +msgstr "Valitse liitäntä" #, fuzzy msgid "Choose network configuration" -msgstr "Ei verkkoasetuksia" +msgstr "Valitse verkkokonfiguraatio" + +msgid "Recommended: Network Manager for desktop, Manual for server" +msgstr "Suositeltu: Network Manager työpöydälle, manuaali palvelinta varten" + +msgid "Warning: no network configuration selected. Network will need to be set up manually on the installed system." +msgstr "Varoitus: verkkokonfiguraatiota ei löytynyt. Verkon on asetettava manuaalisesti asennetulla järjestelmällä." #, fuzzy msgid "No packages found" -msgstr "Määritetty {} liittymää" +msgstr "Paketteja ei löytynyt" #, fuzzy msgid "Select which greeter to install" -msgstr "Valitse asennettava käyttöliittymä" +msgstr "Valitse asennettava tervehtijä (greeter)" #, fuzzy msgid "Select a profile type" -msgstr "Valitut profiilit: " +msgstr "Valitse profiilityyppi" #, fuzzy msgid "Enter new password" -msgstr "Anna salasana: " +msgstr "Anna uusi salasana: " msgid "Enter a username" -msgstr "" +msgstr "Anna käyttäjänimi" #, fuzzy msgid "Enter a password" msgstr "Anna salasana: " msgid "The password did not match, please try again" -msgstr "" +msgstr "Salasanat eivät vastanneet, ole hyvä ja yritä uudelleen" msgid "Password strength: Weak" -msgstr "" +msgstr "Salasanan vahvuus on heikko" msgid "Password strength: Moderate" -msgstr "" +msgstr "Salasanan vahvuus on keskiverto" msgid "Password strength: Strong" -msgstr "" +msgstr "Salasanan vahvuus on vahva" msgid "The selected desktop profile requires a regular user to log in via the greeter" -msgstr "" +msgstr "Valittu työpöydän profiili vaati tavallisen käyttäjän kirjautumisen tervehtijällä" #, fuzzy, python-brace-format msgid "Environment type: {} {}" msgstr "Ympäristötyyppi: {}" msgid "Input cannot be empty" -msgstr "" +msgstr "Syöttö ei voi olla tyhjä" msgid "Recommended" -msgstr "" +msgstr "Suositeltu" msgid "Package" -msgstr "" +msgstr "Paketti" msgid "Curated selection of KDE Plasma packages" -msgstr "" +msgstr "Kuratoitu valikoima KDE Plasma paketeista" msgid "Dependencies" -msgstr "" +msgstr "Riippuvuudet" #, fuzzy msgid "Package group" -msgstr "Määritetty {} liittymää" +msgstr "Pakettiryhmä" msgid "Extensive KDE Plasma installation" -msgstr "" +msgstr "Laaja KDE Plasman asennus" msgid "Packages in group" -msgstr "" +msgstr "Paketit ryhmässä" msgid "Minimal KDE Plasma installation" -msgstr "" +msgstr "Minimaalinen KDE Plasma asennus" #, fuzzy msgid "Description" -msgstr "Levyn salaus" +msgstr "Kuvaus" #, fuzzy msgid "Select a flavor of KDE Plasma to install" -msgstr "Valitse asennettava käyttöliittymä" +msgstr "Valitse asennettavan KDE Plasman maku" msgid "Arial/Times/Courier replacement, Cyrillic support for Steam/games" -msgstr "" +msgstr "Arial/Times/Courier korvaus, kyrillisen kirjaimiston tuki Steam/pelejä varten" msgid "wide Unicode coverage, good fallback font" -msgstr "" +msgstr "laaja Unicode kattavuus, hyvä varafontti " + +#, python-brace-format +msgid "Setting up U2F login: {u2f_config.u2f_login_method.value}" +msgstr "Määritellään U2F kirjautuminen: {u2f_config.u2f_login_method.value}" + +#, python-brace-format +msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" +msgstr "Oletus: {DEFAULT_ITER_TIME}ms, suositeltu väli: 1000-60000" diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json index 2dbcf3b4..22c9c9ec 100644 --- a/archinstall/locales/languages.json +++ b/archinstall/locales/languages.json @@ -42,7 +42,7 @@ {"abbr": "fo", "lang": "Faroese"}, {"abbr": "fa", "lang": "Persian"}, {"abbr": "fj", "lang": "Fijian"}, - {"abbr": "fi", "lang": "Finnish"}, + {"abbr": "fi", "lang": "Finnish", "translated_lang": "Suomi"}, {"abbr": "fr", "lang": "French", "translated_lang": "Français"}, {"abbr": "fy", "lang": "Western Frisian"}, {"abbr": "ff", "lang": "Fulah"}, From b936fa11e39faad818fc06a3e0a9e0d3d35b281e Mon Sep 17 00:00:00 2001 From: correctmost <134317971+correctmost@users.noreply.github.com> Date: Wed, 29 Apr 2026 19:22:45 -0400 Subject: [PATCH 34/40] Fix some inconsistent-return-statements Pylint warnings (#4503) --- archinstall/lib/authentication/authentication_handler.py | 2 +- archinstall/lib/installer.py | 2 +- archinstall/lib/output.py | 2 +- archinstall/tui/ui/components.py | 6 +++--- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/archinstall/lib/authentication/authentication_handler.py b/archinstall/lib/authentication/authentication_handler.py index 9a99ba02..3a3b8cd4 100644 --- a/archinstall/lib/authentication/authentication_handler.py +++ b/archinstall/lib/authentication/authentication_handler.py @@ -53,7 +53,7 @@ class AuthenticationHandler: def _add_u2f_entry(self, file: Path, entry: str) -> None: if not file.exists(): debug(f'File does not exist: {file}') - return None + return content = file.read_text().splitlines() diff --git a/archinstall/lib/installer.py b/archinstall/lib/installer.py index 7bbfbae5..44a10eb2 100644 --- a/archinstall/lib/installer.py +++ b/archinstall/lib/installer.py @@ -402,7 +402,7 @@ class Installer: def _mount_luks_partition(self, part_mod: PartitionModification, luks_handler: Luks2) -> None: if not luks_handler.mapper_dev: - return None + return if part_mod.fs_type == FilesystemType.BTRFS and part_mod.btrfs_subvols: # Only mount BTRFS subvolumes that have mountpoints specified diff --git a/archinstall/lib/output.py b/archinstall/lib/output.py index e01da3eb..bc4bb113 100644 --- a/archinstall/lib/output.py +++ b/archinstall/lib/output.py @@ -133,7 +133,7 @@ class Journald: try: import systemd.journal # type: ignore[import-not-found] except ModuleNotFoundError: - return None + return log_adapter = logging.getLogger('archinstall') log_fmt = logging.Formatter('[%(levelname)s]: %(message)s') diff --git a/archinstall/tui/ui/components.py b/archinstall/tui/ui/components.py index c51d35f9..da6dc66b 100644 --- a/archinstall/tui/ui/components.py +++ b/archinstall/tui/ui/components.py @@ -350,7 +350,7 @@ class OptionListScreen(BaseScreen[ValueT]): def _set_preview(self, item_id: str) -> None: if self._preview_location is None: - return None + return preview_widget = self.query_one('#preview_content', Label) item = self._group.find_by_id(item_id) @@ -530,7 +530,7 @@ class SelectListScreen(BaseScreen[ValueT]): selection_list = self.query_one(SelectionList) if not selection_list.has_focus or event.key != 'enter': - return None + return if len(self._selected_items) < 1: index = selection_list.highlighted @@ -743,7 +743,7 @@ class ConfirmationScreen(BaseScreen[ValueT]): if self._is_btn_focus(): item = self._group.focus_item if not item: - return None + return _ = self.dismiss(Result(ResultType.Selection, _item=item)) From dc7d9cf0a2c0c78eab7716ed25dabae9cacd3d8e Mon Sep 17 00:00:00 2001 From: Softer Date: Thu, 30 Apr 2026 02:23:08 +0300 Subject: [PATCH 35/40] Improve Ukrainian translation (#4502) --- archinstall/locales/uk/LC_MESSAGES/base.mo | Bin 83620 -> 87112 bytes archinstall/locales/uk/LC_MESSAGES/base.po | 62 +++++++++++++-------- 2 files changed, 39 insertions(+), 23 deletions(-) diff --git a/archinstall/locales/uk/LC_MESSAGES/base.mo b/archinstall/locales/uk/LC_MESSAGES/base.mo index 1cb241b953ad7bfa04c89f0cc971028c6c9b569b..7c0230e6ed8ccd09d2990c53220d643d0f3325d4 100644 GIT binary patch delta 17180 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 bAEm>xORTH2Xw++@Xb}|5%5M~HPA&FdBKRr@ delta 14616 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 Date: Thu, 30 Apr 2026 16:37:37 +0900 Subject: [PATCH 36/40] Update Japanese translation (#4504) --- archinstall/locales/ja/LC_MESSAGES/base.mo | Bin 73655 -> 73831 bytes archinstall/locales/ja/LC_MESSAGES/base.po | 10 +++++++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/archinstall/locales/ja/LC_MESSAGES/base.mo b/archinstall/locales/ja/LC_MESSAGES/base.mo index 043a6f2b917c747b6be6e64d592ac7d5e9d89d70..96b625c6736d9cfbb9a41f4b467788c4be643657 100644 GIT binary patch delta 14785 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 A)Bpeg delta 14719 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 OXTrlqx#J(+uKYjUoeA0i diff --git a/archinstall/locales/ja/LC_MESSAGES/base.po b/archinstall/locales/ja/LC_MESSAGES/base.po index 9c568f86..1e0f52e1 100644 --- a/archinstall/locales/ja/LC_MESSAGES/base.po +++ b/archinstall/locales/ja/LC_MESSAGES/base.po @@ -2051,7 +2051,7 @@ msgid "Enter credentials file decryption password" msgstr "認証情報ファイルの復号パスワードを入力" msgid "Enter root password" -msgstr "ルートパスワードを入力" +msgstr "root パスワードを入力" msgid "Select bootloader to install" msgstr "インストールするブートローダーを選択" @@ -2222,3 +2222,11 @@ msgstr "U2F ログインの設定: {u2f_config.u2f_login_method.value}" #, python-brace-format msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" msgstr "デフォルト: {DEFAULT_ITER_TIME}ms, 推奨範囲: 1000-60000" + +#, python-brace-format +msgid "Setting up U2F login: {}" +msgstr "U2F ログインの設定: {}" + +#, python-brace-format +msgid "Default: {}ms, Recommended range: 1000-60000" +msgstr "デフォルト: {}ms, 推奨範囲: 1000-60000" From dd349540112456008643c706673fe6e87e0fc87b Mon Sep 17 00:00:00 2001 From: Softer Date: Sun, 3 May 2026 03:33:48 +0300 Subject: [PATCH 37/40] Remove dead Cutefish desktop profile (#4514) The cutefish package was never in the official Arch repos (AUR only) and the upstream project is abandoned. Installing this profile would always fail with a pacman "not found" error. --- .../default_profiles/desktops/cutefish.py | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 archinstall/default_profiles/desktops/cutefish.py diff --git a/archinstall/default_profiles/desktops/cutefish.py b/archinstall/default_profiles/desktops/cutefish.py deleted file mode 100644 index b014c8ca..00000000 --- a/archinstall/default_profiles/desktops/cutefish.py +++ /dev/null @@ -1,26 +0,0 @@ -from typing import override - -from archinstall.default_profiles.profile import DisplayServerType, GreeterType, Profile, ProfileType - - -class CutefishProfile(Profile): - def __init__(self) -> None: - super().__init__( - 'Cutefish', - ProfileType.DesktopEnv, - support_gfx_driver=True, - display_server=DisplayServerType.Xorg, - ) - - @property - @override - def packages(self) -> list[str]: - return [ - 'cutefish', - 'noto-fonts', - ] - - @property - @override - def default_greeter_type(self) -> GreeterType: - return GreeterType.Sddm From b18cc572163591ac13348dcfa83295ac16539274 Mon Sep 17 00:00:00 2001 From: Daniel Girtler Date: Mon, 4 May 2026 07:54:42 +1000 Subject: [PATCH 38/40] Pull `ui` module one level up (#4515) * Pull the UI module one level up * Update --- archinstall/default_profiles/desktop.py | 4 ++-- archinstall/default_profiles/desktops/hyprland.py | 4 ++-- archinstall/default_profiles/desktops/labwc.py | 4 ++-- archinstall/default_profiles/desktops/niri.py | 4 ++-- archinstall/default_profiles/desktops/plasma.py | 4 ++-- archinstall/default_profiles/desktops/sway.py | 4 ++-- archinstall/default_profiles/server.py | 4 ++-- archinstall/lib/applications/application_menu.py | 4 ++-- archinstall/lib/args.py | 2 +- archinstall/lib/authentication/authentication_menu.py | 4 ++-- archinstall/lib/bootloader/bootloader_menu.py | 4 ++-- archinstall/lib/configuration.py | 4 ++-- archinstall/lib/disk/disk_menu.py | 4 ++-- archinstall/lib/disk/encryption_menu.py | 4 ++-- archinstall/lib/disk/partitioning_menu.py | 4 ++-- archinstall/lib/disk/subvolume_menu.py | 2 +- archinstall/lib/general/general_menu.py | 4 ++-- archinstall/lib/general/system_menu.py | 4 ++-- archinstall/lib/global_menu.py | 4 ++-- archinstall/lib/locale/locale_menu.py | 4 ++-- archinstall/lib/menu/abstract_menu.py | 6 +++--- archinstall/lib/menu/helpers.py | 6 +++--- archinstall/lib/menu/list_manager.py | 4 ++-- archinstall/lib/menu/menu_helper.py | 2 +- archinstall/lib/menu/util.py | 4 ++-- archinstall/lib/mirror/mirror_menu.py | 4 ++-- archinstall/lib/network/network_menu.py | 4 ++-- archinstall/lib/network/wifi_handler.py | 6 +++--- archinstall/lib/packages/packages.py | 4 ++-- archinstall/lib/pacman/pacman_menu.py | 4 ++-- archinstall/lib/profile/profile_menu.py | 4 ++-- archinstall/lib/user/user_menu.py | 4 ++-- archinstall/main.py | 2 +- archinstall/scripts/guided.py | 2 +- archinstall/scripts/minimal.py | 2 +- archinstall/scripts/only_hd.py | 2 +- archinstall/tui/{ui => }/components.py | 4 ++-- archinstall/tui/{ui => }/menu_item.py | 0 archinstall/tui/{ui => }/result.py | 2 +- archinstall/tui/ui/__init__.py | 0 40 files changed, 71 insertions(+), 71 deletions(-) rename archinstall/tui/{ui => }/components.py (99%) rename archinstall/tui/{ui => }/menu_item.py (100%) rename archinstall/tui/{ui => }/result.py (97%) delete mode 100644 archinstall/tui/ui/__init__.py diff --git a/archinstall/default_profiles/desktop.py b/archinstall/default_profiles/desktop.py index 7ffe31a8..19681bc7 100644 --- a/archinstall/default_profiles/desktop.py +++ b/archinstall/default_profiles/desktop.py @@ -4,8 +4,8 @@ from archinstall.default_profiles.profile import DisplayServerType, GreeterType, from archinstall.lib.menu.helpers import Selection from archinstall.lib.output import info from archinstall.lib.profile.profiles_handler import profile_handler -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType if TYPE_CHECKING: from archinstall.lib.installer import Installer diff --git a/archinstall/default_profiles/desktops/hyprland.py b/archinstall/default_profiles/desktops/hyprland.py index fa0bc581..533afce4 100644 --- a/archinstall/default_profiles/desktops/hyprland.py +++ b/archinstall/default_profiles/desktops/hyprland.py @@ -4,8 +4,8 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class HyprlandProfile(Profile): diff --git a/archinstall/default_profiles/desktops/labwc.py b/archinstall/default_profiles/desktops/labwc.py index bf4a3297..49e8c437 100644 --- a/archinstall/default_profiles/desktops/labwc.py +++ b/archinstall/default_profiles/desktops/labwc.py @@ -4,8 +4,8 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class LabwcProfile(Profile): diff --git a/archinstall/default_profiles/desktops/niri.py b/archinstall/default_profiles/desktops/niri.py index 347290fe..8bfda797 100644 --- a/archinstall/default_profiles/desktops/niri.py +++ b/archinstall/default_profiles/desktops/niri.py @@ -4,8 +4,8 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class NiriProfile(Profile): diff --git a/archinstall/default_profiles/desktops/plasma.py b/archinstall/default_profiles/desktops/plasma.py index e90f8a27..66a5ae9a 100644 --- a/archinstall/default_profiles/desktops/plasma.py +++ b/archinstall/default_profiles/desktops/plasma.py @@ -5,8 +5,8 @@ from archinstall.default_profiles.profile import CustomSetting, DisplayServerTyp from archinstall.lib.menu.helpers import Selection from archinstall.lib.packages.packages import available_package, package_group_info from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class PlasmaFlavor(StrEnum): diff --git a/archinstall/default_profiles/desktops/sway.py b/archinstall/default_profiles/desktops/sway.py index 5d222307..d137d03b 100644 --- a/archinstall/default_profiles/desktops/sway.py +++ b/archinstall/default_profiles/desktops/sway.py @@ -4,8 +4,8 @@ from archinstall.default_profiles.desktops import SeatAccess from archinstall.default_profiles.profile import CustomSetting, DisplayServerType, GreeterType, Profile, ProfileType from archinstall.lib.menu.helpers import Selection from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class SwayProfile(Profile): diff --git a/archinstall/default_profiles/server.py b/archinstall/default_profiles/server.py index 6833731f..bdd3d079 100644 --- a/archinstall/default_profiles/server.py +++ b/archinstall/default_profiles/server.py @@ -4,8 +4,8 @@ from archinstall.default_profiles.profile import Profile, ProfileType, SelectRes from archinstall.lib.menu.helpers import Selection from archinstall.lib.output import info from archinstall.lib.profile.profiles_handler import profile_handler -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType if TYPE_CHECKING: from archinstall.lib.installer import Installer diff --git a/archinstall/lib/applications/application_menu.py b/archinstall/lib/applications/application_menu.py index 990dcda7..99e48726 100644 --- a/archinstall/lib/applications/application_menu.py +++ b/archinstall/lib/applications/application_menu.py @@ -17,8 +17,8 @@ from archinstall.lib.models.application import ( PrintServiceConfiguration, ) from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class ApplicationMenu(AbstractSubMenu[ApplicationConfiguration]): diff --git a/archinstall/lib/args.py b/archinstall/lib/args.py index 77545736..8d78f7e6 100644 --- a/archinstall/lib/args.py +++ b/archinstall/lib/args.py @@ -30,7 +30,7 @@ from archinstall.lib.output import debug, error, logger, warn from archinstall.lib.plugins import load_plugin from archinstall.lib.translationhandler import Language, tr, translation_handler from archinstall.lib.version import get_version -from archinstall.tui.ui.components import tui +from archinstall.tui.components import tui @p_dataclass diff --git a/archinstall/lib/authentication/authentication_menu.py b/archinstall/lib/authentication/authentication_menu.py index 6bead8ca..5453099f 100644 --- a/archinstall/lib/authentication/authentication_menu.py +++ b/archinstall/lib/authentication/authentication_menu.py @@ -9,8 +9,8 @@ from archinstall.lib.models.users import Password, User from archinstall.lib.output import FormattedOutput from archinstall.lib.translationhandler import tr from archinstall.lib.user.user_menu import select_users -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class AuthenticationMenu(AbstractSubMenu[AuthenticationConfiguration]): diff --git a/archinstall/lib/bootloader/bootloader_menu.py b/archinstall/lib/bootloader/bootloader_menu.py index 37eaeb8d..d32a5a21 100644 --- a/archinstall/lib/bootloader/bootloader_menu.py +++ b/archinstall/lib/bootloader/bootloader_menu.py @@ -5,8 +5,8 @@ from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.models.bootloader import Bootloader, BootloaderConfiguration from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class BootloaderMenu(AbstractSubMenu[BootloaderConfiguration]): diff --git a/archinstall/lib/configuration.py b/archinstall/lib/configuration.py index 3e9135bf..aba835d9 100644 --- a/archinstall/lib/configuration.py +++ b/archinstall/lib/configuration.py @@ -14,8 +14,8 @@ from archinstall.lib.models.bootloader import Bootloader from archinstall.lib.models.network import NetworkConfiguration from archinstall.lib.output import debug, logger, warn from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class ConfigurationOutput: diff --git a/archinstall/lib/disk/disk_menu.py b/archinstall/lib/disk/disk_menu.py index 9743ee78..26aa145d 100644 --- a/archinstall/lib/disk/disk_menu.py +++ b/archinstall/lib/disk/disk_menu.py @@ -37,8 +37,8 @@ from archinstall.lib.models.device import ( ) from archinstall.lib.output import FormattedOutput, debug from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType @dataclass diff --git a/archinstall/lib/disk/encryption_menu.py b/archinstall/lib/disk/encryption_menu.py index d66ccf92..f5d4f095 100644 --- a/archinstall/lib/disk/encryption_menu.py +++ b/archinstall/lib/disk/encryption_menu.py @@ -19,8 +19,8 @@ from archinstall.lib.models.device import ( from archinstall.lib.models.users import Password from archinstall.lib.output import FormattedOutput from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class DiskEncryptionMenu(AbstractSubMenu[DiskEncryption]): diff --git a/archinstall/lib/disk/partitioning_menu.py b/archinstall/lib/disk/partitioning_menu.py index 7e07d776..a524cf99 100644 --- a/archinstall/lib/disk/partitioning_menu.py +++ b/archinstall/lib/disk/partitioning_menu.py @@ -21,8 +21,8 @@ from archinstall.lib.models.device import ( ) from archinstall.lib.output import FormattedOutput from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class FreeSpace: diff --git a/archinstall/lib/disk/subvolume_menu.py b/archinstall/lib/disk/subvolume_menu.py index 0f8da9e7..94854b3c 100644 --- a/archinstall/lib/disk/subvolume_menu.py +++ b/archinstall/lib/disk/subvolume_menu.py @@ -6,7 +6,7 @@ from archinstall.lib.menu.list_manager import ListManager from archinstall.lib.menu.util import prompt_dir from archinstall.lib.models.device import SubvolumeModification from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.result import ResultType +from archinstall.tui.result import ResultType class SubvolumeMenu(ListManager[SubvolumeModification]): diff --git a/archinstall/lib/general/general_menu.py b/archinstall/lib/general/general_menu.py index 257b61e5..be5498d8 100644 --- a/archinstall/lib/general/general_menu.py +++ b/archinstall/lib/general/general_menu.py @@ -4,8 +4,8 @@ from archinstall.lib.locale.utils import list_timezones from archinstall.lib.menu.helpers import Confirmation, Input, Selection from archinstall.lib.output import warn from archinstall.lib.translationhandler import Language, tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class PostInstallationAction(Enum): diff --git a/archinstall/lib/general/system_menu.py b/archinstall/lib/general/system_menu.py index 7fa0d1f2..82dc4cdb 100644 --- a/archinstall/lib/general/system_menu.py +++ b/archinstall/lib/general/system_menu.py @@ -5,8 +5,8 @@ from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.models.application import ZramAlgorithm, ZramConfiguration from archinstall.lib.models.package_types import DEFAULT_KERNEL, Kernel from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType async def select_kernel(preset: list[Kernel] = []) -> list[Kernel]: diff --git a/archinstall/lib/global_menu.py b/archinstall/lib/global_menu.py index cdd820a9..eac936bd 100644 --- a/archinstall/lib/global_menu.py +++ b/archinstall/lib/global_menu.py @@ -32,8 +32,8 @@ from archinstall.lib.packages.packages import list_available_packages, select_ad from archinstall.lib.pacman.config import PacmanConfig from archinstall.lib.pacman.pacman_menu import PacmanMenu from archinstall.lib.translationhandler import Language, tr, translation_handler -from archinstall.tui.ui.components import tui -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.components import tui +from archinstall.tui.menu_item import MenuItem, MenuItemGroup class GlobalMenu(AbstractMenu[None]): diff --git a/archinstall/lib/locale/locale_menu.py b/archinstall/lib/locale/locale_menu.py index dc743fd3..add9fc2d 100644 --- a/archinstall/lib/locale/locale_menu.py +++ b/archinstall/lib/locale/locale_menu.py @@ -5,8 +5,8 @@ from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.helpers import Selection from archinstall.lib.models.locale import LocaleConfiguration from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class LocaleMenu(AbstractSubMenu[LocaleConfiguration]): diff --git a/archinstall/lib/menu/abstract_menu.py b/archinstall/lib/menu/abstract_menu.py index 8e9cbed7..590cabf1 100644 --- a/archinstall/lib/menu/abstract_menu.py +++ b/archinstall/lib/menu/abstract_menu.py @@ -5,9 +5,9 @@ from typing import Any, Self, override from archinstall.lib.menu.helpers import Selection from archinstall.lib.output import error from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import InstanceRunnable -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.components import InstanceRunnable +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType CONFIG_KEY = '__config__' diff --git a/archinstall/lib/menu/helpers.py b/archinstall/lib/menu/helpers.py index 96361765..b512c956 100644 --- a/archinstall/lib/menu/helpers.py +++ b/archinstall/lib/menu/helpers.py @@ -4,9 +4,9 @@ from typing import Any, Literal, override from textual.validation import ValidationResult, Validator from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import InputInfo, InputScreen, LoadingScreen, NotifyScreen, OptionListScreen, SelectListScreen, TableSelectionScreen -from archinstall.tui.ui.menu_item import MenuItemGroup -from archinstall.tui.ui.result import Result, ResultType +from archinstall.tui.components import InputInfo, InputScreen, LoadingScreen, NotifyScreen, OptionListScreen, SelectListScreen, TableSelectionScreen +from archinstall.tui.menu_item import MenuItemGroup +from archinstall.tui.result import Result, ResultType class Selection[ValueT]: diff --git a/archinstall/lib/menu/list_manager.py b/archinstall/lib/menu/list_manager.py index 54683f54..3b612162 100644 --- a/archinstall/lib/menu/list_manager.py +++ b/archinstall/lib/menu/list_manager.py @@ -4,8 +4,8 @@ from typing import cast from archinstall.lib.menu.helpers import Selection from archinstall.lib.menu.menu_helper import MenuHelper from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class ListManager[ValueT]: diff --git a/archinstall/lib/menu/menu_helper.py b/archinstall/lib/menu/menu_helper.py index 47e04fb8..6ca3b953 100644 --- a/archinstall/lib/menu/menu_helper.py +++ b/archinstall/lib/menu/menu_helper.py @@ -1,5 +1,5 @@ from archinstall.lib.output import FormattedOutput -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.menu_item import MenuItem, MenuItemGroup class MenuHelper[ValueT]: diff --git a/archinstall/lib/menu/util.py b/archinstall/lib/menu/util.py index ff3dea47..10edfd49 100644 --- a/archinstall/lib/menu/util.py +++ b/archinstall/lib/menu/util.py @@ -5,8 +5,8 @@ from pathlib import Path from archinstall.lib.menu.helpers import Confirmation, Input from archinstall.lib.models.users import Password, PasswordStrength from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import InputInfo, InputInfoType, tui -from archinstall.tui.ui.result import ResultType +from archinstall.tui.components import InputInfo, InputInfoType, tui +from archinstall.tui.result import ResultType async def get_password( diff --git a/archinstall/lib/mirror/mirror_menu.py b/archinstall/lib/mirror/mirror_menu.py index 3e899cca..5158bffd 100644 --- a/archinstall/lib/mirror/mirror_menu.py +++ b/archinstall/lib/mirror/mirror_menu.py @@ -15,8 +15,8 @@ from archinstall.lib.models.mirrors import ( from archinstall.lib.models.packages import Repository from archinstall.lib.output import FormattedOutput from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class CustomMirrorRepositoriesList(ListManager[CustomRepository]): diff --git a/archinstall/lib/network/network_menu.py b/archinstall/lib/network/network_menu.py index 2e95a82e..120af19e 100644 --- a/archinstall/lib/network/network_menu.py +++ b/archinstall/lib/network/network_menu.py @@ -6,8 +6,8 @@ from archinstall.lib.menu.list_manager import ListManager from archinstall.lib.models.network import NetworkConfiguration, Nic, NicType from archinstall.lib.networking import list_interfaces from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class ManualNetworkConfig(ListManager[Nic]): diff --git a/archinstall/lib/network/wifi_handler.py b/archinstall/lib/network/wifi_handler.py index 0546310b..4c858601 100644 --- a/archinstall/lib/network/wifi_handler.py +++ b/archinstall/lib/network/wifi_handler.py @@ -9,9 +9,9 @@ from archinstall.lib.models.network import WifiConfiguredNetwork, WifiNetwork from archinstall.lib.network.wpa_supplicant import WpaSupplicantConfig from archinstall.lib.output import debug from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import ConfirmationScreen, InputScreen, InstanceRunnable, LoadingScreen, NotifyScreen, TableSelectionScreen, tui -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import Result, ResultType +from archinstall.tui.components import ConfirmationScreen, InputScreen, InstanceRunnable, LoadingScreen, NotifyScreen, TableSelectionScreen, tui +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import Result, ResultType @dataclass diff --git a/archinstall/lib/packages/packages.py b/archinstall/lib/packages/packages.py index 3572c6c4..dcc4da9e 100644 --- a/archinstall/lib/packages/packages.py +++ b/archinstall/lib/packages/packages.py @@ -6,8 +6,8 @@ from archinstall.lib.models.packages import AvailablePackage, LocalPackage, Pack from archinstall.lib.output import debug from archinstall.lib.pacman.pacman import Pacman from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType def installed_package(package: str) -> LocalPackage | None: diff --git a/archinstall/lib/pacman/pacman_menu.py b/archinstall/lib/pacman/pacman_menu.py index 010c3f6d..16ad6d2b 100644 --- a/archinstall/lib/pacman/pacman_menu.py +++ b/archinstall/lib/pacman/pacman_menu.py @@ -5,8 +5,8 @@ from archinstall.lib.menu.helpers import Confirmation, Input from archinstall.lib.models.pacman import PacmanConfiguration from archinstall.lib.pathnames import PACMAN_CONF from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class PacmanMenu(AbstractSubMenu[PacmanConfiguration]): diff --git a/archinstall/lib/profile/profile_menu.py b/archinstall/lib/profile/profile_menu.py index 0bdc9b0b..d3b35c82 100644 --- a/archinstall/lib/profile/profile_menu.py +++ b/archinstall/lib/profile/profile_menu.py @@ -7,8 +7,8 @@ from archinstall.lib.menu.abstract_menu import AbstractSubMenu from archinstall.lib.menu.helpers import Confirmation, Selection from archinstall.lib.models.profile import ProfileConfiguration from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import ResultType class ProfileMenu(AbstractSubMenu[ProfileConfiguration]): diff --git a/archinstall/lib/user/user_menu.py b/archinstall/lib/user/user_menu.py index e7d77aab..8e6e48fd 100644 --- a/archinstall/lib/user/user_menu.py +++ b/archinstall/lib/user/user_menu.py @@ -6,8 +6,8 @@ from archinstall.lib.menu.list_manager import ListManager from archinstall.lib.menu.util import get_password from archinstall.lib.models.users import User from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem -from archinstall.tui.ui.result import ResultType +from archinstall.tui.menu_item import MenuItem +from archinstall.tui.result import ResultType class UserList(ListManager[User]): diff --git a/archinstall/main.py b/archinstall/main.py index cf0e42f6..505652a4 100644 --- a/archinstall/main.py +++ b/archinstall/main.py @@ -18,7 +18,7 @@ from archinstall.lib.packages.util import check_version_upgrade from archinstall.lib.pacman.pacman import Pacman from archinstall.lib.translationhandler import tr, translation_handler from archinstall.lib.utils.util import running_from_iso -from archinstall.tui.ui.components import tui +from archinstall.tui.components import tui def _log_sys_info() -> None: diff --git a/archinstall/scripts/guided.py b/archinstall/scripts/guided.py index 21228480..899683f2 100644 --- a/archinstall/scripts/guided.py +++ b/archinstall/scripts/guided.py @@ -22,7 +22,7 @@ from archinstall.lib.output import debug, error, info from archinstall.lib.packages.util import check_version_upgrade from archinstall.lib.profile.profiles_handler import profile_handler from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import tui +from archinstall.tui.components import tui def show_menu( diff --git a/archinstall/scripts/minimal.py b/archinstall/scripts/minimal.py index 681d4266..ee4b49c7 100644 --- a/archinstall/scripts/minimal.py +++ b/archinstall/scripts/minimal.py @@ -12,7 +12,7 @@ from archinstall.lib.network.network_handler import install_network_config from archinstall.lib.output import debug, error, info from archinstall.lib.profile.profiles_handler import profile_handler from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import tui +from archinstall.tui.components import tui def perform_installation(arch_config_handler: ArchConfigHandler) -> None: diff --git a/archinstall/scripts/only_hd.py b/archinstall/scripts/only_hd.py index afb1f919..5df72965 100644 --- a/archinstall/scripts/only_hd.py +++ b/archinstall/scripts/only_hd.py @@ -10,7 +10,7 @@ from archinstall.lib.installer import Installer from archinstall.lib.menu.util import delayed_warning from archinstall.lib.output import debug, error from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.components import tui +from archinstall.tui.components import tui def show_menu(arch_config_handler: ArchConfigHandler) -> None: diff --git a/archinstall/tui/ui/components.py b/archinstall/tui/components.py similarity index 99% rename from archinstall/tui/ui/components.py rename to archinstall/tui/components.py index da6dc66b..f92364bb 100644 --- a/archinstall/tui/ui/components.py +++ b/archinstall/tui/components.py @@ -21,8 +21,8 @@ from textual.worker import WorkerCancelled from archinstall.lib.output import debug from archinstall.lib.translationhandler import tr -from archinstall.tui.ui.menu_item import MenuItem, MenuItemGroup -from archinstall.tui.ui.result import Result, ResultType +from archinstall.tui.menu_item import MenuItem, MenuItemGroup +from archinstall.tui.result import Result, ResultType ValueT = TypeVar('ValueT') diff --git a/archinstall/tui/ui/menu_item.py b/archinstall/tui/menu_item.py similarity index 100% rename from archinstall/tui/ui/menu_item.py rename to archinstall/tui/menu_item.py diff --git a/archinstall/tui/ui/result.py b/archinstall/tui/result.py similarity index 97% rename from archinstall/tui/ui/result.py rename to archinstall/tui/result.py index 6258bccf..a2232a4f 100644 --- a/archinstall/tui/ui/result.py +++ b/archinstall/tui/result.py @@ -2,7 +2,7 @@ from dataclasses import dataclass from enum import Enum, auto from typing import Self, cast -from archinstall.tui.ui.menu_item import MenuItem +from archinstall.tui.menu_item import MenuItem class ResultType(Enum): diff --git a/archinstall/tui/ui/__init__.py b/archinstall/tui/ui/__init__.py deleted file mode 100644 index e69de29b..00000000 From 528c27fbe1ce8223cdb5738bb9f310afcb2a737f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 4 May 2026 08:14:56 +1000 Subject: [PATCH 39/40] Update dependency arch/python-textual to v8.2.5 (#4517) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1add6027..358c4ceb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,7 +21,7 @@ dependencies = [ "pyparted==3.13.0", "pydantic==2.12.5", "cryptography==47.0.0", - "textual==8.2.4", + "textual==8.2.5", "markdown-it-py==4.0.0", "linkify-it-py==2.1.0", ] From b5501d9507d824851318df36ed361097c18336d1 Mon Sep 17 00:00:00 2001 From: aronmr-1 Date: Sun, 3 May 2026 22:16:16 +0000 Subject: [PATCH 40/40] Improved Finnish translation further (#4516) --- archinstall/locales/fi/LC_MESSAGES/base.mo | Bin 51470 -> 65318 bytes archinstall/locales/fi/LC_MESSAGES/base.po | 685 ++++++++------------- 2 files changed, 270 insertions(+), 415 deletions(-) diff --git a/archinstall/locales/fi/LC_MESSAGES/base.mo b/archinstall/locales/fi/LC_MESSAGES/base.mo index 43b527d57e25ff1c6ff6397f4403d58f5721cdc1..287472f9243167a877f4f390b3564534ffe7bfd0 100644 GIT binary patch delta 25053 zcma)@2YgjU_V{n;CDagFfLwY)?y( zI*aGdDwfp>?o70-8>(7Xd{@z0R^DLC8Unp=AUq5w!?)l9*d@)fdcvz<0z3sL!6#vR z*p!#&!!+0gUI**IW6*0^QR^O)A$h1Sa21paUWUtI`*h2i12@AN@O{__4j8669yUOp z4{O7GI1Pqjb@&*hKi1Pw8h8OVgCDwb)UtjhA}wl|VOezEN`j4HZ&(kGhIQd|BQJ(h zun$U)g0Lan0HuOmP%5|`PJoZVv9SJd%W45BXq%2 zpj5O3@}CvvPd9kV$REIV$Q?%-i$H1Md{`eYg;H?G2Ct8uTwHW7c52cD_`@{?PReC>2eCGRAYEm^#KAJpsjZ4?}6_%SQehiUq1o z)J%lZuuewq52fK_p_DfRc9!|SgosqM0oI0Fp^V)wSPPzjQt`b|obyR2rhFet1HOY& zVBJZ2?3+RHq1I4*D-HI8mq7lrj_^l@@H<$G`mG;{)I}kyjwHlGX?Y_kEw+u^9ZCa- zLTT_=$kJhD!YS|?Xu~(44Bf9#EZH`&a9HQlnh!&{+@)k{#kw9X96S_sEO>B(W(8$JXXcIzA12@aWQS#9AmDDrxk0FOhd z@C+OYe}+%g;cD0~Wv6W5w!SwyWyP!_a2SREdU5|I~MgDW8Qa;2W?Q&Y0_No7R(1 z-s?9{J5>f0XPau|IY!Qf;%osZ`9p9EybKP6(fIk=>qkRr=>)h4PKWZsNr-z`e}&TW zx(je5I1Wm_JK$2$Gfq9A4~mcMfijy;z(iOIrGbBgZQygTwaou-h%`k}pVH*TjxYlb zg3^GMP+qtKHiI`qhTS?1$HMxH^_b3r@yH5_a~*(U(GOu8_)pjoHeTW`Jk}ssPv-wp zA~K)-P+Ay)GB#^q19%0Lo+v0ovI|Os55bA>uSQ>EsZMVUlhC(;V$n1x?~j5l;CLv` zxeV5b5-BDk6|FJc0;M7QU@|-mrDu;qnI+Fd(OZtL$c9qjP$%^6KZi06t7Yp=t2LB{jD=F+awxNB2kZ&Y zK$%5fL$RElqqpO3P=+Qg2m4D;C!mmmry1r$8GbX<~FNIRj zS5SIVHBUFVE)-L?fZ}W^P#V%3PJ^Rh4R{?CXWa|Mf}a>hza=6j`UOhCHM}}QeJFBs zC_Z5ueP1XRNrz&gOemIE25Gak8p=?;52f6%VN3WktOXPEb^bOG%SEk$M8vsfKrvk* zlnSqe;?=ugHF!G|OWg%K!gEl(`%@@G(4{~xv16g++XoBb2`J^a@@f45D3%-to6G!P zL_{hohGM$SupZnC#RA6+{{qF-r=j%ZZ*UfT9?JVE)W&dILm_L8bu(n9S#f^dfov$V zB@apiH^O?h7v2hoz*1Nnehu5gpP;;u6ws#c2CE|vg>B$SC_~{uX?QUdi>-&! z&`n0a1Bzu2Kq;>jM#bch5a|iugkqZbBJG6jpqOqflm;$^b)e74D-5rI@#wcfY4~0! zPIttl-vPx!_Z$5)umkdoMc7{wenKH*Snm?Ou%tqnKGR_<=!Md-t6(Fz7fQoUKykh& zpp^3-%!EHcak^1K{r+M&9CEUn=?)g;bCb(qohg#WEA1q&u(yTxsNu zP^RgABcF$o|8r|tFS&9&4ithH$t)Wokssolt@1m2@(C`c-RFw2GAup8H_K{L(u_>FARd>Gb7-Ppgsdyfga!dO_ZLNRT%%k^0<1=;^;W{V_(l2l^tac^iFAGKXmAYs7uqyIOC?>lU zipjP>G3kCNmO5e5OJQT=N1%-HD^P~$6DSsGd6l-nIM@UEa+m^7Lb2>?S78cS9rzz!R9Lpnq8_O4JWm;t3>*-#o5hHc?hup>NbZQub|6P|(N;p0YbxLJS7HHYE@b6|gX82aEF zFd2@&T2Jd}9+7kuyI?Q)G87Zmyhb-H4UR+3fL^!(c7oqRF=_KH=B@`OA^YGUxDiUv zABHKgLfH{=pH2_Au&@H;5JF?>5S1&)Rf!%`^u zBG>8$Jq#Bie*>lAQ+DVETo1b!1w5ThN9dLz$K} zcWNJTpbS9{tO0$nHVi>=(lsy@u7lF>+hHGg683-}2&vy{e4QSP5l}2~iQz3q{}LRH zzWVi=6QMM08>}10(7_DkLpSI(|3jFMoV-gr+h!;g-UD014`BdS*^T{WEQ3Ur!`-kE zv~JWDG=`#2g04m20_3-#49Va<`oyyV&PM(U%6c(+uP$dVY=C?M)`t&4Y4|g6A$)l+ z_7{`&-KR~N4x1y7f#T(hVG>*e6X0&6zXP^Lei}B0pTmamKTtYQ|0X>YHf)OA1=fWl zU_8u(P2l{Su>UL~0TjYVq0Hl?{d(+1K=FwJI0bHjW8j-m3Tk&i_pm3FiZkGJI1P#u zAA<7UbFdY(59$V`L-CoJQ6gfJ1yH;*$H?2ESY|g>x%z@O~%-oq=N7H=$VIODN9x z8*Bz^-mEQ@3|k_nLwRp5l=mXA7mQv>qy>>vP%63r)8WT(5bSV^cB(~i0P-#3DNA$tu^=?vBdC>4GP z#ZuN0-Q(I&Ox_Agk9)xCa4f6=C&Nx~29%Dif|74L6kj?D-TnUoBGR)bT?OmGt$M*| zU^vLofgQ=W8Mc8Zp*ZWaP<-K2C`0iB6lbh;RBvi6pft2Ilm-lj(x7Ruew0YAL|`!# zr@0b}>HcEmf57p`Nw?_*BnL``H^3V35R{6KL-F#5pj7lEYz^Os;se$(-H;?G`MSfX zIKyBf(&7nF3Z4(8;9S@q`k|P12doWuL2=fbp}hZhDAVk1C`0%IlyVvz*9~h0rGq_T z9XJe1z6r+}|K3EhQOFQn2Q%Q)uo{fNUBA!>%6x4FYr@_}9t_2_Q=p9LQWy`zP#StU zl!fYQ=)l)t3LJ8WZa~f**uO4{%TS03H^X?i4_1Z8pp4ZC*atoW`@tWfG`!mhy{#@b zd|ChJTL|k$L$x6qEb{rKgD}xyONBU@y2D4u`ixvCvmg z#2Tn%*9?DRS_>11uqH~GJ^eTbU!t3BbcpS?7{{W7K ztxC0XW z$DveM zh={W^zfYgp+Cl003MjsC5;lSl!UXuN;Ri;e0suLG82$p>*g47!~jTh)9xTgfj2zJ*1to2~0-r4eP^cP+nXLWz2)H4Lk#F z_%@VseuG6Y>5M)vTmz>de+s3XfoFAt$DYOhGFI24u;C#n&h;o1XZZp)giRmT7U&E` z?gqt_>99E*W6~GH4#?S1#(X2318;`1ko^p$!)?y#A?R{0s#mrVD8!WGpcFU_ij(9+ zvB+B38g76xmWPf0K{y=w5hxw0eqJ{`0m?!%47P*0umRi*rC~S1zVPlSkxU|=LRlII zJi-|Oj({?sk3h-zJRAvYJgOTq0d_#nHS#r33O)v@JlESs`a?GKmru6Z3(5K-mp5H1f}QG43|K8uMo;mt%Ne>o1m1x z3s!}PU^VKujuMd@~b2Z%_|Yd@_kZU}25FNI=>d?*F2f;HhrlfK=^ zH$v&z%@C7X_rtpIAs7#zgyPJvz-;&xtOch%gZ*U;=M#}0E`^eC36y!g3X1dWhGOdb zq4eNIC_eBFl=tfVUHd{36uB*w_xivga5@xc-3ph%QYZ~;`YiSj5o!Od_Uap;Os{*O zjM+0#TK+i{ueL5|)3=9G(Ksj_m&)1lD*?f4E%w9QOC2 zcprrf!PMvVG?@(>AxEK%^|i1Lya$ejXQ7z5<_o%E39upZ04VQ`gHql+D3(|XyTi4x z0XzYv!4E}^;&Ip*#Vb(8@^dIXk9$!!pcxcX4uN9I6|f)N3&m2;!Fuo?P~QI)%KHf~ z=}jvYO2g8jSZFE~Ux_XzA|}sRw2F{QgIz6N>t;=!=2=P@Js;W&pp)&t}Gm4?F>4p@*K4jPdC&5SIAlT@2 zeKMK|(~#FeG3A4>8+_XECnyc?^oF+RSm;^=%B(7ZQ{XN*l=`hth|Gi?-ZUAYw0sv# zh3BD+`BzXXYW$YoGcsUv9)aSl=U@u_*vJju*5&ktG9-&&0t~^ZjP(X0(vxj) z1-uE$*f)Jg-+qmR;@$aBDp(DB!u@a@eAdX#-qofZ2PM52X22tGIQ$rj={vutXV2{S zu)nlq84BrHF%+-71&YazLhyCPtk~V45uT%4m-l`pXhl%!*C;v zpnnjG)As#TZ$``ERmiWxg>cDdy1@@Xv0U@d^}S$pJrOD3H1xw>U+5m}hqIAyhc#f; zFSWi7tclzV%6v|S;)H#SJPAtv#jq9hK(W9&C_}Ipj)V`ut}_3BBQhLC*RQmRe6Snx ztx$&GMOX)Z4%6WeusZDf4}Fjr4BH~7Lm9dyP~Hne8M@7|3p@yAHa!hH!GFOeGXGnD zt$Vr#W|HtC901#WqYIn|>mvK1^mr8%r`lrVeQ+Z3NhnVE3zVTs_*PqDFq9!24#jc` z4ugB(1nRe5Cz1g>e5dc_a$tMp7ojxd-*7za`Agw=k~4NQbl@!}ywB;yTGobe1C3V(w0;DCSW25yJavkOp6`Y*T)w*8Tl z3|tRo?7xCx_&xj^^!{7luJ!#%58)=b9sT1!VgG4F=Kib;J_e;B7hq%fZzwIV`wRCt za3D;9S3~jYyP*tCqhGb9TEhj%Ghr2Y64r*LP%QNzjECo;H1xu+*k5|`icwVgj~<)a zP@HW%>hBC4}K2QVDf+UN9BAt4*6<02EG8Lq87igg~Ma~=}U`F5}!d_Iw8+h zQ3Ns3bP~_GDt$6BQL7jFO9|D;Hv;w`$n$sPA#fu6D{O`SM&h)~QiQjN&mk-!bRjGy zeK29OdA~L~v1~M#KZj86LLsK#PdHD!gdoqSgmI*gg_8+;39%=DK7>$<(Ap@kgUxyO zN%(^)V~pW-1oP4TZ1f`E#*2?5<4;yP^dkR75_n{$6r$UQ z?t-f+|1%x^y@XYS?+G^$nv+j_WFT=_f2<&pmFAtRi9byI9@qjNC-W%6J0|^U^w$ws z_AL*3dBm|QKI_mQLs0`>3Lht&Am9qtGTyCf-b1t+M2%1g`w@&h6AuS;db=*Lzzi)2@lBlvkY5rqnt;$ zoOpl2ZsOOPLbehgPmt$kI1c{Pl{mVaJo#`xX?4)of&+|Rvh5%=K{u9goVZNeiDl`G zKdYj(*eDvp<7AZQ2Er}GpKzt}KV41U(XbQg17QwfH(9nJe-8f(`=FDxL!Md4>yhOd zX4r>#9U1=wLL)+TGR<(al>d?CR-R^r$)w*2Pr`o_rV)}P(L8rS`Dgq+U`NR6UG{7> zu{G!y@!kPAgh2nxpT;CSYD8H!_aNtzX*WThErij8A?QnBE%befJMa=HPh*pJD=Z+~ zq}A3{#G8_53i3mQw+U@!{Fj**rkVn#l8{4uD*9jHeaMpti%h=#aHNU1CVe|0k+6;+ zPcdn0iN8SDOMDZ$FWnSofO#(rIYwA*;^_YkMk#roHHCCETy1FHFT-u<|3Nrw(wC89 z6Q566w-QzomLkW)mq=>{7ZBvR5q2Xj1UJh1FVDw@3B*4j?lu!pjIZQQ#ZM?coN(0(2{o34J0&sZ|Hmj~Axe2_ zngS($8{s3uEOc^ES#0v`K>iQ$p9sAOSCe)G-3VCm8EJ%nlBXrRv!M;f2_=#-w>+8`3%( zy(z-QLH=$>KY`HA)!_fR=EYeRa}s}y(3P|`gb-mi;dzs%ZiT#`qMvLkn}>cIfrGJi zKjCkrtu<+9k-HH;0wd^Ohpzu!0c%Splv#wA311Q9>50Coj#@{FFCkn`*h~5%qyLil zLBeqK3FbXHq<&}81!G8ajGRRLRq}m-?9TtWDCCJ~xPKor1$~UPhx8MKe&~k62jTUE zcTAo%bXSsZ5b_If1#-Zo-GaOk`KXa?0AmP78Cm2S!hOm(^nD?_u|CRVF#5WV#iT&pj z_7UDU6%2#J2{X~nm~ZYS}tiDweR zrmW~R*fSEujxDZin*xM7V^|gs>8Q2?crJX9Rg#5-u}^SBG~P z{Znv)n?wJ(61mXGbI5lE;Ujceu*O{TlF#sGG9DrRrg=e;NuKU-w8?V{xeK8wx-h&J z{RETt3tWY6NooJCW2@9o$?+_ABEE2HX-W41Rp(_#Lg7H69rP3hLf&v7SYnOH$*~>V z=tG`hu_tJB5hOSI$1hcSC8SDwP3^fn;17r76>r!Z@H;-c$jL5nay^xFWp#T?YxUk8 zS1r%uD=OXDr*~W}U&Ip*1j2dheBa!Tzpr#up5xE;RBEbf+i$fR*|o14(zS)!-nF%` zy3bj*B3ms)gH+A$4SGdrH7YL<2zhM3C%hsMEU>c!{^j1>NYIg{mhSAgHg2#RwTptD zVy|a~HL79;J6uxaNwZh4DN}oFuRrVwE_bp$Ays!k+jcr7SZF)`9NV+f8!l56IiV1B z=BWMyUK$_tQ&CM$lB1Nd(VK4LsgMnZuCYFx`BV@8@4+vSKr_8X+;@X95pHmWu zgsst9OtX8d;{$VRiFb)*)SUx6s>XwE{DYAj?eTfS7meI4gJ#ys4tm|5tA7rEHhE;m|_{1E08^JZA112(O;S2+H#9S+zbr`Y4Z zQ@J|Hn-WTu9IMxq?j4*S*AEZz1t`;|&qa~2y&N0k&xMZP8sm4CF?6x<@_9lbI~2(Y zWT@xUdM4(Oo@2)*o|q;z%~rjJ^dS_eM~4hldxo?yJP<7mMEv2R0M5i~I24mHR_^Z< zX?B?^=n2K9u1960U*Ha% zKj8PID&O#wrhl3=H^E=*4F>#$Owh6kug(l#UDpX_=Xw31u;cToek118V#G^AVNapj zIO5kPtW$+F>`t>L&9El($Hx69&(5?6l@~fauXaqx zjFKXm+&75p(F?h6n7B-aWggp1G*6B-ne{iqa!w=^wk8Lh9Irpu){6>TN-k?ys7H?; zWho4ayZUQgw&UZ?fPga9mlH0JFn(INCnJJ0xI_9pl6&5jdNoH4dZRUW+GqbEIGAE`u#okFk11PV)fbsJDDRZ`DSn1YvMy(W=187ccgi)cKbCC+ z7wOGL!!j=gsOXfYg!|$ORR5{_)Pku=)nvs`Yo}hS{xP+=`p?t?h>OSu=pI(oqM=Pa;jk=V zks^CmpRu+(mq=4jFY2aVT9g!5M}4zs^O(HAik{=WIUZZisn(3jHbq{AKmE~`D@v)! z?#UmuW^wxlW{hP`p@$K*XYr*C{Z3IRk0}^CUaG_;Y3f{hGc{q!oYHHT++3yf7pFL` zG&6flwYs_DC)yoKx8>dyS0(5x9p){Ft7+!7nv<{8NBQkbf6MWbEjjVa@s7JF%0JJ~tHwS@7seQ1-Mx$!;8g zHDL}r_Mc=5d#m~*p3+PG1y$6ZqO2;OQ0Zqy?^a353(A^AC1tCFK9@6mYN6kb3#rFL z?ad*-#?sm9^HA5Sa>gfK+9do#)dVNR+UGb0Ay3F_Gi3u#Xh%uQ8cu!$w^JD_)nGSj zhaIn-fBsPT{2|PrN31~d|Ndpl^4kTDx1hkQl2~YS~?EHQ_)` zX}4ALtJE){AU~6a3jFMJS6>>6T9dt@^M|OZFjC+|!gyY!!h{a|QF4*vEB5%j{<5@! z^M^{pw3e2Z>Hf#!>T!NG}{V3o5rrFNOmsjJt{@wlU9WqE>;NZ6qv-n<;AqOpoRUZ3|5 z^yRB!;15#EY^V!V_Pxzir^`!}vtoeSy<)H}9S-wR$fz@noF~fs#{Gy)QyC@2UN#6BIxb7_{YL{5(wgRystnVgj}g?FrL+Bj^N$od?%Q}l`( zN>y)MKD2``P~gbGuxhwta{d&j+t@iOJ0OR!)E(=ZC70zhsi}5>7YB;fucoeB&}*ja z=yoyX6)<8>%-=c1`4LewJg(9oVMzSyopqzeOsd!&zs?gyINUUV&6)WsH{Een=6~v zH0z6McvWW7q)4&DERDIUELMKT4xjL55 zUtTq=vkVa}iG8N~V>clBJH2cuRq}?!c6ut7=~5VK9J$OHWHU|PkW^0=l~|^5>DUbu z;zo`r2z!eI44ycij|qb(M|?O5f8>nE!8i@Q$BJc)Ih^Z7?&tf~jon-D@y=&TQBlM; zt9zPFrSb{?)yBRAk9u%Zt-*OLnT4`IR-VWHlmKT1KNkt^WDh%%$HAY1VOoomE!)|2Tz}Z}WH++MKHP zZI1T6xG=ZrkqEnWYy>ORkRRd1>sRSlw`|9f8Ou<)ySBS~;RGIwDo0$y7!t+gcNn+nmH+Dy^(#>*ot?!rqK1cCm1|LHQsV#!XLC= zrEl)v&OJDnwJ%nr)EiqK)Gu4I)Hhq!C*n81KdPvaTbHP-w_e|%{B9ymoJ}>~Rv0%^ zHM%^p>6kE=ykc?o4ks@sz@%WwP}{csr{knR9v@DwYnCr{F*2hxS56>YY`B*jvbysXJu@rKuMYw2B)ED=_IgJ=pFPkqdw|RrzgoNF+D798 ze4bCJxXScW*>T;~PPL^9J3xn>En4jDDu-9_-qn4RpR3J#R-*2C&wKEC z&K3nF;R267EXoe1TjV3Z`tSAWYVGyaTdwJ5_mV9{`v1EuORG)AP^w?)WVQH)Ym?`( zeOvP`+V-sxTu=CM>M1*JYd%Wf(a5b1A8Tncn643gKJ1cG;kGB$y}Y@2m2g*SRe#sK zsC?>4_B3ozu>|>)*Ed1B1U&`#MwL}tpH<}5n0k^vRCuwQjI=e`$zgHli0tlv4qp;X zBKOLtEWw>7qdfVpdIUMx=qCTcsfG`AeVi#zb&oKy^G>Q-ziUE0cXxNc_t}blKlB%}fn5d@R z*gV_h@97>?*lFF*S2=`ngy+In%)`OMYp0Z5kzqi6&i|8l_=YKTI4a8z0Pd!sPTtt3 z!$t47$2@l5Q)QQ5UZ%wP8wZzlpxT~5LYCL#XCMn4t_GQbvJR=s_Oy<#q}acw*&k+n zc+ZF_a$3>r9LH`qE@Nk>RQkeBjiqtQ(9y7gOrx^%gg2nN?Co1Ww%y>llf7QGcyG68 z#Mb8|76@yKY$f_mP9Kcj$!6x9yYF-43|q5gW!D#V?lQt9p3mo4W4!$5T3zP5tUcZJ z$r5+7J(7YO>a6bPygqfly0>$KO0K~I8NaV&}?gfpo7 z%_S9Z-Yel#CtSj{oUHr!b4(pB@t5Gz+!s+^fDa+ujt#J+(90aH^s0OiQ&(fY5-xgO z&Dz&a&ED5%sQaBq`R5ODRAz}Z->~i+%Mb9CB8wRgh>w$%PffefT_*7YpE|einkrl+ zX5Q4IZa|KOVSZDKgjL~9D^<}=&0}|t9n`6tk{j4=4!1a}i>UW*>ej&Y%^NJqqtrCj z_KMc3!Txn>^Zw-O9%+I)w!iy`vU^GHK8ho<*2Rv?t{mGx^!+8jKb7ZqW04|N`#{^8 zc6VFGT6H{dO*NSk>h=S-)GP1?^O=zmcN>F7u2d-`^&DSudS>}UdD(k6Zv9@`D{r@Z9mwg zvA@E_u$)#3BI?MkY4u}csJ|@LE4NOlV>V~maGM<+ndlnw;`Lu;9o;@ix0@MW{yi(F zf7#YpLG;&4?5rG$$epBoQurKcPXqbA&(E4_u13_$M<+IpeNMY~6YdVG+TPpL6Dz|V zS-uHn%1S3$p!J>zWocz;ldO2Dz6&lEfnUj4+hTgTIb!0U;w#+U-pjL;HoNU$Tpwnd zH!mFUaF&y8jdfPulp73_)4jT>uq=mF(j6@ul;zURP^XWLQ!gHyuim{iQS~_9Mr9tK zs`eeX8x`^cv{M+NXw2Y#w4XcfBcJ+%F23AIEo+oiX6JJ_<${r(@n$98vfHg*(@tgHeoc~`nDshM_B@uq688)%9-uDV z-bP)05C1oH%pmT)bHVTLoeRBbI!_p9#B4=!bde@-VhF_!s#xFQqtE1wecQXk$a<>Z z7p?qwB_I7}ApCqxlvcT;Wn3q`Qx0mejfmOf$YLG4zoV}**;V5c6UsjAJ^#}?YTk)- zm3yKcx6_+WJkZ3N;+|v=^(>+t0VD1UM`QO@*(H0`}&yFgOf6r3YGW^_@R`wi|@UIceYoL-Z`Y%OfjP0Q@~XM z7A?C9Qor5Vw?#pPuj!DdfPZ=7H6PVIPkPmclWkPe@!I?%jAPRYebS08I@XLx5xa4@ z_560}OD7jqQMF6EButgB4!L9GL@x72mW9!!XKU+~l`&TJ?_OOx^X{xT_1oR;)C2d_ zi^djQk4&L%xKg-)!&rb%-mrVgA8e z&fJv4ZeHNwOskhB`K2$Suk4txIHjyh2719&_ultxRl21%+&`}h8~pqC?@%jG=Tx1= zF9&a&t`avZ>~M|m9xP;DG32>H$63xI!jcthKWmbR?$3y{QZ_h#OC*-+?o86GDf-{k zWV*jR236MwQhTJ8XEi@hi01!#WqJ7J=bEZz4=-+!!nZ@J8F7AvVa0ZT7~y8}^@r^` z6<&-xw=gl{XOr;cnBOdI?zH*mXX>_d6I5V-D|P&wxBa9N*;=jH0Y=Q+&4_K8OnU12 zIpg*|pWLNqA-{8#UGp(F+z)>a^>p0i7q8>Ypf;R$TIBORD@Sq}H}Q`JY0rmGfbXR3COrJ7&1;_jNOCOtMv|MN8w lwm$ZrDtf#hp}BhS@yuqfDa}3@o2tx3)#lz7YUC47|3Aq3#m)c# delta 14635 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 " -msgstr "[oletusarvo: 0] > " +msgstr "[Oletusarvo: 0] > " msgid "To be able to use this translation, please install a font manually that supports the language." -msgstr "Jotta voit käyttää tätä käännöstä, asenna käsin fontti, joka tukee tätä kieltä." +msgstr "Jotta voit käyttää tätä käännöstä, asenna kieltä tukeva fontti manuaalisesti" msgid "The font should be stored as {}" msgstr "Fontti tulee tallentaa {}" msgid "Archinstall requires root privileges to run. See --help for more." -msgstr "Archinstall vaatii toimiakseen root oikeudet. Katso --help ja saat lisätietoja." +msgstr "Archinstall vaatii rootin oikeudet toimiakseen. Katso --help ja saat lisätietoja." msgid "Select an execution mode" msgstr "Valitse suoritustila" @@ -873,7 +877,7 @@ msgstr "Profiilia ei voi hakea määritetystä URL-osoitteesta: {}" #, python-brace-format msgid "Profiles must have unique name, but profile definitions with duplicate name found: {}" -msgstr "Profiilin nimi on oltava yksilöllinen, mutta määrityksistä löytyy päällekkäinen nimi: {}" +msgstr "Profiilin nimi on oltava yksilöllinen, mutta profiilien määrityksistä löytyy päällekkäinen nimi: {}" msgid "Select one or more devices to use and configure" msgstr "Valitse yksi tai useampi laite määritettäväksi" @@ -888,18 +892,18 @@ msgid "Select a partitioning option" msgstr "Valitse osiointivaihtoehto" msgid "Enter the root directory of the mounted devices: " -msgstr "Anna root hahemisto liitetylle laitteelle: " +msgstr "Anna root hakemisto liitetylle laitteelle: " #, python-brace-format msgid "Minimum capacity for /home partition: {}GiB\n" -msgstr "Minimi tila /home osiolle: {}GiB\n" +msgstr "Minimi kapasiteetti /home osiolle: {}GiB\n" #, python-brace-format msgid "Minimum capacity for Arch Linux partition: {}GiB" msgstr "Minimi tila Arch Linux osiolle: {}GiB" msgid "This is a list of pre-programmed profiles_bck, they might make it easier to install things like desktop environments" -msgstr "Lista esiohjelmoiduista profiles_bck paketeista, joka voivat helpottaa asioita, kuten työpöydän asentamista" +msgstr "Tämä on lista esiohjelmoiduista profiles_bck instansseista, jotka voivat helpottaa työpöydäympäristön asentamista tai vastaavaa" msgid "Current profile selection" msgstr "Nykyinen profiilivalinta" @@ -997,7 +1001,7 @@ msgid "Partitions" msgstr "Osiot" msgid "No HSM devices available" -msgstr "Ei HSM-laitteita saatavilla" +msgstr "HSM-laitteita ei saatavilla" msgid "Partitions to be encrypted" msgstr "Salattavat osiot" @@ -1009,7 +1013,7 @@ msgid "Select a FIDO2 device to use for HSM" msgstr "Valitse HSM:ään käytettävä FIDO2-laite" msgid "Use a best-effort default partition layout" -msgstr "Käytä parasta mahdollista oletusosion asettelua" +msgstr "Käytä parhaan edellytyksen oletusosioinnin asettelua" msgid "Manual Partitioning" msgstr "Osiointi käsin" @@ -1046,14 +1050,14 @@ msgid "Back" msgstr "Takaisin" msgid "Please chose which greeter to install for the chosen profiles: {}" -msgstr "Valitse asennettava käyttöliittymä valituille profiileille: {}" +msgstr "Valitse asennettava tervehtijä valituille profiileille: {}" #, python-brace-format msgid "Environment type: {}" msgstr "Ympäristötyyppi: {}" msgid "The proprietary Nvidia driver is not supported by Sway. It is likely that you will run into issues, are you okay with that?" -msgstr "Sway ei tue patentoitua Nvidia-ohjainta. Todennäköistä, että kohtaat joitain ongelmia, kelpaako se silti sinulle?" +msgstr "Sway ei tue patentoitua Nvidia-ohjainta. On todennäköistä että kohtaat joitain ongelmia, kelpaako se silti sinulle?" msgid "Installed packages" msgstr "Asennetut paketit" @@ -1090,7 +1094,7 @@ msgid "" "Select a graphics driver or leave blank to install all open-source drivers" msgstr "" "\n" -"Valitse näytönohjaimen ohjain tai jätä tyhjäksi niin kaikki asennetaan avoimen lähdekoodin ohjaimilla" +"Valitse näytönohjaimen ajuri tai jätä tyhjäksi asentaaksesi ainoastaan kaikki avoimen lähdekoodin ajurit" msgid "Sway needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" msgstr "Sway tarvitsee pääsyn istuntoon (kokoelma laitteistoja, kuten näppäimistö, hiiri jne.)" @@ -1105,13 +1109,13 @@ msgstr "" "Valitse asetus antaaksesi Swaylle pääsyn laitteistoosi" msgid "Graphics driver" -msgstr "Näytönohjaimen ohjain" +msgstr "Näytönohjaimen ajuri" msgid "Greeter" -msgstr "Käyttöliittymä" +msgstr "Tervehtijä" msgid "Please chose which greeter to install" -msgstr "Valitse asennettava käyttöliittymä" +msgstr "Valitse asennettava tervehtijä" msgid "This is a list of pre-programmed default_profiles" msgstr "Tämä on lista esiohjelmoiduista default_profiles" @@ -1123,25 +1127,25 @@ msgid "Profiles" msgstr "Profiilit" msgid "Finding possible directories to save configuration files ..." -msgstr "Etsitään hakemistoja asetustiedostojen tallentamiseen ..." +msgstr "Etsitään mahdollisia hakemistoja asetustiedostojen tallentamiseen ..." msgid "Select directory (or directories) for saving configuration files" msgstr "Valitse hakemisto (tai hakemistot) asetustiedostojen tallentamiseen" msgid "Add a custom mirror" -msgstr "Lisää mukautettu peilipaikka" +msgstr "Lisää mukautettu peili" msgid "Change custom mirror" -msgstr "Vaihda mukautettu peilipaikka" +msgstr "Vaihda mukautettu peili" msgid "Delete custom mirror" -msgstr "Poista mukautettu peilipaikka" +msgstr "Poista mukautettu peili" msgid "Enter name (leave blank to skip): " -msgstr "Anna nimi (jätä tyhjäksi ja ohita): " +msgstr "Anna nimi (jätä tyhjäksi ohittaaksesi): " msgid "Enter url (leave blank to skip): " -msgstr "Anna url (jätä tyhjäksi ja ohita): " +msgstr "Anna url (jätä tyhjäksi ohittaaksesi): " msgid "Select signature check option" msgstr "Valitse allekirjoituksen tarkistusvaihtoehto" @@ -1150,19 +1154,19 @@ msgid "Select signature option" msgstr "Valitse allekirjoituksen asetus" msgid "Custom mirrors" -msgstr "Mukautetut peilipaikat" +msgstr "Mukautetut peilit" msgid "Defined" msgstr "Määritelty" msgid "Save user configuration (including disk layout)" -msgstr "Tallenna käyttäjän asetukset (myös levyasettelu)" +msgstr "Tallenna käyttäjän asetukset (sisältäen levyasettelun)" msgid "" "Enter a directory for the configuration(s) to be saved (tab completion enabled)\n" "Save directory: " msgstr "" -"Anna hakemisto tallennettaville määrityksille (välilehden viimeistely käytössä)\n" +"Anna hakemisto konfiguraation(oiden) tallentamista varten (tab-viimeistely käytössä)\n" "Tallennushakemisto: " msgid "" @@ -1170,30 +1174,30 @@ msgid "" "\n" "{}" msgstr "" -"Haluatko tallentaa {} asetustiedostoa seuraavaan paikkaan?\n" +"Haluatko tallentaa {} asennustiedostot seuraavaan paikkaan?\n" "\n" "{}" msgid "Saving {} configuration files to {}" -msgstr "Tallennetaan {} määritystiedostoa {}" +msgstr "Tallennetaan {} konfiguraatiotiedostot kohteeseen {}" msgid "Mirrors" -msgstr "Peilipaikat" +msgstr "Peilit" msgid "Mirror regions" -msgstr "Peilipaikan maa" +msgstr "Peilin maa" msgid " - Maximum value : {} ( Allows {} parallel downloads, allows {max_downloads+1} downloads at a time )" msgstr " - Suurin arvo : {} ( sallii {} rinnakkaista latausta, sallii {max_downloads+1} latausta kerralla )" msgid "Invalid input! Try again with a valid input [1 to {}, or 0 to disable]" -msgstr "Virheellinen arvo! Yritä uudelleen kelvollisella arvolla [1 - {}, tai 0 on poistettu]" +msgstr "Virheellinen arvo! Yritä uudelleen kelvollisella arvolla [1 - {}, 0 vastaa pois päältä]" msgid "Locales" msgstr "Alueet" msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)" -msgstr "Käytä NetworkManager -ohjelmaa (Internetin määritys graafisesti GNOME ja KDE)" +msgstr "Käytä NetworkManager (Internetin määritys graafisesti GNOMEssa ja KDEssa)" msgid "Total: {} / {}" msgstr "Yhteensä: {} / {}" @@ -1202,7 +1206,7 @@ msgid "All entered values can be suffixed with a unit: B, KB, KiB, MB, MiB..." msgstr "Kaikki annetut arvot voidaan liittää käyttäen yksikköjä: B, KB, KiB, MB, MiB..." msgid "If no unit is provided, the value is interpreted as sectors" -msgstr "Jos yksikköä ei ole annettu, arvo tulkitaan sektoreiksi" +msgstr "Jos yksikköä ei ole annettu, arvo tulkitaan sektoreina" msgid "Enter start (default: sector {}): " msgstr "Anna alku (oletus: sektori {}): " @@ -1211,7 +1215,7 @@ msgid "Enter end (default: {}): " msgstr "Anna loppu (oletus: {}): " msgid "Unable to determine fido2 devices. Is libfido2 installed?" -msgstr "Fido2-laitteita ei voida määrittää. Onko libfido2 asennettu?" +msgstr "Fido2-laitteita ei voitu määrittää. Onko libfido2 asennettu?" msgid "Path" msgstr "Polku" @@ -1232,14 +1236,12 @@ msgstr "Valmis asentamaan" msgid "Disks" msgstr "Levyasemat" -#, fuzzy msgid "Packages" msgstr "Määritetty {} liittymää" msgid "Network" msgstr "Verkko" -#, fuzzy msgid "Locale" msgstr "Alueet" @@ -1283,68 +1285,65 @@ msgstr "" msgid "All entered values can be suffixed with a unit: %, B, KB, KiB, MB, MiB..." msgstr "Kaikki annetut arvot voidaan liittää käyttäen yksikköjä: B, KB, KiB, MB, MiB..." +# unsure msgid "Would you like to use unified kernel images?" -msgstr "Haluatko käyttää Unified Kernel Images, joka voidaan käynnistää suoraan UEFI-ohjelmistosta?" +msgstr "Haluatko käyttää unified kernel images?" +# unsure msgid "Unified kernel images" -msgstr "UKI Unified Kernel Images" +msgstr "Unified Kernel Images" msgid "Waiting for time sync (timedatectl show) to complete." -msgstr "Odotetaan ajan synkronoinnin (timedatectl show) päättymistä." +msgstr "Odotetaan ajan synkronointia (timedatectl show) päättymistä." msgid "Time syncronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" -msgstr "Ajan synkronointi ei ole valmis, kun odotat voit tarkistaa kiertotapoja: https://archinstall.readthedocs.io/" +msgstr "Ajan synkronointi ei ole valmis, odottaessasi voit tarkistaa kiertotapoja: https://archinstall.readthedocs.io/" msgid "Skipping waiting for automatic time sync (this can cause issues if time is out of sync during installation)" -msgstr "Autom. ajan synkronoinnin odottaminen ohitetaan (voi aiheuttaa ongelmia, jos aikaa ei ole synkronoitu asennuksen aikana)" +msgstr "Ohitetaan autom. ajan synkronoinnin (voi aiheuttaa ongelmia, jos aika ei ole synkronoitu asennuksen aikana)" msgid "Waiting for Arch Linux keyring sync (archlinux-keyring-wkd-sync) to complete." -msgstr "Odotetaan Arch Linux avainten synkronoinnin valmistumista (archlinux-keyring-wkd-sync)." +msgstr "Odotetaan Arch Linux avaimien synkronointia (archlinux-keyring-wkd-sync)." msgid "Selected profiles: " msgstr "Valitut profiilit: " msgid "Time synchronization not completing, while you wait - check the docs for workarounds: https://archinstall.readthedocs.io/" -msgstr "Ajan synkronointi ei ole valmis, kun odotat voit tarkistaa kiertotapoja: https://archinstall.readthedocs.io/" +msgstr "Ajan synkronointi ei ole valmistumassa, odottaessasi voit tarkistaa kiertotapoja: https://archinstall.readthedocs.io/" msgid "Mark/Unmark as nodatacow" -msgstr "Merkitse/poista nodatacow merkintä" +msgstr "Lisää/poista nodatacow merkintä" msgid "Would you like to use compression or disable CoW?" -msgstr "Haluatko käyttää pakkausta vai poistaa CoW:n käytöstä?" +msgstr "Haluatko käyttää kompressiota vai poistaa CoW:n käytöstä?" msgid "Use compression" -msgstr "Käytä pakkausta" +msgstr "Käytä kompressiota" msgid "Disable Copy-on-Write" msgstr "Poista kopiointi kirjoittamisen yhteydessä" -#, fuzzy msgid "Provides a selection of desktop environments and tiling window managers, e.g. GNOME, KDE Plasma, Sway" -msgstr "Tarjoaa valikoiman erilaisia työpöytiä ja ikkunointia esim. gnome, kde, sway" +msgstr "Tarjoaa valikoiman erilaisia työpöytäympäristöjä ja järjesteleviä ikkunaympäristöjä esim. gnome, kde, sway" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Configuration type: {}" -msgstr "Asetukset" +msgstr "Konfiguraation tyyppi: {}" -#, fuzzy msgid "LVM configuration type" -msgstr "Ei määritystä" +msgstr "LVM konfiguraation tyyppi" msgid "LVM disk encryption with more than 2 partitions is currently not supported" msgstr "LVM levyaseman salaus enemmällä kuin kahdella osiolla ei ole tällä hetkellä tuettu" -#, fuzzy msgid "Use NetworkManager (necessary to configure internet graphically in GNOME and KDE Plasma)" -msgstr "Käytä NetworkManager -ohjelmaa (Internetin määritys graafisesti GNOME ja KDE)" +msgstr "Käytä NetworkManager (Internetin määritys graafisesti GNOME:ssa ja KDE Plasma:ssa)" -#, fuzzy msgid "Select a LVM option" -msgstr "Valitse aikavyöhyke" +msgstr "Valitse LVM optio" -#, fuzzy msgid "Partitioning" -msgstr "Osio" +msgstr "Osiointi" msgid "Logical Volume Management (LVM)" msgstr "Looginen taltiohallinta (engl. 'Logical Volume Management', LVM)" @@ -1355,115 +1354,93 @@ msgstr "Fyysiset taltiot" msgid "Volumes" msgstr "Taltiot" -#, fuzzy msgid "LVM volumes" -msgstr "Aseta alitaltiot" +msgstr "LVM taltiot" -#, fuzzy msgid "LVM volumes to be encrypted" -msgstr "Salattavat osiot" +msgstr "Salattavat LVM taltiot" -#, fuzzy msgid "Select which LVM volumes to encrypt" -msgstr "Valitse salattavat osiot" +msgstr "Valitse salattavat LVM taltiot" -#, fuzzy msgid "Default layout" -msgstr "Levyn asettelu" +msgstr "Oletusasettelu" -#, fuzzy msgid "No Encryption" -msgstr "Salaustyyppi" +msgstr "Ei salausta" msgid "LUKS" -msgstr "" +msgstr "LUKS" msgid "LVM on LUKS" -msgstr "" +msgstr "LVM LUKS:in päällä (LVM on LUKS)" msgid "LUKS on LVM" -msgstr "" +msgstr "LUKS LVM:än päällä (LUKS on LVM)" -#, fuzzy msgid "Yes" msgstr "Kyllä" msgid "No" msgstr "Ei" -#, fuzzy msgid "Archinstall help" -msgstr "Archinstall kieli" +msgstr "Archinstall apu" -#, fuzzy msgid " (default)" msgstr "(oletus)" msgid "Press Ctrl+h for help" msgstr "Paina Ctrl+h saadaksesi apua" -#, fuzzy msgid "Choose an option to give Sway access to your hardware" -msgstr "" -"\n" -"\n" -"Valitse asetus antaaksesi Swaylle pääsyn laitteistoosi" +msgstr "Valitse asetus antaaksesi Swaylle pääsyn laitteistoosi" msgid "Seat access" msgstr "Istunnon pääsy (seat)" -#, fuzzy msgid "Mountpoint" msgstr "Liitoskohta: " msgid "HSM" -msgstr "" +msgstr "HSM" -#, fuzzy msgid "Enter disk encryption password (leave blank for no encryption)" msgstr "Anna levyn salauksen salasana (jätä tyhjäksi, jos et salaa): " -#, fuzzy msgid "Disk encryption password" msgstr "Salauksen salasana" -#, fuzzy msgid "Partition - New" -msgstr "Osio" +msgstr "Osio - Uusi" -#, fuzzy msgid "Filesystem" -msgstr "Vaihda tiedostojärjestelmä" +msgstr "Tiedostojärjestelmä" msgid "Invalid size" msgstr "Epäkelpo koko" -#, fuzzy msgid "Start (default: sector {}): " -msgstr "Anna alku (oletus: sektori {}): " +msgstr "Alku (oletus: sektori {}): " -#, fuzzy msgid "End (default: {}): " -msgstr "Anna loppu (oletus: {}): " +msgstr "Loppu (oletus: {}): " -#, fuzzy msgid "Subvolume name" msgstr "Alitaltion nimi " -#, fuzzy +# unsure msgid "Disk configuration type" -msgstr "Kiintolevyn määritys" +msgstr "Levyn konfiguraatiotyyppi" msgid "Root mount directory" -msgstr "Juuren (Root) liittämishakemisto (mount directory)" +msgstr "Root:in liittämishakemisto (mount directory)" -#, fuzzy msgid "Select language" -msgstr "Kieli" +msgstr "Valitse kieli" -#, fuzzy msgid "Write additional packages to install (space separated, leave blank to skip)" -msgstr "Kirjoita asennettavat lisäpaketit (välilyönnillä erotettuna, ohita vaihe jättämällä tyhjäksi): " +msgstr "Kirjoita asennettavat lisäpaketit (välilyönnillä erotettuna, ohita jättämällä tyhjäksi): " msgid "Invalid download number" msgstr "Epäkelpo numero lataukseen" @@ -1471,21 +1448,19 @@ msgstr "Epäkelpo numero lataukseen" msgid "Number downloads" msgstr "Numero latauksia" -#, fuzzy msgid "The username you entered is invalid" msgstr "Antamasi käyttäjänimi ei kelpaa. Yritä uudelleen" -#, fuzzy msgid "Username" msgstr "Käyttäjänimi : " -#, fuzzy, python-brace-format +#, python-brace-format msgid "Should \"{}\" be a superuser (sudo)?\n" -msgstr "Pitäisikö \"{}\" olla superkäyttäjä (sudo)?" +msgstr "Pitäisikö \"{}\" olla superkäyttäjä (sudo)?\n" -#, fuzzy +# unsure msgid "Interfaces" -msgstr "Lisää liitäntä" +msgstr "Verkkoliitännät (interfaces)" msgid "You need to enter a valid IP in IP-config mode" msgstr "Sinun on annettava kelvollinen IP-osoite IP-määritystilassa" @@ -1494,121 +1469,97 @@ msgid "Modes" msgstr "Tilat" msgid "IP address" -msgstr "IP osoite" +msgstr "IP-osoite" -#, fuzzy msgid "Enter your gateway (router) IP address (leave blank for none)" -msgstr "Anna yhdyskäytävän (reitittimen) IP-osoite tai jätä tyhjäksi: " +msgstr "Anna yhdyskäytävän (reitittimen) IP-osoite (tai jätä tyhjäksi): " msgid "Gateway address" msgstr "Yhdyskäytävän osoite" -#, fuzzy msgid "Enter your DNS servers with space separated (leave blank for none)" msgstr "Anna DNS-osoitteet (välilyönti erottaa kaksi osoitetta toisistaan, tyhjä ei mitään): " -#, fuzzy msgid "DNS servers" -msgstr "Ei audiopalvelinta" +msgstr "DNS-palvelimet" -#, fuzzy msgid "Configure interfaces" -msgstr "Määritetty {} liittymää" +msgstr "Määritä laitteet" -#, fuzzy msgid "Kernel" -msgstr "Kernelit" +msgstr "Ydin" msgid "UEFI is not detected and some options are disabled" -msgstr "UEFIa ei tunnisteta ja jotkin asetukset on poistettu käytöstä" +msgstr "UEFIa ei tunnisteta ja jotkin asetukset ovat poistettu käytöstä" msgid "Info" msgstr "Informaatio" -#, fuzzy msgid "The proprietary Nvidia driver is not supported by Sway." -msgstr "Sway ei tue patentoitua Nvidia-ohjainta. Todennäköistä, että kohtaat joitain ongelmia, kelpaako se silti sinulle?" +msgstr "Sway ei tue patentoitua Nvidia-ohjainta." -#, fuzzy msgid "It is likely that you will run into issues, are you okay with that?" -msgstr "Sway ei tue patentoitua Nvidia-ohjainta. Todennäköistä, että kohtaat joitain ongelmia, kelpaako se silti sinulle?" +msgstr "On todennäköistä, että kohtaat joitain ongelmia, kelpaako se silti sinulle?" -#, fuzzy msgid "Main profile" msgstr "Pääprofiili" -#, fuzzy msgid "Confirm password" msgstr "Vahvista salasana" msgid "The confirmation password did not match, please try again" msgstr "Salasanat eivät vastannet, ole hyvä ja koita uudestaan" -#, fuzzy msgid "Not a valid directory" msgstr "Hakemisto ei ole kelvollinen: {}" -#, fuzzy msgid "Would you like to continue?" -msgstr "Haluatko käyttää BTRFS-pakkausta?" +msgstr "Haluatko jatkaa?" msgid "Directory" msgstr "Hakemisto" -#, fuzzy msgid "Enter a directory for the configuration(s) to be saved (tab completion enabled)" msgstr "" -"Anna hakemisto tallennettaville määrityksille (välilehden viimeistely käytössä)\n" +"Anna hakemisto konfiguraation(oiden) tallentamista varten (tab viimeistely käytössä)\n" "Tallennushakemisto: " -#, fuzzy, python-brace-format +#, python-brace-format msgid "Do you want to save the configuration file(s) to {}?" -msgstr "" -"Haluatko tallentaa {} asetustiedostoa seuraavaan paikkaan?\n" -"\n" -"{}" +msgstr "Haluatko tallentaa asetustiedoston(tot) kohteeseen {}?" msgid "Enabled" msgstr "Käytössä" msgid "Disabled" -msgstr "Pois Käytostä" +msgstr "Pois käytostä" -#, fuzzy msgid "Please submit this issue (and file) to https://github.com/archlinux/archinstall/issues" -msgstr " Lähetä tämä ongelma (ja tiedosto) osoitteeseen https://github.com/archlinux/archinstall/issues" +msgstr "Lähetä tämä ongelma (ja tiedosto) osoitteeseen https://github.com/archlinux/archinstall/issues" -#, fuzzy msgid "Mirror name" -msgstr "Pakettivarasto" +msgstr "Peilin nimi" msgid "Url" -msgstr "" +msgstr "Url" -#, fuzzy msgid "Select signature check" msgstr "Valitse allekirjoituksen tarkistusvaihtoehto" -#, fuzzy msgid "Select execution mode" msgstr "Valitse suoritustila" msgid "Press ? for help" msgstr "Paina ? saadaksesi apua" -#, fuzzy msgid "Choose an option to give Hyprland access to your hardware" -msgstr "" -"\n" -"\n" -"Valitse asetus antaaksesi Hyprlandille pääsyn laitteistoosi" +msgstr "Valitse asetus antaaksesi Hyprlandille pääsyn laitteistoosi" -#, fuzzy msgid "Additional repositories" msgstr "Valinnaiset arkistot" msgid "NTP" -msgstr "" +msgstr "NTP" msgid "Swap on zram" msgstr "Swap zram:illa (Swap on zram)" @@ -1616,32 +1567,30 @@ msgstr "Swap zram:illa (Swap on zram)" msgid "Name" msgstr "Nimi" -#, fuzzy msgid "Signature check" msgstr "Valitse allekirjoituksen tarkistusvaihtoehto" -#, fuzzy, python-brace-format +# unsure +#, python-brace-format msgid "Selected free space segment on device {}:" -msgstr "Laitteen nykyiset vapaat sektorit {}:" +msgstr "Valittiin vapaan tilan osa laitteella {}:" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Size: {} / {}" -msgstr "Yhteensä: {} / {}" +msgstr "Koko: {} / {}" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Size (default: {}): " -msgstr "Anna loppu (oletus: {}): " +msgstr "Koko (oletus: {}): " -#, fuzzy msgid "HSM device" -msgstr "Laite" +msgstr "HSM laite" msgid "Some packages could not be found in the repository" msgstr "Jotkut paketit eivät löytyneet repositoriosta" -#, fuzzy msgid "User" -msgstr "Käyttäjänimi : " +msgstr "Käyttäjä" msgid "The specified configuration will be applied" msgstr "Käytetään valittua konfiguraatiota" @@ -1649,85 +1598,68 @@ msgstr "Käytetään valittua konfiguraatiota" msgid "Wipe" msgstr "Pyyhi" -#, fuzzy msgid "Mark/Unmark as XBOOTLDR" -msgstr "Merkitse/poista käynnistyvä" +msgstr "Lisää/poista merkintö XBOOTLDRina" -#, fuzzy msgid "Loading packages..." -msgstr "Lisäpaketit" +msgstr "Ladataan paketteja..." msgid "Select any packages from the below list that should be installed additionally" msgstr "Valitse alla olevalta listalta asennettavat lisäpaketit" -#, fuzzy msgid "Add a custom repository" -msgstr "Lisää mukautettu peilipaikka" +msgstr "Lisää mukautettu repositorio" -#, fuzzy msgid "Change custom repository" -msgstr "Vaihda mukautettu peilipaikka" +msgstr "Vaihda mukautettu repositorio" -#, fuzzy msgid "Delete custom repository" -msgstr "Poista mukautettu peilipaikka" +msgstr "Poista mukautettu repositorio" -#, fuzzy msgid "Repository name" -msgstr "Pakettivarasto" +msgstr "Repositorion nimi" -#, fuzzy msgid "Add a custom server" -msgstr "Lisää mukautettu peilipaikka" +msgstr "Lisää mukautettu palvelin" -#, fuzzy msgid "Change custom server" -msgstr "Vaihda mukautettu peilipaikka" +msgstr "Vaihda mukautettu palvelin" -#, fuzzy msgid "Delete custom server" -msgstr "Poista mukautettu peilipaikka" +msgstr "Poista mukautettu palvelin" msgid "Server url" msgstr "Palvelimen url" -#, fuzzy msgid "Select regions" -msgstr "Valitse allekirjoituksen asetus" +msgstr "Valitse alueet" -#, fuzzy msgid "Add custom servers" -msgstr "Lisää mukautettu peilipaikka" +msgstr "Lisää mukautetut palvelimet" -#, fuzzy msgid "Add custom repository" -msgstr "Lisää mukautettu peilipaikka" +msgstr "Lisää mukautettu repositorio" -#, fuzzy msgid "Loading mirror regions..." -msgstr "Peilipaikan maa" +msgstr "Ladataan peilialueita..." -#, fuzzy msgid "Mirrors and repositories" -msgstr "Valinnaiset arkistot" +msgstr "Peilit ja repositoriot" -#, fuzzy msgid "Selected mirror regions" -msgstr "Peilipaikan maa" +msgstr "Valitut peilin aluuet" -#, fuzzy msgid "Custom servers" -msgstr "Mukautetut peilipaikat" +msgstr "Mukautetut palvelimet" -#, fuzzy msgid "Custom repositories" -msgstr "Valinnaiset arkistot" +msgstr "Mukautetut repositoriot" msgid "Only ASCII characters are supported" -msgstr "Ainoastaan ASCII hahmot tuetaan" +msgstr "Ainoastaan ASCII hahmot ovat tuetut" msgid "Show help" -msgstr "Näytä apua" +msgstr "Näytä apu" msgid "Exit help" msgstr "Poistu avusta" @@ -1739,10 +1671,10 @@ msgid "Preview scroll down" msgstr "Esikatsele alaspäin scrollaamista" msgid "Move up" -msgstr "Liikku ylös" +msgstr "Liiku ylös" msgid "Move down" -msgstr "Liikku alas" +msgstr "Liiku alas" msgid "Move right" msgstr "Liiku oikealle" @@ -1759,20 +1691,17 @@ msgstr "Hyppää valinnan yli (jos saatavilla)" msgid "Reset selection (if available)" msgstr "Nollaa valinta (jos saatavilla)" -#, fuzzy msgid "Select on single select" -msgstr "Valitse allekirjoituksen tarkistusvaihtoehto" +msgstr "Valinta yksittöisellä valinnalla" -#, fuzzy msgid "Select on multi select" -msgstr "Valitse aikavyöhyke" +msgstr "Valinta multivalinnalla" msgid "Reset" msgstr "Nollaa" -#, fuzzy msgid "Skip selection menu" -msgstr "Valitse suoritustila" +msgstr "Hyppää valintavalikon yli" msgid "Start search mode" msgstr "Aloita hakutila" @@ -1783,13 +1712,11 @@ msgstr "Poistu hakutilasta" msgid "General" msgstr "Yleinen" -#, fuzzy msgid "Navigation" -msgstr "Tallenna määritykset" +msgstr "Navigaatio" -#, fuzzy msgid "Selection" -msgstr "Valitse allekirjoituksen asetus" +msgstr "Valinta" msgid "Search" msgstr "Haku" @@ -1800,24 +1727,20 @@ msgstr "Alas" msgid "Up" msgstr "Ylös" -#, fuzzy msgid "Confirm" -msgstr "Vahvista ja poistu" +msgstr "Vahvista" -#, fuzzy msgid "Focus right" -msgstr "Liiku oikealle" +msgstr "Kohdista oikealle" -#, fuzzy msgid "Focus left" -msgstr "Liiku vasemmalle" +msgstr "Kohdista vasemmalle" msgid "Toggle" msgstr "Vaihda" -#, fuzzy msgid "Show/Hide help" -msgstr "Näytä apua" +msgstr "Näytä/piilota apu" msgid "Quit" msgstr "Poistu" @@ -1828,44 +1751,38 @@ msgstr "Ensimmäinen" msgid "Last" msgstr "Viimeinen" -#, fuzzy msgid "Select" -msgstr "Valitse allekirjoituksen asetus" +msgstr "Valitse" msgid "Page Up" -msgstr "Liiku ylös" +msgstr "Page up" msgid "Page Down" -msgstr "Liiku alas" +msgstr "Page down" msgid "Page up" -msgstr "Liiku ylös" +msgstr "Page up" -#, fuzzy msgid "Page down" -msgstr "Liiku alas" +msgstr "Page down" msgid "Page Left" -msgstr "Liiku vasemalle" +msgstr "Sivu vasemmalle" -#, fuzzy msgid "Page Right" -msgstr "Liiku oikealle" +msgstr "Sivu oikealle" msgid "Cursor up" msgstr "Kursori ylös" -#, fuzzy msgid "Cursor down" -msgstr "Liikku alas" +msgstr "Kursori alas" -#, fuzzy msgid "Cursor right" -msgstr "Liiku oikealle" +msgstr "Kursori oikealle" -#, fuzzy msgid "Cursor left" -msgstr "Liiku vasemmalle" +msgstr "Kursori vasemmalle" msgid "Top" msgstr "Yläosa" @@ -1874,15 +1791,13 @@ msgid "Bottom" msgstr "Pohja" msgid "Home" -msgstr "Rivin alku" +msgstr "Home" -#, fuzzy msgid "End" -msgstr "Rivin loppu" +msgstr "End" -#, fuzzy msgid "Toggle option" -msgstr "Alitaltion valinnat" +msgstr "Vaihda optio" msgid "Scroll Up" msgstr "Scrollaa ylös" @@ -1911,87 +1826,66 @@ msgstr "Kohdista edeltävä" msgid "Copy selected text" msgstr "Kopioi valittu teksti" -#, fuzzy msgid "labwc needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" -msgstr "Sway tarvitsee pääsyn istuntoon (kokoelma laitteistoja, kuten näppäimistö, hiiri jne.)" +msgstr "labwc tarvitsee pääsyn istuntoon (kokoelma laitteistoja, kuten näppäimistö, hiiri jne.)" -#, fuzzy msgid "Choose an option to give labwc access to your hardware" -msgstr "" -"\n" -"\n" -"Valitse asetus antaaksesi labwc:lle pääsyn laitteistoosi" +msgstr "Valitse asetus antaaksesi labwc:lle pääsyn laitteistoosi" -#, fuzzy msgid "niri needs access to your seat (collection of hardware devices i.e. keyboard, mouse, etc)" msgstr "niri tarvitsee pääsyn istuntoon (kokoelma laitteistoja, kuten näppäimistö, hiiri jne.)" -#, fuzzy msgid "Choose an option to give niri access to your hardware" -msgstr "" -"\n" -"\n" -"Valitse asetus antaaksesi nirin pääsyn laitteistoosi" +msgstr "Valitse asetus antaaksesi nirin pääsyn laitteistoosi" -#, fuzzy msgid "Mark/Unmark as ESP" msgstr "Merkitse/poista käynnistyvä" msgid "Package group:" msgstr "Pakettiryhmä:" -#, fuzzy msgid "Exit archinstall" msgstr "Poistu archinstall:ista" -#, fuzzy msgid "Reboot system" msgstr "Käynnistä järjestelmä uudelleen" -#, fuzzy msgid "chroot into installation for post-installation configurations" msgstr "Haluatko chroot:in uuteen asennukseen ja suorittaa asennuksen jälkeiset asetukset?" msgid "Installation completed" -msgstr "Lataus valmis" +msgstr "Asennus valmis" -#, fuzzy msgid "What would you like to do next?" msgstr "Mitä haluaisit tehdä seuraavaksi?" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Select which mode to configure for \"{}\"" -msgstr "Valitse, mikä tila määritetään \"{}\", tai ohita ja käytä \"{}\" oletusta." +msgstr "Valitse tila jolle tehdä konfiguraatio \"{}\"" -#, fuzzy +# unsure msgid "Incorrect credentials file decryption password" -msgstr "Väärä salasana salausta varten" +msgstr "Väärä salasana pääsytietojen salausta varten" -#, fuzzy msgid "Incorrect password" msgstr "Väärä salasana" -#, fuzzy msgid "Credentials file decryption password" -msgstr "Salauksen salasana" +msgstr "Pääsytietotiedoston salauksen salasana" -#, fuzzy msgid "Do you want to encrypt the user_credentials.json file?" msgstr "Haluatko salata user_crendentials.json tiedoston?" -#, fuzzy msgid "Credentials file encryption password" -msgstr "Salauksen salasana" +msgstr "Pääsytietotiedoston salauksen salasana" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Repositories: {}" -msgstr "Pakettivarasto" +msgstr "Repositoriot: {}" -#, fuzzy msgid "New version available" -msgstr "Ei HSM-laitteita saatavilla" +msgstr "Uusi versio saatavilla" -#, fuzzy msgid "Passwordless login" msgstr "Salasanaton kirjautuminen" @@ -1999,20 +1893,17 @@ msgid "Second factor login" msgstr "Toisen faktorin kirjautuminen" msgid "Bluetooth" -msgstr "" +msgstr "Bluetooth" -#, fuzzy msgid "Would you like to configure Bluetooth?" -msgstr "Haluatko käyttää BTRFS-pakkausta?" +msgstr "Haluatko konfiguroida Bluetooth:in?" msgid "Print service" msgstr "Printtauspalvelu" -#, fuzzy msgid "Would you like to configure the print service?" msgstr "Haluatko konfiguroida printtauspalvelun" -#, fuzzy msgid "Power management" msgstr "Tehohallinta" @@ -2041,7 +1932,7 @@ msgstr "Arvo ei voi olla tyhjä" msgid "Snapshot type" msgstr "Tilannekuvan tyyppi" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Snapshot type: {}" msgstr "Tilannekuvan tyyppi: {}" @@ -2054,13 +1945,12 @@ msgstr "U2F laitteita ei löydetty" msgid "U2F Login Method" msgstr "U2F kirjautumisen menetelmä" -#, fuzzy msgid "Enable passwordless sudo?" msgstr "Aktivoi salasanaton sudo?" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Setting up U2F device for user: {}" -msgstr "Valitse HSM:ään käytettävä FIDO2-laite" +msgstr "Määritetään U2F laitetta käyttäjälle: {}" msgid "You may need to enter the PIN and then touch your U2F device to register it" msgstr "Voit joutua syöttämään PIN:in ja koskettaa U2F laitettasi rekisteröidäksesi sen" @@ -2068,38 +1958,32 @@ msgstr "Voit joutua syöttämään PIN:in ja koskettaa U2F laitettasi rekisterö msgid "Starting device modifications in " msgstr "Aloitetaan laitteen muokkausta " -#, fuzzy msgid "No network connection found" -msgstr "Ei verkkoasetuksia" +msgstr "Verkkoyhteyttä ei löydetty" -#, fuzzy msgid "Would you like to connect to a Wifi?" msgstr "Haluaisitko liittyä langattomaan verkkoon?" -#, fuzzy msgid "No wifi interface found" msgstr "Langattomia liittymiä ei löydetty" -#, fuzzy msgid "Select wifi network to connect to" -msgstr "Valitse wifi verkko johon yhdistää" +msgstr "Valitse wifiverkko johon yhdistää" msgid "Scanning wifi networks..." msgstr "Etsitään wifiyhteyksiä..." -#, fuzzy msgid "No wifi networks found" -msgstr "Ei verkkoasetuksia" +msgstr "Wifiverkkoja ei löytynyt" msgid "Failed setting up wifi" msgstr "Langattoman verkon määrittäminen epäonnistui" -#, fuzzy msgid "Enter wifi password" -msgstr "Anna wifi salasana: " +msgstr "Anna wifi salasana" msgid "Ok" -msgstr "" +msgstr "Ok" msgid "Removable" msgstr "Irrotettava" @@ -2140,18 +2024,15 @@ msgstr "Firmware joka ei kunnolla tue NVRAM käynnistyskohteita kuten useimmat M msgid "most Apple Macs, many laptops..." msgstr "useimmat Apple Macit, monet kannettavat tietokoneet..." -#, fuzzy msgid "Language" msgstr "Kieli" msgid "Compression algorithm" msgstr "Kompressioalgoritmi" -#, fuzzy msgid "Only packages such as base, sudo, linux, linux-firmware, efibootmgr and optional profile packages are installed." msgstr "Vain paketit, kuten base, sudo, linux, linux-firmware, efibootmgr ja valinnaiset profiili-paketit ovat asennettu." -#, fuzzy msgid "Select zram compression algorithm:" msgstr "Valitse zram kompression algoritmi:" @@ -2164,11 +2045,9 @@ msgstr "Käytä Network Manager (iwd backendi)" msgid "Firewall" msgstr "Palomuuri" -#, fuzzy msgid "Additional fonts" msgstr "Lisäfontit" -#, fuzzy msgid "Select font packages to install" msgstr "Valitse asennettavat fonttipaketit" @@ -2181,59 +2060,48 @@ msgstr "väri emojit selaimille ja sovelluksille" msgid "Chinese, Japanese, Korean characters" msgstr "Kiinalaiset, japanilaiset, korealaiset kirjaimet" -#, fuzzy msgid "Select audio configuration" msgstr "Valitse äänen konfiguraatio" -#, fuzzy msgid "Enter credentials file decryption password" -msgstr "Salauksen salasana" +msgstr "Syötä pääsytietotiedoston salauksen salasana" -#, fuzzy msgid "Enter root password" -msgstr "Anna juuren (root) salasana: " +msgstr "Anna rootin salasana" msgid "Select bootloader to install" msgstr "Valitse asennettava käynnistyslataaja" -#, fuzzy msgid "Configuration preview" msgstr "Konfiguraation esikatselu" -#, fuzzy msgid "Enter a directory for the configuration(s) to be saved" msgstr "Anna hakemisto tallennettaville määrityksille: " -#, fuzzy msgid "Select encryption type" msgstr "Salaustyyppi" -#, fuzzy msgid "Select disks for the installation" msgstr "Valitse levyasemat asennukselle" -#, fuzzy msgid "Enter a mountpoint" msgstr "Valitse liitoskohta :" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Enter a size (default: {}): " msgstr "Anna koko (oletus: {}): " -#, fuzzy msgid "Enter subvolume name" -msgstr "Alitaltion nimi " +msgstr "Anna alitaltion nimi " -#, fuzzy msgid "Enter subvolume mountpoint" -msgstr "Alitaltion liitoskohta" +msgstr "Anna alitaltion liitoskohta" -#, fuzzy msgid "Select a disk configuration" msgstr "Kiintolevyn määritys" msgid "Enter root mount directory" -msgstr "Syötä juuren (root) liitoshakemisto" +msgstr "Syötä juuren liitoshakemisto" msgid "You will use whatever drive-setup is mounted at the specified directory" msgstr "Käytät mitä tahansa levykonfiguraatiota joka on liitetty valittuun hakemistoon" @@ -2241,56 +2109,43 @@ msgstr "Käytät mitä tahansa levykonfiguraatiota joka on liitetty valittuun ha msgid "WARNING: Archinstall won't check the suitability of this setup" msgstr "VAROITUS: Archinstall ei tarkista konfiguraation soveltuvuutta" -#, fuzzy msgid "Select main filesystem" msgstr "Vaihda päätiedostojärjestelmä" msgid "Enter a hostname" msgstr "Syötä isäntänimi (hostname)" -#, fuzzy msgid "Select timezone" msgstr "Valitse aikavyöhyke" -#, fuzzy msgid "Enter the number of parallel downloads to be enabled" -msgstr "" -"Anna rinnakkaisten latausten määrä.\n" -"\n" -"Huomaa:\n" +msgstr "Anna rinnakkaisten latausten määrä" #, python-brace-format msgid "Value must be between 1 and {}" msgstr "Arvon on oltava yhden ja {} välillä" -#, fuzzy msgid "Select which kernel(s) to install" msgstr "Valitse asennettavat ytimet (kernel)" -#, fuzzy msgid "Enter a respository name" msgstr "Syötä pakettivaraston nimi" -#, fuzzy msgid "Enter the repository url" msgstr "Syötä pakettivarason url" msgid "Enter server url" msgstr "Syötä palvelimen url" -#, fuzzy msgid "Select mirror regions to be enabled" -msgstr "Peilipaikan maa" +msgstr "Valitse käytössä olevien peilien alueet" -#, fuzzy msgid "Select optional repositories to be enabled" -msgstr "Valitse, valinnaiset lisävarastot jotka otetaan käyttöön" +msgstr "Valitse valinnaiset repositoriot jotka otetaan käyttöön" -#, fuzzy msgid "Select an interface" msgstr "Valitse liitäntä" -#, fuzzy msgid "Choose network configuration" msgstr "Valitse verkkokonfiguraatio" @@ -2300,26 +2155,21 @@ msgstr "Suositeltu: Network Manager työpöydälle, manuaali palvelinta varten" msgid "Warning: no network configuration selected. Network will need to be set up manually on the installed system." msgstr "Varoitus: verkkokonfiguraatiota ei löytynyt. Verkon on asetettava manuaalisesti asennetulla järjestelmällä." -#, fuzzy msgid "No packages found" msgstr "Paketteja ei löytynyt" -#, fuzzy msgid "Select which greeter to install" msgstr "Valitse asennettava tervehtijä (greeter)" -#, fuzzy msgid "Select a profile type" msgstr "Valitse profiilityyppi" -#, fuzzy msgid "Enter new password" msgstr "Anna uusi salasana: " msgid "Enter a username" msgstr "Anna käyttäjänimi" -#, fuzzy msgid "Enter a password" msgstr "Anna salasana: " @@ -2338,7 +2188,7 @@ msgstr "Salasanan vahvuus on vahva" msgid "The selected desktop profile requires a regular user to log in via the greeter" msgstr "Valittu työpöydän profiili vaati tavallisen käyttäjän kirjautumisen tervehtijällä" -#, fuzzy, python-brace-format +#, python-brace-format msgid "Environment type: {} {}" msgstr "Ympäristötyyppi: {}" @@ -2352,12 +2202,11 @@ msgid "Package" msgstr "Paketti" msgid "Curated selection of KDE Plasma packages" -msgstr "Kuratoitu valikoima KDE Plasma paketeista" +msgstr "Kuratoitu valikoima KDE Plasma paketteja" msgid "Dependencies" msgstr "Riippuvuudet" -#, fuzzy msgid "Package group" msgstr "Pakettiryhmä" @@ -2370,11 +2219,9 @@ msgstr "Paketit ryhmässä" msgid "Minimal KDE Plasma installation" msgstr "Minimaalinen KDE Plasma asennus" -#, fuzzy msgid "Description" msgstr "Kuvaus" -#, fuzzy msgid "Select a flavor of KDE Plasma to install" msgstr "Valitse asennettavan KDE Plasman maku" @@ -2391,3 +2238,11 @@ msgstr "Määritellään U2F kirjautuminen: {u2f_config.u2f_login_method.value}" #, python-brace-format msgid "Default: {DEFAULT_ITER_TIME}ms, Recommended range: 1000-60000" msgstr "Oletus: {DEFAULT_ITER_TIME}ms, suositeltu väli: 1000-60000" + +#, python-brace-format +msgid "Setting up U2F login: {}" +msgstr "Määritetään U2F laitetta käyttäjälle: {}" + +#, python-brace-format +msgid "Default: {}ms, Recommended range: 1000-60000" +msgstr "Oletusarvo: 10000ms, suositeltu 1000-60000ms"