Send patches - preferably formatted by git format-patch - to patches at archlinux32 dot org.
summaryrefslogtreecommitdiff
path: root/archinstall
diff options
context:
space:
mode:
Diffstat (limited to 'archinstall')
-rw-r--r--archinstall/__init__.py1
-rw-r--r--archinstall/lib/menu/selection_menu.py50
-rw-r--r--archinstall/lib/translation.py82
-rw-r--r--archinstall/lib/user_interaction.py184
-rw-r--r--archinstall/locales/README.md33
-rw-r--r--archinstall/locales/base.pot354
-rw-r--r--archinstall/locales/de/LC_MESSAGES/base.mobin0 -> 109 bytes
-rw-r--r--archinstall/locales/de/LC_MESSAGES/base.po351
-rw-r--r--archinstall/locales/en/LC_MESSAGES/base.mobin0 -> 368 bytes
-rw-r--r--archinstall/locales/en/LC_MESSAGES/base.po351
-rw-r--r--archinstall/locales/en/LC_MESSAGES/base.po~359
-rw-r--r--archinstall/locales/it/LC_MESSAGES/base.mobin0 -> 98 bytes
-rw-r--r--archinstall/locales/it/LC_MESSAGES/base.po354
-rw-r--r--archinstall/locales/it/LC_MESSAGES/base.po~362
-rw-r--r--archinstall/locales/languages.json184
15 files changed, 2573 insertions, 92 deletions
diff --git a/archinstall/__init__.py b/archinstall/__init__.py
index f0ce026c..c06bb328 100644
--- a/archinstall/__init__.py
+++ b/archinstall/__init__.py
@@ -36,6 +36,7 @@ from .lib.systemd import *
from .lib.user_interaction import *
from .lib.menu import Menu
from .lib.menu.selection_menu import GlobalMenu
+from .lib.translation import Translation
from .lib.plugins import plugins, load_plugin # This initiates the plugin loading ceremony
parser = ArgumentParser()
diff --git a/archinstall/lib/menu/selection_menu.py b/archinstall/lib/menu/selection_menu.py
index 940941be..f3fd3b4c 100644
--- a/archinstall/lib/menu/selection_menu.py
+++ b/archinstall/lib/menu/selection_menu.py
@@ -27,6 +27,8 @@ from ..user_interaction import select_kernel
from ..user_interaction import select_encrypted_partitions
from ..user_interaction import select_harddrives
from ..user_interaction import select_profile
+from ..user_interaction import select_archinstall_language
+from ..translation import Translation
class Selector:
def __init__(
@@ -128,29 +130,36 @@ class Selector:
class GlobalMenu:
def __init__(self):
+ self._translation = Translation.load_nationalization()
self._menu_options = {}
self._setup_selection_menu_options()
def _setup_selection_menu_options(self):
+ self._menu_options['archinstall-language'] = \
+ Selector(
+ _('Select Archinstall language'),
+ lambda: self._select_archinstall_language('English'),
+ default='English',
+ enabled=True)
self._menu_options['keyboard-layout'] = \
- Selector('Select keyboard layout', lambda: select_language('us'), default='us')
+ Selector(_('Select keyboard layout'), lambda: select_language('us'), default='us')
self._menu_options['mirror-region'] = \
Selector(
- 'Select mirror region',
+ _('Select mirror region'),
lambda: select_mirror_regions(),
display_func=lambda x: list(x.keys()) if x else '[]',
default={})
self._menu_options['sys-language'] = \
- Selector('Select locale language', lambda: select_locale_lang('en_US'), default='en_US')
+ Selector(_('Select locale language'), lambda: select_locale_lang('en_US'), default='en_US')
self._menu_options['sys-encoding'] = \
- Selector('Select locale encoding', lambda: select_locale_enc('utf-8'), default='utf-8')
+ Selector(_('Select locale encoding'), lambda: select_locale_enc('utf-8'), default='utf-8')
self._menu_options['harddrives'] = \
Selector(
- 'Select harddrives',
+ _('Select harddrives'),
lambda: self._select_harddrives())
self._menu_options['disk_layouts'] = \
Selector(
- 'Select disk layout',
+ _('Select disk layout'),
lambda: select_disk_layout(
storage['arguments'].get('harddrives', []),
storage['arguments'].get('advanced', False)
@@ -158,60 +167,60 @@ class GlobalMenu:
dependencies=['harddrives'])
self._menu_options['!encryption-password'] = \
Selector(
- 'Set encryption password',
+ _('Set encryption password'),
lambda: get_password(prompt='Enter disk encryption password (leave blank for no encryption): '),
display_func=lambda x: self._secret(x) if x else 'None',
dependencies=['harddrives'])
self._menu_options['swap'] = \
Selector(
- 'Use swap',
+ _('Use swap'),
lambda: ask_for_swap(),
default=True)
self._menu_options['bootloader'] = \
Selector(
- 'Select bootloader',
+ _('Select bootloader'),
lambda: ask_for_bootloader(storage['arguments'].get('advanced', False)),)
self._menu_options['hostname'] = \
Selector('Specify hostname', lambda: ask_hostname())
self._menu_options['!root-password'] = \
Selector(
- 'Set root password',
+ _('Set root password'),
lambda: self._set_root_password(),
display_func=lambda x: self._secret(x) if x else 'None')
self._menu_options['!superusers'] = \
Selector(
- 'Specify superuser account',
+ _('Specify superuser account'),
lambda: self._create_superuser_account(),
dependencies_not=['!root-password'],
display_func=lambda x: list(x.keys()) if x else '')
self._menu_options['!users'] = \
Selector(
- 'Specify user account',
+ _('Specify user account'),
lambda: self._create_user_account(),
default={},
display_func=lambda x: list(x.keys()) if x else '[]')
self._menu_options['profile'] = \
Selector(
- 'Specify profile',
+ _('Specify profile'),
lambda: self._select_profile(),
display_func=lambda x: x if x else 'None')
self._menu_options['audio'] = \
Selector(
- 'Select audio',
+ _('Select audio'),
lambda: ask_for_audio_selection(is_desktop_profile(storage['arguments'].get('profile', None))))
self._menu_options['kernels'] = \
Selector(
- 'Select kernels',
+ _('Select kernels'),
lambda: select_kernel(),
default=['linux'])
self._menu_options['packages'] = \
Selector(
- 'Additional packages to install',
+ _('Additional packages to install'),
lambda: ask_additional_packages_to_install(storage['arguments'].get('packages', None)),
default=[])
self._menu_options['nic'] = \
Selector(
- 'Configure network',
+ _('Configure network'),
lambda: ask_to_configure_network(),
display_func=lambda x: x if x else 'Not configured, unavailable unless setup manually',
default={})
@@ -219,7 +228,7 @@ class GlobalMenu:
Selector('Select timezone', lambda: ask_for_a_timezone())
self._menu_options['ntp'] = \
Selector(
- 'Set automatic time sync (NTP)',
+ _('Set automatic time sync (NTP)'),
lambda: self._select_ntp(),
default=True)
self._menu_options['install'] = \
@@ -323,6 +332,11 @@ class GlobalMenu:
return missing
+ def _select_archinstall_language(self, default_lang):
+ language = select_archinstall_language(default_lang)
+ self._translation.activate(language)
+ return language
+
def _set_root_password(self):
prompt = 'Enter root password (leave blank to disable root & create superuser): '
password = get_password(prompt=prompt)
diff --git a/archinstall/lib/translation.py b/archinstall/lib/translation.py
new file mode 100644
index 00000000..1ae6989d
--- /dev/null
+++ b/archinstall/lib/translation.py
@@ -0,0 +1,82 @@
+from __future__ import annotations
+
+import json
+import os
+import gettext
+
+from pathlib import Path
+from typing import List, Dict
+
+
+class Languages:
+ def __init__(self):
+ self._mappings = self._get_language_mappings()
+
+ def _get_language_mappings(self) -> List[Dict[str, str]]:
+ locales_dir = Translation.get_locales_dir()
+ languages = Path.joinpath(locales_dir, 'languages.json')
+
+ with open(languages, 'r') as fp:
+ return json.load(fp)
+
+ def get_language(self, abbr: str) -> str:
+ for entry in self._mappings:
+ if entry['abbr'] == abbr:
+ return entry['lang']
+
+ raise ValueError(f'No language with abbrevation "{abbr}" found')
+
+
+class DeferredTranslation:
+ def __init__(self, message):
+ self.message = message
+
+ def __len__(self) -> int:
+ return len(self.message)
+
+ def __str__(self) -> str:
+ translate = _
+ if translate is DeferredTranslation:
+ return self.message
+ return translate(self.message)
+
+ @classmethod
+ def install(cls):
+ import builtins
+ builtins._ = cls
+
+
+class Translation:
+ def __init__(self, locales_dir):
+ DeferredTranslation.install()
+
+ self._languages = {}
+
+ for name in self.get_all_names():
+ self._languages[name] = gettext.translation('base', localedir=locales_dir, languages=[name])
+
+ def activate(self, name):
+ if language := self._languages.get(name, None):
+ language.install()
+ else:
+ raise ValueError(f'Language not supported: {name}')
+
+ @classmethod
+ def load_nationalization(cls) -> Translation:
+ locales_dir = cls.get_locales_dir()
+ return Translation(locales_dir)
+
+ @classmethod
+ def get_locales_dir(cls) -> Path:
+ cur_path = Path(__file__).parent.parent
+ locales_dir = Path.joinpath(cur_path, 'locales')
+ return locales_dir
+
+ @classmethod
+ def get_all_names(cls) -> List[str]:
+ locales_dir = cls.get_locales_dir()
+ filenames = os.listdir(locales_dir)
+ def_languages = filter(lambda x: len(x) == 2, filenames)
+
+ languages = Languages()
+ return [languages.get_language(lang) for lang in def_languages]
diff --git a/archinstall/lib/user_interaction.py b/archinstall/lib/user_interaction.py
index 8cc7de0a..b1560ea1 100644
--- a/archinstall/lib/user_interaction.py
+++ b/archinstall/lib/user_interaction.py
@@ -28,6 +28,7 @@ from .mirrors import list_mirrors
# TODO: Some inconsistencies between the selection processes.
# Some return the keys from the options, some the values?
+from .translation import Translation
from .disk.validators import fs_types
from .packages.packages import validate_package_list
@@ -79,7 +80,7 @@ def do_countdown() -> bool:
print(".", end='')
if SIG_TRIGGER:
- prompt = 'Do you really want to abort'
+ prompt = _('Do you really want to abort?')
choice = Menu(prompt, ['yes', 'no'], skip=False).run()
if choice == 'yes':
exit(0)
@@ -97,7 +98,7 @@ def do_countdown() -> bool:
def get_password(prompt :str = "Enter a password: ") -> Optional[str]:
while passwd := getpass.getpass(prompt):
- passwd_verification = getpass.getpass(prompt='And one more time for verification: ')
+ passwd_verification = getpass.getpass(prompt=_('And one more time for verification: '))
if passwd != passwd_verification:
log(' * Passwords did not match * ', fg='red')
continue
@@ -267,24 +268,26 @@ class MiniCurses:
return response
-def ask_for_swap(prompt='Would you like to use swap on zram?', forced=False):
+def ask_for_swap():
+ prompt = _('Would you like to use swap on zram?')
choice = Menu(prompt, ['yes', 'no'], default_option='yes').run()
return False if choice == 'no' else True
def ask_ntp() -> bool:
- prompt = 'Would you like to use automatic time synchronization (NTP) with the default time servers?'
- prompt += 'Hardware time and other post-configuration steps might be required in order for NTP to work. For more information, please check the Arch wiki'
+ prompt = _('Would you like to use automatic time synchronization (NTP) with the default time servers?')
+ prompt += _('Hardware time and other post-configuration steps might be required in order for NTP to work. For more information, please check the Arch wiki')
choice = Menu(prompt, ['yes', 'no'], skip=False, default_option='yes').run()
return False if choice == 'no' else True
def ask_hostname():
- hostname = input('Desired hostname for the installation: ').strip(' ')
+ hostname = input(_('Desired hostname for the installation: ').strip(' '))
return hostname
-def ask_for_superuser_account(prompt :str = 'Username for required superuser with sudo privileges: ', forced :bool = False) -> Dict[str, Dict[str, str]]:
+def ask_for_superuser_account(prompt :str = '', forced :bool = False) -> Dict[str, Dict[str, str]]:
+ prompt = prompt if prompt else _('Username for required superuser with sudo privileges: ')
while 1:
new_user = input(prompt).strip(' ')
@@ -298,11 +301,13 @@ def ask_for_superuser_account(prompt :str = 'Username for required superuser wit
elif not check_for_correct_username(new_user):
continue
- password = get_password(prompt=f'Password for user {new_user}: ')
+ prompt = _('Password for user "{}"').format(new_user)
+ password = get_password(prompt=prompt)
return {new_user: {"!password": password}}
-def ask_for_additional_users(prompt :str = 'Any additional users to install (leave blank for no users): ') -> List[Dict[str, Dict[str, str]]]:
+def ask_for_additional_users(prompt :str = '') -> tuple[dict[str, dict[str, str | None]], dict[str, dict[str, str | None]]]:
+ prompt = prompt if prompt else _('Any additional users to install (leave blank for no users): ')
users = {}
superusers = {}
@@ -312,9 +317,14 @@ def ask_for_additional_users(prompt :str = 'Any additional users to install (lea
break
if not check_for_correct_username(new_user):
continue
- password = get_password(prompt=f'Password for user {new_user}: ')
- if input("Should this user be a superuser (sudoer) [y/N]: ").strip(' ').lower() in ('y', 'yes'):
+ prompt = _('Password for user "{}"').format(new_user)
+ password = get_password(prompt=prompt)
+
+ prompt = _('Should this user be a superuser (sudoer)?')
+ choice = Menu(prompt, ['yes', 'no'], skip=False, default_option='no').run()
+
+ if choice == 'yes':
superusers[new_user] = {"!password": password}
else:
users[new_user] = {"!password": password}
@@ -322,12 +332,12 @@ def ask_for_additional_users(prompt :str = 'Any additional users to install (lea
return users, superusers
-def ask_for_a_timezone() -> str:
+def ask_timezone() -> str:
timezones = list_timezones()
default = 'UTC'
selected_tz = Menu(
- f'Select a timezone or leave blank to use default "{default}"',
+ _('Select a timezone'),
list(timezones),
skip=False,
default_option=default
@@ -340,13 +350,18 @@ def ask_for_bootloader(advanced_options :bool = False) -> str:
bootloader = "systemd-bootctl" if has_uefi() else "grub-install"
if has_uefi():
if not advanced_options:
- bootloader_choice = Menu('Would you like to use GRUB as a bootloader instead of systemd-boot?', ['yes', 'no'], default_option='no').run()
+ bootloader_choice = Menu(
+ _('Would you like to use GRUB as a bootloader instead of systemd-boot?'),
+ ['yes', 'no'],
+ default_option='no'
+ ).run()
+
if bootloader_choice == "yes":
bootloader = "grub-install"
else:
# We use the common names for the bootloader as the selection, and map it back to the expected values.
choices = ['systemd-boot', 'grub', 'efistub']
- selection = Menu('Choose a bootloader or leave blank to use systemd-boot', choices).run()
+ selection = Menu(_('Choose a bootloader'), choices).run()
if selection != "":
if selection == 'systemd-boot':
bootloader = 'systemd-bootctl'
@@ -362,7 +377,7 @@ def ask_for_audio_selection(desktop :bool = True) -> str:
audio = 'pipewire' if desktop else 'none'
choices = ['pipewire', 'pulseaudio'] if desktop else ['pipewire', 'pulseaudio', 'none']
selected_audio = Menu(
- f'Choose an audio server',
+ _('Choose an audio server'),
choices,
default_option=audio,
skip=False
@@ -373,14 +388,13 @@ def ask_for_audio_selection(desktop :bool = True) -> str:
# TODO: Remove? Moved?
def ask_additional_packages_to_install(packages :List[str] = None) -> List[str]:
# Additional packages (with some light weight error handling for invalid package names)
- print(
- "Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.")
- print("If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.")
+ print(_('Only packages such as base, base-devel, linux, linux-firmware, efibootmgr and optional profile packages are installed.'))
+ print(_('If you desire a web browser, such as firefox or chromium, you may specify it in the following prompt.'))
+
while True:
- if packages is None:
- packages = [p for p in input(
- 'Write additional packages to install (space separated, leave blank to skip): '
- ).split(' ') if len(p)]
+ packages = [p for p in input(
+ _('Write additional packages to install (space separated, leave blank to skip): ')
+ ).split(' ') if len(p)]
if len(packages):
# Verify packages that were given
@@ -401,16 +415,20 @@ def ask_to_configure_network() -> Dict[str, Any]:
# Optionally configure one network interface.
# while 1:
# {MAC: Ifname}
+
+ iso_config = _('Copy ISO network configuration to installation')
+ network_manager = _('Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)')
+
interfaces = {
- 'ISO-CONFIG': 'Copy ISO network configuration to installation',
- 'NetworkManager': 'Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)',
+ 'ISO-CONFIG': iso_config,
+ 'NetworkManager': network_manager,
**list_interfaces()
}
- nic = Menu('Select one network interface to configure', list(interfaces.values())).run()
+ nic = Menu(_('Select one network interface to configure'), list(interfaces.values())).run()
- if nic and nic != 'Copy ISO network configuration to installation':
- if nic == 'Use NetworkManager (necessary to configure internet graphically in GNOME and KDE)':
+ if nic and nic != iso_config:
+ if nic == network_manager:
return {'nic': nic, 'NetworkManager': True}
# Current workaround:
@@ -420,15 +438,13 @@ def ask_to_configure_network() -> Dict[str, Any]:
modes = ['DHCP (auto detect)', 'IP (static)']
default_mode = 'DHCP (auto detect)'
- mode = Menu(
- f'Select which mode to configure for "{nic}" or leave blank for default "{default_mode}"',
- modes,
- default_option=default_mode
- ).run()
+ prompt = _('Select which mode to configure for "{}" or skip to use default mode "{}"').format(nic, default_mode)
+ mode = Menu(prompt, modes, default_option=default_mode).run()
if mode == 'IP (static)':
while 1:
- ip = input(f"Enter the IP and subnet for {nic} (example: 192.168.0.5/24): ").strip()
+ prompt = _('Enter the IP and subnet for {} (example: 192.168.0.5/24): ').format(nic)
+ ip = input(prompt).strip()
# Implemented new check for correct IP/subnet input
try:
ipaddress.ip_interface(ip)
@@ -442,7 +458,7 @@ def ask_to_configure_network() -> Dict[str, Any]:
# Implemented new check for correct gateway IP address
while 1:
- gateway = input('Enter your gateway (router) IP address or leave blank for none: ').strip()
+ gateway = input(_('Enter your gateway (router) IP address or leave blank for none: ')).strip()
try:
if len(gateway) == 0:
gateway = None
@@ -457,7 +473,9 @@ def ask_to_configure_network() -> Dict[str, Any]:
)
dns = None
- if len(dns_input := input('Enter your DNS servers (space separated, blank for none): ').strip()):
+ dns_input = input(_('Enter your DNS servers (space separated, blank for none): ')).strip()
+
+ if len(dns_input):
dns = dns_input.split(' ')
return {'nic': nic, 'dhcp': False, 'ip': ip, 'gateway': gateway, 'dns': dns}
@@ -489,7 +507,9 @@ def ask_for_main_filesystem_format(advanced_options=False):
if advanced_options:
options.update(advanced)
- return Menu('Select which filesystem your main partition should use', options, skip=False).run()
+ prompt = _('Select which filesystem your main partition should use')
+ choice = Menu(prompt, options, skip=False).run()
+ return choice
def current_partition_layout(partitions :List[Partition], with_idx :bool = False) -> Dict[str, Any]:
@@ -533,7 +553,8 @@ def current_partition_layout(partitions :List[Partition], with_idx :bool = False
current_layout += f'{row[:-1]}\n'
- return f'\n\nCurrent partition layout:\n\n{current_layout}'
+ title = _('Current partition layout')
+ return f'\n\n{title}:\n\n{current_layout}'
def select_partition(title :str, partitions :List[Partition], multiple :bool = False) -> Union[int, List[int], None]:
@@ -583,7 +604,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
"Set desired filesystem for a partition",
]
- title = f'Select what to do with \n{block_device}'
+ title = _('Select what to do with\n{}').format(block_device)
# show current partition layout:
if len(block_device_struct["partitions"]):
@@ -600,16 +621,19 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
# # https://www.gnu.org/software/parted/manual/html_node/mklabel.html
# name = input("Enter a desired name for the partition: ").strip()
- fstype = Menu('Enter a desired filesystem type for the partition', fs_types(), skip=False).run()
+ fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types(), skip=False).run()
+
+ prompt = _('Enter the start sector (percentage or block number, default: {}): ').format(block_device.first_free_sector)
+ start = input(prompt).strip()
- start = input(f"Enter the start sector (percentage or block number, default: {block_device.first_free_sector}): ").strip()
if not start.strip():
start = block_device.first_free_sector
end_suggested = block_device.first_end_sector
else:
end_suggested = '100%'
- end = input(f"Enter the end sector of the partition (percentage or block number, ex: {end_suggested}): ").strip()
+ prompt = _('Enter the end sector of the partition (percentage or block number, ex: {}): "').format(end_suggested)
+ end = input(prompt).strip()
if not end.strip():
end = end_suggested
@@ -634,7 +658,10 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
continue
elif task[:len("Suggest partition layout")] == "Suggest partition layout":
if len(block_device_struct["partitions"]):
- if input(f"{block_device} contains queued partitions, this will remove those, are you sure? y/N: ").strip().lower() in ('', 'n'):
+ prompt = _('{} contains queued partitions, this will remove those, are you sure?').format(block_device)
+ choice = Menu(prompt, ['yes', 'no'], default_option='no').run()
+
+ if choice == 'no':
continue
block_device_struct.update(suggest_single_disk_layout(block_device)[block_device.path])
@@ -644,7 +671,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
current_layout = current_partition_layout(block_device_struct['partitions'], with_idx=True)
if task == "Delete a partition":
- title = f'{current_layout}\n\nSelect by index which partitions to delete'
+ title = _('{}\n\nSelect by index which partitions to delete').format(current_layout)
to_delete = select_partition(title, block_device_struct["partitions"], multiple=True)
if to_delete:
@@ -652,12 +679,12 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
elif task == "Clear/Delete all partitions":
block_device_struct["partitions"] = []
elif task == "Assign mount-point for a partition":
- title = f'{current_layout}\n\nSelect by index which partition to mount where'
+ title = _('{}\n\nSelect by index which partition to mount where').format(current_layout)
partition = select_partition(title, block_device_struct["partitions"])
if partition is not None:
- print(' * Partition mount-points are relative to inside the installation, the boot would be /boot as an example.')
- mountpoint = input('Select where to mount partition (leave blank to remove mountpoint): ').strip()
+ print(_(' * Partition mount-points are relative to inside the installation, the boot would be /boot as an example.'))
+ mountpoint = input(_('Select where to mount partition (leave blank to remove mountpoint): ')).strip()
if len(mountpoint):
block_device_struct["partitions"][partition]['mountpoint'] = mountpoint
@@ -668,7 +695,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
del(block_device_struct["partitions"][partition]['mountpoint'])
elif task == "Mark/Unmark a partition to be formatted (wipes data)":
- title = f'{current_layout}\n\nSelect which partition to mask for formatting'
+ title = _('{}\n\nSelect which partition to mask for formatting').format(current_layout)
partition = select_partition(title, block_device_struct["partitions"])
if partition is not None:
@@ -679,7 +706,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
if not block_device_struct["partitions"][partition].get('filesystem', None):
block_device_struct["partitions"][partition]['filesystem'] = {}
- fstype = Menu('Enter a desired filesystem type for the partition', fs_types(), skip=False).run()
+ fstype = Menu(_('Enter a desired filesystem type for the partition'), fs_types(), skip=False).run()
block_device_struct["partitions"][partition]['filesystem']['format'] = fstype
@@ -687,7 +714,7 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
block_device_struct["partitions"][partition]['wipe'] = not block_device_struct["partitions"][partition].get('wipe', False)
elif task == "Mark/Unmark a partition as encrypted":
- title = f'{current_layout}\n\nSelect which partition to mark as encrypted'
+ title = _('{}\n\nSelect which partition to mark as encrypted').format(current_layout)
partition = select_partition(title, block_device_struct["partitions"])
if partition is not None:
@@ -695,21 +722,21 @@ def manage_new_and_existing_partitions(block_device :BlockDevice) -> Dict[str, A
block_device_struct["partitions"][partition]['encrypted'] = not block_device_struct["partitions"][partition].get('encrypted', False)
elif task == "Mark/Unmark a partition as bootable (automatic for /boot)":
- title = f'{current_layout}\n\nSelect which partition to mark as bootable'
+ title = _('{}\n\nSelect which partition to mark as bootable').format(current_layout)
partition = select_partition(title, block_device_struct["partitions"])
if partition is not None:
block_device_struct["partitions"][partition]['boot'] = not block_device_struct["partitions"][partition].get('boot', False)
elif task == "Set desired filesystem for a partition":
- title = f'{current_layout}\n\nSelect which partition to set a filesystem on'
+ title = _('{}\n\nSelect which partition to set a filesystem on').format(current_layout)
partition = select_partition(title, block_device_struct["partitions"])
if partition is not None:
if not block_device_struct["partitions"][partition].get('filesystem', None):
block_device_struct["partitions"][partition]['filesystem'] = {}
- fstype_title = 'Enter a desired filesystem type for the partition: '
+ fstype_title = _('Enter a desired filesystem type for the partition: ')
fstype = Menu(fstype_title, fs_types(), skip=False).run()
block_device_struct["partitions"][partition]['filesystem']['format'] = fstype
@@ -728,15 +755,20 @@ def select_individual_blockdevice_usage(block_devices: list) -> Dict[str, Any]:
return result
+def select_archinstall_language(default='English'):
+ languages = Translation.get_all_names()
+ language = Menu(_('Select Archinstall language'), languages, default_option=default).run()
+ return language
+
+
def select_disk_layout(block_devices :list, advanced_options=False) -> Dict[str, Any]:
- modes = [
- "Wipe all selected drives and use a best-effort default partition layout",
- "Select what to do with each individual drive (followed by partition usage)"
- ]
+ wipe_mode = _('Wipe all selected drives and use a best-effort default partition layout')
+ custome_mode = _('Select what to do with each individual drive (followed by partition usage)')
+ modes = [wipe_mode, custome_mode]
- mode = Menu('Select what you wish to do with the selected block devices', modes, skip=False).run()
+ mode = Menu(_('Select what you wish to do with the selected block devices'), modes, skip=False).run()
- if mode == 'Wipe all selected drives and use a best-effort default partition layout':
+ if mode == wipe_mode:
return get_default_partition_layout(block_devices, advanced_options)
else:
return select_individual_blockdevice_usage(block_devices)
@@ -787,8 +819,7 @@ def select_profile() -> Optional[str]:
option = f'{profile.profile}: {description}'
options[option] = profile
- title = 'This is a list of pre-programmed profiles, ' \
- 'they might make it easier to install things like desktop environments'
+ title = _('This is a list of pre-programmed profiles, they might make it easier to install things like desktop environments')
selection = Menu(title=title, p_options=list(options.keys())).run()
@@ -812,7 +843,7 @@ def select_language(default_value :str) -> str:
# allows for searching anyways
sorted_kb_lang = sorted(sorted(list(kb_lang)), key=len)
- selected_lang = Menu('Select Keyboard layout', sorted_kb_lang, default_option=default_value, sort=False).run()
+ selected_lang = Menu(_('Select Keyboard layout'), sorted_kb_lang, default_option=default_value, sort=False).run()
return selected_lang
@@ -827,7 +858,7 @@ def select_mirror_regions() -> Dict[str, Any]:
mirrors = list_mirrors()
selected_mirror = Menu(
- 'Select one of the regions to download packages from',
+ _('Select one of the regions to download packages from'),
list(mirrors.keys()),
multi=True
).run()
@@ -849,7 +880,7 @@ def select_harddrives() -> Optional[str]:
options = {f'{option}': option for option in hard_drives}
selected_harddrive = Menu(
- 'Select one or more hard drives to use and configure',
+ _('Select one or more hard drives to use and configure'),
list(options.keys()),
multi=True
).run()
@@ -876,18 +907,18 @@ def select_driver(options :Dict[str, Any] = AVAILABLE_GFX_DRIVERS, force_ask :bo
title = ''
if has_amd_graphics():
- title += 'For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options.\n'
+ title += _('For the best compatibility with your AMD hardware, you may want to use either the all open-source or AMD / ATI options.') + '\n'
if has_intel_graphics():
- title += 'For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n'
+ title += _('For the best compatibility with your Intel hardware, you may want to use either the all open-source or Intel options.\n')
if has_nvidia_graphics():
- title += 'For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n'
+ title += _('For the best compatibility with your Nvidia hardware, you may want to use the Nvidia proprietary driver.\n')
if not arguments.get('gfx_driver', None) or force_ask:
- title += '\n\nSelect a graphics driver or leave blank to install all open-source drivers'
+ title += _('\n\nSelect a graphics driver or leave blank to install all open-source drivers')
arguments['gfx_driver'] = Menu(title, drivers).run()
if arguments.get('gfx_driver', None) is None:
- arguments['gfx_driver'] = "All open-source (default)"
+ arguments['gfx_driver'] = _("All open-source (default)")
return options.get(arguments.get('gfx_driver'))
@@ -906,7 +937,7 @@ def select_kernel() -> List[str]:
default_kernel = "linux"
selected_kernels = Menu(
- f'Choose which kernels to use or leave blank for default "{default_kernel}"',
+ _('Choose which kernels to use or leave blank for default "{}"').format(default_kernel),
kernels,
sort=True,
multi=True,
@@ -920,7 +951,7 @@ def select_locale_lang(default):
locale_lang = set([locale.split()[0] for locale in locales])
selected_locale = Menu(
- f'Choose which locale language to use',
+ _('Choose which locale language to use'),
locale_lang,
sort=True,
default_option=default
@@ -934,7 +965,7 @@ def select_locale_enc(default):
locale_enc = set([locale.split()[1] for locale in locales])
selected_locale = Menu(
- f'Choose which locale encoding to use',
+ _('Choose which locale encoding to use'),
locale_enc,
sort=True,
default_option=default
@@ -942,8 +973,9 @@ def select_locale_enc(default):
return selected_locale
+
def generic_select(p_options :Union[list,dict],
- input_text :str = "Select one of the values shown below: ",
+ input_text :str = '',
allow_empty_input :bool = True,
options_output :bool = True, # function not available
sort :bool = False,
@@ -974,6 +1006,8 @@ def generic_select(p_options :Union[list,dict],
log(f"invalid parameter at Menu() call was at <{sys._getframe(1).f_code.co_name}>",level=logging.WARNING)
raise RequirementError("generic_select() requires an iterable as option.")
+ input_text = input_text if input_text else _('Select one of the values shown below: ')
+
if isinstance(p_options,dict):
options = list(p_options.values())
else:
@@ -1008,11 +1042,13 @@ def generic_select(p_options :Union[list,dict],
def generic_multi_select(p_options :Union[list,dict],
- text :str = "Select one or more of the options below: ",
+ text :str = '',
sort :bool = False,
default :Any = None,
allow_empty :bool = False) -> Any:
+ text = text if text else _("Select one or more of the options below: ")
+
return generic_select(p_options,
input_text=text,
allow_empty_input=allow_empty,
diff --git a/archinstall/locales/README.md b/archinstall/locales/README.md
new file mode 100644
index 00000000..a2c65f79
--- /dev/null
+++ b/archinstall/locales/README.md
@@ -0,0 +1,33 @@
+# Nationalization
+
+Archinstall supports multiple languages, which depend on translations coming from the community :)
+
+New languages can be added simply by creating a new folder with the proper language abbrevation (see list `languages.json` if unsure).
+Run the following command to create a new template for a language
+```
+ mkdir -p <abbr>/LC_MESSAGES/ && touch <abbr>/LC_MESSAGES/base.po
+```
+
+After that run the script `./locales_generator.sh` it will automatically populate the new `base.po` file with the strings that
+need to be translated into the new language.
+For example the `base.po` might contain something like the following now
+```
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+```
+
+The `msgid` is the identifier of the string in the code as well as the default text to be displayed, meaning that if no
+translation is provided for a language then this is the text that is going to be shown.
+
+To provide a translation for the language, simply write the translation in the `msgstr` part
+
+```
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr "Wollen sie wirklich abbrechen?"
+```
+
+After that run the script once more `./locales_generator.sh` and it will auto-generate the `base.mo` file with the included translations.
+After that you're all ready to go and enjoy Archinstall in the new language :)
+
diff --git a/archinstall/locales/base.pot b/archinstall/locales/base.pot
new file mode 100644
index 00000000..d2c36ffd
--- /dev/null
+++ b/archinstall/locales/base.pot
@@ -0,0 +1,354 @@
+#: lib/user_interaction.py:82 lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+
+#: lib/user_interaction.py:100 lib/user_interaction.py:100
+msgid "And one more time for verification: "
+msgstr ""
+
+#: lib/user_interaction.py:271 lib/user_interaction.py:271
+msgid "Would you like to use swap on zram?"
+msgstr ""
+
+#: lib/user_interaction.py:277 lib/user_interaction.py:277
+msgid ""
+"Would you like to use automatic time synchronization (NTP) with the default "
+"time servers?"
+msgstr ""
+
+#: lib/user_interaction.py:278 lib/user_interaction.py:278
+msgid ""
+"Hardware time and other post-configuration steps might be required in order "
+"for NTP to work. For more information, please check the Arch wiki"
+msgstr ""
+
+#: lib/user_interaction.py:284 lib/user_interaction.py:284
+msgid "Desired hostname for the installation: "
+msgstr ""
+
+#: lib/user_interaction.py:289 lib/user_interaction.py:289
+msgid "Username for required superuser with sudo privileges: "
+msgstr ""
+
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+msgid "Password for user \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:309 lib/user_interaction.py:309
+msgid "Any additional users to install (leave blank for no users): "
+msgstr ""
+
+#: lib/user_interaction.py:323 lib/user_interaction.py:323
+msgid "Should this user be a superuser (sudoer)?"
+msgstr ""
+
+#: lib/user_interaction.py:339 lib/user_interaction.py:339
+msgid "Select a timezone"
+msgstr ""
+
+#: lib/user_interaction.py:353 lib/user_interaction.py:353
+msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?"
+msgstr ""
+
+#: lib/user_interaction.py:363 lib/user_interaction.py:363
+msgid "Choose a bootloader"
+msgstr ""
+
+#: lib/user_interaction.py:379 lib/user_interaction.py:379
+msgid "Choose an audio server"
+msgstr ""
+
+#: lib/user_interaction.py:390 lib/user_interaction.py:390
+msgid ""
+"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr "
+"and optional profile packages are installed."
+msgstr ""
+
+#: lib/user_interaction.py:391 lib/user_interaction.py:391
+msgid ""
+"If you desire a web browser, such as firefox or chromium, you may specify it "
+"in the following prompt."
+msgstr ""
+
+#: lib/user_interaction.py:395 lib/user_interaction.py:395
+msgid ""
+"Write additional packages to install (space separated, leave blank to skip): "
+msgstr ""
+
+#: lib/user_interaction.py:418 lib/user_interaction.py:418
+msgid "Copy ISO network configuration to installation"
+msgstr ""
+
+#: lib/user_interaction.py:419 lib/user_interaction.py:419
+msgid ""
+"Use NetworkManager (necessary to configure internet graphically in GNOME and "
+"KDE)"
+msgstr ""
+
+#: lib/user_interaction.py:427 lib/user_interaction.py:427
+msgid "Select one network interface to configure"
+msgstr ""
+
+#: lib/user_interaction.py:440 lib/user_interaction.py:440
+msgid ""
+"Select which mode to configure for \"{}\" or skip to use default mode \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:445 lib/user_interaction.py:445
+msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): "
+msgstr ""
+
+#: lib/user_interaction.py:460 lib/user_interaction.py:460
+msgid "Enter your gateway (router) IP address or leave blank for none: "
+msgstr ""
+
+#: lib/user_interaction.py:475 lib/user_interaction.py:475
+msgid "Enter your DNS servers (space separated, blank for none): "
+msgstr ""
+
+#: lib/user_interaction.py:509 lib/user_interaction.py:509
+msgid "Select which filesystem your main partition should use"
+msgstr ""
+
+#: lib/user_interaction.py:555 lib/user_interaction.py:555
+msgid "Current partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:606 lib/user_interaction.py:606
+msgid ""
+"Select what to do with\n"
+"{}"
+msgstr ""
+
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+msgid "Enter a desired filesystem type for the partition"
+msgstr ""
+
+#: lib/user_interaction.py:625 lib/user_interaction.py:625
+msgid "Enter the start sector (percentage or block number, default: {}): "
+msgstr ""
+
+#: lib/user_interaction.py:634 lib/user_interaction.py:634
+msgid ""
+"Enter the end sector of the partition (percentage or block number, ex: {}): "
+"\""
+msgstr ""
+
+#: lib/user_interaction.py:660 lib/user_interaction.py:660
+msgid "{} contains queued partitions, this will remove those, are you sure?"
+msgstr ""
+
+#: lib/user_interaction.py:673 lib/user_interaction.py:673
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partitions to delete"
+msgstr ""
+
+#: lib/user_interaction.py:681 lib/user_interaction.py:681
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partition to mount where"
+msgstr ""
+
+#: lib/user_interaction.py:685 lib/user_interaction.py:685
+msgid ""
+" * Partition mount-points are relative to inside the installation, the boot "
+"would be /boot as an example."
+msgstr ""
+
+#: lib/user_interaction.py:686 lib/user_interaction.py:686
+msgid "Select where to mount partition (leave blank to remove mountpoint): "
+msgstr ""
+
+#: lib/user_interaction.py:697 lib/user_interaction.py:697
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mask for formatting"
+msgstr ""
+
+#: lib/user_interaction.py:716 lib/user_interaction.py:716
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as encrypted"
+msgstr ""
+
+#: lib/user_interaction.py:724 lib/user_interaction.py:724
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as bootable"
+msgstr ""
+
+#: lib/user_interaction.py:731 lib/user_interaction.py:731
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to set a filesystem on"
+msgstr ""
+
+#: lib/user_interaction.py:738 lib/user_interaction.py:738
+msgid "Enter a desired filesystem type for the partition: "
+msgstr ""
+
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+msgid "Select Archinstall language"
+msgstr ""
+
+#: lib/user_interaction.py:764 lib/user_interaction.py:764
+msgid "Wipe all selected drives and use a best-effort default partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:765 lib/user_interaction.py:765
+msgid ""
+"Select what to do with each individual drive (followed by partition usage)"
+msgstr ""
+
+#: lib/user_interaction.py:768 lib/user_interaction.py:768
+msgid "Select what you wish to do with the selected block devices"
+msgstr ""
+
+#: lib/user_interaction.py:821 lib/user_interaction.py:821
+msgid ""
+"This is a list of pre-programmed profiles, they might make it easier to "
+"install things like desktop environments"
+msgstr ""
+
+#: lib/user_interaction.py:846 lib/user_interaction.py:846
+msgid "Select Keyboard layout"
+msgstr ""
+
+#: lib/user_interaction.py:861 lib/user_interaction.py:861
+msgid "Select one of the regions to download packages from"
+msgstr ""
+
+#: lib/user_interaction.py:883 lib/user_interaction.py:883
+msgid "Select one or more hard drives to use and configure"
+msgstr ""
+
+#: lib/user_interaction.py:910 lib/user_interaction.py:910
+msgid ""
+"For the best compatibility with your AMD hardware, you may want to use "
+"either the all open-source or AMD / ATI options."
+msgstr ""
+
+#: lib/user_interaction.py:912 lib/user_interaction.py:912
+msgid ""
+"For the best compatibility with your Intel hardware, you may want to use "
+"either the all open-source or Intel options.\n"
+msgstr ""
+
+#: lib/user_interaction.py:914 lib/user_interaction.py:914
+msgid ""
+"For the best compatibility with your Nvidia hardware, you may want to use "
+"the Nvidia proprietary driver.\n"
+msgstr ""
+
+#: lib/user_interaction.py:917 lib/user_interaction.py:917
+msgid ""
+"\n"
+"\n"
+"Select a graphics driver or leave blank to install all open-source drivers"
+msgstr ""
+
+#: lib/user_interaction.py:921 lib/user_interaction.py:921
+msgid "All open-source (default)"
+msgstr ""
+
+#: lib/user_interaction.py:940 lib/user_interaction.py:940
+msgid "Choose which kernels to use or leave blank for default \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:954 lib/user_interaction.py:954
+msgid "Choose which locale language to use"
+msgstr ""
+
+#: lib/user_interaction.py:968 lib/user_interaction.py:968
+msgid "Choose which locale encoding to use"
+msgstr ""
+
+#: lib/user_interaction.py:1009 lib/user_interaction.py:1009
+msgid "Select one of the values shown below: "
+msgstr ""
+
+#: lib/user_interaction.py:1050 lib/user_interaction.py:1050
+msgid "Select one or more of the options below: "
+msgstr ""
+
+#: lib/menu/selection_menu.py:122 lib/menu/selection_menu.py:122
+msgid "Select keyboard layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:125 lib/menu/selection_menu.py:125
+msgid "Select mirror region"
+msgstr ""
+
+#: lib/menu/selection_menu.py:130 lib/menu/selection_menu.py:130
+msgid "Select locale language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:132 lib/menu/selection_menu.py:132
+msgid "Select locale encoding"
+msgstr ""
+
+#: lib/menu/selection_menu.py:135 lib/menu/selection_menu.py:135
+msgid "Select harddrives"
+msgstr ""
+
+#: lib/menu/selection_menu.py:139 lib/menu/selection_menu.py:139
+msgid "Select disk layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:147 lib/menu/selection_menu.py:147
+msgid "Set encryption password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:153 lib/menu/selection_menu.py:153
+msgid "Use swap"
+msgstr ""
+
+#: lib/menu/selection_menu.py:158 lib/menu/selection_menu.py:158
+msgid "Select bootloader"
+msgstr ""
+
+#: lib/menu/selection_menu.py:164 lib/menu/selection_menu.py:164
+msgid "Set root password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:169 lib/menu/selection_menu.py:169
+msgid "Specify superuser account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:175 lib/menu/selection_menu.py:175
+msgid "Specify user account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:181 lib/menu/selection_menu.py:181
+msgid "Specify profile"
+msgstr ""
+
+#: lib/menu/selection_menu.py:186 lib/menu/selection_menu.py:186
+msgid "Select audio"
+msgstr ""
+
+#: lib/menu/selection_menu.py:190 lib/menu/selection_menu.py:190
+msgid "Select kernels"
+msgstr ""
+
+#: lib/menu/selection_menu.py:195 lib/menu/selection_menu.py:195
+msgid "Additional packages to install"
+msgstr ""
+
+#: lib/menu/selection_menu.py:200 lib/menu/selection_menu.py:200
+msgid "Configure network"
+msgstr ""
+
+#: lib/menu/selection_menu.py:208 lib/menu/selection_menu.py:208
+msgid "Set automatic time sync (NTP)"
+msgstr ""
diff --git a/archinstall/locales/de/LC_MESSAGES/base.mo b/archinstall/locales/de/LC_MESSAGES/base.mo
new file mode 100644
index 00000000..20c70492
--- /dev/null
+++ b/archinstall/locales/de/LC_MESSAGES/base.mo
Binary files differ
diff --git a/archinstall/locales/de/LC_MESSAGES/base.po b/archinstall/locales/de/LC_MESSAGES/base.po
new file mode 100644
index 00000000..baf62b98
--- /dev/null
+++ b/archinstall/locales/de/LC_MESSAGES/base.po
@@ -0,0 +1,351 @@
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+
+#: lib/user_interaction.py:100
+msgid "And one more time for verification: "
+msgstr ""
+
+#: lib/user_interaction.py:271
+msgid "Would you like to use swap on zram?"
+msgstr ""
+
+#: lib/user_interaction.py:277
+msgid ""
+"Would you like to use automatic time synchronization (NTP) with the default "
+"time servers?"
+msgstr ""
+
+#: lib/user_interaction.py:278
+msgid ""
+"Hardware time and other post-configuration steps might be required in order "
+"for NTP to work. For more information, please check the Arch wiki"
+msgstr ""
+
+#: lib/user_interaction.py:284
+msgid "Desired hostname for the installation: "
+msgstr ""
+
+#: lib/user_interaction.py:289
+msgid "Username for required superuser with sudo privileges: "
+msgstr ""
+
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+msgid "Password for user \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:309
+msgid "Any additional users to install (leave blank for no users): "
+msgstr ""
+
+#: lib/user_interaction.py:323
+msgid "Should this user be a superuser (sudoer)?"
+msgstr ""
+
+#: lib/user_interaction.py:339
+msgid "Select a timezone"
+msgstr ""
+
+#: lib/user_interaction.py:353
+msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?"
+msgstr ""
+
+#: lib/user_interaction.py:363
+msgid "Choose a bootloader"
+msgstr ""
+
+#: lib/user_interaction.py:379
+msgid "Choose an audio server"
+msgstr ""
+
+#: lib/user_interaction.py:390
+msgid ""
+"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr "
+"and optional profile packages are installed."
+msgstr ""
+
+#: lib/user_interaction.py:391
+msgid ""
+"If you desire a web browser, such as firefox or chromium, you may specify it "
+"in the following prompt."
+msgstr ""
+
+#: lib/user_interaction.py:395
+msgid ""
+"Write additional packages to install (space separated, leave blank to skip): "
+msgstr ""
+
+#: lib/user_interaction.py:418
+msgid "Copy ISO network configuration to installation"
+msgstr ""
+
+#: lib/user_interaction.py:419
+msgid ""
+"Use NetworkManager (necessary to configure internet graphically in GNOME and "
+"KDE)"
+msgstr ""
+
+#: lib/user_interaction.py:427
+msgid "Select one network interface to configure"
+msgstr ""
+
+#: lib/user_interaction.py:440
+msgid ""
+"Select which mode to configure for \"{}\" or skip to use default mode \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:445
+msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): "
+msgstr ""
+
+#: lib/user_interaction.py:460
+msgid "Enter your gateway (router) IP address or leave blank for none: "
+msgstr ""
+
+#: lib/user_interaction.py:475
+msgid "Enter your DNS servers (space separated, blank for none): "
+msgstr ""
+
+#: lib/user_interaction.py:509
+msgid "Select which filesystem your main partition should use"
+msgstr ""
+
+#: lib/user_interaction.py:555
+msgid "Current partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:606
+msgid ""
+"Select what to do with\n"
+"{}"
+msgstr ""
+
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+msgid "Enter a desired filesystem type for the partition"
+msgstr ""
+
+#: lib/user_interaction.py:625
+msgid "Enter the start sector (percentage or block number, default: {}): "
+msgstr ""
+
+#: lib/user_interaction.py:634
+msgid ""
+"Enter the end sector of the partition (percentage or block number, ex: {}): "
+"\""
+msgstr ""
+
+#: lib/user_interaction.py:660
+msgid "{} contains queued partitions, this will remove those, are you sure?"
+msgstr ""
+
+#: lib/user_interaction.py:673
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partitions to delete"
+msgstr ""
+
+#: lib/user_interaction.py:681
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partition to mount where"
+msgstr ""
+
+#: lib/user_interaction.py:685
+msgid ""
+" * Partition mount-points are relative to inside the installation, the boot "
+"would be /boot as an example."
+msgstr ""
+
+#: lib/user_interaction.py:686
+msgid "Select where to mount partition (leave blank to remove mountpoint): "
+msgstr ""
+
+#: lib/user_interaction.py:697
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mask for formatting"
+msgstr ""
+
+#: lib/user_interaction.py:716
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as encrypted"
+msgstr ""
+
+#: lib/user_interaction.py:724
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as bootable"
+msgstr ""
+
+#: lib/user_interaction.py:731
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to set a filesystem on"
+msgstr ""
+
+#: lib/user_interaction.py:738
+msgid "Enter a desired filesystem type for the partition: "
+msgstr ""
+
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+msgid "Select Archinstall language"
+msgstr "Sprache fuer Archinstall"
+
+#: lib/user_interaction.py:764
+msgid "Wipe all selected drives and use a best-effort default partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:765
+msgid ""
+"Select what to do with each individual drive (followed by partition usage)"
+msgstr ""
+
+#: lib/user_interaction.py:768
+msgid "Select what you wish to do with the selected block devices"
+msgstr ""
+
+#: lib/user_interaction.py:821
+msgid ""
+"This is a list of pre-programmed profiles, they might make it easier to "
+"install things like desktop environments"
+msgstr ""
+
+#: lib/user_interaction.py:846
+msgid "Select Keyboard layout"
+msgstr ""
+
+#: lib/user_interaction.py:861
+msgid "Select one of the regions to download packages from"
+msgstr ""
+
+#: lib/user_interaction.py:883
+msgid "Select one or more hard drives to use and configure"
+msgstr ""
+
+#: lib/user_interaction.py:910
+msgid ""
+"For the best compatibility with your AMD hardware, you may want to use "
+"either the all open-source or AMD / ATI options."
+msgstr ""
+
+#: lib/user_interaction.py:912
+msgid ""
+"For the best compatibility with your Intel hardware, you may want to use "
+"either the all open-source or Intel options.\n"
+msgstr ""
+
+#: lib/user_interaction.py:914
+msgid ""
+"For the best compatibility with your Nvidia hardware, you may want to use "
+"the Nvidia proprietary driver.\n"
+msgstr ""
+
+#: lib/user_interaction.py:917
+msgid ""
+"\n"
+"\n"
+"Select a graphics driver or leave blank to install all open-source drivers"
+msgstr ""
+
+#: lib/user_interaction.py:921
+msgid "All open-source (default)"
+msgstr ""
+
+#: lib/user_interaction.py:940
+msgid "Choose which kernels to use or leave blank for default \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:954
+msgid "Choose which locale language to use"
+msgstr ""
+
+#: lib/user_interaction.py:968
+msgid "Choose which locale encoding to use"
+msgstr ""
+
+#: lib/user_interaction.py:1009
+msgid "Select one of the values shown below: "
+msgstr ""
+
+#: lib/user_interaction.py:1050
+msgid "Select one or more of the options below: "
+msgstr ""
+
+#: lib/menu/selection_menu.py:122
+msgid "Select keyboard layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:125
+msgid "Select mirror region"
+msgstr ""
+
+#: lib/menu/selection_menu.py:130
+msgid "Select locale language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:132
+msgid "Select locale encoding"
+msgstr ""
+
+#: lib/menu/selection_menu.py:135
+msgid "Select harddrives"
+msgstr ""
+
+#: lib/menu/selection_menu.py:139
+msgid "Select disk layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:147
+msgid "Set encryption password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:153
+msgid "Use swap"
+msgstr ""
+
+#: lib/menu/selection_menu.py:158
+msgid "Select bootloader"
+msgstr ""
+
+#: lib/menu/selection_menu.py:164
+msgid "Set root password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:169
+msgid "Specify superuser account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:175
+msgid "Specify user account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:181
+msgid "Specify profile"
+msgstr ""
+
+#: lib/menu/selection_menu.py:186
+msgid "Select audio"
+msgstr ""
+
+#: lib/menu/selection_menu.py:190
+msgid "Select kernels"
+msgstr ""
+
+#: lib/menu/selection_menu.py:195
+msgid "Additional packages to install"
+msgstr ""
+
+#: lib/menu/selection_menu.py:200
+msgid "Configure network"
+msgstr ""
+
+#: lib/menu/selection_menu.py:208
+msgid "Set automatic time sync (NTP)"
+msgstr ""
diff --git a/archinstall/locales/en/LC_MESSAGES/base.mo b/archinstall/locales/en/LC_MESSAGES/base.mo
new file mode 100644
index 00000000..bbd3b9e8
--- /dev/null
+++ b/archinstall/locales/en/LC_MESSAGES/base.mo
Binary files differ
diff --git a/archinstall/locales/en/LC_MESSAGES/base.po b/archinstall/locales/en/LC_MESSAGES/base.po
new file mode 100644
index 00000000..ce61097b
--- /dev/null
+++ b/archinstall/locales/en/LC_MESSAGES/base.po
@@ -0,0 +1,351 @@
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+
+#: lib/user_interaction.py:100
+msgid "And one more time for verification: "
+msgstr ""
+
+#: lib/user_interaction.py:271
+msgid "Would you like to use swap on zram?"
+msgstr ""
+
+#: lib/user_interaction.py:277
+msgid ""
+"Would you like to use automatic time synchronization (NTP) with the default "
+"time servers?"
+msgstr ""
+
+#: lib/user_interaction.py:278
+msgid ""
+"Hardware time and other post-configuration steps might be required in order "
+"for NTP to work. For more information, please check the Arch wiki"
+msgstr ""
+
+#: lib/user_interaction.py:284
+msgid "Desired hostname for the installation: "
+msgstr ""
+
+#: lib/user_interaction.py:289
+msgid "Username for required superuser with sudo privileges: "
+msgstr ""
+
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+msgid "Password for user \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:309
+msgid "Any additional users to install (leave blank for no users): "
+msgstr ""
+
+#: lib/user_interaction.py:323
+msgid "Should this user be a superuser (sudoer)?"
+msgstr ""
+
+#: lib/user_interaction.py:339
+msgid "Select a timezone"
+msgstr ""
+
+#: lib/user_interaction.py:353
+msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?"
+msgstr ""
+
+#: lib/user_interaction.py:363
+msgid "Choose a bootloader"
+msgstr ""
+
+#: lib/user_interaction.py:379
+msgid "Choose an audio server"
+msgstr ""
+
+#: lib/user_interaction.py:390
+msgid ""
+"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr "
+"and optional profile packages are installed."
+msgstr ""
+
+#: lib/user_interaction.py:391
+msgid ""
+"If you desire a web browser, such as firefox or chromium, you may specify it "
+"in the following prompt."
+msgstr ""
+
+#: lib/user_interaction.py:395
+msgid ""
+"Write additional packages to install (space separated, leave blank to skip): "
+msgstr ""
+
+#: lib/user_interaction.py:418
+msgid "Copy ISO network configuration to installation"
+msgstr ""
+
+#: lib/user_interaction.py:419
+msgid ""
+"Use NetworkManager (necessary to configure internet graphically in GNOME and "
+"KDE)"
+msgstr ""
+
+#: lib/user_interaction.py:427
+msgid "Select one network interface to configure"
+msgstr ""
+
+#: lib/user_interaction.py:440
+msgid ""
+"Select which mode to configure for \"{}\" or skip to use default mode \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:445
+msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): "
+msgstr ""
+
+#: lib/user_interaction.py:460
+msgid "Enter your gateway (router) IP address or leave blank for none: "
+msgstr ""
+
+#: lib/user_interaction.py:475
+msgid "Enter your DNS servers (space separated, blank for none): "
+msgstr ""
+
+#: lib/user_interaction.py:509
+msgid "Select which filesystem your main partition should use"
+msgstr ""
+
+#: lib/user_interaction.py:555
+msgid "Current partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:606
+msgid ""
+"Select what to do with\n"
+"{}"
+msgstr ""
+
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+msgid "Enter a desired filesystem type for the partition"
+msgstr ""
+
+#: lib/user_interaction.py:625
+msgid "Enter the start sector (percentage or block number, default: {}): "
+msgstr ""
+
+#: lib/user_interaction.py:634
+msgid ""
+"Enter the end sector of the partition (percentage or block number, ex: {}): "
+"\""
+msgstr ""
+
+#: lib/user_interaction.py:660
+msgid "{} contains queued partitions, this will remove those, are you sure?"
+msgstr ""
+
+#: lib/user_interaction.py:673
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partitions to delete"
+msgstr ""
+
+#: lib/user_interaction.py:681
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partition to mount where"
+msgstr ""
+
+#: lib/user_interaction.py:685
+msgid ""
+" * Partition mount-points are relative to inside the installation, the boot "
+"would be /boot as an example."
+msgstr ""
+
+#: lib/user_interaction.py:686
+msgid "Select where to mount partition (leave blank to remove mountpoint): "
+msgstr ""
+
+#: lib/user_interaction.py:697
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mask for formatting"
+msgstr ""
+
+#: lib/user_interaction.py:716
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as encrypted"
+msgstr ""
+
+#: lib/user_interaction.py:724
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as bootable"
+msgstr ""
+
+#: lib/user_interaction.py:731
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to set a filesystem on"
+msgstr ""
+
+#: lib/user_interaction.py:738
+msgid "Enter a desired filesystem type for the partition: "
+msgstr ""
+
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+msgid "Select Archinstall language"
+msgstr ""
+
+#: lib/user_interaction.py:764
+msgid "Wipe all selected drives and use a best-effort default partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:765
+msgid ""
+"Select what to do with each individual drive (followed by partition usage)"
+msgstr ""
+
+#: lib/user_interaction.py:768
+msgid "Select what you wish to do with the selected block devices"
+msgstr ""
+
+#: lib/user_interaction.py:821
+msgid ""
+"This is a list of pre-programmed profiles, they might make it easier to "
+"install things like desktop environments"
+msgstr ""
+
+#: lib/user_interaction.py:846
+msgid "Select Keyboard layout"
+msgstr ""
+
+#: lib/user_interaction.py:861
+msgid "Select one of the regions to download packages from"
+msgstr ""
+
+#: lib/user_interaction.py:883
+msgid "Select one or more hard drives to use and configure"
+msgstr ""
+
+#: lib/user_interaction.py:910
+msgid ""
+"For the best compatibility with your AMD hardware, you may want to use "
+"either the all open-source or AMD / ATI options."
+msgstr ""
+
+#: lib/user_interaction.py:912
+msgid ""
+"For the best compatibility with your Intel hardware, you may want to use "
+"either the all open-source or Intel options.\n"
+msgstr ""
+
+#: lib/user_interaction.py:914
+msgid ""
+"For the best compatibility with your Nvidia hardware, you may want to use "
+"the Nvidia proprietary driver.\n"
+msgstr ""
+
+#: lib/user_interaction.py:917
+msgid ""
+"\n"
+"\n"
+"Select a graphics driver or leave blank to install all open-source drivers"
+msgstr ""
+
+#: lib/user_interaction.py:921
+msgid "All open-source (default)"
+msgstr ""
+
+#: lib/user_interaction.py:940
+msgid "Choose which kernels to use or leave blank for default \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:954
+msgid "Choose which locale language to use"
+msgstr ""
+
+#: lib/user_interaction.py:968
+msgid "Choose which locale encoding to use"
+msgstr ""
+
+#: lib/user_interaction.py:1009
+msgid "Select one of the values shown below: "
+msgstr ""
+
+#: lib/user_interaction.py:1050
+msgid "Select one or more of the options below: "
+msgstr ""
+
+#: lib/menu/selection_menu.py:122
+msgid "Select keyboard layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:125
+msgid "Select mirror region"
+msgstr ""
+
+#: lib/menu/selection_menu.py:130
+msgid "Select locale language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:132
+msgid "Select locale encoding"
+msgstr ""
+
+#: lib/menu/selection_menu.py:135
+msgid "Select harddrives"
+msgstr ""
+
+#: lib/menu/selection_menu.py:139
+msgid "Select disk layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:147
+msgid "Set encryption password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:153
+msgid "Use swap"
+msgstr ""
+
+#: lib/menu/selection_menu.py:158
+msgid "Select bootloader"
+msgstr ""
+
+#: lib/menu/selection_menu.py:164
+msgid "Set root password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:169
+msgid "Specify superuser account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:175
+msgid "Specify user account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:181
+msgid "Specify profile"
+msgstr ""
+
+#: lib/menu/selection_menu.py:186
+msgid "Select audio"
+msgstr ""
+
+#: lib/menu/selection_menu.py:190
+msgid "Select kernels"
+msgstr ""
+
+#: lib/menu/selection_menu.py:195
+msgid "Additional packages to install"
+msgstr ""
+
+#: lib/menu/selection_menu.py:200
+msgid "Configure network"
+msgstr ""
+
+#: lib/menu/selection_menu.py:208
+msgid "Set automatic time sync (NTP)"
+msgstr ""
diff --git a/archinstall/locales/en/LC_MESSAGES/base.po~ b/archinstall/locales/en/LC_MESSAGES/base.po~
new file mode 100644
index 00000000..bf321c2a
--- /dev/null
+++ b/archinstall/locales/en/LC_MESSAGES/base.po~
@@ -0,0 +1,359 @@
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+
+#: lib/user_interaction.py:100
+msgid "And one more time for verification: "
+msgstr ""
+
+#: lib/user_interaction.py:271
+msgid "Would you like to use swap on zram?"
+msgstr ""
+
+#: lib/user_interaction.py:277
+msgid ""
+"Would you like to use automatic time synchronization (NTP) with the default "
+"time servers?"
+msgstr ""
+
+#: lib/user_interaction.py:278
+msgid ""
+"Hardware time and other post-configuration steps might be required in order "
+"for NTP to work. For more information, please check the Arch wiki"
+msgstr ""
+
+#: lib/user_interaction.py:284
+msgid "Desired hostname for the installation: "
+msgstr ""
+
+#: lib/user_interaction.py:289
+msgid "Username for required superuser with sudo privileges: "
+msgstr ""
+
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+msgid "Password for user \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:309
+msgid "Any additional users to install (leave blank for no users): "
+msgstr ""
+
+#: lib/user_interaction.py:323
+msgid "Should this user be a superuser (sudoer)?"
+msgstr ""
+
+#: lib/user_interaction.py:339
+msgid "Select a timezone"
+msgstr ""
+
+#: lib/user_interaction.py:353
+msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?"
+msgstr ""
+
+#: lib/user_interaction.py:363
+msgid "Choose a bootloader"
+msgstr ""
+
+#: lib/user_interaction.py:379
+msgid "Choose an audio server"
+msgstr ""
+
+#: lib/user_interaction.py:390
+msgid ""
+"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr "
+"and optional profile packages are installed."
+msgstr ""
+
+#: lib/user_interaction.py:391
+msgid ""
+"If you desire a web browser, such as firefox or chromium, you may specify it "
+"in the following prompt."
+msgstr ""
+
+#: lib/user_interaction.py:395
+msgid ""
+"Write additional packages to install (space separated, leave blank to skip): "
+msgstr ""
+
+#: lib/user_interaction.py:418
+msgid "Copy ISO network configuration to installation"
+msgstr ""
+
+#: lib/user_interaction.py:419
+msgid ""
+"Use NetworkManager (necessary to configure internet graphically in GNOME and "
+"KDE)"
+msgstr ""
+
+#: lib/user_interaction.py:427
+msgid "Select one network interface to configure"
+msgstr ""
+
+#: lib/user_interaction.py:440
+msgid ""
+"Select which mode to configure for \"{}\" or skip to use default mode \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:445
+msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): "
+msgstr ""
+
+#: lib/user_interaction.py:460
+msgid "Enter your gateway (router) IP address or leave blank for none: "
+msgstr ""
+
+#: lib/user_interaction.py:475
+msgid "Enter your DNS servers (space separated, blank for none): "
+msgstr ""
+
+#: lib/user_interaction.py:509
+msgid "Select which filesystem your main partition should use"
+msgstr ""
+
+#: lib/user_interaction.py:555
+msgid "Current partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:606
+msgid ""
+"Select what to do with\n"
+"{}"
+msgstr ""
+
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+msgid "Enter a desired filesystem type for the partition"
+msgstr ""
+
+#: lib/user_interaction.py:625
+msgid "Enter the start sector (percentage or block number, default: {}): "
+msgstr ""
+
+#: lib/user_interaction.py:634
+msgid ""
+"Enter the end sector of the partition (percentage or block number, ex: {}): "
+"\""
+msgstr ""
+
+#: lib/user_interaction.py:660
+msgid "{} contains queued partitions, this will remove those, are you sure?"
+msgstr ""
+
+#: lib/user_interaction.py:673
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partitions to delete"
+msgstr ""
+
+#: lib/user_interaction.py:681
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partition to mount where"
+msgstr ""
+
+#: lib/user_interaction.py:685
+msgid ""
+" * Partition mount-points are relative to inside the installation, the boot "
+"would be /boot as an example."
+msgstr ""
+
+#: lib/user_interaction.py:686
+msgid "Select where to mount partition (leave blank to remove mountpoint): "
+msgstr ""
+
+#: lib/user_interaction.py:697
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mask for formatting"
+msgstr ""
+
+#: lib/user_interaction.py:716
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as encrypted"
+msgstr ""
+
+#: lib/user_interaction.py:724
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as bootable"
+msgstr ""
+
+#: lib/user_interaction.py:731
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to set a filesystem on"
+msgstr ""
+
+#: lib/user_interaction.py:738
+msgid "Enter a desired filesystem type for the partition: "
+msgstr ""
+
+#: lib/user_interaction.py:759
+msgid "Select archinstall language"
+msgstr ""
+
+#: lib/user_interaction.py:764
+msgid "Wipe all selected drives and use a best-effort default partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:765
+msgid ""
+"Select what to do with each individual drive (followed by partition usage)"
+msgstr ""
+
+#: lib/user_interaction.py:768
+msgid "Select what you wish to do with the selected block devices"
+msgstr ""
+
+#: lib/user_interaction.py:821
+msgid ""
+"This is a list of pre-programmed profiles, they might make it easier to "
+"install things like desktop environments"
+msgstr ""
+
+#: lib/user_interaction.py:846
+msgid "Select Keyboard layout"
+msgstr ""
+
+#: lib/user_interaction.py:861
+msgid "Select one of the regions to download packages from"
+msgstr ""
+
+#: lib/user_interaction.py:883
+msgid "Select one or more hard drives to use and configure"
+msgstr ""
+
+#: lib/user_interaction.py:910
+msgid ""
+"For the best compatibility with your AMD hardware, you may want to use "
+"either the all open-source or AMD / ATI options."
+msgstr ""
+
+#: lib/user_interaction.py:912
+msgid ""
+"For the best compatibility with your Intel hardware, you may want to use "
+"either the all open-source or Intel options.\n"
+msgstr ""
+
+#: lib/user_interaction.py:914
+msgid ""
+"For the best compatibility with your Nvidia hardware, you may want to use "
+"the Nvidia proprietary driver.\n"
+msgstr ""
+
+#: lib/user_interaction.py:917
+msgid ""
+"\n"
+"\n"
+"Select a graphics driver or leave blank to install all open-source drivers"
+msgstr ""
+
+#: lib/user_interaction.py:921
+msgid "All open-source (default)"
+msgstr ""
+
+#: lib/user_interaction.py:940
+msgid "Choose which kernels to use or leave blank for default \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:954
+msgid "Choose which locale language to use"
+msgstr ""
+
+#: lib/user_interaction.py:968
+msgid "Choose which locale encoding to use"
+msgstr ""
+
+#: lib/user_interaction.py:1009
+msgid "Select one of the values shown below: "
+msgstr ""
+
+#: lib/user_interaction.py:1050
+msgid "Select one or more of the options below: "
+msgstr ""
+
+#: lib/menu/selection_menu.py:116
+msgid "Archinstall language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:122
+msgid "Select keyboard layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:125
+msgid "Select mirror region"
+msgstr ""
+
+#: lib/menu/selection_menu.py:130
+msgid "Select locale language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:132
+msgid "Select locale encoding"
+msgstr ""
+
+#: lib/menu/selection_menu.py:135
+msgid "Select harddrives"
+msgstr ""
+
+#: lib/menu/selection_menu.py:139
+msgid "Select disk layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:147
+msgid "Set encryption password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:153
+msgid "Use swap"
+msgstr ""
+
+#: lib/menu/selection_menu.py:158
+msgid "Select bootloader"
+msgstr ""
+
+#: lib/menu/selection_menu.py:164
+msgid "Set root password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:169
+msgid "Specify superuser account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:175
+msgid "Specify user account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:181
+msgid "Specify profile"
+msgstr ""
+
+#: lib/menu/selection_menu.py:186
+msgid "Select audio"
+msgstr ""
+
+#: lib/menu/selection_menu.py:190
+msgid "Select kernels"
+msgstr ""
+
+#: lib/menu/selection_menu.py:195
+msgid "Additional packages to install"
+msgstr ""
+
+#: lib/menu/selection_menu.py:200
+msgid "Configure network"
+msgstr ""
+
+#: lib/menu/selection_menu.py:208
+msgid "Set automatic time sync (NTP)"
+msgstr ""
+
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+msgid "Select Archinstall language"
+msgstr ""
diff --git a/archinstall/locales/it/LC_MESSAGES/base.mo b/archinstall/locales/it/LC_MESSAGES/base.mo
new file mode 100644
index 00000000..f879d813
--- /dev/null
+++ b/archinstall/locales/it/LC_MESSAGES/base.mo
Binary files differ
diff --git a/archinstall/locales/it/LC_MESSAGES/base.po b/archinstall/locales/it/LC_MESSAGES/base.po
new file mode 100644
index 00000000..a399e547
--- /dev/null
+++ b/archinstall/locales/it/LC_MESSAGES/base.po
@@ -0,0 +1,354 @@
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+
+#: lib/user_interaction.py:100
+msgid "And one more time for verification: "
+msgstr ""
+
+#: lib/user_interaction.py:271
+msgid "Would you like to use swap on zram?"
+msgstr ""
+
+#: lib/user_interaction.py:277
+msgid ""
+"Would you like to use automatic time synchronization (NTP) with the default "
+"time servers?"
+msgstr ""
+
+#: lib/user_interaction.py:278
+msgid ""
+"Hardware time and other post-configuration steps might be required in order "
+"for NTP to work. For more information, please check the Arch wiki"
+msgstr ""
+
+#: lib/user_interaction.py:284
+msgid "Desired hostname for the installation: "
+msgstr ""
+
+#: lib/user_interaction.py:289
+msgid "Username for required superuser with sudo privileges: "
+msgstr ""
+
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+msgid "Password for user \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:309
+msgid "Any additional users to install (leave blank for no users): "
+msgstr ""
+
+#: lib/user_interaction.py:323
+msgid "Should this user be a superuser (sudoer)?"
+msgstr ""
+
+#: lib/user_interaction.py:339
+msgid "Select a timezone"
+msgstr ""
+
+#: lib/user_interaction.py:353
+msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?"
+msgstr ""
+
+#: lib/user_interaction.py:363
+msgid "Choose a bootloader"
+msgstr ""
+
+#: lib/user_interaction.py:379
+msgid "Choose an audio server"
+msgstr ""
+
+#: lib/user_interaction.py:390
+msgid ""
+"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr "
+"and optional profile packages are installed."
+msgstr ""
+
+#: lib/user_interaction.py:391
+msgid ""
+"If you desire a web browser, such as firefox or chromium, you may specify it "
+"in the following prompt."
+msgstr ""
+
+#: lib/user_interaction.py:395
+msgid ""
+"Write additional packages to install (space separated, leave blank to skip): "
+msgstr ""
+
+#: lib/user_interaction.py:418
+msgid "Copy ISO network configuration to installation"
+msgstr ""
+
+#: lib/user_interaction.py:419
+msgid ""
+"Use NetworkManager (necessary to configure internet graphically in GNOME and "
+"KDE)"
+msgstr ""
+
+#: lib/user_interaction.py:427
+msgid "Select one network interface to configure"
+msgstr ""
+
+#: lib/user_interaction.py:440
+msgid ""
+"Select which mode to configure for \"{}\" or skip to use default mode \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:445
+msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): "
+msgstr ""
+
+#: lib/user_interaction.py:460
+msgid "Enter your gateway (router) IP address or leave blank for none: "
+msgstr ""
+
+#: lib/user_interaction.py:475
+msgid "Enter your DNS servers (space separated, blank for none): "
+msgstr ""
+
+#: lib/user_interaction.py:509
+msgid "Select which filesystem your main partition should use"
+msgstr ""
+
+#: lib/user_interaction.py:555
+msgid "Current partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:606
+msgid ""
+"Select what to do with\n"
+"{}"
+msgstr ""
+
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+msgid "Enter a desired filesystem type for the partition"
+msgstr ""
+
+#: lib/user_interaction.py:625
+msgid "Enter the start sector (percentage or block number, default: {}): "
+msgstr ""
+
+#: lib/user_interaction.py:634
+msgid ""
+"Enter the end sector of the partition (percentage or block number, ex: {}): "
+"\""
+msgstr ""
+
+#: lib/user_interaction.py:660
+msgid "{} contains queued partitions, this will remove those, are you sure?"
+msgstr ""
+
+#: lib/user_interaction.py:673
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partitions to delete"
+msgstr ""
+
+#: lib/user_interaction.py:681
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partition to mount where"
+msgstr ""
+
+#: lib/user_interaction.py:685
+msgid ""
+" * Partition mount-points are relative to inside the installation, the boot "
+"would be /boot as an example."
+msgstr ""
+
+#: lib/user_interaction.py:686
+msgid "Select where to mount partition (leave blank to remove mountpoint): "
+msgstr ""
+
+#: lib/user_interaction.py:697
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mask for formatting"
+msgstr ""
+
+#: lib/user_interaction.py:716
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as encrypted"
+msgstr ""
+
+#: lib/user_interaction.py:724
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as bootable"
+msgstr ""
+
+#: lib/user_interaction.py:731
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to set a filesystem on"
+msgstr ""
+
+#: lib/user_interaction.py:738
+msgid "Enter a desired filesystem type for the partition: "
+msgstr ""
+
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+msgid "Select Archinstall language"
+msgstr ""
+
+#: lib/user_interaction.py:764
+msgid "Wipe all selected drives and use a best-effort default partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:765
+msgid ""
+"Select what to do with each individual drive (followed by partition usage)"
+msgstr ""
+
+#: lib/user_interaction.py:768
+msgid "Select what you wish to do with the selected block devices"
+msgstr ""
+
+#: lib/user_interaction.py:821
+msgid ""
+"This is a list of pre-programmed profiles, they might make it easier to "
+"install things like desktop environments"
+msgstr ""
+
+#: lib/user_interaction.py:846
+msgid "Select Keyboard layout"
+msgstr ""
+
+#: lib/user_interaction.py:861
+msgid "Select one of the regions to download packages from"
+msgstr ""
+
+#: lib/user_interaction.py:883
+msgid "Select one or more hard drives to use and configure"
+msgstr ""
+
+#: lib/user_interaction.py:910
+msgid ""
+"For the best compatibility with your AMD hardware, you may want to use "
+"either the all open-source or AMD / ATI options."
+msgstr ""
+
+#: lib/user_interaction.py:912
+msgid ""
+"For the best compatibility with your Intel hardware, you may want to use "
+"either the all open-source or Intel options.\n"
+msgstr ""
+
+#: lib/user_interaction.py:914
+msgid ""
+"For the best compatibility with your Nvidia hardware, you may want to use "
+"the Nvidia proprietary driver.\n"
+msgstr ""
+
+#: lib/user_interaction.py:917
+msgid ""
+"\n"
+"\n"
+"Select a graphics driver or leave blank to install all open-source drivers"
+msgstr ""
+
+#: lib/user_interaction.py:921
+msgid "All open-source (default)"
+msgstr ""
+
+#: lib/user_interaction.py:940
+msgid "Choose which kernels to use or leave blank for default \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:954
+msgid "Choose which locale language to use"
+msgstr ""
+
+#: lib/user_interaction.py:968
+msgid "Choose which locale encoding to use"
+msgstr ""
+
+#: lib/user_interaction.py:1009
+msgid "Select one of the values shown below: "
+msgstr ""
+
+#: lib/user_interaction.py:1050
+msgid "Select one or more of the options below: "
+msgstr ""
+
+#: lib/menu/selection_menu.py:122
+msgid "Select keyboard layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:125
+msgid "Select mirror region"
+msgstr ""
+
+#: lib/menu/selection_menu.py:130
+msgid "Select locale language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:132
+msgid "Select locale encoding"
+msgstr ""
+
+#: lib/menu/selection_menu.py:135
+msgid "Select harddrives"
+msgstr ""
+
+#: lib/menu/selection_menu.py:139
+msgid "Select disk layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:147
+msgid "Set encryption password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:153
+msgid "Use swap"
+msgstr ""
+
+#: lib/menu/selection_menu.py:158
+msgid "Select bootloader"
+msgstr ""
+
+#: lib/menu/selection_menu.py:164
+msgid "Set root password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:169
+msgid "Specify superuser account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:175
+msgid "Specify user account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:181
+msgid "Specify profile"
+msgstr ""
+
+#: lib/menu/selection_menu.py:186
+msgid "Select audio"
+msgstr ""
+
+#: lib/menu/selection_menu.py:190
+msgid "Select kernels"
+msgstr ""
+
+#: lib/menu/selection_menu.py:195
+msgid "Additional packages to install"
+msgstr ""
+
+#: lib/menu/selection_menu.py:200
+msgid "Configure network"
+msgstr ""
+
+#: lib/menu/selection_menu.py:208
+msgid "Set automatic time sync (NTP)"
+msgstr ""
+
+#~ msgid "this is a test string"
+#~ msgstr "Questo e un esempio"
diff --git a/archinstall/locales/it/LC_MESSAGES/base.po~ b/archinstall/locales/it/LC_MESSAGES/base.po~
new file mode 100644
index 00000000..2f364d69
--- /dev/null
+++ b/archinstall/locales/it/LC_MESSAGES/base.po~
@@ -0,0 +1,362 @@
+#: lib/user_interaction.py:82
+msgid "Do you really want to abort?"
+msgstr ""
+
+#: lib/user_interaction.py:100
+msgid "And one more time for verification: "
+msgstr ""
+
+#: lib/user_interaction.py:271
+msgid "Would you like to use swap on zram?"
+msgstr ""
+
+#: lib/user_interaction.py:277
+msgid ""
+"Would you like to use automatic time synchronization (NTP) with the default "
+"time servers?"
+msgstr ""
+
+#: lib/user_interaction.py:278
+msgid ""
+"Hardware time and other post-configuration steps might be required in order "
+"for NTP to work. For more information, please check the Arch wiki"
+msgstr ""
+
+#: lib/user_interaction.py:284
+msgid "Desired hostname for the installation: "
+msgstr ""
+
+#: lib/user_interaction.py:289
+msgid "Username for required superuser with sudo privileges: "
+msgstr ""
+
+#: lib/user_interaction.py:303 lib/user_interaction.py:320
+msgid "Password for user \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:309
+msgid "Any additional users to install (leave blank for no users): "
+msgstr ""
+
+#: lib/user_interaction.py:323
+msgid "Should this user be a superuser (sudoer)?"
+msgstr ""
+
+#: lib/user_interaction.py:339
+msgid "Select a timezone"
+msgstr ""
+
+#: lib/user_interaction.py:353
+msgid "Would you like to use GRUB as a bootloader instead of systemd-boot?"
+msgstr ""
+
+#: lib/user_interaction.py:363
+msgid "Choose a bootloader"
+msgstr ""
+
+#: lib/user_interaction.py:379
+msgid "Choose an audio server"
+msgstr ""
+
+#: lib/user_interaction.py:390
+msgid ""
+"Only packages such as base, base-devel, linux, linux-firmware, efibootmgr "
+"and optional profile packages are installed."
+msgstr ""
+
+#: lib/user_interaction.py:391
+msgid ""
+"If you desire a web browser, such as firefox or chromium, you may specify it "
+"in the following prompt."
+msgstr ""
+
+#: lib/user_interaction.py:395
+msgid ""
+"Write additional packages to install (space separated, leave blank to skip): "
+msgstr ""
+
+#: lib/user_interaction.py:418
+msgid "Copy ISO network configuration to installation"
+msgstr ""
+
+#: lib/user_interaction.py:419
+msgid ""
+"Use NetworkManager (necessary to configure internet graphically in GNOME and "
+"KDE)"
+msgstr ""
+
+#: lib/user_interaction.py:427
+msgid "Select one network interface to configure"
+msgstr ""
+
+#: lib/user_interaction.py:440
+msgid ""
+"Select which mode to configure for \"{}\" or skip to use default mode \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:445
+msgid "Enter the IP and subnet for {} (example: 192.168.0.5/24): "
+msgstr ""
+
+#: lib/user_interaction.py:460
+msgid "Enter your gateway (router) IP address or leave blank for none: "
+msgstr ""
+
+#: lib/user_interaction.py:475
+msgid "Enter your DNS servers (space separated, blank for none): "
+msgstr ""
+
+#: lib/user_interaction.py:509
+msgid "Select which filesystem your main partition should use"
+msgstr ""
+
+#: lib/user_interaction.py:555
+msgid "Current partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:606
+msgid ""
+"Select what to do with\n"
+"{}"
+msgstr ""
+
+#: lib/user_interaction.py:623 lib/user_interaction.py:708
+msgid "Enter a desired filesystem type for the partition"
+msgstr ""
+
+#: lib/user_interaction.py:625
+msgid "Enter the start sector (percentage or block number, default: {}): "
+msgstr ""
+
+#: lib/user_interaction.py:634
+msgid ""
+"Enter the end sector of the partition (percentage or block number, ex: {}): "
+"\""
+msgstr ""
+
+#: lib/user_interaction.py:660
+msgid "{} contains queued partitions, this will remove those, are you sure?"
+msgstr ""
+
+#: lib/user_interaction.py:673
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partitions to delete"
+msgstr ""
+
+#: lib/user_interaction.py:681
+msgid ""
+"{}\n"
+"\n"
+"Select by index which partition to mount where"
+msgstr ""
+
+#: lib/user_interaction.py:685
+msgid ""
+" * Partition mount-points are relative to inside the installation, the boot "
+"would be /boot as an example."
+msgstr ""
+
+#: lib/user_interaction.py:686
+msgid "Select where to mount partition (leave blank to remove mountpoint): "
+msgstr ""
+
+#: lib/user_interaction.py:697
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mask for formatting"
+msgstr ""
+
+#: lib/user_interaction.py:716
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as encrypted"
+msgstr ""
+
+#: lib/user_interaction.py:724
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to mark as bootable"
+msgstr ""
+
+#: lib/user_interaction.py:731
+msgid ""
+"{}\n"
+"\n"
+"Select which partition to set a filesystem on"
+msgstr ""
+
+#: lib/user_interaction.py:738
+msgid "Enter a desired filesystem type for the partition: "
+msgstr ""
+
+#: lib/user_interaction.py:759
+msgid "Select archinstall language"
+msgstr ""
+
+#: lib/user_interaction.py:764
+msgid "Wipe all selected drives and use a best-effort default partition layout"
+msgstr ""
+
+#: lib/user_interaction.py:765
+msgid ""
+"Select what to do with each individual drive (followed by partition usage)"
+msgstr ""
+
+#: lib/user_interaction.py:768
+msgid "Select what you wish to do with the selected block devices"
+msgstr ""
+
+#: lib/user_interaction.py:821
+msgid ""
+"This is a list of pre-programmed profiles, they might make it easier to "
+"install things like desktop environments"
+msgstr ""
+
+#: lib/user_interaction.py:846
+msgid "Select Keyboard layout"
+msgstr ""
+
+#: lib/user_interaction.py:861
+msgid "Select one of the regions to download packages from"
+msgstr ""
+
+#: lib/user_interaction.py:883
+msgid "Select one or more hard drives to use and configure"
+msgstr ""
+
+#: lib/user_interaction.py:910
+msgid ""
+"For the best compatibility with your AMD hardware, you may want to use "
+"either the all open-source or AMD / ATI options."
+msgstr ""
+
+#: lib/user_interaction.py:912
+msgid ""
+"For the best compatibility with your Intel hardware, you may want to use "
+"either the all open-source or Intel options.\n"
+msgstr ""
+
+#: lib/user_interaction.py:914
+msgid ""
+"For the best compatibility with your Nvidia hardware, you may want to use "
+"the Nvidia proprietary driver.\n"
+msgstr ""
+
+#: lib/user_interaction.py:917
+msgid ""
+"\n"
+"\n"
+"Select a graphics driver or leave blank to install all open-source drivers"
+msgstr ""
+
+#: lib/user_interaction.py:921
+msgid "All open-source (default)"
+msgstr ""
+
+#: lib/user_interaction.py:940
+msgid "Choose which kernels to use or leave blank for default \"{}\""
+msgstr ""
+
+#: lib/user_interaction.py:954
+msgid "Choose which locale language to use"
+msgstr ""
+
+#: lib/user_interaction.py:968
+msgid "Choose which locale encoding to use"
+msgstr ""
+
+#: lib/user_interaction.py:1009
+msgid "Select one of the values shown below: "
+msgstr ""
+
+#: lib/user_interaction.py:1050
+msgid "Select one or more of the options below: "
+msgstr ""
+
+#: lib/menu/selection_menu.py:116
+msgid "Archinstall language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:122
+msgid "Select keyboard layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:125
+msgid "Select mirror region"
+msgstr ""
+
+#: lib/menu/selection_menu.py:130
+msgid "Select locale language"
+msgstr ""
+
+#: lib/menu/selection_menu.py:132
+msgid "Select locale encoding"
+msgstr ""
+
+#: lib/menu/selection_menu.py:135
+msgid "Select harddrives"
+msgstr ""
+
+#: lib/menu/selection_menu.py:139
+msgid "Select disk layout"
+msgstr ""
+
+#: lib/menu/selection_menu.py:147
+msgid "Set encryption password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:153
+msgid "Use swap"
+msgstr ""
+
+#: lib/menu/selection_menu.py:158
+msgid "Select bootloader"
+msgstr ""
+
+#: lib/menu/selection_menu.py:164
+msgid "Set root password"
+msgstr ""
+
+#: lib/menu/selection_menu.py:169
+msgid "Specify superuser account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:175
+msgid "Specify user account"
+msgstr ""
+
+#: lib/menu/selection_menu.py:181
+msgid "Specify profile"
+msgstr ""
+
+#: lib/menu/selection_menu.py:186
+msgid "Select audio"
+msgstr ""
+
+#: lib/menu/selection_menu.py:190
+msgid "Select kernels"
+msgstr ""
+
+#: lib/menu/selection_menu.py:195
+msgid "Additional packages to install"
+msgstr ""
+
+#: lib/menu/selection_menu.py:200
+msgid "Configure network"
+msgstr ""
+
+#: lib/menu/selection_menu.py:208
+msgid "Set automatic time sync (NTP)"
+msgstr ""
+
+#: lib/user_interaction.py:759 lib/menu/selection_menu.py:116
+msgid "Select Archinstall language"
+msgstr ""
+
+#~ msgid "this is a test string"
+#~ msgstr "Questo e un esempio"
diff --git a/archinstall/locales/languages.json b/archinstall/locales/languages.json
new file mode 100644
index 00000000..c649e346
--- /dev/null
+++ b/archinstall/locales/languages.json
@@ -0,0 +1,184 @@
+[{"abbr": "aa", "lang": "Afar"},
+ {"abbr": "ab", "lang": "Abkhazian"},
+ {"abbr": "af", "lang": "Afrikaans"},
+ {"abbr": "ak", "lang": "Akan"},
+ {"abbr": "am", "lang": "Amharic"},
+ {"abbr": "ar", "lang": "Arabic"},
+ {"abbr": "an", "lang": "Aragonese"},
+ {"abbr": "as", "lang": "Assamese"},
+ {"abbr": "av", "lang": "Avaric"},
+ {"abbr": "ae", "lang": "Avestan"},
+ {"abbr": "ay", "lang": "Aymara"},
+ {"abbr": "az", "lang": "Azerbaijani"},
+ {"abbr": "ba", "lang": "Bashkir"},
+ {"abbr": "bm", "lang": "Bambara"},
+ {"abbr": "be", "lang": "Belarusian"},
+ {"abbr": "bn", "lang": "Bengali"},
+ {"abbr": "bi", "lang": "Bislama"},
+ {"abbr": "bo", "lang": "Tibetan"},
+ {"abbr": "bs", "lang": "Bosnian"},
+ {"abbr": "br", "lang": "Breton"},
+ {"abbr": "bg", "lang": "Bulgarian"},
+ {"abbr": "ca", "lang": "Catalan"},
+ {"abbr": "cs", "lang": "Czech"},
+ {"abbr": "ch", "lang": "Chamorro"},
+ {"abbr": "ce", "lang": "Chechen"},
+ {"abbr": "cu", "lang": "Church Slavic"},
+ {"abbr": "cv", "lang": "Chuvash"},
+ {"abbr": "kw", "lang": "Cornish"},
+ {"abbr": "co", "lang": "Corsican"},
+ {"abbr": "cr", "lang": "Cree"},
+ {"abbr": "cy", "lang": "Welsh"},
+ {"abbr": "da", "lang": "Danish"},
+ {"abbr": "de", "lang": "German"},
+ {"abbr": "dv", "lang": "Dhivehi"},
+ {"abbr": "dz", "lang": "Dzongkha"},
+ {"abbr": "el", "lang": "Modern Greek (1453-)"},
+ {"abbr": "en", "lang": "English"},
+ {"abbr": "eo", "lang": "Esperanto"},
+ {"abbr": "et", "lang": "Estonian"},
+ {"abbr": "eu", "lang": "Basque"},
+ {"abbr": "ee", "lang": "Ewe"},
+ {"abbr": "fo", "lang": "Faroese"},
+ {"abbr": "fa", "lang": "Persian"},
+ {"abbr": "fj", "lang": "Fijian"},
+ {"abbr": "fi", "lang": "Finnish"},
+ {"abbr": "fr", "lang": "French"},
+ {"abbr": "fy", "lang": "Western Frisian"},
+ {"abbr": "ff", "lang": "Fulah"},
+ {"abbr": "gd", "lang": "Scottish Gaelic"},
+ {"abbr": "ga", "lang": "Irish"},
+ {"abbr": "gl", "lang": "Galician"},
+ {"abbr": "gv", "lang": "Manx"},
+ {"abbr": "gn", "lang": "Guarani"},
+ {"abbr": "gu", "lang": "Gujarati"},
+ {"abbr": "ht", "lang": "Haitian"},
+ {"abbr": "ha", "lang": "Hausa"},
+ {"abbr": "sh", "lang": "Serbo-Croatian"},
+ {"abbr": "he", "lang": "Hebrew"},
+ {"abbr": "hz", "lang": "Herero"},
+ {"abbr": "hi", "lang": "Hindi"},
+ {"abbr": "ho", "lang": "Hiri Motu"},
+ {"abbr": "hr", "lang": "Croatian"},
+ {"abbr": "hu", "lang": "Hungarian"},
+ {"abbr": "hy", "lang": "Armenian"},
+ {"abbr": "ig", "lang": "Igbo"},
+ {"abbr": "io", "lang": "Ido"},
+ {"abbr": "ii", "lang": "Sichuan Yi"},
+ {"abbr": "iu", "lang": "Inuktitut"},
+ {"abbr": "ie", "lang": "Interlingue"},
+ {"abbr": "ia", "lang": "Interlingua (International Auxiliary Language Association)"},
+ {"abbr": "id", "lang": "Indonesian"},
+ {"abbr": "ik", "lang": "Inupiaq"},
+ {"abbr": "is", "lang": "Icelandic"},
+ {"abbr": "it", "lang": "Italian"},
+ {"abbr": "jv", "lang": "Javanese"},
+ {"abbr": "ja", "lang": "Japanese"},
+ {"abbr": "kl", "lang": "Kalaallisut"},
+ {"abbr": "kn", "lang": "Kannada"},
+ {"abbr": "ks", "lang": "Kashmiri"},
+ {"abbr": "ka", "lang": "Georgian"},
+ {"abbr": "kr", "lang": "Kanuri"},
+ {"abbr": "kk", "lang": "Kazakh"},
+ {"abbr": "km", "lang": "Central Khmer"},
+ {"abbr": "ki", "lang": "Kikuyu"},
+ {"abbr": "rw", "lang": "Kinyarwanda"},
+ {"abbr": "ky", "lang": "Kirghiz"},
+ {"abbr": "kv", "lang": "Komi"},
+ {"abbr": "kg", "lang": "Kongo"},
+ {"abbr": "ko", "lang": "Korean"},
+ {"abbr": "kj", "lang": "Kuanyama"},
+ {"abbr": "ku", "lang": "Kurdish"},
+ {"abbr": "lo", "lang": "Lao"},
+ {"abbr": "la", "lang": "Latin"},
+ {"abbr": "lv", "lang": "Latvian"},
+ {"abbr": "li", "lang": "Limburgan"},
+ {"abbr": "ln", "lang": "Lingala"},
+ {"abbr": "lt", "lang": "Lithuanian"},
+ {"abbr": "lb", "lang": "Luxembourgish"},
+ {"abbr": "lu", "lang": "Luba-Katanga"},
+ {"abbr": "lg", "lang": "Ganda"},
+ {"abbr": "mh", "lang": "Marshallese"},
+ {"abbr": "ml", "lang": "Malayalam"},
+ {"abbr": "mr", "lang": "Marathi"},
+ {"abbr": "mk", "lang": "Macedonian"},
+ {"abbr": "mg", "lang": "Malagasy"},
+ {"abbr": "mt", "lang": "Maltese"},
+ {"abbr": "mn", "lang": "Mongolian"},
+ {"abbr": "mi", "lang": "Maori"},
+ {"abbr": "ms", "lang": "Malay (macrolanguage)"},
+ {"abbr": "my", "lang": "Burmese"},
+ {"abbr": "na", "lang": "Nauru"},
+ {"abbr": "nv", "lang": "Navajo"},
+ {"abbr": "nr", "lang": "South Ndebele"},
+ {"abbr": "nd", "lang": "North Ndebele"},
+ {"abbr": "ng", "lang": "Ndonga"},
+ {"abbr": "ne", "lang": "Nepali (macrolanguage)"},
+ {"abbr": "nl", "lang": "Dutch"},
+ {"abbr": "nn", "lang": "Norwegian Nynorsk"},
+ {"abbr": "nb", "lang": "Norwegian Bokmål"},
+ {"abbr": "no", "lang": "Norwegian"},
+ {"abbr": "ny", "lang": "Nyanja"},
+ {"abbr": "oc", "lang": "Occitan (post 1500)"},
+ {"abbr": "oj", "lang": "Ojibwa"},
+ {"abbr": "or", "lang": "Oriya (macrolanguage)"},
+ {"abbr": "om", "lang": "Oromo"},
+ {"abbr": "os", "lang": "Ossetian"},
+ {"abbr": "pa", "lang": "Panjabi"},
+ {"abbr": "pi", "lang": "Pali"},
+ {"abbr": "pl", "lang": "Polish"},
+ {"abbr": "pt", "lang": "Portuguese"},
+ {"abbr": "ps", "lang": "Pushto"},
+ {"abbr": "qu", "lang": "Quechua"},
+ {"abbr": "rm", "lang": "Romansh"},
+ {"abbr": "ro", "lang": "Romanian"},
+ {"abbr": "rn", "lang": "Rundi"},
+ {"abbr": "ru", "lang": "Russian"},
+ {"abbr": "sg", "lang": "Sango"},
+ {"abbr": "sa", "lang": "Sanskrit"},
+ {"abbr": "si", "lang": "Sinhala"},
+ {"abbr": "sk", "lang": "Slovak"},
+ {"abbr": "sl", "lang": "Slovenian"},
+ {"abbr": "se", "lang": "Northern Sami"},
+ {"abbr": "sm", "lang": "Samoan"},
+ {"abbr": "sn", "lang": "Shona"},
+ {"abbr": "sd", "lang": "Sindhi"},
+ {"abbr": "so", "lang": "Somali"},
+ {"abbr": "st", "lang": "Southern Sotho"},
+ {"abbr": "es", "lang": "Spanish"},
+ {"abbr": "sq", "lang": "Albanian"},
+ {"abbr": "sc", "lang": "Sardinian"},
+ {"abbr": "sr", "lang": "Serbian"},
+ {"abbr": "ss", "lang": "Swati"},
+ {"abbr": "su", "lang": "Sundanese"},
+ {"abbr": "sw", "lang": "Swahili (macrolanguage)"},
+ {"abbr": "sv", "lang": "Swedish"},
+ {"abbr": "ty", "lang": "Tahitian"},
+ {"abbr": "ta", "lang": "Tamil"},
+ {"abbr": "tt", "lang": "Tatar"},
+ {"abbr": "te", "lang": "Telugu"},
+ {"abbr": "tg", "lang": "Tajik"},
+ {"abbr": "tl", "lang": "Tagalog"},
+ {"abbr": "th", "lang": "Thai"},
+ {"abbr": "ti", "lang": "Tigrinya"},
+ {"abbr": "to", "lang": "Tonga (Tonga Islands)"},
+ {"abbr": "tn", "lang": "Tswana"},
+ {"abbr": "ts", "lang": "Tsonga"},
+ {"abbr": "tk", "lang": "Turkmen"},
+ {"abbr": "tr", "lang": "Turkish"},
+ {"abbr": "tw", "lang": "Twi"},
+ {"abbr": "ug", "lang": "Uighur"},
+ {"abbr": "uk", "lang": "Ukrainian"},
+ {"abbr": "ur", "lang": "Urdu"},
+ {"abbr": "uz", "lang": "Uzbek"},
+ {"abbr": "ve", "lang": "Venda"},
+ {"abbr": "vi", "lang": "Vietnamese"},
+ {"abbr": "vo", "lang": "Volapük"},
+ {"abbr": "wa", "lang": "Walloon"},
+ {"abbr": "wo", "lang": "Wolof"},
+ {"abbr": "xh", "lang": "Xhosa"},
+ {"abbr": "yi", "lang": "Yiddish"},
+ {"abbr": "yo", "lang": "Yoruba"},
+ {"abbr": "za", "lang": "Zhuang"},
+ {"abbr": "zh", "lang": "Chinese"},
+ {"abbr": "zu", "lang": "Zulu"}] \ No newline at end of file