Merge develop: combine the i18n test fixture with #367

Both batches seed the same block for their English-only additions. One
read and one write now cover the PBS key guidance and the Borg SSH keys
together.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
MacRimi
2026-09-22 19:23:10 +02:00
co-authored by Claude Opus 5
20 changed files with 767 additions and 48 deletions
@@ -115,16 +115,21 @@ class CommandDescriptionsTests(unittest.TestCase):
report["recommendations"].setdefault( report["recommendations"].setdefault(
key, source_report["recommendations"][key]) key, source_report["recommendations"][key])
path.write_text(json.dumps(temporary, ensure_ascii=False)) path.write_text(json.dumps(temporary, ensure_ascii=False))
# Model steady-state generation for the six intentional English-only # Model steady state after the bot fills these intentional new
# Borg additions, in temporary copies only. Keep every other gap visible. # messages; keep repository locales and all other leaves intact.
if lang != "en": if lang != "en":
copied = json.loads(path.read_text()) messages = json.loads(path.read_text())
english = catalog("en")["backup"] english = catalog("en")
for section, key in (("encryption", "pbsHelp"),
("keyfileActions", "pveKeyDescription")):
messages["backup"][section].setdefault(key, english["backup"][section][key])
for key in ("sshUserHelpMessage", "sshKeyHelpMessage", "sshKeySetupTitle", for key in ("sshUserHelpMessage", "sshKeyHelpMessage", "sshKeySetupTitle",
"sshKeySetupHelp", "sshAuthorizedKeyHelp"): "sshKeySetupHelp", "sshAuthorizedKeyHelp"):
copied["backup"]["destinations"].setdefault(key, english["destinations"][key]) messages["backup"]["destinations"].setdefault(
copied["backup"]["actions"].setdefault("prepareSshKey", english["actions"]["prepareSshKey"]) key, english["backup"]["destinations"][key])
path.write_text(json.dumps(copied), encoding="utf-8") messages["backup"]["actions"].setdefault(
"prepareSshKey", english["backup"]["actions"]["prepareSshKey"])
path.write_text(json.dumps(messages, ensure_ascii=False))
before = {p: p.read_bytes() for p in root.glob("*/common.json")} before = {p: p.read_bytes() for p in root.glob("*/common.json")}
argv = [str(SCRIPT), "--source", str(root / "en/common.json"), argv = [str(SCRIPT), "--source", str(root / "en/common.json"),
"--messages-dir", str(root), "--languages", languages, "--sleep", "0"] "--messages-dir", str(root), "--languages", languages, "--sleep", "0"]
@@ -0,0 +1,178 @@
"""Offline actual scheduler gates; never source the administrative script."""
import importlib.util
import json
import os
from pathlib import Path
import shlex
import subprocess
import tempfile
import unittest
ROOT = Path(__file__).resolve().parents[3]
SCHEDULER = ROOT / 'scripts/backup_restore/backup_scheduler.sh'
MESSAGES = {
'pbs': 'No matching PVE vzdump jobs were found for the PBS backend.',
'local': 'No matching PVE vzdump jobs were found for the local archive backend.',
}
HINT = 'Create one first in Datacenter → Backup, then return here to attach.'
def function(text, name):
start = text.index(name + '() {')
return text[start:text.index('\n}', start) + 2] + '\n'
def consumers():
text = SCHEDULER.read_text()
attached = function(text, '_create_job_attached').split(' local pve_prune\n')[0] + '}\n'
# Only the backend/attach selection gate, not ID/config writes or scheduling.
new = function(text, '_create_job')
new = '_create_job() {\n local id=fixture backend on_calendar\n' + new[new.index(' backend=$(dialog'):new.index(' on_calendar=$(dialog')]
new += ' return 42\n}\n'
return attached + new
def fixture(directory, backend='pbs', consumer='attached', rows='', second=None,
locale='en', catalog=None, real_dialog=None):
directory = Path(directory)
(directory / 'xx.json').write_text(json.dumps(catalog or {}))
(directory / 'rows').write_text(rows)
(directory / 'second').write_text(rows if second is None else second)
bindir = directory / 'bin'
bindir.mkdir(exist_ok=True)
# Only jq is executable via PATH; wrapper validates all lookup arguments.
(bindir / 'jq').symlink_to('/usr/bin/jq') if not (bindir / 'jq').exists() else None
translation = function((ROOT / 'scripts/utils.sh').read_text(), 'translate')
filter_code = function((ROOT / 'scripts/backup_restore/lib_host_backup_common.sh').read_text(), 'hb_pve_list_vzdump_jobs_for_backend')
preamble = f'''PATH={shlex.quote(str(bindir))}
LANG_DIR={shlex.quote(str(directory))}
LANGUAGE={shlex.quote(locale)}
FIXTURE={shlex.quote(str(directory))}
BACKEND={backend}
HB_UI_MENU_H=20 HB_UI_MENU_W=84 HB_UI_MENU_LIST=10
command_not_found_handle() {{ printf 'FORBIDDEN:%s\\n' "$*" >> "$FIXTURE/errors"; return 99; }}
jq() {{ [[ "$#" == 6 && "$1" == -r && "$2" == --arg && "$3" == text && "$5" == '.[$text] // empty' && "$6" == "$FIXTURE/xx.json" ]] || {{ printf 'bad jq' >> "$FIXTURE/errors"; return 99; }}; command jq "$@"; }}
head() {{ [[ "$*" == '-1' ]] || return 99; local first; IFS= read -r first; printf '%s\\n' "$first"; while IFS= read -r first; do :; done; }}
hb_pve_list_vzdump_jobs() {{
local file="$FIXTURE/rows" line
[[ -f "$FIXTURE/read" ]] && file="$FIXTURE/second"
printf read >> "$FIXTURE/read"
while IFS= read -r line; do printf '%s\\n' "$line"; done < "$file"
}}
dialog() {{
printf '%s\\0' "$@" >> "$FIXTURE/dialogs"
local title='' kind='' message='' previous='' arg
for arg in "$@"; do
[[ "$previous" == --title ]] && title="$arg"
[[ "$previous" == --msgbox || "$previous" == --menu ]] && message="$arg"
[[ "$arg" == --msgbox || "$arg" == --menu ]] && kind="$arg"
previous="$arg"
done
if [[ "$kind" == --msgbox ]]; then
printf '%s' "$message" > "$FIXTURE/message"
{'command ' + shlex.quote(real_dialog) + ' "$@"' if real_dialog else ':'}
return 0
fi
case "$title" in
"$(translate 'Backend')") printf '%s' "$BACKEND" >&2 ;;
"$(translate 'How to schedule')") printf attach >&2 ;;
"$(translate 'Pick PVE vzdump job')") return 1 ;;
*) printf 'unexpected dialog:%s' "$title" >> "$FIXTURE/errors"; return 99 ;;
esac
}}
'''
return preamble + translation + filter_code + consumers() + f'\nif _create_job{"_attached fixture " + backend if consumer == "attached" else ""}; then rc=0; else rc=$?; fi\nprintf "%s" "$rc" > "$FIXTURE/status"\n'
def run_case(**kwargs):
with tempfile.TemporaryDirectory(prefix='scheduler-') as directory:
code = fixture(directory, **kwargs)
result = subprocess.run(['/bin/bash', '--noprofile', '--norc', '-c', code],
env={'PATH': '/nonexistent', 'LC_ALL': 'C.UTF-8'}, capture_output=True, text=True)
if result.returncode or result.stderr:
raise AssertionError((result.returncode, result.stderr))
p = Path(directory)
if (p / 'errors').exists():
raise AssertionError((p / 'errors').read_text())
return {name: (p / name).read_text() if (p / name).exists() else ''
for name in ('message', 'status', 'dialogs', 'read')}
class SchedulerMessages(unittest.TestCase):
def test_new_whole_message_and_separate_hint(self):
for backend in MESSAGES:
with self.subTest(backend=backend):
result = run_case(backend=backend, consumer='new')
self.assertEqual(result['message'], MESSAGES[backend] + '\n\n' + HINT)
self.assertEqual(result['status'], '1')
def test_lookup_cache_modes_at_both_consumers(self):
shipped = json.loads((ROOT / 'lang/it.json').read_text())
for backend, message in MESSAGES.items():
for consumer in ('attached', 'new'):
for locale, catalog, expected in (
('en', {message: 'ignored'}, message),
('missing', {}, message),
('xx', {'unrelated': 'unrelated'}, message),
('xx', shipped, shipped.get(message, message)),
('xx', {message: 'SYNTHETIC reordered backend: ' + backend},
'SYNTHETIC reordered backend: ' + backend),
):
with self.subTest(backend=backend, consumer=consumer, locale=locale, expected=expected):
result = run_case(backend=backend, consumer=consumer, locale=locale, catalog=catalog)
suffix = '\n\n' + catalog.get(HINT, HINT) if consumer == 'new' else ''
self.assertEqual(result['message'], expected + suffix)
self.assertEqual(result['status'], '1')
def test_nonempty_menus_disabled_and_second_read_empty(self):
for backend, storage in (('pbs', 'pbs'), ('local', 'nfs')):
for count in (1, 3):
rows = ''.join(f'job{i}\tstore{i}\t{storage}\tdaily\t-\t0\n' for i in range(count))
for consumer in ('attached', 'new'):
with self.subTest(backend=backend, count=count, consumer=consumer):
result = run_case(backend=backend, consumer=consumer, rows=rows)
self.assertEqual(result['message'], '')
self.assertEqual(result['status'], '1') # cancel at actual parent picker
for i in range(count):
self.assertIn(f'job{i} · store{i} · daily (disabled)', result['dialogs'])
result = run_case(backend=backend, consumer='new', rows=rows, second='')
self.assertEqual(result['message'], MESSAGES[backend])
self.assertEqual(result['read'], 'readread')
self.assertEqual(result['status'], '1')
def test_actual_filter_types_and_enabled_states(self):
for backend in MESSAGES:
for storage in ('pbs', 'dir', 'nfs', 'cifs', 'zfspool', 'lvmthin', 'btrfs', 'rbd', '-'):
for enabled in ('0', '1'):
with self.subTest(backend=backend, storage=storage, enabled=enabled):
result = run_case(backend=backend, rows=f'job\tstore\t{storage}\tdaily\t-\t{enabled}\n')
matches = storage == 'pbs' if backend == 'pbs' else storage in ('dir', 'nfs', 'cifs', 'zfspool', 'lvmthin', 'btrfs')
self.assertEqual(result['message'], '' if matches else MESSAGES[backend])
if matches:
self.assertEqual('(disabled)' in result['dialogs'], enabled == '0')
def test_borg_excludes_attach_gate(self):
result = run_case(backend='borg', consumer='new')
self.assertEqual(result['status'], '42') # stopped before real schedule/config work
self.assertEqual(result['message'], '')
self.assertEqual(result['read'], '')
self.assertNotIn('How to schedule', result['dialogs'])
def test_actual_offline_extractor_discovers_whole_messages(self):
spec = importlib.util.spec_from_file_location('scheduler_cache_builder', ROOT / '.github/scripts/build_translation_cache.py')
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
discovered = module.extract_translate_texts(ROOT / 'scripts')
for message in MESSAGES.values():
self.assertIn(message, discovered)
def test_attached_whole_message(self):
for backend in MESSAGES:
with self.subTest(backend=backend):
result = run_case(backend=backend)
self.assertEqual(result['message'], MESSAGES[backend])
self.assertEqual(result['status'], '1')
if __name__ == '__main__':
unittest.main()
+18 -5
View File
@@ -618,8 +618,11 @@ function PbsKeyfileActions({ pbsRepository }: { pbsRepository?: string }) {
<div className="flex-1 space-y-1"> <div className="flex-1 space-y-1">
<div className="font-semibold text-emerald-300">{t("backup.keyfileActions.pveKeyDetected")}</div> <div className="font-semibold text-emerald-300">{t("backup.keyfileActions.pveKeyDetected")}</div>
<div className="text-muted-foreground"> <div className="text-muted-foreground">
{t("backup.keyfileActions.pveKeyDescriptionBefore")} <code className="font-mono text-[10.5px]">{pveMatch.name}</code> {t("backup.keyfileActions.pveKeyDescriptionMiddle")}{" "} {t("backup.keyfileActions.pveKeyDescription").split(/(\{storage\}|\{path\})/).map((part, index) =>
<code className="font-mono text-[10.5px] break-all">{pveMatch.path}</code>. {t("backup.keyfileActions.pveKeyDescriptionAfter")} part === "{storage}" ? <code key={index} className="font-mono text-[10.5px] break-all">{pveMatch.name}</code>
: part === "{path}" ? <code key={index} className="font-mono text-[10.5px] break-all">{pveMatch.path}</code>
: part
)}
</div> </div>
</div> </div>
</div> </div>
@@ -2131,8 +2134,11 @@ function InspectModal({
<div className="flex-1 space-y-1"> <div className="flex-1 space-y-1">
<div className="font-semibold text-emerald-300">{t("backup.keyfileActions.pveKeyDetected")}</div> <div className="font-semibold text-emerald-300">{t("backup.keyfileActions.pveKeyDetected")}</div>
<div className="text-muted-foreground"> <div className="text-muted-foreground">
{t("backup.keyfileActions.pveKeyDescriptionBefore")} <code className="font-mono text-[10.5px]">{pveMatchInspect.name}</code> {t("backup.keyfileActions.pveKeyDescriptionMiddle")}{" "} {t("backup.keyfileActions.pveKeyDescription").split(/(\{storage\}|\{path\})/).map((part, index) =>
<code className="font-mono text-[10.5px] break-all">{pveMatchInspect.path}</code>. {t("backup.keyfileActions.pveKeyDescriptionAfter")} part === "{storage}" ? <code key={index} className="font-mono text-[10.5px] break-all">{pveMatchInspect.name}</code>
: part === "{path}" ? <code key={index} className="font-mono text-[10.5px] break-all">{pveMatchInspect.path}</code>
: part
)}
</div> </div>
</div> </div>
</div> </div>
@@ -3879,7 +3885,14 @@ function CreateJobDialog({
{t("backup.encryption.encryptBackups")} {t("backup.encryption.encryptBackups")}
</div> </div>
<p className="text-[11px] text-muted-foreground mt-1"> <p className="text-[11px] text-muted-foreground mt-1">
{t("backup.encryption.pbsHelpBefore")} <code className="font-mono">--keyfile</code> {t("backup.encryption.pbsHelpMiddle")} <code className="font-mono">proxmox-backup-client backup</code>. {t("backup.encryption.pbsHelpAfter")} <code className="font-mono">/usr/local/share/proxmenux/pbs-key.conf</code> (chmod 0600) {t("backup.encryption.pbsHelpEnd")} {t("backup.encryption.pbsHelp").split(/(\{keyfile\}|\{option\}|\{mode\})/).map((part, index) => {
const literals: Record<string, string> = {
"{keyfile}": "/usr/local/share/proxmenux/pbs-key.conf",
"{option}": "--keyfile",
"{mode}": "0600",
}
return literals[part] ? <code key={index} className="font-mono break-all">{literals[part]}</code> : part
})}
</p> </p>
</div> </div>
</label> </label>
+2
View File
@@ -4024,6 +4024,7 @@
"passphraseNotSaved": "Passphrase is not saved.", "passphraseNotSaved": "Passphrase is not saved.",
"passphraseSaved": "Passphrase saved", "passphraseSaved": "Passphrase saved",
"pbsHelpAfter": "for encrypted PBS restores.", "pbsHelpAfter": "for encrypted PBS restores.",
"pbsHelp": "Monitor uses {keyfile} with {option} for encrypted PBS backups and restores. The keyfile is stored with mode {mode}. Keep a safe copy outside this host.",
"pbsHelpBefore": "PBS encryption uses", "pbsHelpBefore": "PBS encryption uses",
"pbsHelpEnd": "Keep a safe copy outside this host.", "pbsHelpEnd": "Keep a safe copy outside this host.",
"pbsHelpMiddle": "as the keyfile", "pbsHelpMiddle": "as the keyfile",
@@ -4218,6 +4219,7 @@
"orUploadFromMachine": "or upload one from this machine.", "orUploadFromMachine": "or upload one from this machine.",
"orUploadOwn": "or upload your own keyfile.", "orUploadOwn": "or upload your own keyfile.",
"pveKeyDescriptionAfter": "and can be reused by Monitor.", "pveKeyDescriptionAfter": "and can be reused by Monitor.",
"pveKeyDescription": "PVE storage {storage} has a keyfile at {path}. You can import it into Monitor.",
"pveKeyDescriptionBefore": "A PVE key exists at", "pveKeyDescriptionBefore": "A PVE key exists at",
"pveKeyDescriptionMiddle": "It matches PVE storage encryption", "pveKeyDescriptionMiddle": "It matches PVE storage encryption",
"pveKeyDetected": "PVE key detected", "pveKeyDetected": "PVE key detected",
+110
View File
@@ -0,0 +1,110 @@
// Offline regression: execute the actual message JSX and provider lookup.
// Run with Node 22+, NODE_PATH pointing to a TypeScript installation.
const assert = require('node:assert/strict')
const fs = require('node:fs')
const path = require('node:path')
const vm = require('node:vm')
const test = require('node:test')
const ts = require('typescript')
const root = path.resolve(__dirname, '..')
const source = fs.readFileSync(path.join(root, 'components/host-backup.tsx'), 'utf8')
const provider = fs.readFileSync(path.join(root, 'lib/i18n/provider.tsx'), 'utf8')
const en = JSON.parse(fs.readFileSync(path.join(root, 'messages/en/common.json')))
const ast = ts.createSourceFile('host-backup.tsx', source, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX)
function compile(text) {
return ts.transpileModule(text, { compilerOptions: { jsx: ts.JsxEmit.React, module: ts.ModuleKind.CommonJS } }).outputText
}
function translator(locale) {
const pure = provider.slice(provider.indexOf('function getMessage('), provider.indexOf('export function I18nProvider'))
const callback = provider.slice(provider.indexOf('(key: string, params?: TranslationParams) => {', provider.indexOf('const t = useCallback')), provider.indexOf('\n },', provider.indexOf('const t = useCallback')) + 6)
return vm.runInNewContext(compile(`${pure}\nconst t = ${callback}; t`), { MESSAGE_CATALOG: { en, fixture: locale }, language: 'fixture' })
}
const React = { createElement: (tag, props, ...children) => ({ tag, props, children }) }
function messages(marker) {
const found = []
function visit(node) {
if (ts.isJsxElement(node) && ['p', 'div'].includes(node.openingElement.tagName.getText(ast)) && node.getText(ast).includes(marker)) {
let nested = false
function check(child) {
if (ts.isJsxElement(child) && ['p', 'div'].includes(child.openingElement.tagName.getText(ast)) && child.getText(ast).includes(marker)) nested = true
ts.forEachChild(child, check)
}
node.children.forEach(check)
if (!nested) found.push(node.getText(ast))
}
ts.forEachChild(node, visit)
}
visit(ast)
return found
}
function render(jsx, locale = {}, match = { name: 'STORAGE<&>', path: '/etc/pve/priv/storage/DIFFERENT<&>.enc' }) {
return vm.runInNewContext(compile(`const result = (${jsx}); result`), { React, t: translator(locale), pveMatch: match, pveMatchInspect: match })
}
function text(node) {
if (Array.isArray(node)) return node.map(text).join('')
if (node == null || typeof node === 'boolean') return ''
return typeof node === 'object' ? text(node.children) : String(node)
}
function codes(node) {
if (Array.isArray(node)) return node.flatMap(codes)
if (!node || typeof node !== 'object') return []
return node.tag === 'code' ? [node] : codes(node.children)
}
const help = 'Monitor uses /usr/local/share/proxmenux/pbs-key.conf with --keyfile for encrypted PBS backups and restores. The keyfile is stored with mode 0600. Keep a safe copy outside this host.'
test('PBS help is a complete message with unconditional missing-key English fallback', () => {
const jsx = messages('backup.encryption.pbsHelp')
assert.equal(jsx.length, 1)
const output = render(jsx[0])
assert.equal(text(output), help)
assert.deepEqual(codes(output).map(text), ['/usr/local/share/proxmenux/pbs-key.conf', '--keyfile', '0600'])
})
test('both PVE dialogs distinguish storage from path with missing-key fallback', () => {
const jsx = messages('backup.keyfileActions.pveKeyDescription')
assert.equal(jsx.length, 2)
for (const message of jsx) {
const output = render(message)
assert.equal(text(output), 'PVE storage STORAGE<&> has a keyfile at /etc/pve/priv/storage/DIFFERENT<&>.enc. You can import it into Monitor.')
assert.deepEqual(codes(output).map(text), ['STORAGE<&>', '/etc/pve/priv/storage/DIFFERENT<&>.enc'])
assert.match(codes(output)[1].props.className, /break-all/)
}
})
test('whole-message translations can reorder rich placeholders in all three consumers', () => {
const locale = { backup: {
encryption: { pbsHelp: 'Mode {mode}; option {option}; file {keyfile}.' },
keyfileActions: { pveKeyDescription: 'At {path}: key for {storage}.' },
} }
const helpOutput = render(messages('backup.encryption.pbsHelp')[0], locale)
assert.equal(text(helpOutput), 'Mode 0600; option --keyfile; file /usr/local/share/proxmenux/pbs-key.conf.')
assert.deepEqual(codes(helpOutput).map(text), ['0600', '--keyfile', '/usr/local/share/proxmenux/pbs-key.conf'])
for (const jsx of messages('backup.keyfileActions.pveKeyDescription')) {
const output = render(jsx, locale)
assert.equal(text(output), 'At /etc/pve/priv/storage/DIFFERENT<&>.enc: key for STORAGE<&>.')
assert.deepEqual(codes(output).map(text), ['/etc/pve/priv/storage/DIFFERENT<&>.enc', 'STORAGE<&>'])
}
})
test('shipped locales fall back to complete guidance without changing their catalogs', () => {
for (const lang of fs.readdirSync(path.join(root, 'messages')).filter(name => fs.statSync(path.join(root, 'messages', name)).isDirectory())) {
const locale = JSON.parse(fs.readFileSync(path.join(root, 'messages', lang, 'common.json')))
for (const jsx of messages('backup.keyfileActions.pveKeyDescription')) assert.ok(text(render(jsx, locale)).includes('STORAGE<&>'))
assert.ok(text(render(messages('backup.encryption.pbsHelp')[0], locale)).includes('--keyfile'))
}
})
test('both discovery consumers retain matching-only selection and absent handling', () => {
for (const [name, input] of [['pveMatch', 'pveDiscover'], ['pveMatchInspect', 'pveDiscoverInspect']]) {
let initializer
function visit(node) {
if (ts.isVariableDeclaration(node) && node.name.getText(ast) === name) initializer = node.initializer.getText(ast)
ts.forEachChild(node, visit)
}
visit(ast)
assert.ok(initializer)
for (const data of [undefined, { entries: [] }, { entries: [{ matches_repository: false }] }]) {
assert.equal(vm.runInNewContext(compile(`const result = ${initializer}; result`), { [input]: data }), null)
}
const match = { name: 'chosen', path: '/chosen.enc', matches_repository: true }
assert.equal(vm.runInNewContext(compile(`const result = ${initializer}; result`), { [input]: { entries: [{ matches_repository: false }, match] } }), match)
assert.ok(source.includes(`{${name} && (`))
assert.ok(source.includes(`setImportPath(${name}.path)`))
}
})
module.exports = { messages, render, text, codes }
+3
View File
@@ -120,6 +120,7 @@
"ACL Status:": "ACL-Status:", "ACL Status:": "ACL-Status:",
"ACL permissions applied for local access for user:": "ACL-Berechtigungen für lokalen Zugriff für Benutzer angewendet:", "ACL permissions applied for local access for user:": "ACL-Berechtigungen für lokalen Zugriff für Benutzer angewendet:",
"ADVANCED SETTINGS COMPLETE": "ERWEITERTE EINSTELLUNGEN ABGESCHLOSSEN", "ADVANCED SETTINGS COMPLETE": "ERWEITERTE EINSTELLUNGEN ABGESCHLOSSEN",
"AI / Coding & Dev-Tools": "KI / Codierung und Entwicklungstools",
"ALL DATA ON": "ALLE DATEN EIN", "ALL DATA ON": "ALLE DATEN EIN",
"ALL DATA ON THIS DISK WILL BE PERMANENTLY LOST!": "ALLE DATEN AUF DIESER Diskette gehen dauerhaft verloren!", "ALL DATA ON THIS DISK WILL BE PERMANENTLY LOST!": "ALLE DATEN AUF DIESER Diskette gehen dauerhaft verloren!",
"ALL Utilities": "ALLE Dienstprogramme", "ALL Utilities": "ALLE Dienstprogramme",
@@ -2448,6 +2449,7 @@
"HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One ist ein Community-Image, das Docker im Container ausführt. Der LXC bleibt unprivilegiert, aber die inneren AppArmor-Profile sind möglicherweise nicht verfügbar. Der erste Start lädt Home Assistant Core und seine Add-ons herunter. Wenn die Überprüfung fehlschlägt, werden die CT und / mnt / Daten zur Diagnose aufbewahrt.", "HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One ist ein Community-Image, das Docker im Container ausführt. Der LXC bleibt unprivilegiert, aber die inneren AppArmor-Profile sind möglicherweise nicht verfügbar. Der erste Start lädt Home Assistant Core und seine Add-ons herunter. Wenn die Überprüfung fehlschlägt, werden die CT und / mnt / Daten zur Diagnose aufbewahrt.",
"HAOS One profile declined": "HAOS One-Profil rückläufig", "HAOS One profile declined": "HAOS One-Profil rückläufig",
"HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires ein unprivilegiertes unmanaged LXC mit Nesting und Keyctl, 2 Kernen, 2048 MB RAM, Rootfs von mindestens 12 GB und /mnt / Daten von mindestens 16 GB auf einem Containervolumen, das in Backups enthalten ist", "HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires ein unprivilegiertes unmanaged LXC mit Nesting und Keyctl, 2 Kernen, 2048 MB RAM, Rootfs von mindestens 12 GB und /mnt / Daten von mindestens 16 GB auf einem Containervolumen, das in Backups enthalten ist",
"HTML5 Network Speed Test Server.": "HTML5-Netzwerkgeschwindigkeitstestserver.",
"HTTP service check without a saved URL": "HTTP Service Check ohne gespeicherte URL", "HTTP service check without a saved URL": "HTTP Service Check ohne gespeicherte URL",
"Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emuliert Philips Hue API zu anderen Home Automation Gateways wie einem Amazon Echo / Dot Gen 1 (Gen 2 hat Probleme bei der Erkennung von Ha-Bridge) oder anderen Systemen, die Philips Hue unterstützen. Die Bridge verarbeitet grundlegende Befehle wie Ein-, Aus- und Helligkeitsbefehle des Farbtonprotokolls. Diese Brücke kann die meisten Geräte mit einer bestimmten API steuern.", "Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emuliert Philips Hue API zu anderen Home Automation Gateways wie einem Amazon Echo / Dot Gen 1 (Gen 2 hat Probleme bei der Erkennung von Ha-Bridge) oder anderen Systemen, die Philips Hue unterstützen. Die Bridge verarbeitet grundlegende Befehle wie Ein-, Aus- und Helligkeitsbefehle des Farbtonprotokolls. Diese Brücke kann die meisten Geräte mit einer bestimmten API steuern.",
"HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake ist ein Open-Source-Tool, das von Freiwilligen entwickelt wurde, um Videos aus fast jedem Format in eine Auswahl moderner, weithin unterstützter Codecs zu konvertieren.", "HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake ist ein Open-Source-Tool, das von Freiwilligen entwickelt wurde, um Videos aus fast jedem Format in eine Auswahl moderner, weithin unterstützter Codecs zu konvertieren.",
@@ -5590,6 +5592,7 @@
"Supervisor reports no connectivity; retrying to get versions and install components": "Supervisor meldet keine Konnektivität; erneuter Versuch, Versionen zu erhalten und Komponenten zu installieren", "Supervisor reports no connectivity; retrying to get versions and install components": "Supervisor meldet keine Konnektivität; erneuter Versuch, Versionen zu erhalten und Komponenten zu installieren",
"Supported formats: .img, .qcow2, .vmdk, .raw": "Unterstützte Formate: .img, .qcow2, .vmdk, .raw", "Supported formats: .img, .qcow2, .vmdk, .raw": "Unterstützte Formate: .img, .qcow2, .vmdk, .raw",
"Swap": "Swap", "Swap": "Swap",
"Swap in MB": "In MB tauschen",
"Swap partition detected": "Swap-Partition erkannt", "Swap partition detected": "Swap-Partition erkannt",
"Swappiness configuration created successfully": "Swappiness-Konfiguration erfolgreich erstellt", "Swappiness configuration created successfully": "Swappiness-Konfiguration erfolgreich erstellt",
"Swing Music is a beautifully designed, self-hosted music streaming server. Like a cooler Spotify ... but bring your own music.": "Swing Music ist ein wunderschön gestalteter, selbst gehosteter Musik-Streaming-Server. Wie ein cooler Spotify ... aber bringen Sie Ihre eigene Musik.", "Swing Music is a beautifully designed, self-hosted music streaming server. Like a cooler Spotify ... but bring your own music.": "Swing Music ist ein wunderschön gestalteter, selbst gehosteter Musik-Streaming-Server. Wie ein cooler Spotify ... aber bringen Sie Ihre eigene Musik.",
+51
View File
@@ -37,6 +37,7 @@
"/var/lib/vz/dump (Proxmox default)": "/var/lib/vz/dump (predeterminado de Proxmox)", "/var/lib/vz/dump (Proxmox default)": "/var/lib/vz/dump (predeterminado de Proxmox)",
"1777 = sticky bit + rwx for all. No shared group needed.": "1777 = sticky bit + rwx para todos. No se necesita un grupo compartido.", "1777 = sticky bit + rwx for all. No shared group needed.": "1777 = sticky bit + rwx para todos. No se necesita un grupo compartido.",
"====== PVE UPDATE COMPLETED ======": "====== ACTUALIZACIÓN PVE COMPLETADA ======", "====== PVE UPDATE COMPLETED ======": "====== ACTUALIZACIÓN PVE COMPLETADA ======",
"A GTK Broadway web UI for libvirt and virt-manager.": "una interfaz de usuario web GTK Broadway para libvirt y virt-manager.",
"A Personal Relationship Management tool to help you document your social life.": "Una relación personal Herramienta de gestión para ayudarte a documentar tu vida social.", "A Personal Relationship Management tool to help you document your social life.": "Una relación personal Herramienta de gestión para ayudarte a documentar tu vida social.",
"A VirtIO ISO already exists. Do you want to overwrite it?": "Ya existe una ISO VirtIO. ¿Quieres sobrescribirla?", "A VirtIO ISO already exists. Do you want to overwrite it?": "Ya existe una ISO VirtIO. ¿Quieres sobrescribirla?",
"A ZFS pool with this name already exists.": "Ya existe un grupo ZFS con este nombre.", "A ZFS pool with this name already exists.": "Ya existe un grupo ZFS con este nombre.",
@@ -252,6 +253,9 @@
"Additional audio function(s) to be added": "Funciones de audio adicionales que se agregarán", "Additional audio function(s) to be added": "Funciones de audio adicionales que se agregarán",
"Additional media/GPU GIDs, comma-separated": "GID de medios/GPU adicionales, separados por coma", "Additional media/GPU GIDs, comma-separated": "GID de medios/GPU adicionales, separados por coma",
"Additional paths for": "Rutas adicionales para", "Additional paths for": "Rutas adicionales para",
"Address of the Compose file": "dirección del archivo de redacción",
"Address to reach Pydio Cells (https://domain or https://IP:8080)": "Dirección para llegar a Pydio Cells (https://dominio o https://IP:8080)",
"Address used to reach wallabag (http://IP or https://wallabag.example.com)": "Dirección utilizada para llegar a wallabag (http://IP o https://wallabag.example.com)",
"Addresses to update: ipv4, ipv6 or both (uses an external service)": "Direcciones para actualizar: ipv4, ipv6 o ambos (utiliza un servicio externo)", "Addresses to update: ipv4, ipv6 or both (uses an external service)": "Direcciones para actualizar: ipv4, ipv6 o ambos (utiliza un servicio externo)",
"Adguardhome Sync web interface": "Interfaz web Adguardhome Sync", "Adguardhome Sync web interface": "Interfaz web Adguardhome Sync",
"Adguardhome-sync is a tool to synchronize AdGuardHome config to replica instances.": "Adguardhome-sync es una herramienta para sincronizar AdGuardHome config a replicar instancias.", "Adguardhome-sync is a tool to synchronize AdGuardHome config to replica instances.": "Adguardhome-sync es una herramienta para sincronizar AdGuardHome config a replicar instancias.",
@@ -845,6 +849,7 @@
"Cloning Lynis from GitHub...": "Clonando Lynis desde GitHub...", "Cloning Lynis from GitHub...": "Clonando Lynis desde GitHub...",
"Cloning and applying NVIDIA patch (keylase/nvidia-patch)...": "Clonación y aplicación del parche NVIDIA (keylase/nvidia-patch)...", "Cloning and applying NVIDIA patch (keylase/nvidia-patch)...": "Clonación y aplicación del parche NVIDIA (keylase/nvidia-patch)...",
"Closed": "Cerrado", "Closed": "Cerrado",
"Cloud Database Manager.": "Administrador de bases de datos en la nube.",
"Cloud storage synchronization and FUSE mounts": "Sincronización de almacenamiento en la nube y montajes FUSE", "Cloud storage synchronization and FUSE mounts": "Sincronización de almacenamiento en la nube y montajes FUSE",
"Cloud-Init Automated Installers": "Instaladores automatizados de Cloud-Init", "Cloud-Init Automated Installers": "Instaladores automatizados de Cloud-Init",
"Cluster certificates updated": "Certificados de clúster actualizados", "Cluster certificates updated": "Certificados de clúster actualizados",
@@ -1059,6 +1064,7 @@
"Container recreated": "Container recreated", "Container recreated": "Container recreated",
"Container removed:": "Container removed:", "Container removed:": "Container removed:",
"Container restarted successfully": "El contenedor se reinició correctamente", "Container restarted successfully": "El contenedor se reinició correctamente",
"Container running steadily": "Contenedor funcionando de manera constante",
"Container started": "Container started", "Container started": "Container started",
"Container started successfully": "El contenedor se inició correctamente", "Container started successfully": "El contenedor se inició correctamente",
"Container started successfully.": "El contenedor se inició correctamente.", "Container started successfully.": "El contenedor se inició correctamente.",
@@ -1073,6 +1079,9 @@
"Container with ID": "Contenedor con identificación", "Container with ID": "Contenedor con identificación",
"Container:": "Recipiente:", "Container:": "Recipiente:",
"Containers & Docker": "Containers &amp; Docker", "Containers & Docker": "Containers &amp; Docker",
"Containers returned to their previous state": "Los contenedores regresaron a su estado anterior",
"Containers that are removed:": "Contenedores que se eliminan:",
"Containers that will be created (one LXC per service, on a private network):": "Contenedores que se crearán (un LXC por servicio, en una red privada):",
"Containers:": "Containers:", "Containers:": "Containers:",
"Contains files": "Contiene archivos", "Contains files": "Contiene archivos",
"Contains:": "Contiene:", "Contains:": "Contiene:",
@@ -2440,6 +2449,8 @@
"HA services disabled (configs preserved)": "Servicios HA deshabilitados (configuraciones preservadas)", "HA services disabled (configs preserved)": "Servicios HA deshabilitados (configuraciones preservadas)",
"HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One es una imagen comunitaria que ejecuta Docker dentro del contenedor. El LXC permanece sin privilegios, pero los perfiles de AppArmor internos pueden no estar disponibles. El primer inicio descarga Home Assistant Core y sus complementos. Si el cheque falla, la CT y /mnt/data se mantienen para el diagnóstico.", "HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One es una imagen comunitaria que ejecuta Docker dentro del contenedor. El LXC permanece sin privilegios, pero los perfiles de AppArmor internos pueden no estar disponibles. El primer inicio descarga Home Assistant Core y sus complementos. Si el cheque falla, la CT y /mnt/data se mantienen para el diagnóstico.",
"HAOS One profile declined": "Perfil HAOS One rechazado", "HAOS One profile declined": "Perfil HAOS One rechazado",
"HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires un LXC no administrado y sin privilegios con anidamiento y keyctl, 2 núcleos, 2048 MB de RAM, rootfs de al menos 12 GB y /mnt/data de al menos 16 GB en un volumen contenedor incluido en las copias de seguridad",
"HTML5 Network Speed Test Server.": "Servidor de prueba de velocidad de red HTML5.",
"HTTP service check without a saved URL": "Control de servicio HTTP sin una URL guardada", "HTTP service check without a saved URL": "Control de servicio HTTP sin una URL guardada",
"Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emula Philips Hue API a otras pasarelas de automatización casera como un Amazon Echo/Dot Gen 1 (gen 2 tiene problemas descubriendo ha-bridge) u otros sistemas que apoyan Philips Hue. El puente maneja comandos básicos tales como On, Off y comandos de brillo del protocolo de hue. Este puente puede controlar la mayoría de los dispositivos que tienen una API distinta.", "Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emula Philips Hue API a otras pasarelas de automatización casera como un Amazon Echo/Dot Gen 1 (gen 2 tiene problemas descubriendo ha-bridge) u otros sistemas que apoyan Philips Hue. El puente maneja comandos básicos tales como On, Off y comandos de brillo del protocolo de hue. Este puente puede controlar la mayoría de los dispositivos que tienen una API distinta.",
"HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake es una herramienta de código abierto, construida por voluntarios, para convertir vídeo de casi cualquier formato a una selección de codecs modernos y ampliamente apoyados.", "HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake es una herramienta de código abierto, construida por voluntarios, para convertir vídeo de casi cualquier formato a una selección de codecs modernos y ampliamente apoyados.",
@@ -2483,6 +2494,7 @@
"Home Assistant OS did not pass the Supervisor, Core and Observer checks": "Home Assistant OS no pasó los controles del Supervisor, Core y Observer", "Home Assistant OS did not pass the Supervisor, Core and Observer checks": "Home Assistant OS no pasó los controles del Supervisor, Core y Observer",
"Home Assistant OS ready: Supervisor, Core and Observer running": "Home Assistant OS listo: Supervisor, Core y Observador funcionando", "Home Assistant OS ready: Supervisor, Core and Observer running": "Home Assistant OS listo: Supervisor, Core y Observador funcionando",
"Home Assistant OS was not started: its addresses will be known once Core is running.": "Home Assistant OS no se inició: sus direcciones serán conocidas una vez que Core esté funcionando.", "Home Assistant OS was not started: its addresses will be known once Core is running.": "Home Assistant OS no se inició: sus direcciones serán conocidas una vez que Core esté funcionando.",
"Home Assistant Observer": "Home Assistant Observador",
"Home Automation systems": "Home Sistemas de automatización", "Home Automation systems": "Home Sistemas de automatización",
"Home-Lab-Club logo applied": "Logotipo de Home-Lab-Club aplicado", "Home-Lab-Club logo applied": "Logotipo de Home-Lab-Club aplicado",
"HomeKit support for the impatient.": "Soporte HomeKit para el impaciente.", "HomeKit support for the impatient.": "Soporte HomeKit para el impaciente.",
@@ -2495,6 +2507,7 @@
"Host Config Backup": "Copia de seguridad de la configuración del host", "Host Config Backup": "Copia de seguridad de la configuración del host",
"Host Config Backup / Restore": "Copia de seguridad/restauración de la configuración del host", "Host Config Backup / Restore": "Copia de seguridad/restauración de la configuración del host",
"Host Config Restore": "Restauración de configuración del host", "Host Config Restore": "Restauración de configuración del host",
"Host DVB tuners": "Sintonizadores DVB de host",
"Host Directory": "Directorio de host", "Host Directory": "Directorio de host",
"Host Directory to LXC Mount Point": "Directorio de host para el punto de montaje LXC", "Host Directory to LXC Mount Point": "Directorio de host para el punto de montaje LXC",
"Host Directory:": "Directorio de host:", "Host Directory:": "Directorio de host:",
@@ -2517,6 +2530,12 @@
"Host audio devices": "Dispositivos de audio hosts", "Host audio devices": "Dispositivos de audio hosts",
"Host backup attached to PVE job": "Copia de seguridad del host adjunta al trabajo PVE", "Host backup attached to PVE job": "Copia de seguridad del host adjunta al trabajo PVE",
"Host data is not restored by the backup; confirm it with --acknowledge-external-data": "Los datos de host no son restaurados por el backup; confirme con --acknowledge-external-data", "Host data is not restored by the backup; confirm it with --acknowledge-external-data": "Los datos de host no son restaurados por el backup; confirme con --acknowledge-external-data",
"Host device for /dev/kvm": "Dispositivo host para /dev/kvm",
"Host device for /dev/net/tun": "Dispositivo host para /dev/net/tun",
"Host device for /dev/ttyUSB0": "Dispositivo host para /dev/ttyUSB0",
"Host device for /dev/video10": "Dispositivo host para /dev/video10",
"Host device for /dev/video11": "Dispositivo host para /dev/video11",
"Host device for /dev/video12": "Dispositivo host para /dev/video12",
"Host device node": "Nodo de dispositivo host", "Host device node": "Nodo de dispositivo host",
"Host directories are not included in the backup and are not reverted by a recovery.": "Los directorios host no están incluidos en el backup y no son revertidos por una recuperación.", "Host directories are not included in the backup and are not reverted by a recovery.": "Los directorios host no están incluidos en el backup y no son revertidos por una recuperación.",
"Host directories are not included in the backups and are not reverted by a recovery.": "Los directorios hosts no están incluidos en los backups y no son revertidos por una recuperación.", "Host directories are not included in the backups and are not reverted by a recovery.": "Los directorios hosts no están incluidos en los backups y no son revertidos por una recuperación.",
@@ -2568,6 +2587,7 @@
"ID already in use. Please choose another.": "ID ya en uso. Por favor elige otro.", "ID already in use. Please choose another.": "ID ya en uso. Por favor elige otro.",
"IGDB": "IGDB", "IGDB": "IGDB",
"IGDB Client ID": "IGDB ID de cliente", "IGDB Client ID": "IGDB ID de cliente",
"IGDB Client Secret": "Secreto del cliente IGDB",
"IMPORTANT": "IMPORTANTE", "IMPORTANT": "IMPORTANTE",
"IMPORTANT NOTES:": "NOTAS IMPORTANTES:", "IMPORTANT NOTES:": "NOTAS IMPORTANTES:",
"IMPORTANT PREREQUISITES:": "PRERREQUISITOS IMPORTANTES:", "IMPORTANT PREREQUISITES:": "PRERREQUISITOS IMPORTANTES:",
@@ -2674,6 +2694,7 @@
"Immich GPU profile not validated": "Perfil GPU Immich no validado", "Immich GPU profile not validated": "Perfil GPU Immich no validado",
"Immich configuration cancelled": "Configuración Immich cancelada", "Immich configuration cancelled": "Configuración Immich cancelada",
"Immich device without a validated translation": "dispositivo Immich sin una traducción validada", "Immich device without a validated translation": "dispositivo Immich sin una traducción validada",
"Immich machine learning": "aprendizaje automático Immich",
"Immich requires CUDA compute capability 5.2 or later": "Immich requiere CUDA capacidad de cálculo 5.2 o posterior", "Immich requires CUDA compute capability 5.2 or later": "Immich requiere CUDA capacidad de cálculo 5.2 o posterior",
"Immich runtime without a validated translation": "Immich tiempo de ejecución sin una traducción validada", "Immich runtime without a validated translation": "Immich tiempo de ejecución sin una traducción validada",
"Immich server": "Servidor Immich", "Immich server": "Servidor Immich",
@@ -2969,6 +2990,7 @@
"Invalid configuration path:": "Vía de configuración inválida:", "Invalid configuration path:": "Vía de configuración inválida:",
"Invalid consume/export volumes": "Volumen de consumo/exportación inválidos", "Invalid consume/export volumes": "Volumen de consumo/exportación inválidos",
"Invalid container path:": "Carril de contenedor inválido:", "Invalid container path:": "Carril de contenedor inválido:",
"Invalid credential file path:": "Ruta de archivo credential no válida:",
"Invalid declarative entrypoint": "Punto de entrada declarativo inválido", "Invalid declarative entrypoint": "Punto de entrada declarativo inválido",
"Invalid declarative stop signal": "Parada declarativa inválida signal", "Invalid declarative stop signal": "Parada declarativa inválida signal",
"Invalid declarative working directory": "Directorio de trabajo declarativo inválido", "Invalid declarative working directory": "Directorio de trabajo declarativo inválido",
@@ -3083,6 +3105,7 @@
"Jellyfin did not create encoding.xml before the timeout": "Jellyfin no creó encoding.xml antes del timeout", "Jellyfin did not create encoding.xml before the timeout": "Jellyfin no creó encoding.xml antes del timeout",
"Jellyfin has not created encoding.xml in any declared path": "Jellyfin no ha creado encoding.xml en ningún camino declarado", "Jellyfin has not created encoding.xml in any declared path": "Jellyfin no ha creado encoding.xml en ningún camino declarado",
"Jellyseerr is a free and open source software application for managing requests for your media library.": "Jellyseerr es una aplicación de software libre y de código abierto para gestionar solicitudes para su biblioteca multimedia.", "Jellyseerr is a free and open source software application for managing requests for your media library.": "Jellyseerr es una aplicación de software libre y de código abierto para gestionar solicitudes para su biblioteca multimedia.",
"Jenkins Continuous Integration and Delivery server.": "Servidor de entrega e integración continua de Jenkins.",
"Jenkins unlock": "Jenkins desbloquea", "Jenkins unlock": "Jenkins desbloquea",
"Job ID (letters, numbers, - _)": "ID de trabajo (letras, números, - _)", "Job ID (letters, numbers, - _)": "ID de trabajo (letras, números, - _)",
"Job ID:": "Identificación del trabajo:", "Job ID:": "Identificación del trabajo:",
@@ -3096,6 +3119,7 @@
"Journald configuration updated and service restarted": "Configuración de diario actualizada y servicio reiniciado", "Journald configuration updated and service restarted": "Configuración de diario actualizada y servicio reiniciado",
"Journald optimization completed": "Optimización del diario completada", "Journald optimization completed": "Optimización del diario completada",
"Journald optimized - Max size: 64M": "Diario optimizado - Tamaño máximo: 64M", "Journald optimized - Max size: 64M": "Diario optimizado - Tamaño máximo: 64M",
"Jupyter Lab (token only)": "Jupyter Lab (solo token)",
"KDF:": "KDF:", "KDF:": "KDF:",
"KVM MSR options added to /etc/modprobe.d/kvm.conf": "Opciones de KVM MSR agregadas a /etc/modprobe.d/kvm.conf", "KVM MSR options added to /etc/modprobe.d/kvm.conf": "Opciones de KVM MSR agregadas a /etc/modprobe.d/kvm.conf",
"KVM MSR options ensured in /etc/modprobe.d/kvm.conf": "Opciones de KVM MSR aseguradas en /etc/modprobe.d/kvm.conf", "KVM MSR options ensured in /etc/modprobe.d/kvm.conf": "Opciones de KVM MSR aseguradas en /etc/modprobe.d/kvm.conf",
@@ -3146,6 +3170,7 @@
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita es un programa de pintura profesional GRATIS y de código abierto. Está hecho por artistas que quieren ver herramientas de arte asequibles para todos.", "Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita es un programa de pintura profesional GRATIS y de código abierto. Está hecho por artistas que quieren ver herramientas de arte asequibles para todos.",
"LAN access to the kept containers (stack configuration incomplete):": "Acceso LAN a los contenedores guardados (incompleto de configuración de almacenamiento):", "LAN access to the kept containers (stack configuration incomplete):": "Acceso LAN a los contenedores guardados (incompleto de configuración de almacenamiento):",
"LAN address applied to the application URLs": "Dirección LAN aplicada a las URL de la aplicación", "LAN address applied to the application URLs": "Dirección LAN aplicada a las URL de la aplicación",
"LLM App Development Platform": "Plataforma de desarrollo de aplicaciones LLM",
"LM Studio can run local AI models like gpt-oss, Llama, Gemma, Qwen, and DeepSeek privately on your computer.": "LM Studio puede ejecutar modelos locales de IA como gpt-oss, Llama, Gemma, Qwen y DeepSeek en privado en su computadora.", "LM Studio can run local AI models like gpt-oss, Llama, Gemma, Qwen, and DeepSeek privately on your computer.": "LM Studio puede ejecutar modelos locales de IA como gpt-oss, Llama, Gemma, Qwen y DeepSeek en privado en su computadora.",
"LUNs appear as block devices assignable to VMs": "Los LUN aparecen como dispositivos de bloque asignables a VM", "LUNs appear as block devices assignable to VMs": "Los LUN aparecen como dispositivos de bloque asignables a VM",
"LVM PV headers check completed": "Se completó la verificación de los encabezados fotovoltaicos de LVM", "LVM PV headers check completed": "Se completó la verificación de los encabezados fotovoltaicos de LVM",
@@ -3314,6 +3339,7 @@
"Makefile missing in": "Falta el archivo Makefile", "Makefile missing in": "Falta el archivo Makefile",
"Malformed repository entries cleaned": "Se limpiaron las entradas del repositorio con formato incorrecto", "Malformed repository entries cleaned": "Se limpiaron las entradas del repositorio con formato incorrecto",
"Manage OCI": "Gestionar OCI", "Manage OCI": "Gestionar OCI",
"Manage OCI stack": "Administrar la pila de OCI",
"Manage PBS encryption keyfile": "administrar el archivo de claves de cifrado PBS", "Manage PBS encryption keyfile": "administrar el archivo de claves de cifrado PBS",
"Manage Secure Gateway": "Administrar Secure Gateway", "Manage Secure Gateway": "Administrar Secure Gateway",
"Manage and inspect VM disk images": "Administrar e inspeccionar imágenes de disco de VM", "Manage and inspect VM disk images": "Administrar e inspeccionar imágenes de disco de VM",
@@ -3348,6 +3374,7 @@
"Maximum auto-repair attempts reached (3). Please review the log and run any remaining commands manually.": "Se alcanzó el número máximo de intentos de reparación automática (3). Revise el registro y ejecute los comandos restantes manualmente.", "Maximum auto-repair attempts reached (3). Please review the log and run any remaining commands manually.": "Se alcanzó el número máximo de intentos de reparación automática (3). Revise el registro y ejecute los comandos restantes manualmente.",
"May need to restart terminal": "Puede que sea necesario reiniciar el terminal", "May need to restart terminal": "Puede que sea necesario reiniciar el terminal",
"Media & Streaming": "Media &quot; Streaming", "Media & Streaming": "Media &quot; Streaming",
"Media discovery and request management for Jellyfin, Plex and Emby.": "descubrimiento de medios y gestión de solicitudes para Jellyfin, Plex y Emby.",
"Media library transcoding and health checking, with an internal worker node.": "Transcodificación de la biblioteca de medios y control de salud, con un nodo de trabajador interno.", "Media library transcoding and health checking, with an internal worker node.": "Transcodificación de la biblioteca de medios y control de salud, con un nodo de trabajador interno.",
"Media server": "Servidor multimedia", "Media server": "Servidor multimedia",
"Media server selection cancelled or invalid": "Selección de servidor multimedia cancelada o no válida", "Media server selection cancelled or invalid": "Selección de servidor multimedia cancelada o no válida",
@@ -3362,6 +3389,7 @@
"Memory:": "Memoria:", "Memory:": "Memoria:",
"Memos is a lightweight, self-hosted memo hub. Open Source and Free forever.": "Memos es un centro de memo liviano y auto hospedado. Fuente Abierta y Libre para siempre.", "Memos is a lightweight, self-hosted memo hub. Open Source and Free forever.": "Memos es un centro de memo liviano y auto hospedado. Fuente Abierta y Libre para siempre.",
"Messaging & Queues": "Mensajes &quot; Queues", "Messaging & Queues": "Mensajes &quot; Queues",
"Messenger for the Decentralized Web": "Messenger para la Web descentralizada",
"Method:": "Método:", "Method:": "Método:",
"Microsoft Edge is a cross-platform web browser developed by Microsoft and based on Chromium.": "Microsoft Edge es un navegador web multiplataforma desarrollado por Microsoft y basado en Chromium.", "Microsoft Edge is a cross-platform web browser developed by Microsoft and based on Chromium.": "Microsoft Edge es un navegador web multiplataforma desarrollado por Microsoft y basado en Chromium.",
"Migrate VMs away from node being upgraded": "Migrar las máquinas virtuales fuera del nodo que se está actualizando", "Migrate VMs away from node being upgraded": "Migrar las máquinas virtuales fuera del nodo que se está actualizando",
@@ -3471,12 +3499,14 @@
"Mounting here will hide existing files until unmounted.": "Montar aquí ocultará los archivos existentes hasta que se desmonten.", "Mounting here will hide existing files until unmounted.": "Montar aquí ocultará los archivos existentes hasta que se desmonten.",
"Move that copy offsite (USB, password manager, another host). Delete it from this path when done.": "mueva esa copia fuera del sitio (USB, administrador de contraseñas, otro host).Elimínelo de esta ruta cuando haya terminado.", "Move that copy offsite (USB, password manager, another host). Delete it from this path when done.": "mueva esa copia fuera del sitio (USB, administrador de contraseñas, otro host).Elimínelo de esta ruta cuando haya terminado.",
"Move to target VM (remove from source VM config)": "Mover a la VM de destino (eliminar de la configuración de la VM de origen)", "Move to target VM (remove from source VM config)": "Mover a la VM de destino (eliminar de la configuración de la VM de origen)",
"Moving the data volumes aside": "Mover los volúmenes de datos a un lado",
"Moving the data volumes aside...": "Mover los volúmenes de datos a un lado...", "Moving the data volumes aside...": "Mover los volúmenes de datos a un lado...",
"Multi-container application (experimental)": "Aplicación multicontenedor (experimental)", "Multi-container application (experimental)": "Aplicación multicontenedor (experimental)",
"Multi-line variables are not supported": "No se admiten variables multilíneas", "Multi-line variables are not supported": "No se admiten variables multilíneas",
"Multiple networks or external networks are not yet supported": "Aún no se admiten múltiples redes o redes externas", "Multiple networks or external networks are not yet supported": "Aún no se admiten múltiples redes o redes externas",
"Multiple recovery groups found in PBS. Pick the one that originally created the keyfile:": "Múltiples grupos de recuperación encontrados en PBS. Elige el que creó originalmente el archivo de claves:", "Multiple recovery groups found in PBS. Pick the one that originally created the keyfile:": "Múltiples grupos de recuperación encontrados en PBS. Elige el que creó originalmente el archivo de claves:",
"Multiple rootfs directories were found in this archive. Restore cannot continue automatically.": "Se encontraron varios directorios rootfs en este archivo. La restauración no puede continuar automáticamente.", "Multiple rootfs directories were found in this archive. Restore cannot continue automatically.": "Se encontraron varios directorios rootfs en este archivo. La restauración no puede continuar automáticamente.",
"Music Collection and Streaming Server": "servidor de transmisión y colección de música",
"Music software that transforms your listening experience": "Software de música que transforma tu experiencia de escucha", "Music software that transforms your listening experience": "Software de música que transforma tu experiencia de escucha",
"MySQL Workbench is a unified visual tool for database architects, developers, and DBAs. MySQL Workbench provides data modeling, SQL development, and comprehensive administration tools for server configuration, user administration, backup, and much more.": "MySQL Workbench es una herramienta visual unificada para arquitectos de bases de datos, desarrolladores y DBAs. MySQL Workbench proporciona modelos de datos, desarrollo SQL y herramientas de administración integrales para la configuración del servidor, administración del usuario, backup y mucho más.", "MySQL Workbench is a unified visual tool for database architects, developers, and DBAs. MySQL Workbench provides data modeling, SQL development, and comprehensive administration tools for server configuration, user administration, backup, and much more.": "MySQL Workbench es una herramienta visual unificada para arquitectos de bases de datos, desarrolladores y DBAs. MySQL Workbench proporciona modelos de datos, desarrollo SQL y herramientas de administración integrales para la configuración del servidor, administración del usuario, backup y mucho más.",
"Mylar3 is an automated Comic Book downloader (cbr/cbz) for use with NZB and torrents written in python. It supports SABnzbd, NZBGET, and many torrent clients in addition to DDL.": "Mylar3 es un descargador automatizado Comic Book (cbr/cbz) para uso con NZB y torrents escrito en python. Admite SABnzbd, NZBGET, y muchos clientes torrent además de DDL.", "Mylar3 is an automated Comic Book downloader (cbr/cbz) for use with NZB and torrents written in python. It supports SABnzbd, NZBGET, and many torrent clients in addition to DDL.": "Mylar3 es un descargador automatizado Comic Book (cbr/cbz) para uso con NZB y torrents escrito en python. Admite SABnzbd, NZBGET, y muchos clientes torrent además de DDL.",
@@ -3994,11 +4024,13 @@
"OCI containers require Proxmox VE 9.1 or later.": "Los contenedores OCI requieren Proxmox VE 9.1 o posterior.", "OCI containers require Proxmox VE 9.1 or later.": "Los contenedores OCI requieren Proxmox VE 9.1 o posterior.",
"OCI management": "Gestión OCI", "OCI management": "Gestión OCI",
"OCI management could not be completed. Check the backend status; no additional cleanup has been authorized.": "La gestión OCI no pudo completarse. Comprueba el estado del backend; no se ha autorizado ninguna limpieza adicional.", "OCI management could not be completed. Check the backend status; no additional cleanup has been authorized.": "La gestión OCI no pudo completarse. Comprueba el estado del backend; no se ha autorizado ninguna limpieza adicional.",
"OCI manager Apps (beta)": "Aplicaciones de administrador de OCI (beta)",
"OCI manager Apps is a beta: if something does not work as expected, please report it on GitHub with the application name.": "OCI manager Apps es una beta: si algo no funciona como esperabas, repórtalo en GitHub con el nombre de la aplicación.", "OCI manager Apps is a beta: if something does not work as expected, please report it on GitHub with the application name.": "OCI manager Apps es una beta: si algo no funciona como esperabas, repórtalo en GitHub con el nombre de la aplicación.",
"OCI metadata integrity mismatch": "Desigualdad de la integridad de los metadatos de la OCI", "OCI metadata integrity mismatch": "Desigualdad de la integridad de los metadatos de la OCI",
"OCI metadata too large": "Metadatos demasiado grandes", "OCI metadata too large": "Metadatos demasiado grandes",
"OCI stack management": "Gestión de pilas OCI", "OCI stack management": "Gestión de pilas OCI",
"OCI verification failed:": "La verificación de la OCI falló:", "OCI verification failed:": "La verificación de la OCI falló:",
"OCR language (Tesseract code)": "lenguaje OCR (código Tesseract)",
"OK": "DE ACUERDO", "OK": "DE ACUERDO",
"ONLYOFFICE provides a full range of tools to create, edit and collaborate on text documents, spreadsheets, presentations, PDF forms and regular PDF files on web, desktop and mobile platforms.": "ONLYOFFICE ofrece una amplia gama de herramientas para crear, editar y colaborar en documentos de texto, hojas de cálculo, presentaciones, formularios PDF y archivos PDF regulares en plataformas web, de escritorio y móviles.", "ONLYOFFICE provides a full range of tools to create, edit and collaborate on text documents, spreadsheets, presentations, PDF forms and regular PDF files on web, desktop and mobile platforms.": "ONLYOFFICE ofrece una amplia gama de herramientas para crear, editar y colaborar en documentos de texto, hojas de cálculo, presentaciones, formularios PDF y archivos PDF regulares en plataformas web, de escritorio y móviles.",
"OR add new PVE 9 no-subscription repository:": "O agregue un nuevo repositorio PVE 9 sin suscripción:", "OR add new PVE 9 no-subscription repository:": "O agregue un nuevo repositorio PVE 9 sin suscripción:",
@@ -4188,6 +4220,7 @@
"Password confirmation cannot be empty.": "La confirmación de contraseña no puede estar vacía.", "Password confirmation cannot be empty.": "La confirmación de contraseña no puede estar vacía.",
"Password confirmation is required.": "Se requiere confirmación de contraseña.", "Password confirmation is required.": "Se requiere confirmación de contraseña.",
"Password for": "Contraseña para", "Password for": "Contraseña para",
"Password for aMule external connections (remote client)": "Contraseña para conexiones externas aMule (cliente remoto)",
"Password for the SSH login": "Contraseña para el login SSH", "Password for the SSH login": "Contraseña para el login SSH",
"Password for:": "Contraseña para:", "Password for:": "Contraseña para:",
"Password is correct": "La contraseña es correcta", "Password is correct": "La contraseña es correcta",
@@ -4222,6 +4255,7 @@
"Path must be absolute (start with /)": "La ruta debe ser absoluta (comenzar con /)", "Path must be absolute (start with /)": "La ruta debe ser absoluta (comenzar con /)",
"Path must be absolute (start with /).": "La ruta debe ser absoluta (comenzar con /).", "Path must be absolute (start with /).": "La ruta debe ser absoluta (comenzar con /).",
"Path not found": "Ruta no encontrada", "Path not found": "Ruta no encontrada",
"Path of the Compose file": "ruta del archivo de redacción",
"Path:": "Ruta:", "Path:": "Ruta:",
"Paths applied:": "Rutas aplicadas:", "Paths applied:": "Rutas aplicadas:",
"Paths included in backup": "Rutas incluidas en la copia de seguridad", "Paths included in backup": "Rutas incluidas en la copia de seguridad",
@@ -4230,6 +4264,7 @@
"Paths to back up:": "Rutas para realizar copias de seguridad:", "Paths to back up:": "Rutas para realizar copias de seguridad:",
"Paths:": "Rutas:", "Paths:": "Rutas:",
"Peers reach the server through the public address and the UDP port given during the installation, so that port must be forwarded to this container.": "Peers alcanza el servidor a través de la dirección pública y el puerto UDP dado durante la instalación, de modo que el puerto debe ser enviado a este contenedor.", "Peers reach the server through the public address and the UDP port given during the installation, so that port must be forwarded to this container.": "Peers alcanza el servidor a través de la dirección pública y el puerto UDP dado durante la instalación, de modo que el puerto debe ser enviado a este contenedor.",
"Peers to create: a number (3) or a list of names (phone,laptop)": "Compañeros para crear: un número (3) o una lista de nombres (teléfono, computadora portátil)",
"Pelorus is an AI navigator for Selkies-powered Linux desktops. Pelorus runs a FastAPI server that gives an LLM agent (Ollama, OpenAI-compatible, or Gemini) control over mouse, keyboard, screenshot, and window management via the Pixelflux computer-use backend, a Linux accessibility tree (AT-SPI), and optional KWin D-Bus integration.": "Pelorus es un navegador de IA para los escritorios Linux impulsados por Selkies. Pelorus ejecuta un servidor FastAPI que da un agente LLM (Ollama, OpenAI-compatible, o Gemini) control sobre el ratón, teclado, captura de pantalla y gestión de ventanas a través del backend de uso de computadora Pixelflux, un árbol de accesibilidad de Linux (AT-SPI), y la integración opcional KWin D-Bus.", "Pelorus is an AI navigator for Selkies-powered Linux desktops. Pelorus runs a FastAPI server that gives an LLM agent (Ollama, OpenAI-compatible, or Gemini) control over mouse, keyboard, screenshot, and window management via the Pixelflux computer-use backend, a Linux accessibility tree (AT-SPI), and optional KWin D-Bus integration.": "Pelorus es un navegador de IA para los escritorios Linux impulsados por Selkies. Pelorus ejecuta un servidor FastAPI que da un agente LLM (Ollama, OpenAI-compatible, o Gemini) control sobre el ratón, teclado, captura de pantalla y gestión de ventanas a través del backend de uso de computadora Pixelflux, un árbol de accesibilidad de Linux (AT-SPI), y la integración opcional KWin D-Bus.",
"Pending components:": "Componentes pendientes:", "Pending components:": "Componentes pendientes:",
"Pending restore ID:": "ID de restauración pendiente:", "Pending restore ID:": "ID de restauración pendiente:",
@@ -4299,6 +4334,7 @@
"Please use an SSH session (Linux, macOS, Windows/PuTTY) or a physical console to perform the upgrade.": "Utilice una sesión SSH (Linux, macOS, Windows/PuTTY) o una consola física para realizar la actualización.", "Please use an SSH session (Linux, macOS, Windows/PuTTY) or a physical console to perform the upgrade.": "Utilice una sesión SSH (Linux, macOS, Windows/PuTTY) o una consola física para realizar la actualización.",
"Plex WebUI": "Plex WebUI", "Plex WebUI": "Plex WebUI",
"Plex organizes video, music and photos from personal media libraries and streams them to smart TVs, streaming boxes and mobile devices. This container is packaged as a standalone Plex Media Server. Straightforward design and bulk actions mean getting things done faster.": "Plex organiza vídeo, música y fotos de bibliotecas de medios personales y los transmite a televisores inteligentes, cajas de streaming y dispositivos móviles. Este contenedor se envasa como un servidor multimedia Plex independiente. Diseño directo y acciones a granel significan hacer las cosas más rápido.", "Plex organizes video, music and photos from personal media libraries and streams them to smart TVs, streaming boxes and mobile devices. This container is packaged as a standalone Plex Media Server. Straightforward design and bulk actions mean getting things done faster.": "Plex organiza vídeo, música y fotos de bibliotecas de medios personales y los transmite a televisores inteligentes, cajas de streaming y dispositivos móviles. Este contenedor se envasa como un servidor multimedia Plex independiente. Diseño directo y acciones a granel significan hacer las cosas más rápido.",
"PocketBase admin UI": "Interfaz de usuario de administración PocketBase",
"Podcast synchronization service": "Servicio de sincronización de podcast", "Podcast synchronization service": "Servicio de sincronización de podcast",
"Pool does not appear to use SSD/NVMe devices with discard support. Skipping ZFS autotrim for pool:": "El grupo no parece utilizar dispositivos SSD/NVMe con soporte de descarte. Saltar el ajuste automático de ZFS para el grupo:", "Pool does not appear to use SSD/NVMe devices with discard support. Skipping ZFS autotrim for pool:": "El grupo no parece utilizar dispositivos SSD/NVMe con soporte de descarte. Saltar el ajuste automático de ZFS para el grupo:",
"Pool exists": "Pool existe", "Pool exists": "Pool existe",
@@ -4319,6 +4355,7 @@
"PostgreSQL URL without an associated service:": "URL de PostgreSQL sin un servicio asociado:", "PostgreSQL URL without an associated service:": "URL de PostgreSQL sin un servicio asociado:",
"PostgreSQL creates the database named in POSTGRES_DB on the first start. The installer default is postgresql.": "PostgreSQL crea la base de datos llamada en POSTGRES DB en el primer comienzo. El instalador predeterminado es postgresql.", "PostgreSQL creates the database named in POSTGRES_DB on the first start. The installer default is postgresql.": "PostgreSQL crea la base de datos llamada en POSTGRES DB en el primer comienzo. El instalador predeterminado es postgresql.",
"PostgreSQL is an advanced, enterprise-class, and open-source relational database system. PostgreSQL supports both SQL (relational) and JSON (non-relational) querying.": "PostgreSQL es un sistema de bases de datos relacionales avanzado, de clase empresarial y de código abierto. PostgreSQL soporta tanto SQL (relacional) como JSON (no-relacional) querying.", "PostgreSQL is an advanced, enterprise-class, and open-source relational database system. PostgreSQL supports both SQL (relational) and JSON (non-relational) querying.": "PostgreSQL es un sistema de bases de datos relacionales avanzado, de clase empresarial y de código abierto. PostgreSQL soporta tanto SQL (relacional) como JSON (no-relacional) querying.",
"PostgreSQL requires a password": "PostgreSQL requires una contraseña",
"PostgreSQL volume size in GB": "Tamaño del volumen de PostgreSQL en GB", "PostgreSQL volume size in GB": "Tamaño del volumen de PostgreSQL en GB",
"Potential QEMU startup/assertion failures": "Posibles fallos de inicio/afirmación de QEMU", "Potential QEMU startup/assertion failures": "Posibles fallos de inicio/afirmación de QEMU",
"Power state D3cold/D0 transitions may be inaccessible": "Las transiciones del estado de energía D3cold/D0 pueden ser inaccesibles", "Power state D3cold/D0 transitions may be inaccessible": "Las transiciones del estado de energía D3cold/D0 pueden ser inaccesibles",
@@ -4331,6 +4368,7 @@
"Pre-upgrade check FAILED: the simulation shows that 'proxmox-ve' would be REMOVED.\n This indicates a repository or dependency issue and upgrading now could break your Proxmox installation.": "La verificación previa a la actualización FALLÓ: la simulación muestra que 'proxmox-ve' sería ELIMINADO.\n Esto indica un problema de repositorio o dependencia y actualizar ahora podría interrumpir la instalación de Proxmox.", "Pre-upgrade check FAILED: the simulation shows that 'proxmox-ve' would be REMOVED.\n This indicates a repository or dependency issue and upgrading now could break your Proxmox installation.": "La verificación previa a la actualización FALLÓ: la simulación muestra que 'proxmox-ve' sería ELIMINADO.\n Esto indica un problema de repositorio o dependencia y actualizar ahora podría interrumpir la instalación de Proxmox.",
"Pre-upgrade simulation failed. See log:": "Error en la simulación previa a la actualización. Ver registro:", "Pre-upgrade simulation failed. See log:": "Error en la simulación previa a la actualización. Ver registro:",
"Pre-upgrade simulation passed: 'proxmox-ve' will be kept or upgraded safely.": "Se pasó la simulación previa a la actualización: 'proxmox-ve' se mantendrá o se actualizará de forma segura.", "Pre-upgrade simulation passed: 'proxmox-ve' will be kept or upgraded safely.": "Se pasó la simulación previa a la actualización: 'proxmox-ve' se mantendrá o se actualizará de forma segura.",
"Prepared; the container was not modified yet": "Preparado;el contenedor aún no ha sido modificado",
"Preparing Log2RAM configuration": "Preparando la configuración de Log2RAM", "Preparing Log2RAM configuration": "Preparando la configuración de Log2RAM",
"Preparing files for backup...": "Preparando archivos para copia de seguridad...", "Preparing files for backup...": "Preparando archivos para copia de seguridad...",
"Preparing host mount...": "Preparando el montaje del host...", "Preparing host mount...": "Preparando el montaje del host...",
@@ -4371,6 +4409,7 @@
"Previous shutdowns": "Paradas anteriores", "Previous shutdowns": "Paradas anteriores",
"Primary GID for Emby": "GID primario para Emby", "Primary GID for Emby": "GID primario para Emby",
"Privacy-first finance app with envelope budgeting and multi-device sync.": "Aplicación de privacidad-primera aplicación financiera con sobre budgeting y sincronización multidispositivo.", "Privacy-first finance app with envelope budgeting and multi-device sync.": "Aplicación de privacidad-primera aplicación financiera con sobre budgeting y sincronización multidispositivo.",
"Privacy-first, self-hosted PDF toolkit": "kit de herramientas PDF autohospedado que prioriza la privacidad",
"Private installation record saved": "Registro de instalación privado guardado", "Private installation record saved": "Registro de instalación privado guardado",
"Private network assigned automatically:": "Red privada asignada automáticamente:", "Private network assigned automatically:": "Red privada asignada automáticamente:",
"Private network of the application released:": "Red privada de la aplicación liberada:", "Private network of the application released:": "Red privada de la aplicación liberada:",
@@ -4466,6 +4505,7 @@
"Proxmox web interface: Datacenter > Storage > Add > ZFS": "Interfaz web de Proxmox: Centro de datos > Almacenamiento > Agregar > ZFS", "Proxmox web interface: Datacenter > Storage > Add > ZFS": "Interfaz web de Proxmox: Centro de datos > Almacenamiento > Agregar > ZFS",
"Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Interfaz web de Proxmox: Centro de datos > Almacenamiento > Agregar > iSCSI", "Proxmox web interface: Datacenter > Storage > Add > iSCSI": "Interfaz web de Proxmox: Centro de datos > Almacenamiento > Agregar > iSCSI",
"Public UDP port clients connect to": "Público UDP port clients connect to", "Public UDP port clients connect to": "Público UDP port clients connect to",
"Public UDP port peers connect to": "Los pares del puerto público UDP se conectan",
"Public URL of phpMyAdmin when it is served behind a reverse proxy": "URL pública de phpMyAdmin cuando se sirve detrás de un proxy inverso", "Public URL of phpMyAdmin when it is served behind a reverse proxy": "URL pública de phpMyAdmin cuando se sirve detrás de un proxy inverso",
"Public address clients connect to (vpn.example.com or a public IP)": "Los clientes de dirección pública se conectan a (vpn.example.com o IP pública)", "Public address clients connect to (vpn.example.com or a public IP)": "Los clientes de dirección pública se conectan a (vpn.example.com o IP pública)",
"Public address peers connect to, or auto to detect it (vpn.example.com)": "Los pares de direcciones públicas se conectan a, o auto para detectarlo (vpn.example.com)", "Public address peers connect to, or auto to detect it (vpn.example.com)": "Los pares de direcciones públicas se conectan a, o auto para detectarlo (vpn.example.com)",
@@ -4584,6 +4624,7 @@
"Recreate OCI": "Recrear OCI", "Recreate OCI": "Recrear OCI",
"Recreate with these options?": "¿Recrear con estas opciones?", "Recreate with these options?": "¿Recrear con estas opciones?",
"Recreate: edit resources, network, paths and GPU": "Recrear: editar recursos, red, rutas y GPU", "Recreate: edit resources, network, paths and GPU": "Recrear: editar recursos, red, rutas y GPU",
"Recreating requires a confirmed proposal": "Recreando requires una propuesta confirmada",
"Recreating the container...": "Recreando el contenedor...", "Recreating the container...": "Recreando el contenedor...",
"Recreating the container:": "Recreando el contenedor:", "Recreating the container:": "Recreando el contenedor:",
"Recreation completed. Data kept.": "Recreación completada. Datos guardados.", "Recreation completed. Data kept.": "Recreación completada. Datos guardados.",
@@ -4837,6 +4878,7 @@
"Review what will be removed": "Revisa lo que se eliminará", "Review what will be removed": "Revisa lo que se eliminará",
"Rip DVD and Blu-ray media from a browser": "Rip DVD y Blu-ray medios de un navegador", "Rip DVD and Blu-ray media from a browser": "Rip DVD y Blu-ray medios de un navegador",
"Rollback: nothing to remove (host matches backup)": "Revertir: nada que eliminar (el host coincide con la copia de seguridad)", "Rollback: nothing to remove (host matches backup)": "Revertir: nada que eliminar (el host coincide con la copia de seguridad)",
"Rolling back the incomplete container": "Revertir el contenedor incompleto",
"RomM is a self-hosted ROM manager for managing and playing game collections.": "RomM es un gestor de ROM auto hospedado para gestionar y jugar colecciones de juego.", "RomM is a self-hosted ROM manager for managing and playing game collections.": "RomM es un gestor de ROM auto hospedado para gestionar y jugar colecciones de juego.",
"Root SSH keys/config": "Configuración/claves SSH raíz", "Root SSH keys/config": "Configuración/claves SSH raíz",
"Root inside container = root on host system": "Raíz dentro del contenedor = raíz en el sistema host", "Root inside container = root on host system": "Raíz dentro del contenedor = raíz en el sistema host",
@@ -5472,6 +5514,7 @@
"Starting the service:": "Inicio del servicio:", "Starting the service:": "Inicio del servicio:",
"Starting unprivileged container...": "Iniciando contenedor sin privilegios...", "Starting unprivileged container...": "Iniciando contenedor sin privilegios...",
"Startup: coordinated by the stack startup hook": "Inicio: coordinado por el gancho de arranque de pila", "Startup: coordinated by the stack startup hook": "Inicio: coordinado por el gancho de arranque de pila",
"Startup: independent, without hookscript": "Inicio: independiente, sin gancho",
"Static IP": "IP estática", "Static IP": "IP estática",
"Static IPv4 address": "Dirección IPv4 estática", "Static IPv4 address": "Dirección IPv4 estática",
"Static IPv4 address for": "Dirección IPv4 estática para", "Static IPv4 address for": "Dirección IPv4 estática para",
@@ -5479,6 +5522,7 @@
"Status:": "Estado:", "Status:": "Estado:",
"Steam is the ultimate destination for playing, discussing, and creating games.": "Steam es el destino final para jugar, discutir y crear juegos.", "Steam is the ultimate destination for playing, discussing, and creating games.": "Steam es el destino final para jugar, discutir y crear juegos.",
"SteamGridDB": "SteamGridDB", "SteamGridDB": "SteamGridDB",
"SteamGridDB API key": "SteamClave API de GridDB",
"Step": "Paso", "Step": "Paso",
"Step 2: Testing actual share access with guest...": "Paso 2: Probar el acceso compartido real con los invitados...", "Step 2: Testing actual share access with guest...": "Paso 2: Probar el acceso compartido real con los invitados...",
"Steps that will run:": "Pasos que se ejecutarán:", "Steps that will run:": "Pasos que se ejecutarán:",
@@ -5986,6 +6030,7 @@
"The remote installer must run as root on Proxmox VE": "El instalador remoto debe funcionar como root en Proxmox VE", "The remote installer must run as root on Proxmox VE": "El instalador remoto debe funcionar como root en Proxmox VE",
"The remote must already be created and authorized in the Rclone web UI. This operation restarts the CT and publishes two FUSE views on the host.": "El remoto ya debe estar creado y autorizado en la interfaz web de Rclone. Esta operación reinicia el CT y publica dos puntos de vista FUSE sobre el host.", "The remote must already be created and authorized in the Rclone web UI. This operation restarts the CT and publishes two FUSE views on the host.": "El remoto ya debe estar creado y autorizado en la interfaz web de Rclone. Esta operación reinicia el CT y publica dos puntos de vista FUSE sobre el host.",
"The remote path must be relative and cannot contain line breaks": "La ruta remota debe ser relativa y no puede contener saltos de línea", "The remote path must be relative and cannot contain line breaks": "La ruta remota debe ser relativa y no puede contener saltos de línea",
"The removal could not be prepared:": "No se pudo preparar la eliminación:",
"The repair must preserve the image dependencies:": "La reparación debe preservar las dependencias de la imagen:", "The repair must preserve the image dependencies:": "La reparación debe preservar las dependencias de la imagen:",
"The requested VMID block is already in use": "El bloque VMID solicitado ya está en uso", "The requested VMID block is already in use": "El bloque VMID solicitado ya está en uso",
"The requested machine learning GPU profile is not working; it is not replaced by CPU": "El perfil GPU de aprendizaje automático solicitado no funciona; no es reemplazado por CPU", "The requested machine learning GPU profile is not working; it is not replaced by CPU": "El perfil GPU de aprendizaje automático solicitado no funciona; no es reemplazado por CPU",
@@ -6301,6 +6346,7 @@
"Unexpected Proxmox inventory; recovery blocked": "Inventario Proxmox inesperado; recuperación bloqueada", "Unexpected Proxmox inventory; recovery blocked": "Inventario Proxmox inesperado; recuperación bloqueada",
"Unexpected formatting directory in the new Valkey volume": "directorio de formato inesperado en el nuevo volumen Valkey", "Unexpected formatting directory in the new Valkey volume": "directorio de formato inesperado en el nuevo volumen Valkey",
"Ungoogled Chromium is Google Chromium, sans dependency on Google web services.": "Ungoogled Chromium es Google Chromium, dependencia sans de los servicios web de Google.", "Ungoogled Chromium is Google Chromium, sans dependency on Google web services.": "Ungoogled Chromium es Google Chromium, dependencia sans de los servicios web de Google.",
"Unified LLM Fine-Tuning with 100+ Models": "Ajuste unificado de LLM con más de 100 modelos",
"Uninstall Coral drivers and configuration": "Desinstalar los controladores y la configuración de Coral", "Uninstall Coral drivers and configuration": "Desinstalar los controladores y la configuración de Coral",
"Uninstall Fail2Ban": "Desinstalar Fail2Ban", "Uninstall Fail2Ban": "Desinstalar Fail2Ban",
"Uninstall Lynis": "Desinstalar Lynis", "Uninstall Lynis": "Desinstalar Lynis",
@@ -6331,6 +6377,7 @@
"Unknown CPU vendor. Cannot determine IOMMU parameter.": "Proveedor de CPU desconocido. No se puede determinar el parámetro IOMMU.", "Unknown CPU vendor. Cannot determine IOMMU parameter.": "Proveedor de CPU desconocido. No se puede determinar el parámetro IOMMU.",
"Unknown GPU": "GPU desconocida", "Unknown GPU": "GPU desconocida",
"Unknown adapter role": "Función de adaptador desconocido", "Unknown adapter role": "Función de adaptador desconocido",
"Unknown credential service:": "Servicio credential desconocido:",
"Unknown dependency:": "Dependencia desconocida:", "Unknown dependency:": "Dependencia desconocida:",
"Unknown host monitor": "Monitor de host desconocido", "Unknown host monitor": "Monitor de host desconocido",
"Unknown model": "Modelo desconocido", "Unknown model": "Modelo desconocido",
@@ -6372,6 +6419,7 @@
"Unrecognized stack structure:": "Estructura de pila no reconocida:", "Unrecognized stack structure:": "Estructura de pila no reconocida:",
"Unrecognized volume definition": "Definición de volumen no reconocida", "Unrecognized volume definition": "Definición de volumen no reconocida",
"Unresolved variable:": "Variable sin resolver:", "Unresolved variable:": "Variable sin resolver:",
"Unsafe OCI archive path": "Ruta de archivo OCI no segura",
"Unsafe dependency contract": "Contrato de dependencia en condiciones de seguridad", "Unsafe dependency contract": "Contrato de dependencia en condiciones de seguridad",
"Unsafe dependency hook contract": "Contrato de garantía de dependencia", "Unsafe dependency hook contract": "Contrato de garantía de dependencia",
"Unsafe instance directory": "Directorio de instancias inseguras", "Unsafe instance directory": "Directorio de instancias inseguras",
@@ -6614,6 +6662,7 @@
"Variable name": "Nombre de la variable", "Variable name": "Nombre de la variable",
"Variables": "Variables", "Variables": "Variables",
"Variables the installation asks for:": "Variables que pide la instalación:", "Variables the installation asks for:": "Variables que pide la instalación:",
"Vaultwarden Web Vault": "Bóveda web Vaultwarden",
"Verbose pool status": "Estado detallado del grupo", "Verbose pool status": "Estado detallado del grupo",
"Verification": "Verificación", "Verification": "Verificación",
"Verified": "Verificado", "Verified": "Verificado",
@@ -6730,6 +6779,7 @@
"Web UI": "Web UI", "Web UI": "Web UI",
"Web UI 1": "Web UI 1", "Web UI 1": "Web UI 1",
"Web UI 2": "Web UI 2", "Web UI 2": "Web UI 2",
"Web UI password": "contraseña de la interfaz de usuario web",
"Web UI user": "Usuario de la interfaz web", "Web UI user": "Usuario de la interfaz web",
"Web access": "Acceso web", "Web access": "Acceso web",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Dirección web del AdGuard Home que recibe los ajustes (por ejemplo, http://192.168.1.3)", "Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Dirección web del AdGuard Home que recibe los ajustes (por ejemplo, http://192.168.1.3)",
@@ -7017,6 +7067,7 @@
"imported:": "importado:", "imported:": "importado:",
"in CT": "en TC", "in CT": "en TC",
"in backups": "en backups", "in backups": "en backups",
"incompatible qBittorrent schema": "esquema qBittorrent incompatible",
"individual template is blocked": "la plantilla individual está bloqueada", "individual template is blocked": "la plantilla individual está bloqueada",
"initramfs updated": "initramfs actualizado", "initramfs updated": "initramfs actualizado",
"initramfs updated.": "initramfs actualizado.", "initramfs updated.": "initramfs actualizado.",
+2
View File
@@ -2587,6 +2587,7 @@
"ID already in use. Please choose another.": "ID déjà utilisé. Veuillez en choisir un autre.", "ID already in use. Please choose another.": "ID déjà utilisé. Veuillez en choisir un autre.",
"IGDB": "IGDB", "IGDB": "IGDB",
"IGDB Client ID": "ID client IGDB", "IGDB Client ID": "ID client IGDB",
"IGDB Client Secret": "Secret client IGDB",
"IMPORTANT": "IMPORTANT", "IMPORTANT": "IMPORTANT",
"IMPORTANT NOTES:": "REMARQUES IMPORTANTES :", "IMPORTANT NOTES:": "REMARQUES IMPORTANTES :",
"IMPORTANT PREREQUISITES:": "PRÉREQUIS IMPORTANTS :", "IMPORTANT PREREQUISITES:": "PRÉREQUIS IMPORTANTS :",
@@ -3073,6 +3074,7 @@
"Invalid volume size": "Volume non valide", "Invalid volume size": "Volume non valide",
"Invalid volume size:": "Volume non valide:", "Invalid volume size:": "Volume non valide:",
"Invalid volume target": "Cible de volume non valable", "Invalid volume target": "Cible de volume non valable",
"IoT & Smart Home": "IoT et maison intelligente",
"Is the value a password or secret?": "La valeur est-elle un mot de passe ou un secret ?", "Is the value a password or secret?": "La valeur est-elle un mot de passe ou un secret ?",
"Issue": "Problème", "Issue": "Problème",
"Issues found": "Problèmes trouvés", "Issues found": "Problèmes trouvés",
+20
View File
@@ -120,6 +120,7 @@
"ACL Status:": "Stato ACL:", "ACL Status:": "Stato ACL:",
"ACL permissions applied for local access for user:": "ACL permissions applied for local access for user:", "ACL permissions applied for local access for user:": "ACL permissions applied for local access for user:",
"ADVANCED SETTINGS COMPLETE": "IMPOSTAZIONI AVANZATE COMPLETATE", "ADVANCED SETTINGS COMPLETE": "IMPOSTAZIONI AVANZATE COMPLETATE",
"AI / Coding & Dev-Tools": "AI/codifica e strumenti di sviluppo",
"ALL DATA ON": "TUTTI I DATI SU", "ALL DATA ON": "TUTTI I DATI SU",
"ALL DATA ON THIS DISK WILL BE PERMANENTLY LOST!": "TUTTI I DATI SU QUESTO DISCO SARANNO PERDUTI PERMANENTEMENTE!", "ALL DATA ON THIS DISK WILL BE PERMANENTLY LOST!": "TUTTI I DATI SU QUESTO DISCO SARANNO PERDUTI PERMANENTEMENTE!",
"ALL Utilities": "TUTTE le utenze", "ALL Utilities": "TUTTE le utenze",
@@ -848,6 +849,7 @@
"Cloning Lynis from GitHub...": "Clonazione di Lynis da GitHub...", "Cloning Lynis from GitHub...": "Clonazione di Lynis da GitHub...",
"Cloning and applying NVIDIA patch (keylase/nvidia-patch)...": "Clonazione e applicazione della patch NVIDIA (keylase/nvidia-patch)...", "Cloning and applying NVIDIA patch (keylase/nvidia-patch)...": "Clonazione e applicazione della patch NVIDIA (keylase/nvidia-patch)...",
"Closed": "Chiuso", "Closed": "Chiuso",
"Cloud Database Manager.": "Gestore database cloud.",
"Cloud storage synchronization and FUSE mounts": "Sincronizzazione di storage cloud e supporti FUSE", "Cloud storage synchronization and FUSE mounts": "Sincronizzazione di storage cloud e supporti FUSE",
"Cloud-Init Automated Installers": "Programmi di installazione automatizzati Cloud-Init", "Cloud-Init Automated Installers": "Programmi di installazione automatizzati Cloud-Init",
"Cluster certificates updated": "Certificati cluster aggiornati", "Cluster certificates updated": "Certificati cluster aggiornati",
@@ -2448,6 +2450,7 @@
"HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One è un'immagine comunitaria che gestisce Docker all'interno del contenitore. Il LXC rimane non privato, ma i profili interni AppArmor potrebbero non essere disponibili. Il primo avvio scarica Home Assistant Core e i suoi componenti aggiuntivi. Se il controllo fallisce, la CT e /mnt/data sono tenuti per la diagnosi.", "HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One è un'immagine comunitaria che gestisce Docker all'interno del contenitore. Il LXC rimane non privato, ma i profili interni AppArmor potrebbero non essere disponibili. Il primo avvio scarica Home Assistant Core e i suoi componenti aggiuntivi. Se il controllo fallisce, la CT e /mnt/data sono tenuti per la diagnosi.",
"HAOS One profile declined": "Profilo HAOS One declinato", "HAOS One profile declined": "Profilo HAOS One declinato",
"HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requi è una LXC non gestita con nidificazione e keyctl, 2 core, 2048 MB RAM, rootf di almeno 12 GB e /mnt/dati di almeno 16 GB su un volume di container incluso in backup", "HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requi è una LXC non gestita con nidificazione e keyctl, 2 core, 2048 MB RAM, rootf di almeno 12 GB e /mnt/dati di almeno 16 GB su un volume di container incluso in backup",
"HTML5 Network Speed Test Server.": "Server di test della velocità di rete HTML5.",
"HTTP service check without a saved URL": "Controllo del servizio HTTP senza un URL salvato", "HTTP service check without a saved URL": "Controllo del servizio HTTP senza un URL salvato",
"Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emula Philips Hue API ad altri gateway di automazione domestica come un Amazon Echo/Dot Gen 1 (gen 2 ha problemi di scoperta ha-bridge) o altri sistemi che supportano Philips Hue. Il Bridge gestisce comandi di base come On, Off e comandi di luminosità del protocollo hue. Questo ponte può controllare la maggior parte dei dispositivi che hanno una API distinta.", "Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emula Philips Hue API ad altri gateway di automazione domestica come un Amazon Echo/Dot Gen 1 (gen 2 ha problemi di scoperta ha-bridge) o altri sistemi che supportano Philips Hue. Il Bridge gestisce comandi di base come On, Off e comandi di luminosità del protocollo hue. Questo ponte può controllare la maggior parte dei dispositivi che hanno una API distinta.",
"HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake è uno strumento open source, costruito da volontari, per convertire video da quasi qualsiasi formato in una selezione di codec moderni e ampiamente supportati.", "HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake è uno strumento open source, costruito da volontari, per convertire video da quasi qualsiasi formato in una selezione di codec moderni e ampiamente supportati.",
@@ -2518,6 +2521,7 @@
"Host Path": "Percorso dell'ospite", "Host Path": "Percorso dell'ospite",
"Host Path:": "Percorso host:", "Host Path:": "Percorso host:",
"Host Storage (NFS / Samba via Proxmox)": "Archiviazione host (NFS/Samba tramite Proxmox)", "Host Storage (NFS / Samba via Proxmox)": "Archiviazione host (NFS/Samba tramite Proxmox)",
"Host USB bus": "bus USB host",
"Host VFIO config was already up to date — no reboot needed.": "La configurazione dell'host VFIO era già aggiornata: non è necessario il riavvio.", "Host VFIO config was already up to date — no reboot needed.": "La configurazione dell'host VFIO era già aggiornata: non è necessario il riavvio.",
"Host VFIO configuration already up to date": "Configurazione Host VFIO già aggiornata", "Host VFIO configuration already up to date": "Configurazione Host VFIO già aggiornata",
"Host VFIO configuration changed (initramfs updated). Reboot required before starting the VM.": "La configurazione dell'host VFIO è stata modificata (initramfs aggiornato). Riavvio richiesto prima di avviare la VM.", "Host VFIO configuration changed (initramfs updated). Reboot required before starting the VM.": "La configurazione dell'host VFIO è stata modificata (initramfs aggiornato). Riavvio richiesto prima di avviare la VM.",
@@ -2690,6 +2694,7 @@
"Immich GPU profile not validated": "Profilo GPU Immich non convalidato", "Immich GPU profile not validated": "Profilo GPU Immich non convalidato",
"Immich configuration cancelled": "Cancellazione della configurazione Immich", "Immich configuration cancelled": "Cancellazione della configurazione Immich",
"Immich device without a validated translation": "Dispositivo Immich senza traduzione convalidata", "Immich device without a validated translation": "Dispositivo Immich senza traduzione convalidata",
"Immich machine learning": "apprendimento automatico Immich",
"Immich requires CUDA compute capability 5.2 or later": "Immich requires CUDA capacità di calcolo 5.2 o versioni successive", "Immich requires CUDA compute capability 5.2 or later": "Immich requires CUDA capacità di calcolo 5.2 o versioni successive",
"Immich runtime without a validated translation": "Tempo di esecuzione Immich senza traduzione convalidata", "Immich runtime without a validated translation": "Tempo di esecuzione Immich senza traduzione convalidata",
"Immich server": "Server Immich", "Immich server": "Server Immich",
@@ -2950,6 +2955,7 @@
"Interrupted stack operation found": "Pila interrotta operation trovata", "Interrupted stack operation found": "Pila interrotta operation trovata",
"Invalid 'proxmox-ve' candidate (not 9.x or none). Please verify your repository configuration and network, then retry.": "Candidato 'proxmox-ve' non valido (non 9.xo nessuno). Verifica la configurazione e la rete del repository, quindi riprova.", "Invalid 'proxmox-ve' candidate (not 9.x or none). Please verify your repository configuration and network, then retry.": "Candidato 'proxmox-ve' non valido (non 9.xo nessuno). Verifica la configurazione e la rete del repository, quindi riprova.",
"Invalid ALLOWED_HOSTS value": "Valore non valido ALLOWED HOSTs", "Invalid ALLOWED_HOSTS value": "Valore non valido ALLOWED HOSTs",
"Invalid Home Assistant OS check timeout": "Timeout controllo sistema operativo Home Assistant non valido",
"Invalid ID": "ID non valido", "Invalid ID": "ID non valido",
"Invalid Intel render path": "percorso di rendering Intel non valido", "Invalid Intel render path": "percorso di rendering Intel non valido",
"Invalid Jellyfin path:": "Invalid Jellyfin percorso:", "Invalid Jellyfin path:": "Invalid Jellyfin percorso:",
@@ -2958,10 +2964,12 @@
"Invalid NVIDIA device:": "Dispositivo NVIDIA non valido:", "Invalid NVIDIA device:": "Dispositivo NVIDIA non valido:",
"Invalid Nextcloud volume": "Volume non valido Nextcloud", "Invalid Nextcloud volume": "Volume non valido Nextcloud",
"Invalid OCI Entrypoint": "Invalid OCI", "Invalid OCI Entrypoint": "Invalid OCI",
"Invalid OCI digest": "digest OCI non valido",
"Invalid OCR language:": "Lingua OCR non valida:", "Invalid OCR language:": "Lingua OCR non valida:",
"Invalid Option": "Opzione non valida", "Invalid Option": "Opzione non valida",
"Invalid Path": "Percorso non valido", "Invalid Path": "Percorso non valido",
"Invalid Proxmox inventory": "inventario Proxmox non valido", "Invalid Proxmox inventory": "inventario Proxmox non valido",
"Invalid Python index:": "indice Python non valido:",
"Invalid Python module:": "Modulo Python non valido:", "Invalid Python module:": "Modulo Python non valido:",
"Invalid Python package:": "Pacchetto Python non valido:", "Invalid Python package:": "Pacchetto Python non valido:",
"Invalid Python path in the repair:": "Invalid Python percorso nella riparazione:", "Invalid Python path in the repair:": "Invalid Python percorso nella riparazione:",
@@ -2998,6 +3006,7 @@
"Invalid healthcheck request timeout": "Invalid healthcheck richiesta timeout", "Invalid healthcheck request timeout": "Invalid healthcheck richiesta timeout",
"Invalid healthcheck scheme": "Programma di controllo sanitario non valido", "Invalid healthcheck scheme": "Programma di controllo sanitario non valido",
"Invalid healthcheck stability period": "Periodo di stabilità del controllo sanitario non valido", "Invalid healthcheck stability period": "Periodo di stabilità del controllo sanitario non valido",
"Invalid healthcheck timeout": "timeout del controllo integrità non valido",
"Invalid host kernel module name:": "Nome del modulo del kernel host non valido:", "Invalid host kernel module name:": "Nome del modulo del kernel host non valido:",
"Invalid host monitor PID": "Monitor host non valido PID", "Invalid host monitor PID": "Monitor host non valido PID",
"Invalid host path:": "Percorso non valido:", "Invalid host path:": "Percorso non valido:",
@@ -3010,7 +3019,9 @@
"Invalid main member or duplicated members": "Membro principale non valido o membri duplicati", "Invalid main member or duplicated members": "Membro principale non valido o membri duplicati",
"Invalid media path": "Sentiero dei media non valido", "Invalid media path": "Sentiero dei media non valido",
"Invalid media volume": "Volume dei media non valido", "Invalid media volume": "Volume dei media non valido",
"Invalid mediafiles volume": "volume dei file multimediali non valido",
"Invalid minimum version:": "Versione minima non valida:", "Invalid minimum version:": "Versione minima non valida:",
"Invalid mount name": "nome di montaggio non valido",
"Invalid mount type": "Tipo di montaggio non valido", "Invalid mount type": "Tipo di montaggio non valido",
"Invalid name": "Nome non valido", "Invalid name": "Nome non valido",
"Invalid name. Use only letters, numbers, hyphens and underscores.": "Nome non valido. Utilizza solo lettere, numeri, trattini e trattini bassi.", "Invalid name. Use only letters, numbers, hyphens and underscores.": "Nome non valido. Utilizza solo lettere, numeri, trattini e trattini bassi.",
@@ -3036,8 +3047,10 @@
"Invalid resources": "Risorse non valide", "Invalid resources": "Risorse non valide",
"Invalid restored volume path": "percorso di volume non valido restaurato", "Invalid restored volume path": "percorso di volume non valido restaurato",
"Invalid running state": "Stato in esecuzione non valido", "Invalid running state": "Stato in esecuzione non valido",
"Invalid security.unprivileged value:": "valore security.unprivileged non valido:",
"Invalid selection": "Selezione non valida", "Invalid selection": "Selezione non valida",
"Invalid service alias": "Servizio non valido alias", "Invalid service alias": "Servizio non valido alias",
"Invalid service check URL": "URL di controllo del servizio non valido",
"Invalid service check arguments": "Argomenti di controllo del servizio non valido", "Invalid service check arguments": "Argomenti di controllo del servizio non valido",
"Invalid service check timeout": "Servizio non valido check timeout", "Invalid service check timeout": "Servizio non valido check timeout",
"Invalid shared path": "percorso condiviso non valido", "Invalid shared path": "percorso condiviso non valido",
@@ -3061,6 +3074,7 @@
"Invalid volume size": "Dimensione del volume non valido", "Invalid volume size": "Dimensione del volume non valido",
"Invalid volume size:": "Dimensioni del volume non valido:", "Invalid volume size:": "Dimensioni del volume non valido:",
"Invalid volume target": "Obiettivo del volume non valido", "Invalid volume target": "Obiettivo del volume non valido",
"IoT & Smart Home": "IoT e casa intelligente",
"Is the value a password or secret?": "Il valore è una password o un segreto?", "Is the value a password or secret?": "Il valore è una password o un segreto?",
"Issue": "Problema", "Issue": "Problema",
"Issues found": "Problemi rilevati", "Issues found": "Problemi rilevati",
@@ -3742,6 +3756,7 @@
"No Exports": "Nessuna esportazione", "No Exports": "Nessuna esportazione",
"No Exports Found": "Nessuna esportazione trovata", "No Exports Found": "Nessuna esportazione trovata",
"No Folders": "Nessuna cartella", "No Folders": "Nessuna cartella",
"No GPU (CPU)": "Messaggio tecnico per Proxmox e IT.Traduzione: No GPU (CPU)",
"No GPU Detected": "Nessuna GPU rilevata", "No GPU Detected": "Nessuna GPU rilevata",
"No GPU selected.": "Nessuna GPU selezionata.", "No GPU selected.": "Nessuna GPU selezionata.",
"No GPU selected. Please select at least one GPU to continue.": "Nessuna GPU selezionata. Seleziona almeno una GPU per continuare.", "No GPU selected. Please select at least one GPU to continue.": "Nessuna GPU selezionata. Seleziona almeno una GPU per continuare.",
@@ -4010,6 +4025,7 @@
"OCI containers require Proxmox VE 9.1 or later.": "I contenitori OCI richiedono Proxmox VE 9.1 o versione successiva.", "OCI containers require Proxmox VE 9.1 or later.": "I contenitori OCI richiedono Proxmox VE 9.1 o versione successiva.",
"OCI management": "Gestione OCI", "OCI management": "Gestione OCI",
"OCI management could not be completed. Check the backend status; no additional cleanup has been authorized.": "La gestione OCI non poteva essere completata. Controlla lo stato del backend; non è stata autorizzata alcuna pulizia aggiuntiva.", "OCI management could not be completed. Check the backend status; no additional cleanup has been authorized.": "La gestione OCI non poteva essere completata. Controlla lo stato del backend; non è stata autorizzata alcuna pulizia aggiuntiva.",
"OCI manager Apps (beta)": "App di gestione OCI (beta)",
"OCI manager Apps is a beta: if something does not work as expected, please report it on GitHub with the application name.": "OCI manager Apps è una beta: se qualcosa non funziona come previsto, si prega di segnalarlo su GitHub con il nome dell'applicazione.", "OCI manager Apps is a beta: if something does not work as expected, please report it on GitHub with the application name.": "OCI manager Apps è una beta: se qualcosa non funziona come previsto, si prega di segnalarlo su GitHub con il nome dell'applicazione.",
"OCI metadata integrity mismatch": "OCI metadati integrità mismatch", "OCI metadata integrity mismatch": "OCI metadati integrità mismatch",
"OCI metadata too large": "OCI metadati troppo grandi", "OCI metadata too large": "OCI metadati troppo grandi",
@@ -4075,6 +4091,7 @@
"Open the dashboard to create a new admin account:": "Apri la dashboard per creare un nuovo account amministratore:", "Open the dashboard to create a new admin account:": "Apri la dashboard per creare un nuovo account amministratore:",
"Open-source AI-powered coding assistant": "Assistente di codifica AI-powered open source", "Open-source AI-powered coding assistant": "Assistente di codifica AI-powered open source",
"Open-source UI for building and debugging multi-agent and RAG applications": "UI open source per la costruzione e il debug di applicazioni multi-agent e RAG", "Open-source UI for building and debugging multi-agent and RAG applications": "UI open source per la costruzione e il debug di applicazioni multi-agent e RAG",
"Open-source self-hosted SQL IDE.": "IDE SQL open source self-hosted.",
"OpenClaw is a personal AI assistant you run on your own devices": "OpenClaw è un assistente personale AI che si esegue sui propri dispositivi", "OpenClaw is a personal AI assistant you run on your own devices": "OpenClaw è un assistente personale AI che si esegue sui propri dispositivi",
"OpenList": "OpenList", "OpenList": "OpenList",
"OpenShot Video Editor is an award-winning free and open-source video editor for Linux, Mac, and Windows, and is dedicated to delivering high quality video editing and animation solutions to the world.": "OpenShot Video Editor è un premiato editor video gratuito e open source per Linux, Mac e Windows, ed è dedicato a fornire soluzioni di video editing e animazione di alta qualità al mondo.", "OpenShot Video Editor is an award-winning free and open-source video editor for Linux, Mac, and Windows, and is dedicated to delivering high quality video editing and animation solutions to the world.": "OpenShot Video Editor è un premiato editor video gratuito e open source per Linux, Mac e Windows, ed è dedicato a fornire soluzioni di video editing e animazione di alta qualità al mondo.",
@@ -4393,6 +4410,7 @@
"Previous shutdowns": "Arresti precedenti", "Previous shutdowns": "Arresti precedenti",
"Primary GID for Emby": "GID primario per Emby", "Primary GID for Emby": "GID primario per Emby",
"Privacy-first finance app with envelope budgeting and multi-device sync.": "Privacy-primo app di finanza con busta budgeting e sincronizzazione multi-dispositivo.", "Privacy-first finance app with envelope budgeting and multi-device sync.": "Privacy-primo app di finanza con busta budgeting e sincronizzazione multi-dispositivo.",
"Privacy-first, self-hosted PDF toolkit": "toolkit PDF self-hosted, incentrato sulla privacy",
"Private installation record saved": "Registrazione di installazione privata salvata", "Private installation record saved": "Registrazione di installazione privata salvata",
"Private network assigned automatically:": "Rete privata assegnata automaticamente:", "Private network assigned automatically:": "Rete privata assegnata automaticamente:",
"Private network of the application released:": "Rete privata dell'applicazione rilasciata:", "Private network of the application released:": "Rete privata dell'applicazione rilasciata:",
@@ -6760,6 +6778,7 @@
"Web UI": "Web UI", "Web UI": "Web UI",
"Web UI 1": "Web UI 1", "Web UI 1": "Web UI 1",
"Web UI 2": "Web UI 2", "Web UI 2": "Web UI 2",
"Web UI password": "password dell'interfaccia utente Web",
"Web UI user": "Web UI utente", "Web UI user": "Web UI utente",
"Web access": "Accesso al Web", "Web access": "Accesso al Web",
"Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Indirizzo Web del AdGuard Home che riceve le impostazioni (ad esempio http://192.168.1.3)", "Web address of the AdGuard Home that receives the settings (e.g. http://192.168.1.3)": "Indirizzo Web del AdGuard Home che riceve le impostazioni (ad esempio http://192.168.1.3)",
@@ -6772,6 +6791,7 @@
"Webstation is a web native emulation focused LXQt desktop based on Ubuntu.": "Webstation è un desktop LXQt basato su Ubuntu.", "Webstation is a web native emulation focused LXQt desktop based on Ubuntu.": "Webstation è un desktop LXQt basato su Ubuntu.",
"Webtop - Alpine, Ubuntu, Fedora, and Arch based containers containing full desktop environments in officially supported flavors accessible via any modern web browser.": "Webtop - contenitori Alpine, Ubuntu, Fedora e Arch, contenenti ambienti desktop completi in gusti ufficialmente supportati accessibili tramite qualsiasi browser web moderno.", "Webtop - Alpine, Ubuntu, Fedora, and Arch based containers containing full desktop environments in officially supported flavors accessible via any modern web browser.": "Webtop - contenitori Alpine, Ubuntu, Fedora e Arch, contenenti ambienti desktop completi in gusti ufficialmente supportati accessibili tramite qualsiasi browser web moderno.",
"Weixin (WeChat) is an instant messaging, social media, and mobile payment app developed by Tencent.": "Weixin (WeChat) è un'applicazione di messaggistica istantanea, social media e pagamento mobile sviluppata da Tencent.", "Weixin (WeChat) is an instant messaging, social media, and mobile payment app developed by Tencent.": "Weixin (WeChat) è un'applicazione di messaggistica istantanea, social media e pagamento mobile sviluppata da Tencent.",
"What cannot be translated:": "Ciò che non può essere tradotto:",
"What do you want to do?": "Cosa vuoi fare?", "What do you want to do?": "Cosa vuoi fare?",
"What would you like to do?": "Cosa ti piacerebbe fare?", "What would you like to do?": "Cosa ti piacerebbe fare?",
"When asked to select a disk, click Load Driver and load the VirtIO drivers.": "Quando viene richiesto di selezionare un disco, fare clic su Carica driver e caricare i driver VirtIO.", "When asked to select a disk, click Load Driver and load the VirtIO drivers.": "Quando viene richiesto di selezionare un disco, fare clic su Carica driver e caricare i driver VirtIO.",
+2
View File
@@ -2694,6 +2694,7 @@
"Immich GPU profile not validated": "Perfil Immich GPU não validado", "Immich GPU profile not validated": "Perfil Immich GPU não validado",
"Immich configuration cancelled": "Configuração do Immich cancelada", "Immich configuration cancelled": "Configuração do Immich cancelada",
"Immich device without a validated translation": "Dispositivo Immich sem tradução validada", "Immich device without a validated translation": "Dispositivo Immich sem tradução validada",
"Immich machine learning": "aprendizado de máquina Immich",
"Immich requires CUDA compute capability 5.2 or later": "Immich requires Capacidade de computação CUDA 5.2 ou posterior", "Immich requires CUDA compute capability 5.2 or later": "Immich requires Capacidade de computação CUDA 5.2 ou posterior",
"Immich runtime without a validated translation": "Immich runtime sem uma tradução validada", "Immich runtime without a validated translation": "Immich runtime sem uma tradução validada",
"Immich server": "Servidor Immich", "Immich server": "Servidor Immich",
@@ -3073,6 +3074,7 @@
"Invalid volume size": "Tamanho de volume inválido", "Invalid volume size": "Tamanho de volume inválido",
"Invalid volume size:": "Tamanho de volume inválido:", "Invalid volume size:": "Tamanho de volume inválido:",
"Invalid volume target": "Alvo de volume inválido", "Invalid volume target": "Alvo de volume inválido",
"IoT & Smart Home": "IoT e casa inteligente",
"Is the value a password or secret?": "O valor é uma senha ou segredo?", "Is the value a password or secret?": "O valor é uma senha ou segredo?",
"Issue": "Emitir", "Issue": "Emitir",
"Issues found": "Problemas encontrados", "Issues found": "Problemas encontrados",
+10
View File
@@ -636,6 +636,7 @@
"CT": "CT", "CT": "CT",
"CT started successfully.": "CT bol úspešne spustený.", "CT started successfully.": "CT bol úspešne spustený.",
"CUDA requires a working NVIDIA driver": "CUDA requires pracovný ovládač NVIDIA", "CUDA requires a working NVIDIA driver": "CUDA requires pracovný ovládač NVIDIA",
"CUDA requires the NVIDIA Container Toolkit on the host": "CUDA requires the NVIDIA Container Toolkit na hostiteľovi",
"Calculate all kinds of statistics from your (local) Emby or Jellyfin server": "Vypočítajte všetky druhy štatistík z vášho (miestneho) servera Emby alebo Jellyfin", "Calculate all kinds of statistics from your (local) Emby or Jellyfin server": "Vypočítajte všetky druhy štatistík z vášho (miestneho) servera Emby alebo Jellyfin",
"Calibre is a powerful and easy to use e-book manager. Users say it's outstanding and a must-have. It'll allow you to do nearly everything and it takes things a step beyond normal e-book software. It's also completely free and open source and great for both casual users and computer experts.": "Calibre je výkonný a ľahko použiteľný e-kniha manažér. Užívatelia hovoria, že je vynikajúci a musí mať. To vám umožní robiť takmer všetko a to trvá veci krok za normálne e-knihy softvér. Je to tiež úplne zadarmo a otvorený zdroj a skvelé ako pre príležitostných užívateľov a počítačových odborníkov.", "Calibre is a powerful and easy to use e-book manager. Users say it's outstanding and a must-have. It'll allow you to do nearly everything and it takes things a step beyond normal e-book software. It's also completely free and open source and great for both casual users and computer experts.": "Calibre je výkonný a ľahko použiteľný e-kniha manažér. Užívatelia hovoria, že je vynikajúci a musí mať. To vám umožní robiť takmer všetko a to trvá veci krok za normálne e-knihy softvér. Je to tiež úplne zadarmo a otvorený zdroj a skvelé ako pre príležitostných užívateľov a počítačových odborníkov.",
"Calibre-web is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. It is also possible to integrate google drive and edit metadata and your calibre library through the app itself.": "Calibre-web je webová aplikácia poskytujúca čisté rozhranie pre prehliadanie, čítanie a sťahovanie elektronických kníh pomocou existujúcej databázy Calibre. Je tiež možné integrovať Google disk a upraviť metaúdaje a knižnicu calibre prostredníctvom samotnej aplikácie.", "Calibre-web is a web app providing a clean interface for browsing, reading and downloading eBooks using an existing Calibre database. It is also possible to integrate google drive and edit metadata and your calibre library through the app itself.": "Calibre-web je webová aplikácia poskytujúca čisté rozhranie pre prehliadanie, čítanie a sťahovanie elektronických kníh pomocou existujúcej databázy Calibre. Je tiež možné integrovať Google disk a upraviť metaúdaje a knižnicu calibre prostredníctvom samotnej aplikácie.",
@@ -2448,6 +2449,7 @@
"HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One je obraz spoločenstva, ktorý prevádzkuje Docker vnútri kontajnera. LXC zostáva neprivilegovaný, ale vnútorné profily AppArmor nemusí byť k dispozícii. Prvý štart stiahne Home Assistant jadro a jeho doplnky. Ak kontrola zlyhá, CT a / mnt/ dáta sa uchovávajú na určenie diagnózy.", "HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One je obraz spoločenstva, ktorý prevádzkuje Docker vnútri kontajnera. LXC zostáva neprivilegovaný, ale vnútorné profily AppArmor nemusí byť k dispozícii. Prvý štart stiahne Home Assistant jadro a jeho doplnky. Ak kontrola zlyhá, CT a / mnt/ dáta sa uchovávajú na určenie diagnózy.",
"HAOS One profile declined": "Profil HAOS One klesol", "HAOS One profile declined": "Profil HAOS One klesol",
"HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires an unprivileged unmanaged LXC with nestering and keyctl, 2 cores, 2048 MB RAM, rootfs najmenej 12 GB a /mnt/data najmenej 16 GB on a container volume included in backions", "HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires an unprivileged unmanaged LXC with nestering and keyctl, 2 cores, 2048 MB RAM, rootfs najmenej 12 GB a /mnt/data najmenej 16 GB on a container volume included in backions",
"HTML5 Network Speed Test Server.": "HTML5 Network Speed ​​Test Server.",
"HTTP service check without a saved URL": "Kontrola služby HTTP bez uloženého URL", "HTTP service check without a saved URL": "Kontrola služby HTTP bez uloženého URL",
"Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge napodobňuje Philipsa Spoločnosť Amazon tvrdí, že spoločnosť LuxOpCo by mala mať prístup k webovým stránkam spoločnosti LuxOpCo. Most riadi základné príkazy, ako je On, Off a jas príkazy protokolu odtieňov. Tento most môže ovládať väčšinu zariadení, ktoré majú odlišné API.", "Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge napodobňuje Philipsa Spoločnosť Amazon tvrdí, že spoločnosť LuxOpCo by mala mať prístup k webovým stránkam spoločnosti LuxOpCo. Most riadi základné príkazy, ako je On, Off a jas príkazy protokolu odtieňov. Tento most môže ovládať väčšinu zariadení, ktoré majú odlišné API.",
"HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake je open-source nástroj, postavený dobrovoľníkmi, pre konverziu video z takmer akéhokoľvek formátu na výber moderných, široko podporovaných kodekov.", "HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake je open-source nástroj, postavený dobrovoľníkmi, pre konverziu video z takmer akéhokoľvek formátu na výber moderných, široko podporovaných kodekov.",
@@ -3071,6 +3073,7 @@
"Invalid volume size": "Neplatná veľkosť objemu", "Invalid volume size": "Neplatná veľkosť objemu",
"Invalid volume size:": "Neplatná veľkosť hlasitosti:", "Invalid volume size:": "Neplatná veľkosť hlasitosti:",
"Invalid volume target": "Neplatný cieľ objemu", "Invalid volume target": "Neplatný cieľ objemu",
"IoT & Smart Home": "IoT a inteligentná domácnosť",
"Is the value a password or secret?": "Je hodnota heslo alebo tajomstvo?", "Is the value a password or secret?": "Je hodnota heslo alebo tajomstvo?",
"Issue": "Problém", "Issue": "Problém",
"Issues found": "Nájdené problémy", "Issues found": "Nájdené problémy",
@@ -3166,6 +3169,7 @@
"Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita je profesionálny zadarmo a open source maliarsky program. Je vyrobený umelcami, ktorí chcú vidieť dostupné umelecké nástroje pre každého.", "Krita is a professional FREE and open source painting program. It is made by artists that want to see affordable art tools for everyone.": "Krita je profesionálny zadarmo a open source maliarsky program. Je vyrobený umelcami, ktorí chcú vidieť dostupné umelecké nástroje pre každého.",
"LAN access to the kept containers (stack configuration incomplete):": "Prístup LAN k uloženým kontajnerom (konfigurácia koša neúplná):", "LAN access to the kept containers (stack configuration incomplete):": "Prístup LAN k uloženým kontajnerom (konfigurácia koša neúplná):",
"LAN address applied to the application URLs": "LAN adresa použitá na URL aplikácie", "LAN address applied to the application URLs": "LAN adresa použitá na URL aplikácie",
"LLM App Development Platform": "Platforma vývoja aplikácií LLM",
"LM Studio can run local AI models like gpt-oss, Llama, Gemma, Qwen, and DeepSeek privately on your computer.": "LM Studio môže spustiť miestne modely AI ako Gpt-oss, Llama, Gemma, Qwen, a DeepSeek súkromne na vašom počítači.", "LM Studio can run local AI models like gpt-oss, Llama, Gemma, Qwen, and DeepSeek privately on your computer.": "LM Studio môže spustiť miestne modely AI ako Gpt-oss, Llama, Gemma, Qwen, a DeepSeek súkromne na vašom počítači.",
"LUNs appear as block devices assignable to VMs": "LUNy sa zobrazia ako blokové zariadenia priraditeľné k VM", "LUNs appear as block devices assignable to VMs": "LUNy sa zobrazia ako blokové zariadenia priraditeľné k VM",
"LVM PV headers check completed": "Kontrola LVM PV hlavičiek dokončená", "LVM PV headers check completed": "Kontrola LVM PV hlavičiek dokončená",
@@ -4086,6 +4090,7 @@
"Open the dashboard to create a new admin account:": "Otvorte dashboard a vytvorte nový admin účet:", "Open the dashboard to create a new admin account:": "Otvorte dashboard a vytvorte nový admin účet:",
"Open-source AI-powered coding assistant": "Open-source AI-poháňaný asistent kódovania", "Open-source AI-powered coding assistant": "Open-source AI-poháňaný asistent kódovania",
"Open-source UI for building and debugging multi-agent and RAG applications": "Open-source UI pre stavebné a ladiace multi-agent a RAG aplikácie", "Open-source UI for building and debugging multi-agent and RAG applications": "Open-source UI pre stavebné a ladiace multi-agent a RAG aplikácie",
"Open-source self-hosted SQL IDE.": "Samoobslužné SQL IDE s otvoreným zdrojom.",
"OpenClaw is a personal AI assistant you run on your own devices": "OpenClaw je osobný asistent AI, ktorý beží na svoje vlastné zariadenia", "OpenClaw is a personal AI assistant you run on your own devices": "OpenClaw je osobný asistent AI, ktorý beží na svoje vlastné zariadenia",
"OpenList": "OpenList", "OpenList": "OpenList",
"OpenShot Video Editor is an award-winning free and open-source video editor for Linux, Mac, and Windows, and is dedicated to delivering high quality video editing and animation solutions to the world.": "OpenShot Video Editor je ocenený bezplatný a open-source video editor pre Linux, Mac a Windows a je venovaný poskytovaniu kvalitných riešení pre editáciu videa a animácie svetu.", "OpenShot Video Editor is an award-winning free and open-source video editor for Linux, Mac, and Windows, and is dedicated to delivering high quality video editing and animation solutions to the world.": "OpenShot Video Editor je ocenený bezplatný a open-source video editor pre Linux, Mac a Windows a je venovaný poskytovaniu kvalitných riešení pre editáciu videa a animácie svetu.",
@@ -4329,6 +4334,7 @@
"Please use an SSH session (Linux, macOS, Windows/PuTTY) or a physical console to perform the upgrade.": "Na aktualizáciu použite SSH reláciu (Linux, macOS, Windows/PuTTY) alebo fyzickú konzolu.", "Please use an SSH session (Linux, macOS, Windows/PuTTY) or a physical console to perform the upgrade.": "Na aktualizáciu použite SSH reláciu (Linux, macOS, Windows/PuTTY) alebo fyzickú konzolu.",
"Plex WebUI": "Plex WebUI", "Plex WebUI": "Plex WebUI",
"Plex organizes video, music and photos from personal media libraries and streams them to smart TVs, streaming boxes and mobile devices. This container is packaged as a standalone Plex Media Server. Straightforward design and bulk actions mean getting things done faster.": "Plex organizuje video, hudbu a fotografie z osobných mediálnych knižníc a vysiela ich do smart TV, streaming boxov a mobilných zariadení. Tento kontajner je balený ako samostatný Plex Media Server. Straightforward dizajn a hromadný akcie znamená dostať veci robiť rýchlejšie.", "Plex organizes video, music and photos from personal media libraries and streams them to smart TVs, streaming boxes and mobile devices. This container is packaged as a standalone Plex Media Server. Straightforward design and bulk actions mean getting things done faster.": "Plex organizuje video, hudbu a fotografie z osobných mediálnych knižníc a vysiela ich do smart TV, streaming boxov a mobilných zariadení. Tento kontajner je balený ako samostatný Plex Media Server. Straightforward dizajn a hromadný akcie znamená dostať veci robiť rýchlejšie.",
"PocketBase admin UI": "používateľské rozhranie správcu PocketBase",
"Podcast synchronization service": "Služba synchronizácie podcastov", "Podcast synchronization service": "Služba synchronizácie podcastov",
"Pool does not appear to use SSD/NVMe devices with discard support. Skipping ZFS autotrim for pool:": "Pool pravdepodobne nepoužíva SSD/NVMe zariadenia s podporou discard. ZFS autotrim sa preskočí pre pool:", "Pool does not appear to use SSD/NVMe devices with discard support. Skipping ZFS autotrim for pool:": "Pool pravdepodobne nepoužíva SSD/NVMe zariadenia s podporou discard. ZFS autotrim sa preskočí pre pool:",
"Pool exists": "Pool už existuje", "Pool exists": "Pool už existuje",
@@ -4403,6 +4409,7 @@
"Previous shutdowns": "Predchádzajúce vypnutia", "Previous shutdowns": "Predchádzajúce vypnutia",
"Primary GID for Emby": "Primárne GID pre Emby", "Primary GID for Emby": "Primárne GID pre Emby",
"Privacy-first finance app with envelope budgeting and multi-device sync.": "Privacy-first finance app s obálkou budgeting a multi-device synchronizácia.", "Privacy-first finance app with envelope budgeting and multi-device sync.": "Privacy-first finance app s obálkou budgeting a multi-device synchronizácia.",
"Privacy-first, self-hosted PDF toolkit": "Súprava nástrojov PDF s vlastným hosťovaním na prvom mieste",
"Private installation record saved": "Uložené súkromné záznamy o inštalácii", "Private installation record saved": "Uložené súkromné záznamy o inštalácii",
"Private network assigned automatically:": "Privátne siete pridelené automaticky:", "Private network assigned automatically:": "Privátne siete pridelené automaticky:",
"Private network of the application released:": "Súkromná sieť uvoľnenej žiadosti:", "Private network of the application released:": "Súkromná sieť uvoľnenej žiadosti:",
@@ -5787,6 +5794,7 @@
"The command does not name an image": "Príkaz nepomenuje obrázok", "The command does not name an image": "Príkaz nepomenuje obrázok",
"The command reads its variables from a file; write them in the command or use a Compose file": "Príkaz číta svoje premenné zo súboru; zapíšte ich do príkazu alebo použite súbor", "The command reads its variables from a file; write them in the command or use a Compose file": "Príkaz číta svoje premenné zo súboru; zapíšte ich do príkazu alebo použite súbor",
"The command runs the container as the user of the host; the container uses the user of its image instead.": "Príkaz spustí kontajner ako užívateľ hostiteľa; kontajner používa užívateľa svojho obrazu miesto.", "The command runs the container as the user of the host; the container uses the user of its image instead.": "Príkaz spustí kontajner ako užívateľ hostiteľa; kontajner používa užívateľa svojho obrazu miesto.",
"The command uses options that cannot be translated:": "Príkaz používa možnosti, ktoré nemožno preložiť:",
"The command works out a value by running another command:": "Príkaz vytvorí hodnotu spustením iného príkazu:", "The command works out a value by running another command:": "Príkaz vytvorí hodnotu spustením iného príkazu:",
"The compatibility check raised failures that may break the system after restore.": "Kontrola kompatibility našla zlyhania, ktoré môžu po obnove poškodiť systém.", "The compatibility check raised failures that may break the system after restore.": "Kontrola kompatibility našla zlyhania, ktoré môžu po obnove poškodiť systém.",
"The configuration changed after the backup was restored; the recovery is not confirmed": "Konfigurácia zmenená po obnovení zálohy; obnova nie je potvrdená", "The configuration changed after the backup was restored; the recovery is not confirmed": "Konfigurácia zmenená po obnovení zálohy; obnova nie je potvrdená",
@@ -6783,6 +6791,7 @@
"Webstation is a web native emulation focused LXQt desktop based on Ubuntu.": "Webstation je webová natívne emulácia zameraná LXQt plocha na základe Ubuntu.", "Webstation is a web native emulation focused LXQt desktop based on Ubuntu.": "Webstation je webová natívne emulácia zameraná LXQt plocha na základe Ubuntu.",
"Webtop - Alpine, Ubuntu, Fedora, and Arch based containers containing full desktop environments in officially supported flavors accessible via any modern web browser.": "Webtop - Alpine, Ubuntu, Fedora, a Arch založené kontajnery obsahujúce plné pracovné prostredie v oficiálne podporovaných príchutiach prístupných cez akýkoľvek moderný webový prehliadač.", "Webtop - Alpine, Ubuntu, Fedora, and Arch based containers containing full desktop environments in officially supported flavors accessible via any modern web browser.": "Webtop - Alpine, Ubuntu, Fedora, a Arch založené kontajnery obsahujúce plné pracovné prostredie v oficiálne podporovaných príchutiach prístupných cez akýkoľvek moderný webový prehliadač.",
"Weixin (WeChat) is an instant messaging, social media, and mobile payment app developed by Tencent.": "Weixin (WeChat) je okamžité správy, sociálne médiá, a mobilné platobné aplikácie vyvinuté Tencent.", "Weixin (WeChat) is an instant messaging, social media, and mobile payment app developed by Tencent.": "Weixin (WeChat) je okamžité správy, sociálne médiá, a mobilné platobné aplikácie vyvinuté Tencent.",
"What cannot be translated:": "Čo sa nedá preložiť:",
"What do you want to do?": "Čo chcete urobiť?", "What do you want to do?": "Čo chcete urobiť?",
"What would you like to do?": "Čo chcete urobiť?", "What would you like to do?": "Čo chcete urobiť?",
"When asked to select a disk, click Load Driver and load the VirtIO drivers.": "Keď sa zobrazí výber disku, kliknite na Load Driver a načítajte VirtIO ovládače.", "When asked to select a disk, click Load Driver and load the VirtIO drivers.": "Keď sa zobrazí výber disku, kliknite na Load Driver a načítajte VirtIO ovládače.",
@@ -6901,6 +6910,7 @@
"Zeroing partition": "Nulujem oddiel", "Zeroing partition": "Nulujem oddiel",
"Znc is an IRC network bouncer or BNC. It can detach the client from the actual IRC server, and also from selected channels. Multiple clients from different locations can connect to a single ZNC account simultaneously and therefore appear under the same nickname on IRC.": "Znc je vyhadzovač siete IRC alebo BNC. Môže odpojiť klienta od aktuálneho IRC servera, ako aj od vybraných kanálov. Viacerí klienti z rôznych miest sa môžu pripojiť na jeden ZNC účet súčasne, a preto sa objaví pod rovnakou prezývkou na IRC.", "Znc is an IRC network bouncer or BNC. It can detach the client from the actual IRC server, and also from selected channels. Multiple clients from different locations can connect to a single ZNC account simultaneously and therefore appear under the same nickname on IRC.": "Znc je vyhadzovač siete IRC alebo BNC. Môže odpojiť klienta od aktuálneho IRC servera, ako aj od vybraných kanálov. Viacerí klienti z rôznych miest sa môžu pripojiť na jeden ZNC účet súčasne, a preto sa objaví pod rovnakou prezývkou na IRC.",
"Zotero is a free, easy-to-use tool to help you collect, organize, annotate, cite, and share research.": "Zotero je bezplatný, ľahko použiteľný nástroj, ktorý vám pomôže zhromažďovať, organizovať, anotovať, citovať a zdieľať výskum.", "Zotero is a free, easy-to-use tool to help you collect, organize, annotate, cite, and share research.": "Zotero je bezplatný, ľahko použiteľný nástroj, ktorý vám pomôže zhromažďovať, organizovať, anotovať, citovať a zdieľať výskum.",
"a device it asks for cannot be translated:": "zariadenie, ktoré požaduje, nemožno preložiť:",
"a value is required": "hodnota je required", "a value is required": "hodnota je required",
"aMule WebUI (password only, no username)": "aMule WebUI (iba heslo, žiadne užívateľské meno)", "aMule WebUI (password only, no username)": "aMule WebUI (iba heslo, žiadne užívateľské meno)",
"aMule is a multi-platform client for the ED2K file sharing network and based on the windows client eMule. aMule started in August 2003, as a fork of xMule, which is a fork of lMule.": "aMule je multiplatformový klient pre sieť zdieľania súborov ED2K a založený na eMule klienta okien. aMule začal v auguste 2003, ako fork xMule, čo je fork lMule.", "aMule is a multi-platform client for the ED2K file sharing network and based on the windows client eMule. aMule started in August 2003, as a fork of xMule, which is a fork of lMule.": "aMule je multiplatformový klient pre sieť zdieľania súborov ED2K a založený na eMule klienta okien. aMule začal v auguste 2003, ako fork xMule, čo je fork lMule.",
+21
View File
@@ -431,6 +431,7 @@
"Attempting passthrough with this GPU typically results in": "Försök att passera med denna GPU resulterar vanligtvis i", "Attempting passthrough with this GPU typically results in": "Försök att passera med denna GPU resulterar vanligtvis i",
"Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Observera: Att ta bort prenumerationsbannern kan orsaka problem i webbgränssnittet efter en framtida uppdatering.", "Attention: Removing the subscription banner may cause issues in the web interface after a future update.": "Observera: Att ta bort prenumerationsbannern kan orsaka problem i webbgränssnittet efter en framtida uppdatering.",
"Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity är en lättanvänd, multi-track ljudredigerare och inspelare. Utvecklad av en grupp frivilliga som öppen källkod.", "Audacity is an easy-to-use, multi-track audio editor and recorder. Developed by a group of volunteers as open source.": "Audacity är en lättanvänd, multi-track ljudredigerare och inspelare. Utvecklad av en grupp frivilliga som öppen källkod.",
"Audio device directory": "Ljudenhetskatalog",
"Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf är en själv värd ljudbok och podcast server.", "Audiobookshelf is a self-hosted audiobook and podcast server.": "Audiobookshelf är en själv värd ljudbok och podcast server.",
"Audit completed. Press Enter to continue...": "Revision avslutad. Tryck på Enter för att fortsätta...", "Audit completed. Press Enter to continue...": "Revision avslutad. Tryck på Enter för att fortsätta...",
"Audit socket disabled or not required": "Granskningsuttaget inaktiverat eller inte nödvändigt", "Audit socket disabled or not required": "Granskningsuttaget inaktiverat eller inte nödvändigt",
@@ -2447,6 +2448,7 @@
"HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One är en gemenskapsbild som kör Docker inuti behållaren. LXC är oprivilegierad, men de inre AppArmor-profilerna kanske inte är tillgängliga. Den första starten hämtar Home Assistant Core och dess tillägg. Om kontrollen misslyckas, CT och /mnt / data hålls för diagnos.", "HAOS One is a community image that runs Docker inside the container. The LXC stays unprivileged, but the inner AppArmor profiles may not be available. The first start downloads Home Assistant Core and its add-ons. If the check fails, the CT and /mnt/data are kept for diagnosis.": "HAOS One är en gemenskapsbild som kör Docker inuti behållaren. LXC är oprivilegierad, men de inre AppArmor-profilerna kanske inte är tillgängliga. Den första starten hämtar Home Assistant Core och dess tillägg. Om kontrollen misslyckas, CT och /mnt / data hålls för diagnos.",
"HAOS One profile declined": "HAOS One-profilen minskade", "HAOS One profile declined": "HAOS One-profilen minskade",
"HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires en oprivilegierad ohanterad LXC med häckning och keyctl, 2 kärnor, 2048 MB RAM, rötter på minst 12 GB och /mnt / data på minst 16 GB på en behållarvolym som ingår i backups", "HAOS One requires an unprivileged unmanaged LXC with nesting and keyctl, 2 cores, 2048 MB RAM, rootfs of at least 12 GB and /mnt/data of at least 16 GB on a container volume included in backups": "HAOS One requires en oprivilegierad ohanterad LXC med häckning och keyctl, 2 kärnor, 2048 MB RAM, rötter på minst 12 GB och /mnt / data på minst 16 GB på en behållarvolym som ingår i backups",
"HTML5 Network Speed Test Server.": "HTML5 Network Speed ​​Test Server.",
"HTTP service check without a saved URL": "HTTP service check utan sparad URL", "HTTP service check without a saved URL": "HTTP service check utan sparad URL",
"Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emulerar Philips Hue API till andra hemautomatiseringsgateways som Amazon Echo / Dot Gen 1 (gen 2 har problem med att upptäcka ha-bro) eller andra system som stöder Philips Hue. Bron hanterar grundläggande kommandon som On, Off och ljusstyrka kommandon av nyansprotokollet. Denna bro kan styra de flesta enheter som har ett tydligt API.", "Habridge emulates Philips Hue API to other home automation gateways such as an Amazon Echo/Dot Gen 1 (gen 2 has issues discovering ha-bridge) or other systems that support Philips Hue. The Bridge handles basic commands such as On, Off and brightness commands of the hue protocol. This bridge can control most devices that have a distinct API.": "Habridge emulerar Philips Hue API till andra hemautomatiseringsgateways som Amazon Echo / Dot Gen 1 (gen 2 har problem med att upptäcka ha-bro) eller andra system som stöder Philips Hue. Bron hanterar grundläggande kommandon som On, Off och ljusstyrka kommandon av nyansprotokollet. Denna bro kan styra de flesta enheter som har ett tydligt API.",
"HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake är ett open-source verktyg, byggt av volontärer, för att konvertera video från nästan alla format till ett urval av moderna, allmänt stödda codecs.", "HandBrake is an open-source tool, built by volunteers, for converting video from nearly any format to a selection of modern, widely supported codecs.": "HandBrake är ett open-source verktyg, byggt av volontärer, för att konvertera video från nästan alla format till ett urval av moderna, allmänt stödda codecs.",
@@ -2924,6 +2926,7 @@
"Intel render device for recognition": "Intel render enhet för erkännande", "Intel render device for recognition": "Intel render enhet för erkännande",
"Intel/AMD (VA-API and QSV)": "Intel/AMD (VA-API och QSV)", "Intel/AMD (VA-API and QSV)": "Intel/AMD (VA-API och QSV)",
"Intel/AMD (VA-API)": "Intel/AMD (VA-API)", "Intel/AMD (VA-API)": "Intel/AMD (VA-API)",
"Intel/AMD (streaming rendering and encoding)": "Intel/AMD (strömmande rendering och kodning)",
"Intel/AMD VA-API": "Intel/AMD VA-API", "Intel/AMD VA-API": "Intel/AMD VA-API",
"Intel/AMD VA-API (no OpenCL mod)": "Intel/AMD VA-API (ingen OpenCL-mod)", "Intel/AMD VA-API (no OpenCL mod)": "Intel/AMD VA-API (ingen OpenCL-mod)",
"Intel/AMD render node": "Intel/AMD gör nod", "Intel/AMD render node": "Intel/AMD gör nod",
@@ -2952,6 +2955,7 @@
"Invalid Intel render path": "Invalid Intel render bana", "Invalid Intel render path": "Invalid Intel render bana",
"Invalid Jellyfin path:": "Invalid Jellyfin väg:", "Invalid Jellyfin path:": "Invalid Jellyfin väg:",
"Invalid MAC address:": "Ogiltig MAC-adress:", "Invalid MAC address:": "Ogiltig MAC-adress:",
"Invalid NVIDIA destination": "Ogiltig NVIDIA-destination",
"Invalid NVIDIA device:": "Invalid NVIDIA-enhet:", "Invalid NVIDIA device:": "Invalid NVIDIA-enhet:",
"Invalid Nextcloud volume": "Ogiltig Nextcloud volym", "Invalid Nextcloud volume": "Ogiltig Nextcloud volym",
"Invalid OCI Entrypoint": "Ogiltig OCI Entrypoint", "Invalid OCI Entrypoint": "Ogiltig OCI Entrypoint",
@@ -2960,6 +2964,7 @@
"Invalid Option": "Ogiltigt alternativ", "Invalid Option": "Ogiltigt alternativ",
"Invalid Path": "Ogiltig sökväg", "Invalid Path": "Ogiltig sökväg",
"Invalid Proxmox inventory": "Invalid Proxmox inventering", "Invalid Proxmox inventory": "Invalid Proxmox inventering",
"Invalid Python index:": "Ogiltigt Python-index:",
"Invalid Python module:": "Invalid Python modul:", "Invalid Python module:": "Invalid Python modul:",
"Invalid Python package:": "Invalid Python-paket:", "Invalid Python package:": "Invalid Python-paket:",
"Invalid Python path in the repair:": "Invalid Python väg i reparationen:", "Invalid Python path in the repair:": "Invalid Python väg i reparationen:",
@@ -3000,6 +3005,7 @@
"Invalid host kernel module name:": "Invalid värd kernel modul namn:", "Invalid host kernel module name:": "Invalid värd kernel modul namn:",
"Invalid host monitor PID": "Invalid värd monitor PID", "Invalid host monitor PID": "Invalid värd monitor PID",
"Invalid host path:": "Invalid värdväg:", "Invalid host path:": "Invalid värdväg:",
"Invalid image probe descriptor": "Ogiltig bildsondsbeskrivning",
"Invalid input": "Ogiltig inmatning", "Invalid input": "Ogiltig inmatning",
"Invalid internal volume": "Invalid intern volym", "Invalid internal volume": "Invalid intern volym",
"Invalid list:": "Invalid lista:", "Invalid list:": "Invalid lista:",
@@ -3014,6 +3020,7 @@
"Invalid mount type": "Ogiltig montering typ", "Invalid mount type": "Ogiltig montering typ",
"Invalid name": "Ogiltigt namn", "Invalid name": "Ogiltigt namn",
"Invalid name. Use only letters, numbers, hyphens and underscores.": "Ogiltigt namn. Använd endast bokstäver, siffror, bindestreck och understreck.", "Invalid name. Use only letters, numbers, hyphens and underscores.": "Ogiltigt namn. Använd endast bokstäver, siffror, bindestreck och understreck.",
"Invalid native entrypoint": "Ogiltig ursprunglig ingångspunkt",
"Invalid octal permissions": "Ogiltiga okta tillstånd", "Invalid octal permissions": "Ogiltiga okta tillstånd",
"Invalid option": "Ogiltigt alternativ", "Invalid option": "Ogiltigt alternativ",
"Invalid option, please try again.": "Ogiltigt alternativ, försök igen.", "Invalid option, please try again.": "Ogiltigt alternativ, försök igen.",
@@ -3042,8 +3049,10 @@
"Invalid service check arguments": "Invalid service check argument", "Invalid service check arguments": "Invalid service check argument",
"Invalid service check timeout": "Ogiltig service check timeout", "Invalid service check timeout": "Ogiltig service check timeout",
"Invalid shared path": "Invalid delad väg", "Invalid shared path": "Invalid delad väg",
"Invalid shutdown timeout": "Ogiltig avstängningstid",
"Invalid size. Please enter a number in MB (e.g., 128, 256, 512).": "Ogiltig storlek. Ange ett nummer i MB (t.ex. 128, 256, 512).", "Invalid size. Please enter a number in MB (e.g., 128, 256, 512).": "Ogiltig storlek. Ange ett nummer i MB (t.ex. 128, 256, 512).",
"Invalid stack contract": "Invalid stack kontrakt", "Invalid stack contract": "Invalid stack kontrakt",
"Invalid stack journal": "Ogiltig stackjournal",
"Invalid stack members": "Ogiltiga stackmedlemmar", "Invalid stack members": "Ogiltiga stackmedlemmar",
"Invalid stack name": "Invalid stack namn", "Invalid stack name": "Invalid stack namn",
"Invalid stack operation": "Ogiltig stack operation", "Invalid stack operation": "Ogiltig stack operation",
@@ -3060,6 +3069,7 @@
"Invalid volume size": "Invalid volymstorlek", "Invalid volume size": "Invalid volymstorlek",
"Invalid volume size:": "Ogiltig volymstorlek:", "Invalid volume size:": "Ogiltig volymstorlek:",
"Invalid volume target": "Ogiltigt volymmål", "Invalid volume target": "Ogiltigt volymmål",
"IoT & Smart Home": "IoT och smarta hem",
"Is the value a password or secret?": "Är värdet ett lösenord eller en hemlighet?", "Is the value a password or secret?": "Är värdet ett lösenord eller en hemlighet?",
"Issue": "Utfärda", "Issue": "Utfärda",
"Issues found": "Problem hittades", "Issues found": "Problem hittades",
@@ -3090,6 +3100,7 @@
"Jellyfin did not create encoding.xml before the timeout": "Jellyfin skapade inte encoding.xml före timeout", "Jellyfin did not create encoding.xml before the timeout": "Jellyfin skapade inte encoding.xml före timeout",
"Jellyfin has not created encoding.xml in any declared path": "Jellyfin har inte skapat kodning.xml i någon förklarad väg", "Jellyfin has not created encoding.xml in any declared path": "Jellyfin har inte skapat kodning.xml i någon förklarad väg",
"Jellyseerr is a free and open source software application for managing requests for your media library.": "Jellyseerr är en fri och öppen källkod program för hantering av förfrågningar för ditt mediebibliotek.", "Jellyseerr is a free and open source software application for managing requests for your media library.": "Jellyseerr är en fri och öppen källkod program för hantering av förfrågningar för ditt mediebibliotek.",
"Jenkins Continuous Integration and Delivery server.": "Jenkins kontinuerliga integrations- och leveransserver.",
"Jenkins unlock": "Jenkins låser upp", "Jenkins unlock": "Jenkins låser upp",
"Job ID (letters, numbers, - _)": "Jobb-ID (bokstäver, siffror, - _)", "Job ID (letters, numbers, - _)": "Jobb-ID (bokstäver, siffror, - _)",
"Job ID:": "Jobb-ID:", "Job ID:": "Jobb-ID:",
@@ -3384,6 +3395,7 @@
"Mirror URL not available for this script.": "Mirror URL inte tillgänglig för det här skriptet.", "Mirror URL not available for this script.": "Mirror URL inte tillgänglig för det här skriptet.",
"Miscellaneous": "Miscellan", "Miscellaneous": "Miscellan",
"Missing": "Saknad", "Missing": "Saknad",
"Missing OCI metadata:": "OCI-metadata saknas:",
"Missing commands after installation:": "Saknade kommandon efter installation:", "Missing commands after installation:": "Saknade kommandon efter installation:",
"Missing dependency": "Saknat beroende", "Missing dependency": "Saknat beroende",
"Missing native directive:": "Missing native direktiv:", "Missing native directive:": "Missing native direktiv:",
@@ -3460,6 +3472,7 @@
"Mount point removed successfully": "Monteringspunkten har tagits bort", "Mount point removed successfully": "Monteringspunkten har tagits bort",
"Mount point:": "Monteringspunkt:", "Mount point:": "Monteringspunkt:",
"Mount points added:": "Mount poäng tillsatt:", "Mount points added:": "Mount poäng tillsatt:",
"Mount read-only": "Montera skrivskyddad",
"Mount shares on HOST first": "Montera andelar på HOST först", "Mount shares on HOST first": "Montera andelar på HOST först",
"Mount specific dataset": "Montera specifik datauppsättning", "Mount specific dataset": "Montera specifik datauppsättning",
"Mount status:": "Monteringsstatus:", "Mount status:": "Monteringsstatus:",
@@ -4010,6 +4023,7 @@
"OCI manager Apps is a beta: if something does not work as expected, please report it on GitHub with the application name.": "OCI Manager Apps är en beta: om något inte fungerar som förväntat, vänligen rapportera det på GitHub med applikationsnamnet.", "OCI manager Apps is a beta: if something does not work as expected, please report it on GitHub with the application name.": "OCI Manager Apps är en beta: om något inte fungerar som förväntat, vänligen rapportera det på GitHub med applikationsnamnet.",
"OCI metadata integrity mismatch": "OCI metadata integritet mismatch", "OCI metadata integrity mismatch": "OCI metadata integritet mismatch",
"OCI metadata too large": "OCI metadata för stor", "OCI metadata too large": "OCI metadata för stor",
"OCI stack management": "OCI stackhantering",
"OCI verification failed:": "OCI-verifiering misslyckades:", "OCI verification failed:": "OCI-verifiering misslyckades:",
"OCR language (Tesseract code)": "OCR-språk (Tesseract code)", "OCR language (Tesseract code)": "OCR-språk (Tesseract code)",
"OK": "OK", "OK": "OK",
@@ -4549,6 +4563,7 @@
"Reading SMART data...": "Läser SMART-data...", "Reading SMART data...": "Läser SMART-data...",
"Reading SMART self-test log...": "Läser SMART självtestlogg...", "Reading SMART self-test log...": "Läser SMART självtestlogg...",
"Reading full SMART report...": "Läser hela SMART-rapporten...", "Reading full SMART report...": "Läser hela SMART-rapporten...",
"Real-time Performance Monitoring": "Prestandaövervakning i realtid",
"Real-time bandwidth usage (press q to exit)": "Användning av bandbredd i realtid (tryck på q för att avsluta)", "Real-time bandwidth usage (press q to exit)": "Användning av bandbredd i realtid (tryck på q för att avsluta)",
"Real-time collaborative document editor": "Realtidssamverkan dokument redaktör", "Real-time collaborative document editor": "Realtidssamverkan dokument redaktör",
"Real-time network monitoring (press q to exit)": "Nätverksövervakning i realtid (tryck på q för att avsluta)", "Real-time network monitoring (press q to exit)": "Nätverksövervakning i realtid (tryck på q för att avsluta)",
@@ -5203,6 +5218,7 @@
"Selection": "Urval", "Selection": "Urval",
"Self-custodial Bitcoin Lightning wallet with integrated node and app connections.": "Självhäktande Bitcoin Lightning plånbok med integrerade nod- och appanslutningar.", "Self-custodial Bitcoin Lightning wallet with integrated node and app connections.": "Självhäktande Bitcoin Lightning plånbok med integrerade nod- och appanslutningar.",
"Self-hosted ZeroTier network controller with web UI for centralized management.": "Self-hosted ZeroTier nätverkskontroller med webb-UI för centraliserad förvaltning.", "Self-hosted ZeroTier network controller with web UI for centralized management.": "Self-hosted ZeroTier nätverkskontroller med webb-UI för centraliserad förvaltning.",
"Self-hosted cloud data migration & sync manager": "Self-hosted molndatamigrerings- och synkroniseringshanterare",
"Self-hosted collaborative bookmark manager to collect, read, annotate, and fully preserve what matters, all in one place.": "Self-hosted collaborative bookmark manager för att samla, läsa, notera och helt bevara vad som är viktigt, allt på ett ställe.", "Self-hosted collaborative bookmark manager to collect, read, annotate, and fully preserve what matters, all in one place.": "Self-hosted collaborative bookmark manager för att samla, läsa, notera och helt bevara vad som är viktigt, allt på ett ställe.",
"Self-hosted file sharing with a modern web interface": "Självhäftad fildelning med ett modernt webbgränssnitt", "Self-hosted file sharing with a modern web interface": "Självhäftad fildelning med ett modernt webbgränssnitt",
"Self-hosted file toolkit for images, video, audio, PDFs, and files": "Självvärd filverktyg för bilder, video, ljud, PDF-filer och filer", "Self-hosted file toolkit for images, video, audio, PDFs, and files": "Självvärd filverktyg för bilder, video, ljud, PDF-filer och filer",
@@ -6426,12 +6442,16 @@
"Unsupported device type:": "Ostödd enhetstyp:", "Unsupported device type:": "Ostödd enhetstyp:",
"Unsupported dynamic NVIDIA capabilities:": "Ostödd dynamisk NVIDIA-kapacitet:", "Unsupported dynamic NVIDIA capabilities:": "Ostödd dynamisk NVIDIA-kapacitet:",
"Unsupported format. Only .ova and .ovf files are supported.": "Format som inte stöds. Endast .ova- och .ovf-filer stöds.", "Unsupported format. Only .ova and .ovf files are supported.": "Format som inte stöds. Endast .ova- och .ovf-filer stöds.",
"Unsupported media storage mode:": "Medialagringsläge som inte stöds:",
"Unsupported mount type": "Unsupported Mount Typ", "Unsupported mount type": "Unsupported Mount Typ",
"Unsupported mount type:": "Unsupported Mount Typ:", "Unsupported mount type:": "Unsupported Mount Typ:",
"Unsupported native device type:": "Inbyggd enhetstyp som inte stöds:",
"Unsupported operation": "Unsupported operation", "Unsupported operation": "Unsupported operation",
"Unsupported output format:": "Utdataformat som inte stöds:", "Unsupported output format:": "Utdataformat som inte stöds:",
"Unsupported post-start configuration:": "Unsupported post-start konfiguration:", "Unsupported post-start configuration:": "Unsupported post-start konfiguration:",
"Unsupported pre-start check:": "Kontroll före start som inte stöds:",
"Unsupported pre-start repair:": "Unsupported pre-start reparation:", "Unsupported pre-start repair:": "Unsupported pre-start reparation:",
"Unsupported prlimit resource": "Prlimit-resurs som inte stöds",
"Unsupported secret generator:": "Ostödd hemlig generator:", "Unsupported secret generator:": "Ostödd hemlig generator:",
"Unsupported storage mode:": "Ostödd lagringsläge:", "Unsupported storage mode:": "Ostödd lagringsläge:",
"Unsupported tmpfs options": "Ostödda tmpfs alternativ", "Unsupported tmpfs options": "Ostödda tmpfs alternativ",
@@ -6588,6 +6608,7 @@
"VFIO modules removed from /etc/modules": "VFIO-moduler har tagits bort från /etc/modules", "VFIO modules removed from /etc/modules": "VFIO-moduler har tagits bort från /etc/modules",
"VFIO orphans cleared and initramfs rebuilt — next boot will free the GPU.": "VFIO föräldralösa enheter rensades och initramfs återuppbyggda — nästa uppstart kommer att frigöra GPU:n.", "VFIO orphans cleared and initramfs rebuilt — next boot will free the GPU.": "VFIO föräldralösa enheter rensades och initramfs återuppbyggda — nästa uppstart kommer att frigöra GPU:n.",
"VFIO orphans cleared but initramfs rebuild failed; check /var/log/proxmenux logs.": "VFIO föräldralösa enheter rensades men återuppbyggnaden av initramfs misslyckades; kontrollera /var/log/proxmenux loggar.", "VFIO orphans cleared but initramfs rebuild failed; check /var/log/proxmenux logs.": "VFIO föräldralösa enheter rensades men återuppbyggnaden av initramfs misslyckades; kontrollera /var/log/proxmenux loggar.",
"VFS cache mode": "VFS-cacheläge",
"VLAN": "VLAN", "VLAN": "VLAN",
"VLC Media Player is a free and open source cross-platform multimedia player and framework that delivers dependable performance across multiple devices.": "VLC media Spelare är en fri och öppen källkod multimediaspelare och ram som levererar pålitlig prestanda över flera enheter.", "VLC Media Player is a free and open source cross-platform multimedia player and framework that delivers dependable performance across multiple devices.": "VLC media Spelare är en fri och öppen källkod multimediaspelare och ram som levererar pålitlig prestanda över flera enheter.",
"VM": "VM", "VM": "VM",
+14 -2
View File
@@ -394,8 +394,14 @@ _create_job_attached() {
local -a jobs=() local -a jobs=()
mapfile -t jobs < <(hb_pve_list_vzdump_jobs_for_backend "$backend") mapfile -t jobs < <(hb_pve_list_vzdump_jobs_for_backend "$backend")
if (( ${#jobs[@]} == 0 )); then if (( ${#jobs[@]} == 0 )); then
local empty_message
if [[ "$backend" == "pbs" ]]; then
empty_message=$(translate "No matching PVE vzdump jobs were found for the PBS backend.")
else
empty_message=$(translate "No matching PVE vzdump jobs were found for the local archive backend.")
fi
dialog --backtitle "ProxMenux" --title "$(translate "No compatible PVE jobs")" \ dialog --backtitle "ProxMenux" --title "$(translate "No compatible PVE jobs")" \
--msgbox "$(translate "No PVE vzdump job uses a") $backend $(translate "storage.")" 8 70 --msgbox "$empty_message" 8 70
return 1 return 1
fi fi
@@ -559,8 +565,14 @@ _create_job() {
# If no compatible PVE job exists yet, show a helpful pointer # If no compatible PVE job exists yet, show a helpful pointer
# instead of silently dropping back to "new" mode. # instead of silently dropping back to "new" mode.
if [[ -z "$(hb_pve_list_vzdump_jobs_for_backend "$backend" 2>/dev/null | head -1)" ]]; then if [[ -z "$(hb_pve_list_vzdump_jobs_for_backend "$backend" 2>/dev/null | head -1)" ]]; then
local empty_message
if [[ "$backend" == "pbs" ]]; then
empty_message=$(translate "No matching PVE vzdump jobs were found for the PBS backend.")
else
empty_message=$(translate "No matching PVE vzdump jobs were found for the local archive backend.")
fi
dialog --backtitle "ProxMenux" --title "$(translate "No compatible PVE jobs")" \ dialog --backtitle "ProxMenux" --title "$(translate "No compatible PVE jobs")" \
--msgbox "$(translate "No PVE vzdump job uses a") $backend $(translate "storage yet.")"$'\n\n'"$(translate "Create one first in Datacenter → Backup, then return here to attach.")" \ --msgbox "$empty_message"$'\n\n'"$(translate "Create one first in Datacenter → Backup, then return here to attach.")" \
12 78 12 78
return 1 return 1
fi fi
+1 -1
View File
@@ -382,7 +382,7 @@ show_storage_commands() {
echo -en "\n${TAB}${BOLD}${YW}${HOLD}$(translate 'Enter full path to the disk image (e.g., /var/lib/vz/images/xyz.img): ')${CL}" echo -en "\n${TAB}${BOLD}${YW}${HOLD}$(translate 'Enter full path to the disk image (e.g., /var/lib/vz/images/xyz.img): ')${CL}"
read -r image_path read -r image_path
echo -e "\n${YELLOW}$(translate 'Available storage volumes:')${NC}" echo -e "\n${YELLOW}$(translate 'Storage IDs:')${NC}"
pvesm status | awk 'NR>1 {print " - "$1}' pvesm status | awk 'NR>1 {print " - "$1}'
echo -en "\n${TAB}${BOLD}${YW}${HOLD}$(translate 'Enter target storage name (e.g., local-lvm): ')${CL}" echo -en "\n${TAB}${BOLD}${YW}${HOLD}$(translate 'Enter target storage name (e.g., local-lvm): ')${CL}"
+17 -17
View File
@@ -218,7 +218,7 @@ validate_guest_access() {
local server="$1" local server="$1"
show_proxmenux_logo show_proxmenux_logo
msg_info "$(translate "Testing comprehensive guest access to server") $server..." msg_info "$(translate "Testing guest listing and share access on server") $server..."
GUEST_LIST_OUTPUT=$(smbclient -L "$server" -N 2>&1) GUEST_LIST_OUTPUT=$(smbclient -L "$server" -N 2>&1)
GUEST_LIST_RESULT=$? GUEST_LIST_RESULT=$?
@@ -226,12 +226,12 @@ validate_guest_access() {
if [[ $GUEST_LIST_RESULT -ne 0 ]]; then if [[ $GUEST_LIST_RESULT -ne 0 ]]; then
cleanup cleanup
if echo "$GUEST_LIST_OUTPUT" | grep -qi "access denied\|logon failure"; then if echo "$GUEST_LIST_OUTPUT" | grep -qi "access denied\|logon failure"; then
whiptail --title "$(translate "Guest Access Denied")" \ whiptail --title "$(translate "Guest Listing Failed")" \
--msgbox "$(translate "Guest access is not allowed on this server.")\n\n$(translate "You need to use username and password authentication.")" \ --msgbox "$(translate "Guest share listing failed.")\n\n$(translate "Try username and password authentication.")" \
10 70 10 70
else else
whiptail --title "$(translate "Guest Access Error")" \ whiptail --title "$(translate "Guest Listing Failed")" \
--msgbox "$(translate "Guest access failed.")\n\n$(translate "Error details:")\n$(echo "$GUEST_LIST_OUTPUT" | head -3)" \ --msgbox "$(translate "Guest share listing failed.")\n\n$(translate "Error details:")\n$(echo "$GUEST_LIST_OUTPUT" | head -3)" \
12 70 12 70
fi fi
return 1 return 1
@@ -241,13 +241,13 @@ validate_guest_access() {
GUEST_SHARES=$(echo "$GUEST_LIST_OUTPUT" | awk '/Disk/ && !/IPC\$/ && !/ADMIN\$/ && !/print\$/ {print $1}' | grep -v "^$") GUEST_SHARES=$(echo "$GUEST_LIST_OUTPUT" | awk '/Disk/ && !/IPC\$/ && !/ADMIN\$/ && !/print\$/ {print $1}' | grep -v "^$")
if [[ -z "$GUEST_SHARES" ]]; then if [[ -z "$GUEST_SHARES" ]]; then
whiptail --title "$(translate "No Guest Shares")" \ whiptail --title "$(translate "No Shares to Test")" \
--msgbox "$(translate "Guest access works for listing, but no shares are available.")\n\n$(translate "The server may require authentication for actual share access.")" \ --msgbox "$(translate "No disk shares were selected from the guest listing.")\n\n$(translate "The server may require authentication for actual share access.")" \
10 70 12 70
return 1 return 1
fi fi
msg_ok "$(translate "Found guest-accessible shares:") $(echo "$GUEST_SHARES" | wc -l)" msg_ok "$(translate "Shares selected from guest listing:") $(echo "$GUEST_SHARES" | wc -l)"
msg_info "$(translate "Step 2: Testing actual share access with guest...")" msg_info "$(translate "Step 2: Testing actual share access with guest...")"
ACCESSIBLE_SHARES="" ACCESSIBLE_SHARES=""
@@ -265,15 +265,15 @@ validate_guest_access() {
echo -e echo -e
ACCESSIBLE_SHARES="$ACCESSIBLE_SHARES$share\n" ACCESSIBLE_SHARES="$ACCESSIBLE_SHARES$share\n"
else else
msg_error "$(translate "Guest access denied for share:") $share" msg_error "$(translate "Guest access test failed for share:") $share"
FAILED_SHARES="$FAILED_SHARES$share\n" FAILED_SHARES="$FAILED_SHARES$share\n"
if echo "$SHARE_TEST_OUTPUT" | grep -qi "access denied\|logon failure\|authentication"; then if echo "$SHARE_TEST_OUTPUT" | grep -qi "access denied\|logon failure\|authentication"; then
msg_warn " $(translate "Reason: Authentication required")" msg_warn " $(translate "Test output mentions authentication or access denial.")"
elif echo "$SHARE_TEST_OUTPUT" | grep -qi "permission denied"; then elif echo "$SHARE_TEST_OUTPUT" | grep -qi "permission denied"; then
msg_warn " $(translate "Reason: Permission denied")" msg_warn " $(translate "Test output reports permission denied.")"
else else
msg_warn " $(translate "Reason: Access denied")" msg_warn " $(translate "The guest access test did not succeed.")"
fi fi
fi fi
fi fi
@@ -287,7 +287,7 @@ validate_guest_access() {
msg_info2 "$(translate "Guest Access Validation Results:")" msg_info2 "$(translate "Guest Access Validation Results:")"
echo -e "${TAB}${BGN}$(translate "Shares found:")${CL} ${BL}$(echo "$GUEST_SHARES" | wc -l)${CL}" echo -e "${TAB}${BGN}$(translate "Shares found:")${CL} ${BL}$(echo "$GUEST_SHARES" | wc -l)${CL}"
echo -e "${TAB}${BGN}$(translate "Guest accessible:")${CL} ${GN}$ACCESSIBLE_COUNT${CL}" echo -e "${TAB}${BGN}$(translate "Guest accessible:")${CL} ${GN}$ACCESSIBLE_COUNT${CL}"
echo -e "${TAB}${BGN}$(translate "Authentication required:")${CL} ${YW}$FAILED_COUNT${CL}" echo -e "${TAB}${BGN}$(translate "Guest share access tests failed:")${CL} ${YW}$FAILED_COUNT${CL}"
if [[ $ACCESSIBLE_COUNT -gt 0 ]]; then if [[ $ACCESSIBLE_COUNT -gt 0 ]]; then
msg_ok "$(translate "Guest access validated successfully!")" msg_ok "$(translate "Guest access validated successfully!")"
@@ -307,7 +307,7 @@ validate_guest_access() {
msg_success "$(translate "Press Enter to continue...")" msg_success "$(translate "Press Enter to continue...")"
read -r read -r
whiptail --title "$(translate "Guest Access Failed")" \ whiptail --title "$(translate "Guest Access Failed")" \
--msgbox "$(translate "While the server allows guest listing, no shares are actually accessible without authentication.")\n\n$(translate "You need to use username and password authentication.")" \ --msgbox "$(translate "No share access test succeeded with guest authentication.")\n\n$(translate "Try username and password authentication.")" \
12 70 12 70
clear clear
return 1 return 1
@@ -322,7 +322,7 @@ validate_guest_access() {
get_samba_credentials() { get_samba_credentials() {
while true; do while true; do
CHOICE=$(whiptail --title "$(translate "Samba Credentials")" \ CHOICE=$(whiptail --title "$(translate "Samba Credentials")" \
--menu "$(translate "Select authentication mode:")" 13 60 2 \ --menu "$(translate "Select authentication mode:")" 0 0 2 \
"1" "$(translate "Configure with username and password")" \ "1" "$(translate "Configure with username and password")" \
"2" "$(translate "Configure as guest (no authentication)")" \ "2" "$(translate "Configure as guest (no authentication)")" \
3>&1 1>&2 2>&3) 3>&1 1>&2 2>&3)
@@ -480,7 +480,7 @@ EOF
esac esac
if ! whiptail --yesno "$(translate "Authentication failed.")\n\n$(translate "Do you want to try different credentials or authentication method?")" 10 70 --title "$(translate "Try Again")"; then if ! whiptail --yesno "$(translate "Samba access setup did not complete.")\n\n$(translate "Do you want to try different credentials or authentication method?")" 10 70 --title "$(translate "Try Again")"; then
return 1 return 1
fi fi
+3 -3
View File
@@ -141,7 +141,7 @@ function select_disk_type() {
# Select Virtual Disks # Select Virtual Disks
# ========================================================== # ==========================================================
function select_virtual_disk() { function select_virtual_disk() {
msg_info "Detecting available storage volumes..." msg_info "$(translate "Detecting storage for disk images...")"
local STORAGE_MENU=() local STORAGE_MENU=()
local TAG TYPE FREE ITEM local TAG TYPE FREE ITEM
@@ -165,8 +165,8 @@ function select_virtual_disk() {
STORAGE=${STORAGE_MENU[0]} STORAGE=${STORAGE_MENU[0]}
else else
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1 [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage Volume")" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage")" --radiolist \
"$(translate "Choose the storage volume for the virtual disk:\n")" 20 78 10 \ "$(translate "Choose the storage for the virtual disk:")"$'\n' 20 78 10 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3)
if [ $? -ne 0 ] || [ -z "$STORAGE" ]; then if [ $? -ne 0 ] || [ -z "$STORAGE" ]; then
+6 -6
View File
@@ -540,7 +540,7 @@ function select_disk_type() {
} }
function select_virtual_disk() { function select_virtual_disk() {
msg_info "Detecting available storage volumes..." msg_info "$(translate "Detecting storage for disk images...")"
local STORAGE_MENU=() local STORAGE_MENU=()
local TAG TYPE FREE ITEM local TAG TYPE FREE ITEM
@@ -564,8 +564,8 @@ function select_virtual_disk() {
STORAGE=${STORAGE_MENU[0]} STORAGE=${STORAGE_MENU[0]}
else else
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1 [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage Volume")" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage")" --radiolist \
"$(translate "Choose the storage volume for the virtual disk:\n")" 20 78 10 \ "$(translate "Choose the storage for the virtual disk:")"$'\n' 20 78 10 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || return 0 "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || return 0
[[ -z "$STORAGE" ]] && return 0 [[ -z "$STORAGE" ]] && return 0
fi fi
@@ -953,7 +953,7 @@ function select_efi_storage() {
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" > /dev/null 2>&1 [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" > /dev/null 2>&1
while [ -z "${STORAGE:+x}" ]; do while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "EFI Disk Storage" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "EFI Disk Storage" --radiolist \
"$(translate "Choose the storage volume for the EFI disk (4MB):\n\nUse Spacebar to select.")" \ "$(translate "Choose the storage for the EFI disk (4MB):")"$'\n\n'"$(translate "Use Spacebar to select.")" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || { "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_warn "$(translate "EFI storage selection cancelled.")" >&2 msg_warn "$(translate "EFI storage selection cancelled.")" >&2
@@ -1004,8 +1004,8 @@ function select_storage_volume() {
STORAGE=${STORAGE_MENU[0]} STORAGE=${STORAGE_MENU[0]}
else else
while [ -z "${STORAGE:+x}" ]; do while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "Storage Pools" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage")" --radiolist \
"$(translate "Choose the storage volume for $purpose:\n\nUse Spacebar to select.")" \ "$(translate "Choose the storage for the loader disk:")"$'\n\n'"$(translate "Use Spacebar to select.")" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || { "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_warn "$(translate "Storage selection cancelled for $purpose.")" >&2 msg_warn "$(translate "Storage selection cancelled for $purpose.")" >&2
+7 -1
View File
@@ -179,8 +179,14 @@ function select_storage_target() {
STORAGE="${STORAGE_MENU[0]}" STORAGE="${STORAGE_MENU[0]}"
else else
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1 [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1
local storage_prompt
case "$PURPOSE" in
EFI) storage_prompt=$(translate "Choose the storage for the EFI disk (4MB):") ;;
TPM) storage_prompt=$(translate "Choose the storage for the TPM disk (4MB):") ;;
*) storage_prompt=$(translate "Choose the storage volume for the $PURPOSE disk (4MB):") ;;
esac
STORAGE=$(whiptail --backtitle "ProxMenux" --title "$(translate "$PURPOSE Disk Storage")" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenux" --title "$(translate "$PURPOSE Disk Storage")" --radiolist \
"$(translate "Choose the storage volume for the $PURPOSE disk (4MB):\n\nUse Spacebar to select.")" 16 70 6 \ "$storage_prompt"$'\n\n'"$(translate "Use Spacebar to select.")" 16 70 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || { "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_warn "$(translate "$PURPOSE disk storage selection cancelled.")" >&2 msg_warn "$(translate "$PURPOSE disk storage selection cancelled.")" >&2
return 1 return 1
+6 -6
View File
@@ -555,7 +555,7 @@ function select_disk_type() {
} }
function select_virtual_disk() { function select_virtual_disk() {
msg_info "Detecting available storage volumes..." msg_info "$(translate "Detecting storage for disk images...")"
local STORAGE_MENU=() local STORAGE_MENU=()
local TAG TYPE FREE ITEM local TAG TYPE FREE ITEM
@@ -579,8 +579,8 @@ function select_virtual_disk() {
STORAGE=${STORAGE_MENU[0]} STORAGE=${STORAGE_MENU[0]}
else else
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1 [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" >/dev/null 2>&1
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage Volume")" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage")" --radiolist \
"$(translate "Choose the storage volume for the virtual disk:\n")" 20 78 10 \ "$(translate "Choose the storage for the virtual disk:")"$'\n' 20 78 10 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || return 0 "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || return 0
[[ -z "$STORAGE" ]] && return 0 [[ -z "$STORAGE" ]] && return 0
fi fi
@@ -990,7 +990,7 @@ function select_efi_storage() {
[[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" > /dev/null 2>&1 [[ -n "${SPINNER_PID:-}" ]] && kill "$SPINNER_PID" > /dev/null 2>&1
while [ -z "${STORAGE:+x}" ]; do while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "EFI Disk Storage" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "EFI Disk Storage" --radiolist \
"$(translate "Choose the storage volume for the EFI disk (4MB):\n\nUse Spacebar to select.")" \ "$(translate "Choose the storage for the EFI disk (4MB):")"$'\n\n'"$(translate "Use Spacebar to select.")" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || { "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_warn "$(translate "EFI storage selection cancelled.")" >&2 msg_warn "$(translate "EFI storage selection cancelled.")" >&2
@@ -1041,8 +1041,8 @@ function select_storage_volume() {
STORAGE=${STORAGE_MENU[0]} STORAGE=${STORAGE_MENU[0]}
else else
while [ -z "${STORAGE:+x}" ]; do while [ -z "${STORAGE:+x}" ]; do
STORAGE=$(whiptail --backtitle "ProxMenuX" --title "Storage Pools" --radiolist \ STORAGE=$(whiptail --backtitle "ProxMenuX" --title "$(translate "Select Storage")" --radiolist \
"$(translate "Choose the storage volume for $purpose:")" \ "$(translate "Choose the storage for the loader disk:")" \
16 $(($MSG_MAX_LENGTH + 23)) 6 \ 16 $(($MSG_MAX_LENGTH + 23)) 6 \
"${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || { "${STORAGE_MENU[@]}" 3>&1 1>&2 2>&3) || {
msg_warn "$(translate "Storage selection cancelled for $purpose.")" >&2 msg_warn "$(translate "Storage selection cancelled for $purpose.")" >&2
+284
View File
@@ -0,0 +1,284 @@
#!/usr/bin/env python3
"""Offline extracted Bash message contracts; never sources admin scripts."""
import importlib.util, json, pathlib, re, shlex, subprocess, tempfile, unittest
R = pathlib.Path(__file__).resolve().parents[1]
SOURCE = R / 'scripts/share/samba_client.sh'
# Credentials never reach the operational write path in these fixtures.
# Remove its redirection as well as the command: shell redirects before calling.
CREDENTIAL_WRITE = ''' TEMP_CRED="/tmp/validate_cred_$$"
cat > "$TEMP_CRED" << EOF
username=$USERNAME
password=$PASSWORD
EOF'''
def functions():
source = SOURCE.read_text()
bounded = source[source.index('validate_guest_access() {'):source.index('select_samba_share() {')]
assert bounded.count(CREDENTIAL_WRITE) == 1
return bounded.replace(CREDENTIAL_WRITE, "printf 'FORBIDDEN:credential-write\\n' >&4; exit 91")
def lookup():
source = (R / 'scripts/utils.sh').read_text()
return re.search(r'^translate\(\) \{.*?^\}', source, re.M | re.S).group()
def init_fixture(fixture):
name, status, listing, tests, expected = fixture
values = {'LIST_STATUS': status, 'LISTING': listing}
for i in range(3):
values.update({f'STATUS{i}': tests[i][0] if i < len(tests) else 91,
f'OUTPUT{i}': tests[i][1] if i < len(tests) else 'FORBIDDEN:unexpected-share'})
return '\n'.join(k + '=' + shlex.quote(str(v)) for k, v in values.items())
def run_fixture(fixture, caller=False, extra='', language='en', lang_dir='/nonexistent', tail=None):
script = PRELUDE + '\n' + lookup() + '\n' + init_fixture(fixture) + '\n' + functions()
script += '\nLANGUAGE=' + shlex.quote(language) + '\nLANG_DIR=' + shlex.quote(str(lang_dir)) + '\n'
# jq is the actual parser, constrained to this fixture/catalog only.
script += '''
jq() {
[[ "$#" == 6 && "$1" == -r && "$2" == --arg && "$3" == text && "$5" == '.[$text] // empty' && "$6" == "$LANG_DIR/$LANGUAGE.json" ]] || { printf 'FORBIDDEN:jq-args\\n' >&4; exit 91; }
/usr/bin/jq "$@"
}
'''
script += extra + '\n'
call = 'get_samba_credentials' if caller else 'validate_guest_access example.invalid'
script += tail if tail is not None else call + ' <<< ""\nrc=$?\nprintf "RETURN:%s\\nVALIDATED:%q\\nUSE_GUEST:%s\\n" "$rc" "$VALIDATED_GUEST_SHARES" "$USE_GUEST"\n'
p = subprocess.run(['/bin/bash', '--noprofile', '--norc'], input=script, text=True,
capture_output=True, env={'PATH': '/nonexistent', 'LANG': 'C'}, timeout=5)
assert p.returncode == 0 and not p.stderr and 'FORBIDDEN:' not in p.stdout, (p.returncode, p.stdout, p.stderr)
return p.stdout
class GuestOutcomeTests(unittest.TestCase):
def test_each_replacement_is_emitted(self):
outputs = '\n'.join(run_fixture(fixture, True) for fixture in FIXTURES)
for text in (
'Testing guest listing and share access on server',
'Guest Listing Failed', 'Guest share listing failed.',
'Try username and password authentication.', 'No Shares to Test',
'No disk shares were selected from the guest listing.',
'Shares selected from guest listing:', 'Guest access test failed for share:',
'Test output mentions authentication or access denial.',
'Test output reports permission denied.', 'The guest access test did not succeed.',
'Guest share access tests failed:',
'No share access test succeeded with guest authentication.',
'Samba access setup did not complete.',
):
with self.subTest(message=text):
self.assertIn(text, outputs)
def test_outcome_matrix(self):
for fixture in FIXTURES:
name, ls, listing, tests, status = fixture
for caller in (False, True):
with self.subTest(case=name, caller=caller):
out = run_fixture(fixture, caller)
self.assertIn(f'RETURN:{status}\n', out)
calls = [x for x in out.splitlines() if x.startswith('SMB\t')]
self.assertEqual(len(calls), 1 + len(tests))
self.assertEqual(calls[0], 'SMB\t-L\texample.invalid\t-N')
self.assertEqual(calls[1:], [f'SMB\t//example.invalid/share{i}\t-N\t-c\tls' for i in range(len(tests))])
success = [f'share{i}' for i, t in enumerate(tests) if t[0] == 0]
encoded = ''.join(x + '\\\\n' for x in success) if success else "''"
self.assertIn('VALIDATED:' + encoded + '\n', out)
self.assertIn('Testing guest listing and share access on server example.invalid...', out)
if ls:
self.assertIn('Guest Listing Failed', out)
self.assertIn('Guest share listing failed.', out)
self.assertNotIn('Guest share listing successful', out)
if name == 'listing-error-denial-text':
self.assertIn('Try username and password authentication.', out)
self.assertNotIn('Error details:', out)
else:
self.assertIn('Error details:', out)
elif not tests:
self.assertIn('No Shares to Test', out)
self.assertIn('No disk shares were selected from the guest listing.', out)
else:
self.assertIn(f'Shares selected from guest listing: {len(tests)}', out)
self.assertLess(out.index('Shares selected from guest listing:'), out.index('SMB\t//'))
self.assertIn(f'Shares found: {len(tests)}', out)
self.assertIn(f'Guest accessible: {len(success)}', out)
self.assertIn(f'Guest share access tests failed: {len(tests) - len(success)}', out)
for i, (rc, diagnostic) in enumerate(tests):
label = 'Guest access confirmed for share:' if rc == 0 else 'Guest access test failed for share:'
self.assertIn(f'{label} share{i}', out)
self.assertLess(out.index(f'SMB\t//example.invalid/share{i}'), out.index(f'{label} share{i}'))
if success:
self.assertIn('Guest access validated successfully!', out)
self.assertNotIn('No share access test succeeded', out)
else:
self.assertIn('No share access test succeeded with guest authentication.', out)
self.assertIn('Try username and password authentication.', out)
if name == 'failed-auth-text':
self.assertIn('Test output mentions authentication or access denial.', out)
if name in ('failed-status-token', 'all-failed-generic'):
self.assertIn('The guest access test did not succeed.', out)
self.assertNotIn('Test output mentions authentication', out)
if name == 'partial':
self.assertIn('Test output reports permission denied.', out)
if caller:
self.assertEqual('Samba access setup did not complete.' in out, status == 1)
self.assertIn(f'USE_GUEST:{str(status == 0).lower()}', out)
def test_retry_yes_new_selection_then_cancel(self):
# Each menu is a subshell: consume choices from an inherited FD, not a
# variable counter that would reset at every command substitution.
extra = '''
exec 5<<< $'2\\n1\\ncancel'
whiptail() {
{ printf 'DIALOG'; printf '\\t%s' "$@"; printf '\\n'; } >&4
if [[ "$1" == --title && "$2" == 'Samba Credentials' ]]; then
IFS= read -r next <&5
[[ "$next" != cancel ]] || return 1
printf '%s' "$next" >&2; return 0
fi
[[ "$1" != --inputbox ]] || return 1
return 0
}
'''
out = run_fixture(FIXTURES[0], True, extra)
self.assertIn('RETURN:1', out)
self.assertEqual(out.count('Samba access setup did not complete.'), 2)
self.assertEqual(out.count('DIALOG\t--title\tSamba Credentials'), 3)
self.assertIn('Enter username for Samba server:', out)
self.assertIn('USE_GUEST:false', out)
self.assertEqual(out.count('SMB\t'), 1)
def test_real_translation_and_extractor(self):
spec = importlib.util.spec_from_file_location('cache_builder', R / '.github/scripts/build_translation_cache.py')
builder = importlib.util.module_from_spec(spec)
spec.loader.exec_module(builder)
discovered = set(builder.extract_translate_texts(R / 'scripts/share'))
keys = set(re.findall(r'translate "([^"\n]+)"', functions()))
self.assertTrue(keys <= discovered)
with tempfile.TemporaryDirectory(prefix='samba-guest-lookup-') as directory:
lang_dir = pathlib.Path(directory)
(lang_dir / 'missing.json').write_text('{}')
synthetic = {key: 'SYNTHETIC ' + key + ' translated' for key in keys}
(lang_dir / 'xx.json').write_text(json.dumps(synthetic))
shipped = json.loads((R / 'lang/it.json').read_text())
for language, location, catalog in (
('en', lang_dir, {}), ('absent', lang_dir, {}),
('missing', lang_dir, {}), ('it', R / 'lang', shipped),
('xx', lang_dir, synthetic),
):
# Directly check every lookup using the actual Bash function.
calls = '\n'.join('translate ' + shlex.quote(key) for key in sorted(keys))
expected = '\n'.join(catalog.get(key) or key for key in sorted(keys)) + '\n'
with self.subTest(language=language, scope='lookup'):
self.assertEqual(run_fixture(FIXTURES[0], language=language,
lang_dir=location, tail=calls), expected)
for fixture in FIXTURES:
for caller in (False, True):
with self.subTest(language=language, case=fixture[0], caller=caller):
baseline = run_fixture(fixture, caller)
out = run_fixture(fixture, caller, language=language, lang_dir=location)
# Replace complete literals longest-first, once in a regex pass:
# substitutions cannot recursively retranslate synthetic values.
pattern = '|'.join(re.escape(key) for key in sorted(keys, key=len, reverse=True))
expected = re.sub(pattern, lambda match: catalog.get(match[0]) or match[0], baseline)
self.assertEqual(out, expected)
def test_noncompleted_password_path(self):
extra = '''
exec 5<<< $'fixture-user-not-a-secret\\ncancel'
exec 6<<< $'fixture-password-not-a-secret\\ncancel\\ncancel'
whiptail() {
{ printf 'DIALOG'; printf '\\t%s' "$@"; printf '\\n'; } >&4
if [[ "$1" == --title && "$2" == 'Samba Credentials' ]]; then printf '1' >&2; return 0; fi
if [[ "$1" == --inputbox ]]; then
IFS= read -r next <&5
[[ "$next" != cancel ]] || return 1
printf '%s' "$next" >&2; return 0
fi
if [[ "$1" == --passwordbox ]]; then
IFS= read -r next <&6
[[ "$next" != cancel ]] || return 1
printf '%s' "$next" >&2; return 0
fi
[[ "$1" != --yesno ]] || return 1
printf 'FORBIDDEN:dialog\\n' >&4; return 91
}
'''
out = run_fixture(FIXTURES[0], True, extra)
self.assertIn('Enter password for fixture-user-not-a-secret:', out)
self.assertIn('Confirm password for fixture-user-not-a-secret:', out)
self.assertNotIn('fixture-password-not-a-secret', out)
self.assertIn('Samba access setup did not complete.', out)
self.assertIn('RETURN:1', out)
self.assertNotIn('SMB\t', out)
self.assertNotIn('Authentication failed.', out)
PRELUDE = r'''
set -u
export PATH=/nonexistent
exec 4>&1
command_not_found_handle() { printf 'FORBIDDEN:%s\n' "$*" >&4; return 127; }
show_proxmenux_logo() { :; }
cleanup() { :; }
clear() { :; }
sleep() { [[ "$*" == 1 || "$*" == 2 ]] || { printf 'FORBIDDEN:sleep\n' >&4; exit 91; }; }
awk() { [[ "$#" == 1 && "$1" == '/Disk/ && !/IPC\$/ && !/ADMIN\$/ && !/print\$/ {print $1}' ]] || { printf 'FORBIDDEN:awk\n' >&4; exit 91; }; /usr/bin/awk "$@"; }
grep() { [[ "$#" == 2 && ( "$*" == '-v ^$' || "$*" == '-qi access denied\|logon failure' || "$*" == '-qi access denied\|logon failure\|authentication' || "$*" == '-qi permission denied' ) ]] || { printf 'FORBIDDEN:grep\n' >&4; exit 91; }; /usr/bin/grep "$@"; }
wc() { [[ "$*" == '-l' ]] || { printf 'FORBIDDEN:wc\n' >&4; exit 91; }; /usr/bin/wc "$@"; }
head() { [[ "$*" == '-3' ]] || { printf 'FORBIDDEN:head\n' >&4; exit 91; }; /usr/bin/head "$@"; }
whiptail() {
{ printf 'DIALOG'; printf '\t%s' "$@"; printf '\n'; } >&4
if [[ "$1" == --title && "$3" == --menu ]]; then printf '2' >&2; return 0; fi
if [[ "$1" == --yesno ]]; then return 1; fi
return 0
}
smbclient() {
{ printf 'SMB'; printf '\t%s' "$@"; printf '\n'; } >&4
if [[ "$#" == 4 && "$1" == -L && "$2" == example.invalid && "$3" == -N ]]; then printf 'FORBIDDEN:argc\n' >&4; exit 91; fi
if [[ "$#" == 3 && "$*" == '-L example.invalid -N' ]]; then printf '%s' "$LISTING"; return "$LIST_STATUS"; fi
if [[ "$#" == 4 && "$1" == //example.invalid/share* && "$2" == -N && "$3" == -c && "$4" == ls ]]; then
case "$1" in
//example.invalid/share0) printf '%s' "$OUTPUT0"; return "$STATUS0";;
//example.invalid/share1) printf '%s' "$OUTPUT1"; return "$STATUS1";;
//example.invalid/share2) printf '%s' "$OUTPUT2"; return "$STATUS2";;
esac
fi
printf 'FORBIDDEN:smbclient:%s\n' "$*" >&4; exit 91
}
TAB='' BGN='' CL='' BL='' GN='' YW='' BOLD=''
VALIDATED_GUEST_SHARES='' SAMBA_SERVER=example.invalid USE_GUEST=false
msg_info() { printf "msg_info:%s\n" "$*" >&4; }
msg_info2() { printf "msg_info2:%s\n" "$*" >&4; }
msg_ok() { printf "msg_ok:%s\n" "$*" >&4; }
msg_error() { printf "msg_error:%s\n" "$*" >&4; }
msg_warn() { printf "msg_warn:%s\n" "$*" >&4; }
msg_success() { printf "msg_success:%s\n" "$*" >&4; }
'''
FIXTURES = [('listing-empty', 0, '', [], 1),
('listing-filtered-only', 0, 'IPC$ IPC fixture\nADMIN$ Disk fixture\nprint$ Disk fixture', [], 1),
('listing-error-generic', 1, 'Connection timed out', [], 1),
('listing-error-denial-text', 1, 'access denied', [], 1),
('listing-error-status-token', 1, 'NT_STATUS_ACCESS_DENIED', [], 1),
('one-success', 0, 'share0 Disk fixture', [(0, '')], 0),
('three-success',
0,
'share0 Disk fixture\nshare1 Disk fixture\nshare2 Disk fixture',
[(0, ''), (0, ''), (0, '')],
0),
('partial',
0,
'share0 Disk fixture\nshare1 Disk fixture\nshare2 Disk fixture',
[(0, ''), (1, 'Connection timed out'), (1, 'permission denied')],
0),
('all-failed-generic',
0,
'share0 Disk fixture\nshare1 Disk fixture\nshare2 Disk fixture',
[(1, 'Connection timed out'), (1, 'Connection timed out'), (1, 'Connection timed out')],
1),
('failed-auth-text', 0, 'share0 Disk fixture', [(1, 'authentication service unavailable')], 1),
('failed-status-token', 0, 'share0 Disk fixture', [(1, 'NT_STATUS_LOGON_FAILURE')], 1),
('listing-nonzero-with-disk', 1, 'share0 Disk fixture', [], 1)]
if __name__ == '__main__':
unittest.main()