From 98c8863143224a240985c2399b2455d8efb4f3b5 Mon Sep 17 00:00:00 2001 From: Daniel Castro Brito Date: Sun, 18 Oct 2026 22:04:00 -0300 Subject: [PATCH] Add Spanish translation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds es.json with all 694 translated keys, registers Español in LocalizationService (auto-picked for Spanish OS cultures) and adds es to localization and render tests. --- src/Filee.App/Assets/i18n/es.json | 696 ++++++++++++++++++ src/Filee.App/Services/LocalizationService.cs | 3 + tests/Filee.App.Tests/LocalizationTests.cs | 4 +- tests/Filee.App.Tests/RenderTests.cs | 1 + 4 files changed, 702 insertions(+), 2 deletions(-) create mode 100644 src/Filee.App/Assets/i18n/es.json diff --git a/src/Filee.App/Assets/i18n/es.json b/src/Filee.App/Assets/i18n/es.json new file mode 100644 index 000000000..5e168e022 --- /dev/null +++ b/src/Filee.App/Assets/i18n/es.json @@ -0,0 +1,696 @@ +{ + "app.name": "Filee", + "app.tagline": "Arrastra, suelta y convierte.", + "nav.home": "Inicio", + "nav.general": "General", + "nav.triggers": "Atajos", + "nav.toolbar": "Menú circular", + "nav.presets": "Ajustes preestablecidos", + "nav.watch": "Carpetas supervisadas", + "nav.theme": "Tema", + "nav.engines": "Motores", + "nav.about": "Acerca de", + "tray.open": "Abrir Filee", + "tray.pause": "Pausar atajos", + "tray.resume": "Reanudar atajos", + "tray.quit": "Salir", + "tray.update": "Actualizar a {0}", + "tray.tooltip": "Filee: mantén {0} y arrastra archivos", + "close.title": "¿Mantener Filee en ejecución?", + "close.text": "En la bandeja del sistema, el menú circular y las carpetas supervisadas siguen funcionando.\nPuedes cambiarlo más adelante en Ajustes → General.", + "close.tray": "Mantener en la bandeja", + "close.quit": "Salir", + "close.dont_ask": "No volver a preguntar", + "home.title": "Inicio", + "home.drop_title": "Suelta archivos aquí", + "home.drop_hint": "O mantén {0} mientras arrastras archivos en el Explorador. El menú circular se abre donde esté el cursor.", + "home.drop_hint_macos": "O mantén {0} mientras arrastras archivos en Finder. El menú circular se abre donde esté el cursor.", + "home.drop_hint_linux": "O mantén {0} mientras arrastras archivos en tu gestor de archivos. El menú circular se abre donde esté el cursor.", + "home.accessibility_needed": "Para abrir el menú circular al arrastrar con ⌥ Opción, autoriza a Filee en Accesibilidad.\nFuncionará en cuanto lo actives.", + "home.elevated": "Filee se está ejecutando como administrador, por lo que el Explorador no puede arrastrar archivos sobre él ni usar su menú.\nEl atajo tampoco puede leer la selección del Explorador.\nReinicia Filee sin permisos de administrador para solucionar esto.", + "home.elevated_restart": "Reiniciar sin permisos de administrador", + "home.elevated_restart_failed": "Filee no pudo reiniciarse automáticamente.\nCierra Filee desde la bandeja del sistema y vuelve a iniciarlo.", + "elevation.notice_title": "Filee se está ejecutando como administrador", + "elevation.notice_text": "El Explorador no puede arrastrar archivos sobre Filee ni usar su menú mientras se ejecute de este modo.\nReinícialo sin permisos de administrador.", + "startup.elevated_other": "Otra instancia de Filee se está ejecutando como administrador.\nEl Explorador no puede transferirle archivos.\nCierra Filee desde la bandeja del sistema y vuelve a iniciarlo.", + "startup.no_answer": "Filee se está ejecutando pero no responde.\nSi se está ejecutando como administrador, ciérralo desde la bandeja del sistema y vuelve a iniciarlo.", + "home.recent": "Conversiones recientes", + "home.recent_empty": "Tus archivos convertidos aparecerán aquí.", + "home.open_folder": "Abrir carpeta", + "home.clear_history": "Borrar", + "home.files": "{0} archivos", + "home.failed_files": "{0} con error", + "donut.center_drag": "Trae los archivos aquí", + "donut.files_same": "{0} × {1}", + "donut.files_mixed": "{0} archivos", + "donut.drop_to": "Suelta → {0}", + "donut.pick_in_group": "Muévete hacia fuera para elegir", + "donut.group_empty": "No quedan ajustes preestablecidos en este grupo. Edítalo en Ajustes → Menú circular", + "donut.click_to": "Clic → {0}", + "donut.cancel": "Suelta aquí para cancelar", + "donut.close_hint": "Esc para cerrar", + "donut.edit": "Editar ajuste preestablecido", + "donut.empty": "Arrastra ajustes preestablecidos aquí", + "donut.same_format": "Mismo formato", + "donut.group_caption": "Grupo de {0}", + "toast.converting": "{0} → {1}", + "toast.done": "Hecho", + "toast.done_errors": "Fallaron {0} de {1}", + "toast.failed": "Falló la conversión", + "toast.cancelled": "Cancelado", + "toast.skipped": "Omitido (el archivo ya existe)", + "toast.open_folder": "Mostrar", + "toast.cancel": "Cancelar", + "error.unsupported_source": "Este tipo de archivo no es compatible", + "format_request.request": "Solicitar este formato", + "format_request.notice_title": "Filee aún no puede convertir archivos {0}", + "format_request.notice_text": "Cuéntanos qué formato necesitas.\nLas solicitudes determinan qué formatos admitirá Filee a continuación.\nLos archivos cifrados o con protección de copia (DRM) no se pueden convertir, sea cual sea su formato.", + "error.no_route": "Ningún motor puede hacer esta conversión", + "error.cannot_turn": "Rotar y voltear solo funcionan con imágenes", + "error.too_many_frames": "Demasiados fotogramas para guardar como imágenes; aumenta «Cada N fotogramas»", + "error.not_enough_space": "Espacio libre en disco insuficiente para las imágenes", + "error.rhwp_timeout": "rhwp no pudo terminar este documento largo a tiempo", + "error.rhwp_timeout_calibre": "rhwp no pudo terminar este documento largo a tiempo. Para un libro electrónico, mueve Calibre por encima del escritor HWPX en Ajustes → Motores; Calibre genera el PDF mucho más rápido", + "error.conversion_failed": "El motor devolvió un error", + "notice.pdf_not_smaller": "No se pudo reducir su tamaño, por lo que se copió tal cual", + "engine.reason.not_installed": "No instalado", + "engine.reason.error": "Error al comprobar", + "engine.reason.unsupported_platform": "No disponible en esta plataforma", + "engine.reason.needs_package": "Necesita {0}. Instálalo en Ajustes → Motores", + "engine.magick.description": "JPG, PNG, WEBP, AVIF, HEIC, TIFF, GIF, APNG, PSD, RAW de cámara y más.\nLa calidad, el tamaño y los DPI siguen tu ajuste preestablecido.", + "engine.pdfium.description": "Convierte páginas PDF a PNG, JPG y TIFF (también TIFF multipágina y GIF) en la resolución del ajuste preestablecido.", + "engine.pdfsharp.description": "Crea PDF a partir de imágenes y combina, divide o extrae rangos de páginas de PDF.\nTambién reduce el tamaño de los PDF reduciendo sus imágenes.", + "engine.rhwp.description": "Renderiza HWP/HWPX a PDF y convierte HWP ↔ HWPX.\nTambién dibuja en PDF los documentos que llegan a PDF a través de HWPX (DOCX, XLSX, PPTX, libros electrónicos…).", + "engine.unhwp.description": "Extrae texto, Markdown y HTML de HWP y HWPX.", + "engine.markdown.description": "Markdown → HTML y texto sin formato.", + "engine.spreadsheet.description": "XLSX, XLS, ODS, CSV y TSV entre sí (XLS es de solo lectura).\nUn CSV por hoja.", + "engine.ooxml.description": "Archivos y plantillas con macros (DOCM, XLSM, PPTM, DOTX…) ↔ DOCX, XLSX, PPTX.\nLas macros se eliminan.", + "engine.hwpx-writer.description": "Escribe HWPX desde Word, Excel, PowerPoint, PDF, HTML, libros electrónicos y Markdown.\nEl primer paso para pasar documentos a PDF sin Office.", + "engine.docx-writer.description": "Escribe documentos de Word (DOCX) desde PDF, HWP/HWPX, Markdown, HTML, hojas de cálculo, diapositivas y libros electrónicos.", + "engine.pdf-text.description": "Extrae el texto de los PDF en orden de lectura, también de páginas en dos columnas (sin OCR para escaneos).", + "engine.pdf-slides.description": "Convierte PDF en diapositivas de PowerPoint: cada página pasa a ser una imagen en su propia diapositiva (con el aspecto del PDF, no editable), con el texto de la página en las notas del orador.", + "engine.email.description": "Correos electrónicos (EML, Outlook MSG) a HTML y texto con remitente, destinatarios y fecha, imágenes incluidas; los adjuntos van a un ZIP.\nMSG a EML.", + "engine.data.description": "JSON, JSON Lines, YAML, TOML, XML y CSV entre sí.\nContactos vCard a CSV y viceversa.\nLos comentarios se descartan. CSV solo admite tablas.", + "engine.vector.description": "SVG y SVGZ a PDF vectorial, imágenes y DXF; imágenes trazadas a SVG; archivos de Illustrator guardados con contenido PDF.", + "engine.icns.description": "Iconos de apps de macOS (ICNS) desde y hacia imágenes.", + "engine.font.description": "Tipografías: TTF, OTF, WOFF, WOFF2 y EOT entre sí.", + "engine.cad.description": "Planos de AutoCAD: DWG ↔ DXF, y ambos a PDF, SVG y PNG.", + "engine.model3d.description": "Modelos 3D: GLB, glTF, STL, OBJ, 3MF y PLY entre sí, además de una vista previa en PNG.", + "engine.archive.description": "Extrae ZIP, 7Z, RAR, TAR, ISO y más, y empaqueta en ZIP, 7Z o TAR.GZ (7-Zip).", + "engine.ebook.description": "EPUB, MOBI, AZW3, FB2 y cómics (CBZ, CBR) a PDF, EPUB, DOCX y texto.\nTambién documentos a EPUB, EPUB a KEPUB para Kobo y PDF a CBZ.", + "engine.subtitle.description": "Subtítulos: SRT, ASS/SSA, WebVTT, SAMI (SMI), LRC, TTML, MicroDVD y SCC entre sí, guardados como UTF-8.\nLee correctamente archivos SMI y SRT coreanos en CP949 / EUC-KR.", + "engine.ffmpeg.description": "Vídeo y audio: MP4, MOV, MKV, WEBM, MP3, M4A, WAV, FLAC y más.\nTambién extrae sonido y subtítulos, crea animaciones GIF y APNG y guarda imágenes como HEIC.", + "engine.pandoc.description": "Markdown y HTML ↔ ODT y RTF, DOCX → Markdown\nreStructuredText, LaTeX, Org, AsciiDoc, Typst, MediaWiki, DocBook, Jupyter y más ↔ Markdown, HTML, DOCX y ODT\nMarkdown y Org → diapositivas PPTX", + "engine.ghostscript.description": "EPS, PostScript y archivos antiguos de Illustrator a PDF e imágenes; PDF a EPS y PS.", + "engine.calibre.description": "Formatos raros de libros electrónicos (LIT, LRF, CHM, PDB, RB…) y salida Kindle (MOBI, AZW3).\nPor encima del escritor HWPX, también crea los PDF de libros electrónicos (mucho más rápido para libros largos).", + "engine.libreoffice.description": "Lee formatos antiguos y poco habituales: DOC, PPT, Pages, Keynote, Numbers, WordPerfect, ClarisWorks, Publisher, Visio…\nTambién guarda como DOC, XLS, PPT, ODT, ODP, plantillas OpenDocument y EMF.", + "profile.images": "Imágenes", + "profile.pdf": "PDF", + "profile.office": "Documentos", + "profile.spreadsheets": "Hojas de cálculo", + "profile.presentations": "Presentaciones", + "profile.hwp": "HWP / HWPX", + "profile.text": "Texto y Markdown", + "profile.ebooks": "Libros electrónicos", + "profile.video": "Vídeo", + "profile.audio": "Audio", + "profile.subtitles": "Subtítulos", + "profile.vector": "Gráficos vectoriales", + "profile.archives": "Archivos comprimidos", + "profile.cad": "Planos CAD", + "profile.fonts": "Tipografías", + "profile.data": "Datos", + "profile.models": "Modelos 3D", + "profile.mixed": "Archivos mixtos", + "preset.half_size": "Reducir 50 %", + "preset.grayscale": "Grises", + "preset.remove_background": "Quitar fondo", + "preset.group_rotate": "Rotar", + "preset.rotate_left": "Girar izquierda", + "preset.rotate_left.short": "Izquierda", + "preset.rotate_right": "Girar derecha", + "preset.rotate_right.short": "Derecha", + "preset.rotate_180": "Rotar 180°", + "preset.rotate_180.short": "180°", + "preset.group_flip": "Voltear", + "preset.flip_horizontal": "Volteo horizontal", + "preset.flip_horizontal.short": "Horizontal", + "preset.flip_vertical": "Volteo vertical", + "preset.flip_vertical.short": "Vertical", + "preset.merge_pdf": "Combinar PDF", + "preset.split_pdf": "Dividir PDF", + "preset.compress_pdf": "Comprimir PDF", + "preset.long_image": "Imagen larga", + "preset.pdf_slides": "PPTX (diapositivas)", + "preset.extract": "Extraer", + "preset.zip_all": "Un solo ZIP", + "preset.extract_subtitles": "Extraer subtítulos", + "preset.trace_svg": "Trazar a SVG", + "preset.trace_line_art": "Líneas a SVG", + "preset.extract_frames_png": "Extraer fotogramas (PNG)", + "preset.extract_frames_jpg": "Extraer fotogramas (JPG)", + "format.folder": "Carpeta", + "format.category.Image": "Imagen", + "format.category.Pdf": "PDF", + "format.category.Document": "Documento", + "format.category.Spreadsheet": "Hoja de cálculo", + "format.category.Presentation": "Presentación", + "format.category.Hwp": "HWP", + "format.category.Text": "Texto", + "format.category.Video": "Vídeo", + "format.category.Audio": "Audio", + "format.category.Ebook": "Libro electrónico", + "format.category.Archive": "Archivo comprimido", + "format.category.Vector": "Vectorial", + "format.category.Cad": "CAD", + "format.category.Font": "Tipografía", + "format.category.Subtitle": "Subtítulo", + "format.category.Data": "Datos", + "format.category.Model3D": "Modelo 3D", + "general.title": "General", + "general.language": "Idioma", + "general.language_auto": "Predeterminado del sistema", + "general.start_with_system": "Iniciar Filee al iniciar sesión", + "general.context_menu": "Mostrar «Convertir con Filee» en el menú contextual del Explorador", + "general.context_menu_label": "Convertir con Filee", + "general.context_menu_macos": "Mostrar «Convertir con Filee» al hacer clic derecho sobre archivos en Finder", + "general.context_menu_linux": "Añadir «Convertir con Filee» al gestor de archivos", + "general.integration_macos": "Finder lo muestra en el menú contextual (en Acciones rápidas o Servicios si el menú es largo).\nMantén Filee en Aplicaciones.", + "general.integration_linux": "Añade acciones de archivos a Thunar, Nautilus, Nemo y Dolphin.\nPara cambiar el atajo de Thunar, cierra Thunar antes y vuelve a abrirlo después.", + "general.integration_failed": "No se pudo aplicar la integración con el sistema: {0}", + "general.modern_menu_hint": "En Windows 11 esta entrada está en «Mostrar más opciones».\nTambién puede ir al menú principal (Windows pide permiso de administrador una sola vez).", + "general.modern_menu_on": "«Convertir con Filee» está en el menú principal de Windows 11.", + "general.modern_menu_outdated": "La entrada del menú principal pertenece a una copia antigua de Filee o a una que cambió de carpeta.\nAñádela otra vez para actualizarla.", + "general.modern_menu_add": "Añadir al menú principal", + "general.modern_menu_remove": "Quitar del menú principal", + "general.modern_menu_busy": "Esperando a Windows…", + "general.modern_menu_cancelled": "Cancelado. La entrada seguirá en «Mostrar más opciones».", + "general.modern_menu_failed": "Windows no añadió la entrada: {0}", + "general.modern_menu_remove_failed": "Windows no quitó la entrada: {0}", + "general.default_output": "Carpeta de guardado predeterminada", + "general.default_output_hint": "Los ajustes preestablecidos configurados en «Carpeta de guardado predeterminada» guardan aquí.\nUn ajuste preestablecido con su propia carpeta la conserva.", + "general.keep_dates": "Conservar las fechas originales de los archivos en todas las conversiones", + "general.keep_dates_hint": "Los archivos convertidos conservan las fechas de creación y modificación del original, con todos los ajustes preestablecidos.\nDesactivado: solo lo hacen los ajustes preestablecidos con «Conservar las fechas del archivo original».", + "general.check_updates": "Buscar actualizaciones automáticamente", + "general.close_action": "Al cerrar la ventana", + "general.close.Ask": "Preguntar cada vez", + "general.close.Tray": "Mantener Filee en la bandeja", + "general.close.Quit": "Salir de Filee", + "general.history": "Historial de conversiones", + "general.no_history": "No guardar un historial de las conversiones recientes", + "general.clear_history": "Borrar historial", + "general.history_count": "{0} conversión(es) en el historial", + "general.history_cleared": "Historial borrado.", + "general.check_now": "Comprobar ahora", + "general.update_available": "La versión {0} está disponible", + "general.update_none": "Estás al día ({0})", + "update.sidebar": "Actualizar a {0}", + "update.notice_title": "Filee {0} está disponible", + "update.notice_text": "Pulsa Actualizar y Filee descarga e instala la versión nueva. Tus ajustes se conservan.", + "update.download": "Descargar", + "update.later": "Más tarde", + "update.install": "Actualizar", + "update.notice_text_portable": "Esta es la versión portátil.\nDescarga el ZIP nuevo y descomprímelo sobre esta carpeta. Tus ajustes se conservan.", + "update.downloading": "Descargando la actualización… {0}%", + "update.installing_short": "Instalando…", + "update.installing": "El instalador se está ejecutando. Filee se reinicia cuando termina.", + "update.failed": "No se pudo actualizar automáticamente. Descarga la versión nueva en filee.sh.", + "update.failed_alert": "No se pudo descargar la actualización.\nPulsa Aceptar para abrir filee.sh y descargar allí la versión nueva.", + "update.cancelled": "Actualización cancelada. Pulsa Actualizar otra vez para instalarla.", + "update.level.Required": "Actualización obligatoria", + "update.level.Recommended": "Actualización recomendada", + "update.level.Optional": "Actualización opcional", + "update.level_hint.Required": "Corrige problemas que afectan a tus archivos. Actualiza, por favor.", + "update.level_hint.Recommended": "Corrige errores.", + "update.level_hint.Optional": "Novedades. Actualiza cuando quieras.", + "update.pill.Required": "Obligatoria", + "update.pill.Optional": "Opcional", + "update.more_changes": "… y {0} más", + "general.data_folder": "Carpeta de ajustes", + "general.open_data_folder": "Abrir", + "general.library": "Ajustes preestablecidos y menús circulares", + "general.export": "Exportar…", + "general.import": "Importar…", + "general.reset_library": "Restablecer los valores predeterminados", + "general.reset_confirm": "¿Reemplazar todos los ajustes preestablecidos y los perfiles de menú circular por los valores predeterminados?", + "general.imported": "Se importaron {0} elementos", + "triggers.title": "Atajos", + "triggers.description": "Elige cómo se abre el menú circular. Puedes añadir tantos gestos como quieras.", + "triggers.macos_permissions": "Permite Filee en Ajustes del Sistema > Privacidad y seguridad > Accesibilidad.\nFinder también pide permiso de Automatización la primera vez que uses un atajo de selección.", + "triggers.linux_x11": "Los gestos de arrastre funcionan en X11.\nCon la integración con el gestor de archivos activada, el primer atajo de teclado ejecuta la acción de Filee en Thunar (vuelve a abrir Thunar después de cambiarlo).\nLos gestos de pulsación mantenida y los atajos en otros gestores de archivos no están disponibles. Usa el menú de Filee o la zona de suelta.", + "triggers.linux_wayland": "Los gestos que siguen el cursor no están disponibles en Wayland.\nUsa una sesión X11 o convierte con el menú del gestor de archivos y la zona de suelta.\nThunar puede usar el primer atajo de teclado cuando se reinicie.", + "triggers.open_accessibility": "Abrir los ajustes de Accesibilidad", + "triggers.retry_hook": "Reintentar los gestos", + "triggers.hook_running": "La detección global de entrada está en ejecución.", + "triggers.hook_stopped": "La detección global de entrada está detenida.\nLas acciones del gestor de archivos y la zona de suelta siguen disponibles.", + "triggers.hook_failed": "Falló la detección global de entrada: {0}", + "triggers.hook_linux_backend": "Los gestos no se pudieron iniciar porque las bibliotecas de entrada de X11 no se cargaron.\nUsa una sesión X11 e instala libxtst6 y libxt6 (Ubuntu/Debian: sudo apt install libxtst6 libxt6) y vuelve a intentarlo.\nLas acciones del gestor de archivos y la zona de suelta siguen disponibles.", + "triggers.add": "Añadir gesto", + "triggers.remove": "Quitar", + "triggers.enabled": "Activado", + "triggers.kind": "Gesto", + "triggers.kind.Drag": "Tecla modificadora + arrastrar archivos", + "triggers.kind.Hold": "Tecla modificadora + mantener pulsado", + "triggers.kind.KeyChord": "Atajo de teclado (archivos seleccionados)", + "triggers.modifiers": "Teclas modificadoras", + "triggers.button": "Botón del ratón", + "triggers.button.None": "Ninguno", + "triggers.button.Left": "Izquierdo", + "triggers.button.Right": "Derecho", + "triggers.button.Middle": "Central", + "triggers.button.X1": "Atrás (X1)", + "triggers.button.X2": "Adelante (X2)", + "triggers.key": "Tecla", + "triggers.record": "Grabar", + "triggers.recording": "Pulsa una combinación de teclas…", + "triggers.clear": "Borrar", + "triggers.threshold": "Distancia de arrastre", + "triggers.threshold_system": "Predeterminado del sistema", + "triggers.hold_ms": "Tiempo de pulsación", + "triggers.scope": "Activo en", + "triggers.scope.FileManager": "Gestores de archivos y escritorio", + "triggers.scope.FileManager_macos": "Finder y el escritorio", + "triggers.scope.FileManager_linux": "El gestor de archivos y el escritorio", + "triggers.scope.Anywhere": "En todo el sistema", + "triggers.excluded": "Nunca se activa en estas apps", + "triggers.excluded_hint": "Escribe el nombre de una app y pulsa Intro, p. ej. photoshop", + "triggers.excluded_pick": "Elige una app en ejecución", + "triggers.excluded_none_running": "Ninguna otra app tiene una ventana abierta.", + "triggers.excluded_note": "Los gestos y los atajos no hacen nada mientras el puntero esté sobre estas apps.", + "triggers.paused": "Los atajos están en pausa", + "toolbar.title": "Menú circular", + "toolbar.step_profile": "1. Elige un perfil", + "toolbar.step_arrange": "2. Coloca los ajustes preestablecidos", + "toolbar.add_profile": "Nuevo perfil", + "toolbar.profile_new": "Nuevo perfil", + "toolbar.delete_profile": "Eliminar perfil", + "toolbar.name": "Nombre", + "toolbar.extensions": "Usar para estas extensiones", + "toolbar.extensions_hint": "Añade una extensión, p. ej. jpg", + "toolbar.available": "Ajustes preestablecidos disponibles", + "toolbar.hint_add": "Arrastra una etiqueta al menú circular para añadirla", + "toolbar.hint_remove": "Arrastra una porción aquí para quitarla", + "toolbar.hint_reorder": "Arrastra una porción sobre otra para reordenar", + "toolbar.hint_edit": "Haz clic derecho en una porción o usa ✎ para editarla", + "toolbar.max_reached": "Un menú circular admite hasta {0} ajustes preestablecidos", + "toolbar.appearance": "Aspecto", + "toolbar.size": "Tamaño", + "toolbar.hole": "Hueco", + "toolbar.opacity": "Opacidad", + "toolbar.new_preset": "Nuevo ajuste", + "toolbar.new_group": "Nuevo grupo", + "group.editor_title": "Grupo", + "group.hint": "Un grupo es una sola porción del menú circular para varios ajustes preestablecidos: detente en él o muévete hacia fuera y se despliegan a su alrededor.", + "group.members": "Ajustes preestablecidos ({0} / {1})", + "group.empty": "Todavía no hay ajustes preestablecidos. Añade algunos abajo.", + "group.add": "Añadir", + "group.add_placeholder": "Elige un ajuste preestablecido", + "group.full": "Un grupo admite hasta {0} ajustes preestablecidos.", + "group.move_up": "Mover arriba", + "group.move_down": "Mover abajo", + "group.remove": "Quitar del grupo", + "group.delete": "Eliminar el grupo", + "group.delete_confirm": "¿Eliminar el grupo «{0}»? Sus ajustes preestablecidos permanecen.", + "toolbar.ext_none": "Todavía no hay extensiones. Este perfil solo se usa cuando añadas alguna.", + "toolbar.ext_invalid": "«{0}» no es una extensión de archivo (p. ej. jpg o tar.gz).", + "toolbar.ext_duplicate": "{0} ya está en la lista.", + "toolbar.ext_also_in": "También en «{0}»", + "toolbar.ext_in_profile": "en {0}", + "toolbar.ext_claimed_first": "{0}: también en «{1}», que va antes en la lista, así que estos archivos siguen abriendo «{1}».", + "toolbar.ext_claimed_later": "{0}: también en «{1}».\nEste perfil va antes en la lista, así que ahora estos archivos abren este en su lugar.", + "toolbar.ext_unknown": "{0}: Filee no conoce este tipo de archivo.\nPuedes conservarlo, pero estos archivos no se pueden convertir.", + "toolbar.ext_unknown_tip": "Tipo de archivo desconocido", + "toolbar.mixed_toggle": "Usar para selecciones mixtas (archivos de tipos distintos)", + "toolbar.mixed_locked": "Filee necesita al menos un perfil para selecciones mixtas, así que este se queda.", + "toolbar.mixed_badge": "Para selecciones mixtas", + "toolbar.mixed_title": "Mostrar este menú circular cuando todos los archivos seleccionados sean de esta lista:", + "toolbar.mixed_expand": "Mostrar las extensiones", + "toolbar.mixed_other_group": "Otras extensiones", + "toolbar.mixed_catch_all": "Sin ninguna marcada: se usa para cualquier combinación de archivos que ningún otro perfil tome.", + "toolbar.mixed_shadowed": "No hay ninguna marcada, así que «{0}», que va antes en la lista, toma todas las combinaciones.\nMarca algunas extensiones para usar este perfil.", + "toolbar.mixed_covered": "«{0}» va antes y admite todas las extensiones marcadas aquí, así que este perfil no se usa nunca.", + "toolbar.mixed_others": "Las demás combinaciones de archivos abren «{0}».", + "toolbar.mixed_others_self": "Ningún perfil mixto quedó sin nada marcado, así que este también se usa para todas las demás combinaciones.", + "tags.remove": "Quitar", + "presets.title": "Ajustes preestablecidos", + "presets.add": "Nuevo", + "presets.duplicate": "Duplicar", + "presets.delete": "Eliminar", + "presets.save": "Guardar", + "presets.revert": "Revertir", + "presets.name": "Nombre", + "presets.target": "Convertir a", + "presets.same_as_source": "El mismo formato que el original", + "presets.group.image": "Imagen", + "presets.quality": "Calidad", + "presets.resize": "Cambiar tamaño", + "presets.resize.None": "Tamaño original", + "presets.resize.Percent": "Escalar por porcentaje", + "presets.resize.LongEdge": "Limitar el lado largo", + "presets.resize.Width": "Fijar el ancho", + "presets.rotation": "Rotar", + "presets.rotation.None": "No rotar", + "presets.rotation.Right90": "90° a la derecha", + "presets.rotation.Left90": "90° a la izquierda", + "presets.rotation.Rotate180": "180°", + "presets.flip": "Voltear", + "presets.flip.None": "No voltear", + "presets.flip.Horizontal": "Izquierda ↔ derecha", + "presets.flip.Vertical": "Arriba ↔ abajo", + "presets.percent": "Porcentaje", + "presets.long_edge": "Lado largo (px)", + "presets.width": "Ancho (px)", + "presets.dpi": "DPI", + "presets.dpi_keep": "Conservar", + "presets.keep_metadata": "Conservar los metadatos (EXIF)", + "presets.keep_color_profile": "Conservar el perfil de color (ICC)", + "presets.keep_color_profile_hint": "Disponible cuando se quitan los metadatos.\nSin él, las fotos de gama amplia (Display P3 de los móviles) pueden verse decoloradas.", + "presets.grayscale": "Escala de grises", + "presets.remove_background": "Quitar el fondo", + "presets.remove_background_hint": "Vuelve transparente un fondo liso: el papel detrás de una firma o un sello, el fondo de un logotipo.\nCuenta como fondo el color del borde, así que deja algo de papel alrededor del dibujo.\nJPG no admite transparencia y usa el color de fondo elegido. No es apto para fotos de personas.", + "presets.background_tolerance": "Tolerancia del fondo", + "presets.background_tolerance_hint": "Con valor más alto se elimina más, como papel en sombra o manchas. Demasiado alto adelgaza los trazos claros.\nPara conservar un relleno claro dentro de un contorno, activa «Conservar las áreas cerradas».", + "presets.keep_enclosed_background": "Conservar las áreas cerradas", + "presets.keep_enclosed_background_hint": "Solo quita el fondo que toca el borde, así que el blanco de dentro de un logotipo se conserva.\nDéjalo desactivado para escritura a mano (conservaría el papel dentro de letras como «o»).", + "presets.background": "Fondo para la transparencia", + "presets.tiff_compression": "Compresión TIFF", + "presets.webp_lossless": "WEBP sin pérdida", + "presets.multipage_tiff": "Poner todos los archivos en un TIFF multipágina", + "presets.multipage_tiff_hint": "Cada imagen y cada página de PDF o TIFF pasa a ser una página, en orden.\nCon un PDF basta para un TIFF multipágina.", + "presets.save_every_frame": "Guardar cada fotograma de un vídeo", + "presets.save_every_frame_hint": "El vídeo se convierte en una carpeta con una imagen por cada fotograma en lugar de una única imagen fija.\nUn vídeo largo generará muchos archivos.", + "presets.frame_interval": "Cada N fotogramas", + "presets.frame_estimate": "Un minuto de vídeo a 30 fps genera {0} imágenes, como máximo {1} por vídeo.", + "presets.ico_sizes": "Tamaños de icono", + "presets.group.pdf": "PDF", + "presets.merge": "Combinar todos los archivos en un PDF", + "presets.page_size": "Tamaño de página", + "presets.page_size.FitImage": "Ajustar a la imagen", + "presets.page_size.A4": "A4", + "presets.page_size.Letter": "Carta", + "presets.margin": "Margen (mm)", + "presets.render_dpi": "DPI de renderizado (PDF → imagen)", + "presets.page_range": "Páginas", + "presets.page_range_hint": "Todas las páginas o, por ejemplo, 1-3, 5", + "presets.split": "Un archivo por página", + "presets.pdf_compression": "Comprimir", + "presets.pdf_compression.None": "No comprimir", + "presets.pdf_compression.Screen": "El más pequeño (imágenes a 72 ppp)", + "presets.pdf_compression.Ebook": "Equilibrado (imágenes a 150 ppp)", + "presets.pdf_compression.Print": "Alta calidad (imágenes a 300 ppp)", + "presets.pdf_compression_hint": "Las imágenes se reducen y se guardan como JPEG.\nEl texto, las fuentes y los dibujos permanecen iguales.\nSi el resultado no es más pequeño, se conserva el original.", + "presets.pdf_ghostscript": "Probar también con Ghostscript (si está instalado)", + "presets.pdf_ghostscript_hint": "A menudo es más pequeño, pero reescribe todo el archivo.\nSe conserva el resultado más pequeño.", + "presets.pdf_keep_metadata": "Conservar metadatos de página e imagen (XMP)", + "presets.combine_pages_hint": "Pone todas las páginas una debajo de otra en una sola imagen.\nLos resultados muy largos se escalan al límite del formato (JPG 65 500 px, WebP 16 383 px).", + "presets.combine_pages": "Apilar las páginas en una imagen alta (cuando se convierte un PDF)", + "presets.trim_page_margins": "Recortar el espacio en blanco de arriba y abajo de cada página", + "presets.split_tall_image": "Demasiado alta para el formato: dividir en varias imágenes", + "presets.split_tall_image_hint": "Desactivado: una imagen larga se reduce al límite del formato (JPG 65 500 px, WebP 16 383 px).\nActivado: conserva su tamaño y se reparte entre páginas en varios archivos (nombre_1, nombre_2, …).", + "presets.group.document": "Documentos", + "presets.pdfa": "PDF/A (para archivado)", + "presets.target_folder": "Carpeta (extraer archivos comprimidos)", + "presets.group.media": "Vídeo y audio", + "presets.media_quality": "Calidad", + "presets.media_quality_hint": "Cuando el formato nuevo puede conservar los códecs tal como están (MOV de iPhone → MP4), el vídeo solo se cambia de contenedor sin recodificar.\nSin pérdida de calidad, HDR conservado, listo en segundos.\nPequeño siempre recodifica para que el archivo pese menos.", + "presets.media_quality.High": "Alta (archivos más grandes)", + "presets.media_quality.Balanced": "Equilibrada", + "presets.media_quality.Small": "Pequeño (para compartir)", + "presets.max_height": "Altura máxima", + "presets.max_height.original": "Original", + "presets.audio_bitrate": "Tasa de bits del audio", + "presets.audio_bitrate.auto": "Automática", + "presets.remove_audio": "Quitar el sonido", + "presets.audio_channels": "Canales", + "presets.audio_channels.0": "Igual que el original", + "presets.audio_channels.1": "Mono", + "presets.audio_channels.2": "Estéreo", + "presets.sample_rate": "Frecuencia de muestreo", + "presets.sample_rate.source": "Igual que el original", + "presets.wav_format": "Profundidad de bits", + "presets.wav_format.Pcm16": "16 bits", + "presets.wav_format.Pcm8": "8 bits", + "presets.wav_format.Pcm24": "24 bits", + "presets.wav_format.Pcm32": "32 bits", + "presets.wav_format.Float32": "32 bits flotante", + "presets.video_codec": "Códec de vídeo", + "presets.video_codec_hint": "H.264 se reproduce en todas partes.\nLos archivos HEVC pesan aproximadamente la mitad y se reproducen en la mayoría de móviles, televisores y PC recientes.\nAV1 pesa todavía menos, pero codifica despacio y necesita un dispositivo reciente.\nUn vídeo que ya esté en el códec elegido solo se cambia de contenedor sin recodificar.", + "presets.video_codec.h264": "H.264 (se reproduce en todas partes)", + "presets.video_codec.vp9": "VP9", + "presets.video_codec.hevc": "HEVC / H.265 (más pequeño)", + "presets.video_codec.av1": "AV1 (el más pequeño, lento)", + "presets.hardware_encoding": "Usar aceleración por hardware (chip gráfico)", + "presets.hardware_encoding_hint": "Codifica H.264 y HEVC en el chip gráfico.\nMucho más rápido y consume menos energía.\nCalidad ligeramente inferior con el mismo tamaño de archivo.\nSin un chip compatible, el vídeo se codifica de la forma habitual.", + "presets.audio_codec": "Códec de audio", + "presets.audio_codec.aac": "AAC", + "presets.audio_codec.alac": "ALAC (sin pérdida)", + "presets.group.archive": "Archivo comprimido", + "presets.archive_level": "Compresión", + "presets.archive_level.Store": "Ninguna (solo almacenar)", + "presets.archive_level.Fast": "Rápida", + "presets.archive_level.Normal": "Normal", + "presets.archive_level.Maximum": "Máxima (más lenta)", + "presets.combine": "Empaquetar todos los archivos en uno solo", + "presets.extract_note": "Cada archivo comprimido se extrae en una carpeta propia. El destino se define en Salida.", + "presets.group.trace": "Trazado", + "presets.trace_note": "Se usa cuando una imagen (PNG, JPG, …) se traza a formas vectoriales.", + "presets.trace_mode": "Modo", + "presets.trace_mode.Color": "Color", + "presets.trace_mode.BlackAndWhite": "Blanco y negro (dibujo de líneas)", + "presets.trace_colors": "Colores", + "presets.trace_detail": "Detalle", + "presets.trace_detail_hint": "Bajo suaviza los contornos y descarta motas.\nAlto sigue los píxeles de cerca y conserva los detalles pequeños.", + "presets.group.output": "Salida", + "presets.location": "Guardar en", + "presets.location.Default": "Carpeta de guardado predeterminada (Ajustes > General)", + "presets.location.SameFolder": "La misma carpeta que el original", + "presets.location.Subfolder": "Una subcarpeta", + "presets.location.CustomFolder": "Una carpeta fija", + "presets.subfolder": "Nombre de la subcarpeta", + "presets.custom_folder": "Carpeta", + "presets.browse": "Examinar…", + "presets.pattern": "Nombre del archivo", + "presets.pattern_hint": "{name} {ext} {preset} {date} {time} {index}", + "presets.keep_dates": "Conservar las fechas del archivo original", + "presets.keep_dates_hint": "Los archivos convertidos reciben las fechas de creación y modificación del original, así que las fotos siguen ordenándose por fecha.", + "presets.conflict": "Si el archivo existe", + "presets.conflict.Rename": "Añadir un número", + "presets.conflict.Overwrite": "Reemplazarlo", + "presets.conflict.Skip": "Omitir", + "presets.editor_title": "Editar ajuste preestablecido", + "presets.delete_confirm": "¿Eliminar «{0}»? También se quitará de todos los menús circulares y grupos.", + "presets.name_required": "Escribe un nombre", + "presets.select": "Elige un ajuste preestablecido para editarlo", + "theme.title": "Tema", + "theme.mode": "Aspecto", + "theme.mode.System": "Sistema", + "theme.mode.Light": "Claro", + "theme.mode.Dark": "Oscuro", + "theme.accent": "Color de acento", + "theme.custom_color": "Personalizado", + "theme.corner_radius": "Redondeo", + "theme.reduce_motion": "Reducir las animaciones", + "theme.reduce_motion_hint": "Recomendado para PC antiguos. Desactiva las transiciones y el rebote del menú circular.", + "theme.preview": "Vista previa", + "engines.title": "Motores de conversión", + "engines.description": "Filee elige el mejor motor disponible para cada conversión.\nCuando varios pueden hacer el mismo trabajo, gana el que está más arriba.", + "engines.available": "Disponible", + "engines.unavailable": "No disponible", + "engines.move_up": "Mover arriba", + "engines.move_down": "Mover abajo", + "engines.recheck": "Comprobar otra vez", + "engines.conversions": "{0} conversiones", + "engines.optional_title": "Motores opcionales", + "engines.optional_description": "Los motores grandes solo se descargan si tú lo pides.\nSe conservan al actualizar Filee y se eliminan al desinstalarlo.", + "engines.all_title": "Todos los motores", + "engines.update": "Actualizar", + "engines.state.update_available": "Versión nueva {0}", + "engines.update_notice_title": "Los motores que instalaste tienen una versión nueva", + "engines.settings": "Ajustes", + "engines.all_description": "Arrastra una tarjeta (o usa sus flechas) para cambiar el orden.", + "engines.lo_title": "Cuando LibreOffice está instalado", + "engines.lo_description": "LibreOffice puede hacerse cargo de las conversiones que él realiza con más fidelidad.\nSin LibreOffice estos interruptores no cambian nada.", + "engines.lo_slides": "Usar LibreOffice para presentaciones → PDF", + "engines.lo_slides_hint": "Los fondos de las diapositivas y las posiciones de las formas salen como en PowerPoint.\nDesactivado: la ruta integrada, que puede perder fondos o mover formas.", + "engines.lo_documents": "Usar LibreOffice para documentos de Word → PDF", + "engines.lo_documents_hint": "Se maquetan como en Word, incluidas las reglas de puntuación china y japonesa.\nDesactivado: la ruta integrada.", + "engines.lo_sheets": "Usar LibreOffice para hojas de cálculo → PDF", + "engines.lo_sheets_hint": "Se imprimen como en Excel, con el área de impresión, la configuración de página y los saltos de página.\nDesactivado: la ruta integrada ajusta cada hoja al ancho de la página (los saltos de página se conservan).", + "engines.lo_hwp": "Usar LibreOffice para HWP·HWPX → PDF", + "engines.lo_hwp_hint": "Desactivado de forma predeterminada: rhwp suele parecerse más a 한글.\nActívalo para comparar cuando rhwp se equivoque con un documento (texto superpuesto, tablas mal colocadas).", + "engines.package.libreoffice.name": "LibreOffice (formatos antiguos y poco habituales)", + "engines.package.libreoffice.description": "Necesario para formatos antiguos o poco habituales: DOC·PPT, presentaciones OpenDocument, WordPerfect, ClarisWorks·MacWrite, Apple Pages·Numbers·Keynote, Publisher·Visio y más.\nTambién guarda como DOC·XLS·PPT·ODT·ODP·EMF y hace las presentaciones → PDF con más fidelidad.\nWord, Excel, PowerPoint, PDF y HWP se convierten sin él.", + "engines.package.pandoc.name": "Pandoc (Markdown, LaTeX, Org y más)", + "engines.package.pandoc.description": "Añade Markdown y HTML ↔ ODT y RTF, DOCX → Markdown, y LaTeX, Org, AsciiDoc, Typst, Jupyter y otros lenguajes de marcado.\nTambién crea diapositivas PPTX desde Markdown.\nMarkdown y HTML → PDF, DOCX y HWPX funcionan sin él.", + "engines.package.ghostscript.name": "Ghostscript (EPS y PostScript)", + "engines.package.ghostscript.description": "EPS, PS y archivos antiguos de Illustrator → PDF e imágenes, PDF o SVG → EPS/PS.\nSVG y AI compatibles con PDF se convierten sin él.", + "engines.package.ffmpeg.name": "FFmpeg (vídeo y audio)", + "engines.package.ffmpeg.description": "Añade conversión de vídeo y audio, vídeo → GIF o imagen fija, sonido de vídeos y GIF → MP4.\nSolo es necesario para vídeo y audio.", + "engines.package.calibre.name": "Calibre (Kindle y libros electrónicos poco habituales)", + "engines.package.calibre.description": "Guarda MOBI y AZW3 para Kindle y convierte formatos de libro electrónico poco habituales (LIT, LRF, PDB, CHM…).\nEPUB, MOBI, AZW3, FB2 y cómics se leen sin él.", + "engines.package.size": "Descargar {0} · {1} en disco", + "engines.package.system_required": "Usa una copia instalada en este equipo.", + "engines.guidance.macos": "Instala {0} para este Mac y luego elige «Usar mi copia…» y selecciona su programa o su carpeta .app.", + "engines.guidance.macos.ffmpeg": "Instálalo con Homebrew (brew install ffmpeg) y luego elige «Comprobar otra vez».\nO bien elige «Usar mi copia…» y selecciona su carpeta bin.", + "engines.guidance.macos.ghostscript": "Instálalo con Homebrew (brew install ghostscript) y luego elige «Comprobar otra vez».\nO bien elige «Usar mi copia…» y selecciona su carpeta bin.", + "engines.guidance.linux": "Instala {0} con el gestor de paquetes de tu distribución y luego elige «Usar mi copia…» y selecciona su carpeta de programa.", + "engines.guidance.linux.libreoffice": "Instálalo con tu gestor de paquetes (Ubuntu/Debian: sudo apt install libreoffice) y luego elige «Comprobar otra vez».\nAbrir HWP necesita además Java y la extensión H2Orestart.", + "engines.guidance.linux.ghostscript": "Instálalo con tu gestor de paquetes (Ubuntu/Debian: sudo apt install ghostscript) y luego elige «Comprobar otra vez».", + "engines.guidance.windows": "Filee no tiene una descarga de {0} para este PC.\nElige «Usar mi copia…» y selecciona una copia instalada.", + "engines.use_own_app_folder": "Elige la carpeta que contiene {0}.app", + "engines.progress_detail": "{0} de {1} · {2}/s · {3}", + "engines.eta.estimating": "calculando el tiempo restante…", + "engines.eta.seconds": "quedan {0} s", + "engines.eta.minutes": "quedan {0} min", + "engines.install": "Instalar", + "engines.cancel": "Cancelar", + "engines.remove": "Quitar", + "engines.remove_confirm": "¿Quitar {0}? Podrás descargarlo de nuevo más tarde.", + "engines.state.own_copy": "Tu copia", + "engines.state.system_copy": "Encontrado en este equipo", + "engines.update_recommended": "Actualización recomendada: esta copia es la {0} y Filee está probado con la {1}.\nLa mayoría de las conversiones seguirán funcionando.", + "engines.use_own": "Usar mi copia…", + "engines.use_own_hint": "¿Ya lo tienes? Elige su programa y Filee usará ese en lugar de descargar el suyo.", + "engines.use_own_title": "Elige el programa de tu {0}", + "engines.use_own_missing": "Esa carpeta no tiene todo lo que Filee necesita: {0}.", + "engines.stop_own": "Dejar de usarlo", + "engines.remove_failed": "El motor está en uso. Inténtalo otra vez cuando terminen las conversiones en curso.", + "engines.state.not_installed": "No instalado", + "engines.state.queued": "En espera…", + "engines.state.downloading": "Descargando {0}%", + "engines.state.unpacking": "Instalando…", + "engines.state.installed": "Instalado", + "engines.state.failed": "Error: {0}", + "about.title": "Acerca de", + "about.updates": "Actualizaciones", + "common.search": "Buscar", + "common.retry": "Reintentar", + "about.version": "Versión {0}", + "about.license": "Filee es software libre bajo la licencia MIT.", + "about.notices": "Avisos de terceros", + "about.github": "Repositorio en GitHub", + "about.support_title": "Ayuda a Filee a crecer", + "about.support_text": "Filee es libre y de código abierto.\nUna estrella en GitHub, un informe de error, una idea o un patrocinio, todo ayuda.", + "about.sponsor": "Patrocinar", + "sponsor.title": "Patrocina Filee", + "sponsor.lead": "Filee es libre y seguirá siéndolo. Si quieres apoyar su desarrollo, elige la forma que mejor te venga.", + "sponsor.note.github": "Mensual o puntual, con tarjeta a través de GitHub", + "sponsor.note.fairy": "Tarjetas coreanas y pago sencillo", + "sponsor.note.patreon": "Membresía mensual", + "sponsor.note.kofi": "Un café puntual, sin necesidad de cuenta", + "sponsor.note.paypal": "El importe que quieras con PayPal", + "sponsor.thanks": "Gracias a nuestros patrocinadores", + "sponsor.star": "Una ⭐ en GitHub no cuesta nada y ayuda a que otras personas encuentren Filee.", + "feedback.notice_title": "¿Te está resultando útil Filee?", + "feedback.notice_text": "Una estrella en GitHub ayuda a que otras personas encuentren Filee.\nLos problemas y las ideas también son bienvenidos.", + "feedback.star": "Dar una estrella en GitHub", + "feedback.issue": "Informar de un problema o una idea", + "common.ok": "Aceptar", + "common.cancel": "Cancelar", + "common.save": "Guardar", + "common.close": "Cerrar", + "common.delete": "Eliminar", + "common.yes": "Sí", + "common.no": "No", + "setup.title": "Elige motores de conversión", + "setup.description": "Imágenes, PDF, documentos de Office, HWP, libros electrónicos, archivos comprimidos, tipografías, CAD y modelos 3D ya se convierten.\nDescarga motores solo para vídeo y audio o formatos poco habituales.", + "setup.note": "Puedes instalar o quitar motores en cualquier momento en Ajustes → Motores.", + "setup.install": "Instalar la selección", + "setup.later": "Más tarde", + "setup.background": "Continuar en segundo plano", + "setup.done": "Hecho", + "setup.selection": "Descarga: {0}", + "setup.nothing_selected": "Nada seleccionado", + "watch.title": "Carpetas supervisadas", + "watch.description": "Los archivos que lleguen a estas carpetas se convierten mientras Filee esté en ejecución.\nLas descargas y las copias se convierten cuando terminan.", + "watch.add": "Añadir carpeta", + "watch.empty": "Todavía no hay carpetas supervisadas.", + "watch.enabled": "Activada", + "watch.remove": "Quitar", + "watch.folder": "Carpeta a supervisar", + "watch.folder_placeholder": "Elige una carpeta", + "watch.preset": "Convertir con", + "watch.originals": "Después de convertir", + "watch.originals_keep": "Dejar el original donde está", + "watch.originals_move": "Mover el original a \"originals\"", + "watch.originals_hint": "Mover los originales hace que la carpeta funcione como una bandeja de entrada, y los archivos que ya estén esperando allí cuando Filee se abra también se convierten.", + "watch.output": "Guardar los archivos convertidos en", + "watch.output_placeholder": "\"converted\" dentro de la carpeta supervisada", + "watch.subfolders": "Incluir subcarpetas", + "watch.options": "Más opciones (opcionales)", + "watch.include": "Archivos a convertir", + "watch.include_placeholder": "Escribe una extensión o un nombre y pulsa Intro (p. ej. heic, scan_*)", + "watch.include_hint": "Déjalo vacío para convertir todos los archivos.\n· heic → archivos que terminan en .heic\n· scan → archivos con \"scan\" en el nombre\n· * equivale a cualquier texto y ? a un carácter (p. ej. scan_*.jpg)", + "watch.name": "Nombre base", + "watch.name_placeholder": "Igual que el ajuste preestablecido: {0}", + "watch.name_hint": "Los botones añaden partes del nombre. Déjalo vacío para usar el nombre del ajuste preestablecido.", + "watch.rename": "Nombres de los archivos convertidos", + "watch.rename_find": "Buscar, p. ej. IMG_(\\d+)", + "watch.rename_replace": "Reemplazar por, p. ej. Photo_$1", + "watch.name_summary": "Nombre: {0}", + "watch.name_summary_preset": "Nombre: {0} (igual que el ajuste preestablecido)", + "watch.token.name": "Nombre original", + "watch.token.ext": "Extensión original", + "watch.token.date": "Fecha", + "watch.token.time": "Hora", + "watch.token.index": "Número", + "watch.token.preset": "Nombre del ajuste preestablecido", + "watch.kind.Replace": "Reemplazar texto", + "watch.kind.Remove": "Quitar texto", + "watch.kind.Prefix": "Añadir al principio", + "watch.kind.Suffix": "Añadir al final", + "watch.kind.SpacesToUnderscores": "Espacios a _", + "watch.kind.RemoveCopyNumber": "Quitar un número de copia como (2)", + "watch.kind.RemoveBrackets": "Quitar el texto entre paréntesis y corchetes", + "watch.kind.RemoveLeadingNumber": "Quitar un número inicial", + "watch.kind.RemoveSymbols": "Quitar símbolos", + "watch.kind.Lowercase": "todo en minúsculas", + "watch.kind.Uppercase": "TODO EN MAYÚSCULAS", + "watch.kind.Regex": "Avanzado: expresión regular", + "watch.ph.find": "Texto a buscar, p. ej. IMG_", + "watch.ph.replace": "Reemplazar por, p. ej. Photo_", + "watch.ph.remove": "Texto a quitar, p. ej. _copy", + "watch.ph.prefix": "Texto a añadir, p. ej. 2026_", + "watch.ph.suffix": "Texto a añadir, p. ej. _final", + "watch.advanced": "Avanzado", + "watch.recipe.camera_to_photo": "Cambiar IMG_ por Photo_", + "watch.recipe.lowercase": "Todo en minúsculas", + "watch.rename_edit": "Editar reglas de nombre", + "watch.rename_title": "Nombrar los archivos convertidos", + "watch.rename_intro": "Define el nombre base y, si hace falta, cambia partes con reglas.\nLa vista previa muestra el nombre que recibirá cada archivo.", + "watch.rename_steps": "Cambios (se aplican de arriba a abajo)", + "watch.rename_no_steps": "No hay cambios. Elige uno a la izquierda o añade uno si lo necesitas.", + "watch.step_up": "Mover arriba (se ejecuta antes)", + "watch.rename_try": "Prueba un nombre", + "watch.rename_try_placeholder": "Escribe un nombre de archivo, p. ej. IMG_0412.jpg", + "watch.include_matches": "{0} archivo(s) de la carpeta coinciden ahora", + "watch.add_step": "Añadir una regla", + "watch.remove_step": "Quitar esta regla", + "watch.recipes": "Reemplazos habituales", + "watch.recipes_hint": "Doble clic en uno (o pulsa +) para añadirlo como regla; después cámbialo si quieres.", + "watch.recipe_add": "Añadir como regla", + "watch.recipe_removes": "(se quita)", + "watch.recipe.drop_camera_prefix": "Quitar IMG_", + "watch.recipe.spaces": "Espacios a guiones bajos", + "watch.recipe.copy_number": "Quitar un número de copia como (2)", + "watch.recipe.brackets": "Quitar el texto entre paréntesis y corchetes", + "watch.recipe.leading_number": "Quitar un número inicial", + "watch.recipe.date_dashes": "Poner guiones en las fechas", + "watch.recipe.symbols": "Quitar símbolos", + "watch.recipe.prefix": "Añadir texto al principio", + "watch.recipe.suffix": "Añadir texto al final", + "watch.invalid_regex": "No es una expresión regular válida: {0}", + "watch.preview": "Vista previa", + "watch.results": "Resultados recientes", + "watch.results_ok": "{0} archivo(s) convertido(s), ninguno falló", + "watch.results_failed": "{0} archivo(s) convertido(s) · {1} con error", + "watch.sample_file": "foto.jpg", + "watch.preview_keep": "El original se queda donde está", + "watch.preview_move": "El original se mueve a \"originals\"", + "watch.status_off": "Desactivado", + "watch.status_no_folder": "Elige una carpeta para empezar", + "watch.status_watching": "Supervisando", + "watch.status_starting": "Iniciando…", + "watch.status_error": "No se puede supervisar esta carpeta: {0}", + "watch.cli_hint": "También en la línea de comandos: filee watch --to " +} diff --git a/src/Filee.App/Services/LocalizationService.cs b/src/Filee.App/Services/LocalizationService.cs index f2bf03cca..9b0470444 100644 --- a/src/Filee.App/Services/LocalizationService.cs +++ b/src/Filee.App/Services/LocalizationService.cs @@ -19,6 +19,7 @@ public sealed class LocalizationService : ILocalizer public static readonly IReadOnlyList<(string Code, string NativeName)> Languages = [ ("en", "English"), + ("es", "Español"), ("ko", "한국어"), ("zh-CN", "简体中文"), ("pl", "Polski"), @@ -100,6 +101,8 @@ public static string Resolve(string setting) return "zh-CN"; if (ui.StartsWith("pl", StringComparison.OrdinalIgnoreCase)) return "pl"; + if (ui.StartsWith("es", StringComparison.OrdinalIgnoreCase)) + return "es"; return "en"; } diff --git a/tests/Filee.App.Tests/LocalizationTests.cs b/tests/Filee.App.Tests/LocalizationTests.cs index e27a85f7d..0edeb6c27 100644 --- a/tests/Filee.App.Tests/LocalizationTests.cs +++ b/tests/Filee.App.Tests/LocalizationTests.cs @@ -3,7 +3,7 @@ namespace Filee.App.Tests; -/// Keeps en / ko / zh-CN in sync so no language silently falls back to English. +/// Keeps en / es / ko / zh-CN in sync so no language silently falls back to English. public partial class LocalizationTests { private static string I18nDirectory @@ -20,7 +20,7 @@ private static string I18nDirectory private static Dictionary Load(string code) => JsonSerializer.Deserialize>(File.ReadAllText(Path.Combine(I18nDirectory, code + ".json")))!; - public static TheoryData Languages => new() { "ko", "zh-CN", "pl" }; + public static TheoryData Languages => new() { "es", "ko", "zh-CN", "pl" }; [Theory] [MemberData(nameof(Languages))] diff --git a/tests/Filee.App.Tests/RenderTests.cs b/tests/Filee.App.Tests/RenderTests.cs index d284a6f39..4a1d57bf2 100644 --- a/tests/Filee.App.Tests/RenderTests.cs +++ b/tests/Filee.App.Tests/RenderTests.cs @@ -27,6 +27,7 @@ public class RenderTests { "presets", "en" }, { "theme", "en" }, { "engines", "en" }, { "about", "en" }, { "toolbar", "ko" }, { "home", "ko" }, { "presets", "zh-CN" }, { "toolbar", "zh-CN" }, { "home", "zh-CN" }, { "toolbar", "pl" }, { "presets", "pl" }, { "home", "pl" }, + { "home", "es" }, { "general", "es" }, { "toolbar", "es" }, { "presets", "es" }, { "engines", "es" }, }; [AvaloniaTheory]