feat: mirada standalone — compositor Wayland + WM sobre Llimphi (build magro)

Stack de display extraído del monorepo: compositor teselante (Cuerpo smithay
+ Cerebro WM agnóstico), greeter PAM, portal XDG, CLI de control. Llimphi se
consume por git desde su repo publicado; las hojas compartidas (format,
auth-core, rimay-localize, wawa-config, app-bus) y el widget menubar van
vendorizados. Sin el asistente IA (pluma-llm) ni la barra web wasm — el
compositor no los necesita. cargo check --workspace pasa (18 crates, 0 warn).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-04 11:01:49 +00:00
commit 3dc85ebdcd
116 changed files with 31060 additions and 0 deletions
+20
View File
@@ -0,0 +1,20 @@
[package]
name = "rimay-localize"
version.workspace = true
edition.workspace = true
rust-version.workspace = true
license.workspace = true
authors.workspace = true
publish.workspace = true
description = "rimay-localize — i18n del escritorio gioser sobre fluent. Catálogos .ftl embebidos por idioma, API global t!(id) con args opcionales, detección de locale del sistema con fallback a es-PE. Los *-core no contienen strings de UI: emiten IDs (MsgId) que las apps Llimphi resuelven aquí."
[dependencies]
fluent-bundle = { workspace = true }
unic-langid = { workspace = true }
sys-locale = { workspace = true }
once_cell = { workspace = true }
parking_lot = { workspace = true }
thiserror = { workspace = true }
tracing = { workspace = true }
[dev-dependencies]
+34
View File
@@ -0,0 +1,34 @@
# rimay-localize — localización (i18n) declarativa
Catálogos de cadenas por idioma + una API de lookup minimalista para las apps de
gioser. Los catálogos son **datos** (JSON) cargables en tiempo de ejecución; el
código pide una clave y un idioma y obtiene la cadena, con interpolación de
placeholders `{nombre}`.
## Qué expone
- `Lang` — etiqueta de idioma (BCP-47 simplificado).
- `Catalog` — mapa clave → cadena para un idioma.
- `Localizer` — colección de catálogos + idioma activo + fallback.
- Lookup con sustitución de placeholders por argumentos con nombre.
## Nota de naming
`rimay` es el dominio de lenguaje/voz; este crate es su utilidad de localización
transversal (no es parte del núcleo de `rimay`).
## Estado (2026-05-31)
### Hecho
- Carga de catálogos JSON por idioma.
- Lookup con idioma activo + fallback y tests.
- Interpolación de placeholders `{nombre}`.
### Pendiente
- Pluralización compleja (ICU) y reglas por idioma.
- Detección del idioma del sistema (hoy lo decide la app).
- Herramienta de extracción/validación de claves faltantes.
## Lugar en el repo
`shared/rimay-localize` — utilidad i18n transversal para apps gioser.
@@ -0,0 +1,37 @@
//! `showcase` — imprime todos los IDs del catálogo en los 3 idiomas
//! soportados. Smoke test visual + referencia para revisores.
//!
//! Ejecutar con: `cargo run -p rimay-localize --example showcase`
use std::borrow::Cow;
use rimay_localize as l10n;
/// IDs en el orden de aparición en los `.ftl`. Mantener sincronizado a
/// mano — el ejemplo es referencia, no test exhaustivo.
const IDS: &[&str] = &[
"save", "load", "open", "close", "cancel", "confirm", "yes", "no", "delete", "edit", "new",
"play", "pause", "resume", "stop", "file", "view", "help", "settings", "exit", "info",
"warning", "error", "success",
];
fn main() {
let locales = l10n::available_locales();
for locale in &locales {
l10n::set_locale(locale).unwrap();
println!("\n========= {locale} =========");
for id in IDS {
println!(" {:<10} {}", id, l10n::t(id));
}
println!(
" {:<10} {}",
"welcome-user",
l10n::t_args("welcome-user", &[("name", Cow::Borrowed("Sergio"))])
);
println!(
" {:<10} {}",
"items-count",
l10n::t_args("items-count", &[("count", Cow::Borrowed("3"))])
);
}
}
+720
View File
@@ -0,0 +1,720 @@
# rimay-localize — en-US catalog
# === generic actions ===
save = Save
load = Load
open = Open
close = Close
cancel = Cancel
confirm = OK
yes = Yes
no = No
delete = Delete
edit = Edit
new = New
# === state ===
play = Play
pause = Pause
resume = Resume
stop = Stop
# === menus ===
file = File
view = View
help = Help
settings = Settings
exit = Exit
# === common chrome (reusable across all Llimphi apps) ===
# Shared menu/action labels. An app only mints its own (`<app>-*`) IDs
# for text not covered here.
search = Search
language = Language
undo = Undo
redo = Redo
cut = Cut
copy = Copy
paste = Paste
select-all = Select All
open-dots = Open…
save-as = Save As…
close-tab = Close Tab
find-in-file = Find in File
find-in-project = Find in Project
symbols = Symbols
goto-definition = Go to Definition
terminal = Terminal
command-palette = Command Palette
minimap = Minimap
cycle-theme = Cycle Theme
editing = Editing
about = About
refresh = Refresh
reconnect = Reconnect
# === nada (file editor) ===
nada-tagline = a sovereign editor on Llimphi
# === message levels ===
info = Info
warning = Warning
error = Error
success = Done
# === interpolation ===
welcome-user = Welcome, { $name }.
items-count = { $count } items.
# === dominium (mean-field simulator) ===
dominium-status-running = ● running
dominium-status-paused = ‖ paused
dominium-status-line = dominium · mean field · epoch { $epoch } · tick { $tick }
dominium-btn-pause = ‖ Pause
dominium-btn-resume = ▶ Resume
dominium-btn-reseed = ↺ Reseed
dominium-btn-create-concept = ✦ Create concept
dominium-btn-seed-pack = ✚ Seed pack
dominium-btn-clear = ✖ Clear
dominium-btn-save = 💾 Save
dominium-btn-load-saved = 📂 Load saved
dominium-btn-load-named = ✓ Load «{ $name }»
dominium-header-sim = [ SIM ]
dominium-header-conceptos = [ CONCEPTS ]
dominium-header-metricas = [ METRICS ]
dominium-header-editar = [ EDIT ]
dominium-active-count = { $count } active
dominium-stat-population = Population
dominium-stat-materia = Matter
dominium-stat-oro = Gold
dominium-stat-energia = Energy
dominium-stat-epoca = Epoch
dominium-stat-gini-energia = Gini energy
dominium-stat-edad-media = Mean age
dominium-stat-var-psi-orden = Var ψ order
dominium-stat-var-psi-miedo = Var ψ fear
dominium-stat-var-psi-curiosidad = Var ψ curiosity
dominium-stat-var-psi-corruptib = Var ψ corrupt.
dominium-action-mover = → move
dominium-action-extraer = → extract
dominium-action-sincronizar = → sync
dominium-action-intercambiar = → swap
dominium-action-replicar = → replicate
dominium-action-degradar = → degrade
dominium-slider-nombre = name
dominium-slider-radius = radius
dominium-slider-materia = matter
dominium-slider-psique = psyche
dominium-slider-poder = power
dominium-slider-oro = gold
dominium-label-hack = hack:
# === cosmos (overlay modules) ===
cosmos-btn-save-transit = 💾 Save transit as free chart
cosmos-btn-save-progressed = 💾 Save progressed as free chart
cosmos-btn-save-return = 💾 Save return as free chart
cosmos-header = cosmos · { $title } · Asc { $asc }° · MC { $mc }°
cosmos-demo-title = Sample chart (Lima)
cosmos-demo-subtitle = computed by cosmos-engine (VSOP2013)
cosmos-status = { $ms } ms · { $layers } layers · { $overlays } overlays · { $aspects } aspects
cosmos-status-error = error: { $err }
cosmos-overlay-transit = transit
cosmos-overlay-progression = progression
cosmos-overlay-solar-arc = solar arc
cosmos-overlay-uranian = uranian
cosmos-overlay-lots = lots
cosmos-overlay-fixed-stars = fixed stars
cosmos-overlay-midpoints = midpoints
cosmos-harmonic-label = harmonic
cosmos-empty = (empty)
cosmos-tile-carta = chart
cosmos-tile-modulos = modules
cosmos-tile-armonico = harmonic
cosmos-tile-cuerpos = bodies
cosmos-tile-aspectos = aspects
cosmos-tile-box-graph = aspectarian
cosmos-tile-cualidades = qualities
cosmos-elementos = elements
cosmos-modalidades = modalities
cosmos-polaridad = polarity
cosmos-elem-fuego = fire
cosmos-elem-tierra = earth
cosmos-elem-aire = air
cosmos-elem-agua = water
cosmos-mod-cardinal = cardinal
cosmos-mod-fijo = fixed
cosmos-mod-mutable = mutable
cosmos-pol-yang = yang
cosmos-pol-yin = yin
cosmos-tile-astrocarto = astrocartography
cosmos-astrocarto-leyenda = MC solid · IC dashed · Asc/Desc curves · • natal place
cosmos-tile-cartas = saved charts
cosmos-cartas-duplicar = + duplicate current
cosmos-cartas-vacio = (empty — duplicate current or drop JSONs in the dir)
cosmos-tile-corpus = corpus
cosmos-tile-lotes = lots
cosmos-tile-estrellas-fijas = fixed stars
cosmos-tile-puntos-medios = midpoints
cosmos-corpus-header = { $pasajes } passages · { $huecos } gaps · { $total } combos
cosmos-corpus-vacio = (no passages — write your corpus in cosmos-corpus/ejemplo.ron)
cosmos-tile-uraniano = uranian dial 90°
cosmos-tile-cross-transit = cross · transit
cosmos-tile-cross-progression = cross · progression
cosmos-tile-cross-solar-arc = cross · solar arc
# === wawa-explorer (Wawa image browser) ===
wawa-marker-via-aoe = · via AoE
wawa-marker-searching = · searching…
wawa-marker-fetch-failed = · fetch failed
wawa-marker-not-in-image = · (not in image)
wawa-iface-ok = · AoE iface: { $name }
wawa-iface-err = · AoE: no interface
wawa-header-error = wawa-explorer · error: { $err }
wawa-header = wawa-explorer · { $source } · { $bytes } bytes · v{ $version } · cursor sector { $cursor } · { $objects } objects{ $iface }
wawa-detail-empty = (select an object from the tree)
wawa-detail-title = object { $hash } · { $bytes } bytes · { $children } children{ $origen }
wawa-detail-title-missing = object { $hash } · not present locally
wawa-detail-payload-header = payload (first 256 bytes):
wawa-detail-children-header = children:
wawa-detail-child-missing = (not in image)
wawa-detail-searching-aoe-1 = searching the local network (AoE)…
wawa-detail-searching-aoe-2 = broadcast SolicitarObjeto, awaiting ProveedorObjeto with verified hash.
wawa-detail-fetch-error-1 = last AoE attempt failed:
wawa-detail-fetch-error-2 = you can retry with the button below.
wawa-detail-needs-fetch-1 = this object is referenced by a parent but does not live in the local image.
wawa-detail-needs-fetch-2 = you can request it from Wawa peers on the local network (AoE, iface `{ $iface }`).
wawa-detail-aoe-disabled-1 = this object is referenced by a parent but does not live in the local image.
wawa-detail-aoe-disabled-2 = AoE disabled: { $why }
wawa-detail-aoe-disabled-3 = pass `<iface>` as the second CLI argument or run with CAP_NET_RAW (`sudo setcap cap_net_raw=eip <binary>`).
wawa-btn-fetch = fetch from peers
wawa-btn-retry-fetch = retry fetch from peers
# main menu bar
wawa-menu-file = File
wawa-menu-reload = Reload image
wawa-menu-quit = Quit
wawa-menu-view = View
wawa-menu-fetch = Fetch node via AoE
wawa-menu-theme = Toggle theme
wawa-menu-help = Help
wawa-menu-about = About
# context menu on the selected node
wawa-ctx-select = Select
wawa-ctx-expand = Expand
wawa-ctx-collapse = Collapse
wawa-ctx-fetch = Fetch via AoE
# === minga-explorer (repo browser) ===
minga-header-loaded = Repo: { $path } · reload { $ms } ms
minga-header-searching = Searching repo at { $path }…
minga-error-read = could not read repo { $path }: { $err }
minga-card-nodes-title = AST Nodes
minga-card-nodes-desc = code fragments parsed
minga-card-attestations-title = Attestations
minga-card-attestations-desc = Ed25519 signatures over nodes
minga-card-mst-title = MST Keys
minga-card-mst-desc = Merkle Search Tree entries
minga-empty = Waiting for first refresh…
minga-menu-file = File
minga-menu-view = View
minga-menu-help = Help
minga-menu-refresh = Refresh
minga-menu-quit = Quit
minga-menu-theme = Toggle theme
minga-menu-about = About
minga-menu-context-title = Repo
# === nakui-explorer (event log) ===
nakui-explorer-header = Log: { $path } · { $entries } entries ({ $seeds } seeds, { $morphisms } morphisms) · reload { $ms } ms
nakui-explorer-breakdown = breakdown: { $parts }
# === supay (doom) ===
supay-mode-real = REAL ENGINE
supay-mode-stub = STUB
supay-view-fb = view=FB (F3→3D)
supay-view-3d = view=3D (F3→FB)
supay-header = { $title } · tick { $tick } · { $mode } · { $view } · { $scene }
supay-stub-title = supay-doom-llimphi is running in STUB mode
supay-stub-step-1 = Clone doomgeneric
supay-stub-step-1-cmd = cd 02_ruway/supay/supay-core/vendor && git clone https://github.com/ozkl/doomgeneric.git
supay-stub-step-2 = Drop the shareware WAD in the cwd
supay-stub-step-2-cmd = curl -O https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
supay-stub-step-3 = Run it again
supay-stub-step-3-cmd = cargo run -p supay-doom-llimphi --release
supay-stub-footer = doomgeneric (C) ticks at 35 Hz; the 320×200 ARGB framebuffer paints in aspect-fit.
supay-controls-hint = WASD · Ctrl fire · Space use · Tab map · F3 view · F4 cross · F5 vig · F6 HUD · F7 shadows · F8 muzzle · F9 occl · F10 mobj-lit · F11 rim · F12 quit
supay-stub-controls-hint = F3 toggles FB/3D · F12 closes the window
# === shuma-shell ===
shuma-label-launcher = Launcher
shuma-label-command = Command
shuma-label-shell = Shell
shuma-label-matilda = Matilda
shuma-label-canvas = Canvas
shuma-label-monitors = Monitors
shuma-empty-main-incompat = Main module not compatible
shuma-empty-no-tabs = No tabs configured.
shuma-empty-no-tabs-compat = This module cannot be a tab.
shuma-empty-no-data-linux = no data (not Linux?)
shuma-empty-no-data = no data
shuma-stat-samples = samples: { $have } / { $total }
# === nahual (viewers) ===
nahual-image-unsupported = unsupported format (only PNG/JPEG in this build)
# === greeter (mirada login) ===
greeter-subtitle = sign in
greeter-label-user = username
greeter-label-password = password
greeter-placeholder-user = enter your username
greeter-status-authenticating = verifying…
greeter-error-empty-user = enter a username
# === nakui (ERP shell) ===
nakui-header = Nakui · { $count } module(s)
nakui-sidebar-modules = Modules ({ $count })
nakui-sidebar-menu = Menu
nakui-empty-no-modules = No modules loaded
nakui-empty-pick-module = Pick a module in the sidebar
nakui-empty-pick-menu = Pick a menu in the sidebar
nakui-pending-edit = edit pending: requires Llimphi meta-form
nakui-pending-render-detail = render pending: requires Llimphi meta-form
nakui-pending-render-dashboard = render pending: requires Llimphi dashboard
# === pluma (DAG editor) ===
pluma-tone-valid = coherent
pluma-tone-pending = pending
pluma-tone-conflict = conflict
# === gioser-edit (code editor) ===
edit-status-find = find · Ctrl+G next · Esc closes
edit-status-goto-def-waiting = goto-def · waiting for LSP…
edit-status-references-waiting = references · waiting for LSP…
edit-status-rename-input = rename · Enter applies · Esc cancels
edit-status-rename-waiting = rename → «{ $name }» · waiting for LSP…
edit-status-rename-error = rename · error in { $path }: { $err }
edit-status-rename-done = rename · { $files } files · { $bytes } bytes
edit-status-formatting-waiting = formatting · waiting for LSP…
edit-status-formatting-done = formatting · applied
edit-status-goto-def-at = goto-def · { $path }:{ $line }
edit-status-goto-def-error = goto-def · error opening { $path }: { $err }
edit-status-saved = saved · { $path }
edit-status-save-error = save error: { $err }
edit-header-hint = Ctrl+Shift+P palette · Ctrl+P files · Ctrl+Shift+F search
edit-status-position = Ln { $line }, Col { $col } · { $lang }
# === chasqui-explorer (monads) ===
chasqui-header = Engine '{ $engine }' · { $count } monad(s) · socket: { $socket } ({ $src }){ $watching }
chasqui-header-watching = · watching: { $name }
chasqui-header-searching = Searching chasqui daemon via brahman-broker…
chasqui-field-id = id: { $id }
chasqui-field-watching = watching: { $name }
chasqui-field-keywords = keywords: { $keywords }
chasqui-field-path = path: { $path }
chasqui-field-model = model: { $name }
# === wawa-panel (wawa OS control panel) ===
wawa-panel-title = wawa · control panel
wawa-panel-cat-appearance = Appearance
wawa-panel-cat-language = Language
wawa-panel-cat-apps = Applications
wawa-panel-cat-monitor = Monitor
wawa-panel-cat-modules = Modules
wawa-panel-cat-about = About
wawa-panel-section-appearance-hint = Theme variant and accent.
wawa-panel-section-language-hint = System language and clock format.
wawa-panel-section-apps-hint = Launch wawa native apps.
wawa-panel-section-monitor-hint = Live system state.
wawa-panel-section-modules-hint = Enable or disable OS modules.
wawa-panel-section-about-hint = Operating system information.
wawa-panel-label-variant = Variant
wawa-panel-label-accent = Accent
wawa-panel-label-language = Language
wawa-panel-label-clock = Clock
wawa-panel-variant-dark = Dark
wawa-panel-variant-light = Light
wawa-panel-variant-aurora = Aurora
wawa-panel-variant-sunset = Sunset
wawa-panel-clock-24h = 24 h
wawa-panel-clock-12h = 12 h
wawa-panel-stat-time = Time
wawa-panel-stat-uptime = Uptime
wawa-panel-stat-mem = Memory
wawa-panel-stat-load = Load
wawa-panel-stat-host = Host
wawa-panel-stat-kernel = Kernel
wawa-panel-action-launch = Launch
wawa-panel-action-save = Save config
wawa-panel-action-reset = Reset
wawa-panel-saved = Configuration saved to { $path }
wawa-panel-reset = Configuration reset to defaults
wawa-panel-menu-file = File
wawa-panel-menu-view = View
wawa-panel-menu-help = Help
wawa-panel-menu-quit = Quit
wawa-panel-status-hint = ↑↓ navigate · Enter activate · Ctrl+S save · Esc exit
wawa-panel-about-name = System
wawa-panel-about-version = Version
wawa-panel-about-kernel = Kernel
wawa-panel-about-toolkit = Toolkit
wawa-panel-about-blurb = wawa is the operating system of the gioser suite. arje kernel and llimphi apps over a minimal userland.
wawa-panel-mod-mirada = mirada · wayland compositor
wawa-panel-mod-shuma = shuma · packaging and releases
wawa-panel-mod-chasqui = chasqui · mail and messaging
wawa-panel-mod-akasha = akasha · update channel
wawa-panel-mod-minga = minga · p2p storage
wawa-panel-mod-agora = agora · public square
wawa-panel-mod-on = on
wawa-panel-mod-off = off
# === mirada-asistente ===
# Llimphi app that translates natural language into mirada-ctl commands
# by consulting an LLM. The AI proposes; the human confirms before executing.
asistente-title = carmen · assistant
asistente-sub = tell me what you want to do; the assistant proposes, you confirm.
asistente-placeholder = what do you want to do? (Enter to ask, Esc to clear)
asistente-banner-no-llm = LLM unavailable: { $motivo }
asistente-status-pensando = thinking…
asistente-boton-ejecutar = Run
asistente-boton-descartar = Discard
asistente-ejecutado-ok = ✓ { $accion } executed
asistente-ejecutado-fallo = ✗ { $accion } failed
asistente-error-transporte = transport: { $motivo }
asistente-error-sin-llm = LLM not initialized
asistente-error-sin-json = response without JSON: { $crudo }
asistente-error-accion-vacia = proposal without action: { $crudo }
asistente-error-json-invalido = unrecognized JSON: { $crudo }
asistente-error-spawn = spawn failed: { $err } (is mirada-ctl in PATH?)
asistente-cero-salida = (no output)
asistente-codigo-salida = exit code { $codigo }
asistente-error-accion-desconocida = LLM proposed an unknown action: { $accion }
# === ayni-llimphi ===
ayni-menu-admitir = Admit selected
ayni-menu-atestar = Attest selected
ayni-menu-expulsar = Expel selected
ayni-menu-enviar-msg = Send message
ayni-menu-adjuntar = Attach file…
ayni-menu-acuse = Read receipt
ayni-menu-cifrado = E2EE Encryption
ayni-menu-recibos = Read receipts
ayni-menu-comandos-barra = Slash commands
ayni-label-gente-miembros = PEOPLE — members
ayni-label-otros-vistos = others seen
ayni-label-acciones = actions
ayni-label-elige-alguien = pick someone above
ayni-btn-admitir = admit
ayni-btn-atestar = attest
ayni-btn-expulsar = expel
ayni-btn-acuse = receipt
ayni-label-confianza = trust (hops)
ayni-label-sin-atestaciones = — no attestations —
ayni-label-sin-mensajes = — no messages. Type below (or /help for commands). —
ayni-compose-placeholder = type a message, or /adjuntar <path>, /atestar <hex> …
ayni-btn-enviar = send
# === chaka-app-llimphi ===
chaka-menu-run = Run
chaka-menu-run-pipeline = Run pipeline
chaka-tab-output = Output
chaka-tab-rust = Generated Rust
chaka-tab-diag = Diagnostics
chaka-btn-run = Run
chaka-corpus-empty = empty corpus
chaka-corpus-header = CORPUS
chaka-editor-placeholder = select a program from the corpus
chaka-no-file = no file
chaka-banner-open-corpus = open a program from the corpus on the left
chaka-banner-step-limit = shadow ⚠ step limit reached (infinite loop?)
chaka-banner-pipeline-error = the pipeline failed — see the «Diag» tab for details
chaka-status-no-open-file = no open file to save
chaka-about-text = chaka · COBOL → Rust transpiler · pipeline lex→parse→ir→codegen→shadow
# === chasqui-explorer-llimphi ===
chasqui-explorer-ctx-detail = View detail
chasqui-explorer-monad-label = Monad
chasqui-explorer-monad-stats = { $count } files · ent { $entropy } · { $lens }
# === media-app ===
media-settings-tab-audio = Audio
media-settings-tab-video = Video
media-settings-tab-playback = Playback
media-settings-tab-bars = Bars
media-settings-tab-controls = Controls
media-audio-volume = Volume
media-audio-eq = Equalizer
media-audio-normalization = Normalization
media-audio-lufs-target = LUFS Target
media-audio-downmix = Stereo downmix
media-video-color = Color
media-video-enable = Enable
media-video-brightness = Brightness
media-video-contrast = Contrast
media-video-gamma = Gamma
media-video-saturation = Saturation
media-video-hue = Hue
media-video-orientation = Orientation
media-video-rotation = Rotation
media-video-rotate-cw = rotate 90°
media-video-flip-h = Flip H
media-video-flip-v = Flip V
media-action-reset = reset
media-action-cycle = cycle
media-playback-playlist = Playlist
media-playback-resume = Resume on open
media-playback-repeat = Repeat
media-playback-shuffle = Shuffle
media-playback-subtitles = Subtitles
media-playback-autoload-sidecar = Auto-load sidecar
media-playback-sub-delay = Delay (ms)
media-playback-font-size = Font size
media-playback-behavior = Behavior
media-playback-crossfade = Crossfade (s)
media-controls-header = Controls (keyboard)
media-controls-hint = Edit controles.ron and press F5 to reassign keys. The visual shortcut editor is coming later.
media-bars-header = Control bars — click an item to remove it
media-bars-bar-label = Bar
media-bars-remove-bar = remove bar
media-bars-add-bar = + new bar
media-bars-add-items-to = Add items to:
media-settings-footer = Saved to config.ron · Esc closes · in Bars: click an item to remove, reorder
media-playlist-header = Playlist — click a track to jump
media-playlist-empty = No playlist.
media-win-config-title = Settings — media
media-win-playlist-title = Playlist — media
media-help-title = media · shortcuts
media-help-group-playback = Playback
media-help-toggle = Show/hide this help
media-help-close = Close help
media-help-reload = Hot-reload controles.ron
media-menu-capture-frame = Capture frame
media-menu-record = Record / stop
media-menu-reload-controls = Reload controls
media-menu-playback = Playback
media-menu-play-pause = Play / pause
media-menu-seek-back = Seek backward
media-menu-seek-fwd = Seek forward
media-menu-prev-track = Previous track
media-menu-next-track = Next track
media-menu-volume-up = Volume up
media-menu-volume-down = Volume down
media-menu-playlist = Playlist
media-menu-visualizers = Audio visualizers
media-menu-shortcuts-help = Shortcut help
media-ctx-stop-record = Stop recording
media-ctx-record-audio = Record audio
# === mirada-app-llimphi ===
mirada-menu-open-window = Open window
mirada-menu-open-output = Open monitor
mirada-menu-close-focused = Close focused
mirada-menu-window = Window
mirada-win-promote = Promote to master
mirada-win-float = Float / anchor
mirada-win-fullscreen = Full screen
mirada-win-scratchpad = Send to scratchpad
mirada-win-label-fallback = window
mirada-layout-cycle = Cycle layout
mirada-layout-master-stack = Master + stack
mirada-layout-monocle = Monocle
mirada-layout-grid = Grid
mirada-layout-columns = Columns
mirada-layout-rows = Rows
mirada-layout-centered = Centered master
mirada-layout-spiral = Spiral
mirada-layout-shrink = Shrink master
mirada-layout-grow = Grow master
mirada-output-next = Next monitor
mirada-status-body-connected = Body connected
mirada-status-simulation = simulation — no Body
mirada-status-keymap-reloaded = keymap reloaded
mirada-status-keymap-invalid = invalid keymap
mirada-label-layout = layout
mirada-label-focus = focus
mirada-label-output = output
mirada-label-workspace = workspace
mirada-canvas-empty-hint = empty workspace — press n to open a window
mirada-win-kind-fullscreen = · full screen ·
mirada-win-kind-floating = · floating window ·
mirada-win-kind-surface = · body surface ·
# === mirada-greeter ===
mirada-greeter-menu-session = Session
mirada-greeter-session-submit = Log in
mirada-greeter-session-goto-user = Go to username
mirada-greeter-session-goto-pass = Go to password
mirada-greeter-label-desktop = Desktop
mirada-greeter-btn-submit = Log in
mirada-greeter-btn-submitting = Logging in…
mirada-greeter-hint-nav = ↑/↓: desktop · Enter: log in
mirada-greeter-hint-console = Ctrl+Alt+F1…F12: console · Ctrl+Alt+⌫: exit
# === nakui-explorer-llimphi ===
nakui-explorer-menu-refresh-log = Refresh log
nakui-explorer-ctx-view-detail = View detail
nakui-explorer-ctx-refresh-log = Refresh log
nakui-explorer-ctx-entry-fallback = Entry
# === nakui-sheet-llimphi ===
nakui-sheet-ctx-clear = Clear
nakui-sheet-fmt-number = Format: Number
nakui-sheet-fmt-currency = Format: Currency $
nakui-sheet-fmt-percent = Format: Percentage
nakui-sheet-fmt-general = Format: General
nakui-sheet-freeze-here = Freeze Panes Here
nakui-sheet-unfreeze = Unfreeze Panes
nakui-sheet-pivot = Pivot Table…
nakui-sheet-menu-cell-cut = Cut Cell
nakui-sheet-menu-cell-copy = Copy Cell
nakui-sheet-menu-cell-paste = Paste Cell
nakui-sheet-menu-cell-clear = Clear Cell
nakui-sheet-menu-bar-cut = Cut Text
nakui-sheet-menu-bar-copy = Copy Text
nakui-sheet-menu-bar-paste = Paste Text
nakui-sheet-menu-bar-select-all = Select All (text)
nakui-sheet-menu-import-csv = Import CSV
nakui-sheet-menu-export-csv = Export CSV
nakui-sheet-menu-about = About Nakui Sheet
nakui-sheet-formula-placeholder = enter formula or value
nakui-sheet-pivot-title = Pivot Table
nakui-sheet-pivot-close = ✕ Esc
nakui-sheet-pivot-group-by = Group by «
nakui-sheet-pivot-over = over
nakui-sheet-pivot-with-header = w/header
nakui-sheet-pivot-no-header = no header
nakui-sheet-pivot-more-groups = groups
nakui-sheet-pivot-total = TOTAL
nakui-sheet-pivot-groups = groups
nakui-sheet-pivot-rows = rows
nakui-sheet-pivot-hint = A function · G group · V value · H header · Esc close
# === paloma-llimphi ===
paloma-status-init = paloma · not synced
paloma-status-search-semantic = semantic search (rimay): pending — using exact
paloma-status-view-rich = rich HTML via puriy: pending (plain text for now)
paloma-status-no-recipient = cannot send: missing a valid recipient
paloma-status-sent = sent
paloma-status-sent-signed = sent · signed (Ed25519)
paloma-placeholder-search = Search… ( / )
paloma-btn-compose = ✎ Compose
paloma-nav-calendar = Calendar
paloma-nav-contacts = Contacts
paloma-nav-soon = soon
paloma-empty-threads = Empty inbox
paloma-empty-search = no matches
paloma-search-exact = Exact
paloma-search-semantic = Semantic
paloma-no-subject = (no subject)
paloma-placeholder-read = Select a thread to read it
paloma-btn-reply = Reply
paloma-btn-forward = Forward
paloma-btn-star = Star
paloma-btn-starred = Starred
paloma-btn-mark-unread = Mark as unread
paloma-btn-mark-read = Mark as read
paloma-btn-view-rich = View rich HTML
paloma-msg-to-label = to
paloma-sig-verified = signed
paloma-sig-invalid = invalid signature
paloma-compose-new = New message
paloma-compose-reply-title = Reply
paloma-compose-placeholder-to = To: name <email@domain>
paloma-compose-placeholder-cc = Cc: (optional)
paloma-compose-placeholder-subject = Subject
paloma-compose-placeholder-body = Write your message…
paloma-compose-sign = Sign (Ed25519)
paloma-compose-send = Send
# === pluma-notebook-llimphi ===
pluma-notebook-fit-all = Fit All
pluma-notebook-center = Center
pluma-notebook-zoom-reset = Zoom 100%
# === raymi-llimphi ===
raymi-tab-calendar = Calendar
raymi-tab-contacts = Contacts
raymi-view-month = Month
raymi-view-week = Week
raymi-view-day = Day
raymi-btn-new-event = Event
raymi-btn-today = Today
raymi-btn-new-contact = Contact
raymi-no-events = no events
raymi-all-day = all day
raymi-no-contacts = no contacts
raymi-search-contact-placeholder = 🔍 Search contact…
raymi-select-contact-hint = Select a contact
raymi-title-edit-event = Edit event
raymi-title-new-event = New event
raymi-title-edit-contact = Edit contact
raymi-title-new-contact = New contact
raymi-change-cycle = change
raymi-field-summary = Subject
raymi-field-all-day = All day
raymi-field-apply-to = Apply to
raymi-field-calendar = Calendar
raymi-field-date = Date
raymi-field-start = Start
raymi-field-end = End
raymi-field-location = Location
raymi-ph-location = Location (optional)
raymi-field-description = Description
raymi-ph-description = Notes (optional)
raymi-field-attendees = Attendees
raymi-ph-invitee = Name <email> · Enter
raymi-field-repeat = Repeat
raymi-field-every = Every
raymi-field-days = Days
raymi-field-ends = Ends
raymi-field-name = Name
raymi-field-emails = Emails
raymi-field-phones = Phones
raymi-field-org = Organization
raymi-field-note = Note
raymi-ph-full-name = Full name
raymi-ph-emails = email@domain, other@…
raymi-ph-phones = +1 555…, …
raymi-ph-org = Company (optional)
raymi-ph-note = Note (optional)
raymi-scope-series = All events in series
raymi-scope-this-only = This event only
raymi-scope-this-and-future = This and following events
raymi-repeat-none = Does not repeat
raymi-repeat-daily = Daily
raymi-repeat-weekly = Weekly
raymi-repeat-monthly = Monthly
raymi-repeat-yearly = Yearly
raymi-unit-days = day(s)
raymi-unit-weeks = week(s)
raymi-unit-months = month(s)
raymi-unit-years = year(s)
raymi-end-never = Never ends
raymi-end-count = After N times
raymi-end-until = Until date
raymi-status-no-calendars = no calendars available to create an event
raymi-status-no-books = no address books available to create a contact
raymi-status-invalid-datetime = invalid date or time (use YYYY-MM-DD and HH:MM)
raymi-status-contact-needs-name = contact requires a name
# === shuma-shell-llimphi ===
shuma-shell-clear-input = Clear input
shuma-shell-clear-screen = Clear screen
shuma-shell-cancel-cmd = Cancel command
shuma-shell-about = About shuma
# === supay-app-llimphi ===
supay-hud-health = HEALTH
supay-hud-ammo = AMMO
supay-hud-target = TARGET
supay-action-fire = Fire
supay-action-reset = Restart game
supay-menu-play = Play
supay-status-game-over = game over
supay-status-victory = victory
supay-status-dead = DEAD
supay-hint-space-restart = SPACE to restart
# === wawa-panel-llimphi ===
wawa-panel-status-config-updated = ↻ config updated from bus
wawa-panel-ctx-refresh-monitor = Refresh monitor
wawa-panel-autosave-ok = ↻ applied
+723
View File
@@ -0,0 +1,723 @@
# rimay-localize — catálogo es-PE
# Convención: IDs en kebab-case, ASCII, en inglés (estables); traducción
# en este archivo. Comentarios (#) describen contexto cuando el ID no
# basta.
# === acciones genéricas ===
save = Guardar
load = Cargar
open = Abrir
close = Cerrar
cancel = Cancelar
confirm = Aceptar
yes = Sí
no = No
delete = Eliminar
edit = Editar
new = Nuevo
# === estado ===
play = Reproducir
pause = Pausar
resume = Reanudar
stop = Detener
# === menús ===
file = Archivo
view = Vista
help = Ayuda
settings = Configuración
exit = Salir
# === chrome común (reutilizable por todas las apps Llimphi) ===
# Etiquetas de menú/acción compartidas. Una app sólo crea IDs propios
# (`<app>-*`) para texto que no aparezca acá.
search = Buscar
language = Idioma
undo = Deshacer
redo = Rehacer
cut = Cortar
copy = Copiar
paste = Pegar
select-all = Seleccionar todo
open-dots = Abrir…
save-as = Guardar como…
close-tab = Cerrar pestaña
find-in-file = Buscar en archivo
find-in-project = Buscar en proyecto
symbols = Símbolos
goto-definition = Ir a definición
terminal = Terminal
command-palette = Paleta de comandos
minimap = Minimapa
cycle-theme = Cambiar tema
editing = Edición
about = Acerca de
refresh = Refrescar
reconnect = Reconectar
# === nada (editor de archivos) ===
nada-tagline = editor soberano sobre Llimphi
# === niveles de mensaje ===
info = Información
warning = Advertencia
error = Error
success = Listo
# === interpolación ===
welcome-user = Bienvenido, { $name }.
items-count = { $count } elementos.
# === dominium (simulador de campo medio) ===
dominium-status-running = ● corriendo
dominium-status-paused = ‖ en pausa
dominium-status-line = dominium · campo medio · época { $epoch } · tick { $tick }
dominium-btn-pause = ‖ Pausar
dominium-btn-resume = ▶ Reanudar
dominium-btn-reseed = ↺ Re-sembrar
dominium-btn-create-concept = ✦ Crear concepto
dominium-btn-seed-pack = ✚ Sembrar pack
dominium-btn-clear = ✖ Limpiar
dominium-btn-save = 💾 Guardar
dominium-btn-load-saved = 📂 Cargar guardado
dominium-btn-load-named = ✓ Cargar «{ $name }»
dominium-header-sim = [ SIM ]
dominium-header-conceptos = [ CONCEPTOS ]
dominium-header-metricas = [ MÉTRICAS ]
dominium-header-editar = [ EDITAR ]
dominium-active-count = { $count } activos
dominium-stat-population = Población
dominium-stat-materia = Materia
dominium-stat-oro = Oro
dominium-stat-energia = Energía
dominium-stat-epoca = Época
dominium-stat-gini-energia = Gini energía
dominium-stat-edad-media = Edad media
dominium-stat-var-psi-orden = Var ψ orden
dominium-stat-var-psi-miedo = Var ψ miedo
dominium-stat-var-psi-curiosidad = Var ψ curiosidad
dominium-stat-var-psi-corruptib = Var ψ corruptib.
dominium-action-mover = → mover
dominium-action-extraer = → extraer
dominium-action-sincronizar = → sincronizar
dominium-action-intercambiar = → intercambiar
dominium-action-replicar = → replicar
dominium-action-degradar = → degradar
dominium-slider-nombre = nombre
dominium-slider-radius = radius
dominium-slider-materia = materia
dominium-slider-psique = psique
dominium-slider-poder = poder
dominium-slider-oro = oro
dominium-label-hack = hack:
# === cosmos (módulos overlay) ===
cosmos-btn-save-transit = 💾 Guardar tránsito como carta libre
cosmos-btn-save-progressed = 💾 Guardar progresada como carta libre
cosmos-btn-save-return = 💾 Guardar retorno como carta libre
cosmos-header = cosmos · { $title } · Asc { $asc }° · MC { $mc }°
cosmos-demo-title = Carta de muestra (Lima)
cosmos-demo-subtitle = computada por cosmos-engine (VSOP2013)
cosmos-status = { $ms } ms · { $layers } capas · { $overlays } overlays · { $aspects } aspectos
cosmos-status-error = error: { $err }
cosmos-overlay-transit = tránsito
cosmos-overlay-progression = progresión
cosmos-overlay-solar-arc = arco solar
cosmos-overlay-uranian = uraniano
cosmos-overlay-lots = lotes
cosmos-overlay-fixed-stars = est. fijas
cosmos-overlay-midpoints = puntos medios
cosmos-harmonic-label = armónico
cosmos-empty = (vacío)
cosmos-tile-carta = carta
cosmos-tile-modulos = módulos
cosmos-tile-armonico = armónico
cosmos-tile-cuerpos = cuerpos
cosmos-tile-aspectos = aspectos
cosmos-tile-box-graph = aspectarian
cosmos-tile-cualidades = cualidades
cosmos-elementos = elementos
cosmos-modalidades = modalidades
cosmos-polaridad = polaridad
cosmos-elem-fuego = fuego
cosmos-elem-tierra = tierra
cosmos-elem-aire = aire
cosmos-elem-agua = agua
cosmos-mod-cardinal = cardinal
cosmos-mod-fijo = fijo
cosmos-mod-mutable = mutable
cosmos-pol-yang = yang
cosmos-pol-yin = yin
cosmos-tile-astrocarto = astrocartografía
cosmos-astrocarto-leyenda = MC sólido · IC punteado · Asc/Desc curvas · • lugar natal
cosmos-tile-cartas = cartas guardadas
cosmos-cartas-duplicar = + duplicar la actual
cosmos-cartas-vacio = (vacío — duplicá la actual o copiá JSONs al dir)
cosmos-tile-corpus = corpus
cosmos-tile-lotes = lotes
cosmos-tile-estrellas-fijas = estrellas fijas
cosmos-tile-puntos-medios = puntos medios
cosmos-corpus-header = { $pasajes } pasajes · { $huecos } huecos · { $total } combinaciones
cosmos-corpus-vacio = (sin pasajes — escribí el corpus en cosmos-corpus/ejemplo.ron)
cosmos-tile-uraniano = dial uraniano 90°
cosmos-tile-cross-transit = cross · tránsito
cosmos-tile-cross-progression = cross · progresión
cosmos-tile-cross-solar-arc = cross · arco solar
# === wawa-explorer (Wawa image browser) ===
wawa-marker-via-aoe = · via AoE
wawa-marker-searching = · buscando…
wawa-marker-fetch-failed = · fetch falló
wawa-marker-not-in-image = · (no en imagen)
wawa-iface-ok = · AoE iface: { $name }
wawa-iface-err = · AoE: sin interfaz
wawa-header-error = wawa-explorer · error: { $err }
wawa-header = wawa-explorer · { $source } · { $bytes } bytes · v{ $version } · cursor sector { $cursor } · { $objects } objetos{ $iface }
wawa-detail-empty = (seleccioná un objeto del tree)
wawa-detail-title = objeto { $hash } · { $bytes } bytes · { $children } hijos{ $origen }
wawa-detail-title-missing = objeto { $hash } · no presente localmente
wawa-detail-payload-header = payload (primeros 256 bytes):
wawa-detail-children-header = hijos:
wawa-detail-child-missing = (no en imagen)
wawa-detail-searching-aoe-1 = buscando en la red local (AoE)…
wawa-detail-searching-aoe-2 = broadcast SolicitarObjeto, espera ProveedorObjeto con hash verificado.
wawa-detail-fetch-error-1 = último intento de AoE falló:
wawa-detail-fetch-error-2 = podés reintentar con el botón debajo.
wawa-detail-needs-fetch-1 = este objeto está referenciado por un padre pero no vive en la imagen local.
wawa-detail-needs-fetch-2 = podés pedirlo a peers Wawa de la red local (AoE, iface `{ $iface }`).
wawa-detail-aoe-disabled-1 = este objeto está referenciado por un padre pero no vive en la imagen local.
wawa-detail-aoe-disabled-2 = AoE deshabilitado: { $why }
wawa-detail-aoe-disabled-3 = pasá `<iface>` como segundo argumento de CLI o ejecutá con CAP_NET_RAW (`sudo setcap cap_net_raw=eip <binario>`).
wawa-btn-fetch = fetch from peers
wawa-btn-retry-fetch = reintentar fetch from peers
# menú principal
wawa-menu-file = Archivo
wawa-menu-reload = Recargar imagen
wawa-menu-quit = Salir
wawa-menu-view = Ver
wawa-menu-fetch = Traer nodo por AoE
wawa-menu-theme = Cambiar tema
wawa-menu-help = Ayuda
wawa-menu-about = Acerca de
# menú contextual sobre el nodo seleccionado
wawa-ctx-select = Seleccionar
wawa-ctx-expand = Expandir
wawa-ctx-collapse = Contraer
wawa-ctx-fetch = Traer por AoE
# === minga-explorer (repo browser) ===
minga-header-loaded = Repo: { $path } · reload { $ms } ms
minga-header-searching = Buscando repo en { $path }…
minga-error-read = no pude leer repo { $path }: { $err }
minga-card-nodes-title = Nodos AST
minga-card-nodes-desc = fragments parseados del código
minga-card-attestations-title = Atestaciones
minga-card-attestations-desc = firmas Ed25519 sobre los nodos
minga-card-mst-title = Claves MST
minga-card-mst-desc = entradas del Merkle Search Tree
minga-empty = Esperando primer refresh…
minga-menu-file = Archivo
minga-menu-view = Ver
minga-menu-help = Ayuda
minga-menu-refresh = Refrescar
minga-menu-quit = Salir
minga-menu-theme = Cambiar tema
minga-menu-about = Acerca de
minga-menu-context-title = Repo
# === nakui-explorer (event log) ===
nakui-explorer-header = Log: { $path } · { $entries } entries ({ $seeds } seeds, { $morphisms } morphisms) · reload { $ms } ms
nakui-explorer-breakdown = breakdown: { $parts }
# === supay (doom) ===
supay-mode-real = ENGINE REAL
supay-mode-stub = STUB
supay-view-fb = view=FB (F3→3D)
supay-view-3d = view=3D (F3→FB)
supay-header = { $title } · tick { $tick } · { $mode } · { $view } · { $scene }
supay-stub-title = supay-doom-llimphi corre en modo STUB
supay-stub-step-1 = Cloná doomgeneric
supay-stub-step-1-cmd = cd 02_ruway/supay/supay-core/vendor && git clone https://github.com/ozkl/doomgeneric.git
supay-stub-step-2 = Bajá el WAD shareware al cwd
supay-stub-step-2-cmd = curl -O https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
supay-stub-step-3 = Volvé a correr
supay-stub-step-3-cmd = cargo run -p supay-doom-llimphi --release
supay-stub-footer = doomgeneric (C) avanza a 35 Hz; el framebuffer 320×200 ARGB se pinta en aspect-fit.
supay-controls-hint = WASD · Ctrl disp · Space usa · Tab map · F3 vista · F4 mira · F5 viñeta · F6 HUD · F7 sombras · F8 fogonazo · F9 oclusión · F10 luz-mobj · F11 rim-arma · F12 salir
supay-stub-controls-hint = F3 alterna FB/3D · F12 cierra la ventana
# === shuma-shell ===
shuma-label-launcher = Launcher
shuma-label-command = Command
shuma-label-shell = Shell
shuma-label-matilda = Matilda
shuma-label-canvas = Lienzo
shuma-label-monitors = Monitores
shuma-empty-main-incompat = Módulo Main no compatible
shuma-empty-no-tabs = Sin tabs configuradas.
shuma-empty-no-tabs-compat = Este módulo no puede ser tab.
shuma-empty-no-data-linux = sin datos (¿no es Linux?)
shuma-empty-no-data = sin datos
shuma-stat-samples = muestras: { $have } / { $total }
# === nahual (visores) ===
nahual-image-unsupported = formato no soportado (sólo PNG/JPEG en esta build)
# === greeter (mirada login) ===
greeter-subtitle = iniciá tu sesión
greeter-label-user = usuario
greeter-label-password = contraseña
greeter-placeholder-user = ingresá tu usuario
greeter-status-authenticating = verificando…
greeter-error-empty-user = ingresá un usuario
# === nakui (ERP shell) ===
nakui-header = Nakui · { $count } módulo(s)
nakui-sidebar-modules = Módulos ({ $count })
nakui-sidebar-menu = Menú
nakui-empty-no-modules = Sin módulos cargados
nakui-empty-pick-menu = Elegí un menú en la barra lateral
nakui-empty-pick-module = Elegí un módulo en la barra lateral
nakui-pending-edit = edición pendiente: requiere meta-form Llimphi
nakui-pending-render-detail = render pendiente: requiere meta-form Llimphi
nakui-pending-render-dashboard = render pendiente: requiere dashboard Llimphi
# === pluma (editor DAG) ===
pluma-tone-valid = coherente
pluma-tone-pending = por evaluar
pluma-tone-conflict = en conflicto
# === gioser-edit (editor de código) ===
edit-status-find = find · Ctrl+G siguiente · Esc cierra
edit-status-goto-def-waiting = goto-def · esperando LSP…
edit-status-references-waiting = references · esperando LSP…
edit-status-rename-input = rename · Enter aplica · Esc cancela
edit-status-rename-waiting = rename → «{ $name }» · esperando LSP…
edit-status-rename-error = rename · error en { $path }: { $err }
edit-status-rename-done = rename · { $files } archivos · { $bytes } bytes
edit-status-formatting-waiting = formatting · esperando LSP…
edit-status-formatting-done = formatting · aplicado
edit-status-goto-def-at = goto-def · { $path }:{ $line }
edit-status-goto-def-error = goto-def · error abriendo { $path }: { $err }
edit-status-saved = guardado · { $path }
edit-status-save-error = error guardando: { $err }
edit-header-hint = Ctrl+Shift+P palette · Ctrl+P files · Ctrl+Shift+F search
edit-status-position = Ln { $line }, Col { $col } · { $lang }
# === chasqui-explorer (mónadas) ===
chasqui-header = Engine '{ $engine }' · { $count } mónada(s) · socket: { $socket } ({ $src }){ $watching }
chasqui-header-watching = · watching: { $name }
chasqui-header-searching = Buscando daemon chasqui vía brahman-broker…
chasqui-field-id = id: { $id }
chasqui-field-watching = watching: { $name }
chasqui-field-keywords = keywords: { $keywords }
chasqui-field-path = path: { $path }
chasqui-field-model = model: { $name }
# === wawa-panel (panel de control del SO wawa) ===
wawa-panel-title = wawa · panel de control
wawa-panel-cat-appearance = Apariencia
wawa-panel-cat-language = Idioma
wawa-panel-cat-apps = Aplicaciones
wawa-panel-cat-monitor = Monitor
wawa-panel-cat-modules = Módulos
wawa-panel-cat-about = Acerca de
wawa-panel-section-appearance-hint = Variante del tema y acento.
wawa-panel-section-language-hint = Idioma del sistema y formato de hora.
wawa-panel-section-apps-hint = Lanzá las apps nativas de wawa.
wawa-panel-section-monitor-hint = Estado vivo del sistema.
wawa-panel-section-modules-hint = Activar o desactivar piezas del SO.
wawa-panel-section-about-hint = Información del sistema operativo.
wawa-panel-label-variant = Variante
wawa-panel-label-accent = Acento
wawa-panel-label-language = Idioma
wawa-panel-label-clock = Reloj
wawa-panel-variant-dark = Oscuro
wawa-panel-variant-light = Claro
wawa-panel-variant-aurora = Aurora
wawa-panel-variant-sunset = Sunset
wawa-panel-clock-24h = 24 h
wawa-panel-clock-12h = 12 h
wawa-panel-stat-time = Hora
wawa-panel-stat-uptime = Uptime
wawa-panel-stat-mem = Memoria
wawa-panel-stat-load = Carga
wawa-panel-stat-host = Host
wawa-panel-stat-kernel = Kernel
wawa-panel-action-launch = Lanzar
wawa-panel-action-save = Guardar config
wawa-panel-action-reset = Restablecer
wawa-panel-saved = Configuración guardada en { $path }
wawa-panel-reset = Configuración restablecida a valores por defecto
wawa-panel-menu-file = Archivo
wawa-panel-menu-view = Ver
wawa-panel-menu-help = Ayuda
wawa-panel-menu-quit = Salir
wawa-panel-status-hint = ↑↓ navegar · Enter activar · Ctrl+S guardar · Esc salir
wawa-panel-about-name = Sistema
wawa-panel-about-version = Versión
wawa-panel-about-kernel = Núcleo
wawa-panel-about-toolkit = Toolkit
wawa-panel-about-blurb = wawa es el sistema operativo de la suite gioser. El kernel arje y las apps llimphi sobre un userland mínimo.
wawa-panel-mod-mirada = mirada · compositor wayland
wawa-panel-mod-shuma = shuma · empaquetado y release
wawa-panel-mod-chasqui = chasqui · correo y mensajería
wawa-panel-mod-akasha = akasha · canal de actualizaciones
wawa-panel-mod-minga = minga · almacenamiento p2p
wawa-panel-mod-agora = agora · plaza pública
wawa-panel-mod-on = encendido
wawa-panel-mod-off = apagado
# === mirada-asistente ===
# App Llimphi que traduce lenguaje natural a comandos de mirada-ctl
# consultando un LLM. La IA propone, el humano confirma antes de ejecutar.
asistente-title = carmen · asistente
asistente-sub = describí lo que querés hacer; el asistente propone, vos confirmás.
asistente-placeholder = ¿qué querés hacer? (Enter para preguntar, Esc para limpiar)
asistente-banner-no-llm = LLM no disponible: { $motivo }
asistente-status-pensando = pensando…
asistente-boton-ejecutar = Ejecutar
asistente-boton-descartar = Descartar
asistente-ejecutado-ok = ✓ { $accion } ejecutado
asistente-ejecutado-fallo = ✗ { $accion } falló
asistente-error-transporte = transporte: { $motivo }
asistente-error-sin-llm = LLM no inicializado
asistente-error-sin-json = respuesta sin JSON: { $crudo }
asistente-error-accion-vacia = propuesta sin accion: { $crudo }
asistente-error-json-invalido = JSON no reconocido: { $crudo }
asistente-error-spawn = spawn falló: { $err } (¿está mirada-ctl en PATH?)
asistente-cero-salida = (sin salida)
asistente-codigo-salida = código { $codigo }
asistente-error-accion-desconocida = el LLM propuso una accion desconocida: { $accion }
# === ayni-llimphi ===
ayni-menu-admitir = Admitir seleccionado
ayni-menu-atestar = Atestar seleccionado
ayni-menu-expulsar = Expulsar seleccionado
ayni-menu-enviar-msg = Enviar mensaje
ayni-menu-adjuntar = Adjuntar archivo…
ayni-menu-acuse = Acuse de recibo
ayni-menu-cifrado = Cifrado E2EE
ayni-menu-recibos = Recibos de lectura
ayni-menu-comandos-barra = Comandos de la barra /
ayni-label-gente-miembros = GENTE — miembros
ayni-label-otros-vistos = otros vistos
ayni-label-acciones = acciones
ayni-label-elige-alguien = elegí a alguien arriba
ayni-btn-admitir = admitir
ayni-btn-atestar = atestar
ayni-btn-expulsar = expulsar
ayni-btn-acuse = acuse
ayni-label-confianza = confianza (saltos)
ayni-label-sin-atestaciones = — sin atestaciones —
ayni-label-sin-mensajes = — sin mensajes. Escribí abajo (o /ayuda para comandos). —
ayni-compose-placeholder = escribí un mensaje, o /adjuntar <ruta>, /atestar <hex> …
ayni-btn-enviar = enviar
# === chaka-app-llimphi ===
chaka-menu-run = Ejecutar
chaka-menu-run-pipeline = Correr pipeline
chaka-tab-output = Salida
chaka-tab-rust = Rust generado
chaka-tab-diag = Diagnósticos
chaka-btn-run = Correr
chaka-corpus-empty = corpus vacío
chaka-corpus-header = CORPUS
chaka-editor-placeholder = seleccioná un programa del corpus
chaka-no-file = sin archivo
chaka-banner-open-corpus = abrí un programa del corpus a la izquierda
chaka-banner-step-limit = shadow ⚠ se agotó el tope de pasos (¿bucle sin fin?)
chaka-banner-pipeline-error = el pipeline falló — ver tab «Diag» para detalles
chaka-status-no-open-file = no hay archivo abierto para guardar
chaka-about-text = chaka · transpilador COBOL → Rust · pipeline lex→parse→ir→codegen→shadow
# === chasqui-explorer-llimphi ===
chasqui-explorer-ctx-detail = Ver detalle
chasqui-explorer-monad-label = Mónada
chasqui-explorer-monad-stats = { $count } files · ent { $entropy } · { $lens }
# === media-app ===
media-settings-tab-audio = Audio
media-settings-tab-video = Video
media-settings-tab-playback = Reproducción
media-settings-tab-bars = Barras
media-settings-tab-controls = Controles
media-audio-volume = Volumen
media-audio-eq = Ecualizador
media-audio-normalization = Normalización
media-audio-lufs-target = Objetivo LUFS
media-audio-downmix = Downmix estéreo
media-video-color = Color
media-video-enable = Activar
media-video-brightness = Brillo
media-video-contrast = Contraste
media-video-gamma = Gamma
media-video-saturation = Saturación
media-video-hue = Matiz
media-video-orientation = Orientación
media-video-rotation = Rotación
media-video-rotate-cw = rotar 90°
media-video-flip-h = Espejo H
media-video-flip-v = Espejo V
media-action-reset = reset
media-action-cycle = ciclar
media-playback-playlist = Playlist
media-playback-resume = Reanudar al abrir
media-playback-repeat = Repetición
media-playback-shuffle = Aleatorio
media-playback-subtitles = Subtítulos
media-playback-autoload-sidecar = Auto-cargar sidecar
media-playback-sub-delay = Desfase (ms)
media-playback-font-size = Tamaño de letra
media-playback-behavior = Comportamiento
media-playback-crossfade = Crossfade (s)
media-controls-header = Controles (teclado)
media-controls-hint = Editá controles.ron y apretá F5 para reasignar teclas. El editor visual de atajos llega después.
media-bars-header = Barras de controles — clic en un item lo quita
media-bars-bar-label = Barra
media-bars-remove-bar = quitar barra
media-bars-add-bar = + barra nueva
media-bars-add-items-to = Agregar items a:
media-settings-footer = Se guarda en config.ron · Esc cierra · en Barras: clic en un item lo quita, reordenan
media-playlist-header = Lista de reproducción — clic en una pista para saltar
media-playlist-empty = Sin lista de reproducción.
media-win-config-title = Configuración — media
media-win-playlist-title = Lista de reproducción — media
media-help-title = media · atajos
media-help-group-playback = Reproducción
media-help-toggle = Mostrar/ocultar esta ayuda
media-help-close = Cerrar la ayuda
media-help-reload = Recargar controles.ron en caliente
media-menu-capture-frame = Capturar fotograma
media-menu-record = Grabar / detener
media-menu-reload-controls = Recargar controles
media-menu-playback = Reproducción
media-menu-play-pause = Reproducir / pausar
media-menu-seek-back = Retroceder
media-menu-seek-fwd = Avanzar
media-menu-prev-track = Pista anterior
media-menu-next-track = Pista siguiente
media-menu-volume-up = Subir volumen
media-menu-volume-down = Bajar volumen
media-menu-playlist = Lista de reproducción
media-menu-visualizers = Visualizadores de audio
media-menu-shortcuts-help = Ayuda de atajos
media-ctx-stop-record = Detener grabación
media-ctx-record-audio = Grabar audio
# === mirada-app-llimphi ===
mirada-menu-open-window = Abrir ventana
mirada-menu-open-output = Abrir monitor
mirada-menu-close-focused = Cerrar enfocada
mirada-menu-window = Ventana
mirada-win-promote = Promover a maestra
mirada-win-float = Flotar / anclar
mirada-win-fullscreen = Pantalla completa
mirada-win-scratchpad = Enviar al scratchpad
mirada-win-label-fallback = ventana
mirada-layout-cycle = Ciclar layout
mirada-layout-master-stack = Maestro + pila
mirada-layout-monocle = Monóculo
mirada-layout-grid = Rejilla
mirada-layout-columns = Columnas
mirada-layout-rows = Filas
mirada-layout-centered = Maestro centrado
mirada-layout-spiral = Espiral
mirada-layout-shrink = Achicar maestra
mirada-layout-grow = Agrandar maestra
mirada-output-next = Siguiente monitor
mirada-status-body-connected = Cuerpo conectado
mirada-status-simulation = simulación — sin Cuerpo
mirada-status-keymap-reloaded = keymap recargado
mirada-status-keymap-invalid = keymap inválido
mirada-label-layout = layout
mirada-label-focus = foco
mirada-label-output = salida
mirada-label-workspace = escritorio
mirada-canvas-empty-hint = escritorio vacío — pulsa n para abrir una ventana
mirada-win-kind-fullscreen = · pantalla completa ·
mirada-win-kind-floating = · ventana flotante ·
mirada-win-kind-surface = · superficie del Cuerpo ·
# === mirada-greeter ===
mirada-greeter-menu-session = Sesión
mirada-greeter-session-submit = Iniciar sesión
mirada-greeter-session-goto-user = Ir a usuario
mirada-greeter-session-goto-pass = Ir a contraseña
mirada-greeter-label-desktop = Escritorio
mirada-greeter-btn-submit = Entrar
mirada-greeter-btn-submitting = Entrando…
mirada-greeter-hint-nav = ↑/↓: escritorio · Enter: entrar
mirada-greeter-hint-console = Ctrl+Alt+F1…F12: consola · Ctrl+Alt+⌫: salir
# === nakui-explorer-llimphi ===
nakui-explorer-menu-refresh-log = Refrescar log
nakui-explorer-ctx-view-detail = Ver detalle
nakui-explorer-ctx-refresh-log = Refrescar log
nakui-explorer-ctx-entry-fallback = Entrada
# === nakui-sheet-llimphi ===
nakui-sheet-ctx-clear = Limpiar
nakui-sheet-fmt-number = Formato: Número
nakui-sheet-fmt-currency = Formato: Moneda $
nakui-sheet-fmt-percent = Formato: Porcentaje
nakui-sheet-fmt-general = Formato: General
nakui-sheet-freeze-here = Inmovilizar paneles aquí
nakui-sheet-unfreeze = Liberar paneles
nakui-sheet-pivot = Tabla dinámica…
nakui-sheet-menu-cell-cut = Cortar celda
nakui-sheet-menu-cell-copy = Copiar celda
nakui-sheet-menu-cell-paste = Pegar celda
nakui-sheet-menu-cell-clear = Limpiar celda
nakui-sheet-menu-bar-cut = Cortar texto
nakui-sheet-menu-bar-copy = Copiar texto
nakui-sheet-menu-bar-paste = Pegar texto
nakui-sheet-menu-bar-select-all = Seleccionar todo (texto)
nakui-sheet-menu-import-csv = Importar CSV
nakui-sheet-menu-export-csv = Exportar CSV
nakui-sheet-menu-about = Acerca de Nakui Sheet
nakui-sheet-formula-placeholder = ingresa fórmula o valor
nakui-sheet-pivot-title = Tabla dinámica
nakui-sheet-pivot-close = ✕ Esc
nakui-sheet-pivot-group-by = Agrupar por «
nakui-sheet-pivot-over = sobre
nakui-sheet-pivot-with-header = c/encab.
nakui-sheet-pivot-no-header = s/encab.
nakui-sheet-pivot-more-groups = grupos
nakui-sheet-pivot-total = TOTAL
nakui-sheet-pivot-groups = grupos
nakui-sheet-pivot-rows = filas
nakui-sheet-pivot-hint = A función · G grupo · V valor · H encabezado · Esc cerrar
# === paloma-llimphi ===
paloma-status-init = paloma · sin sincronizar
paloma-status-search-semantic = búsqueda semántica (rimay): pendiente — usando exacta
paloma-status-view-rich = HTML enriquecido vía puriy: pendiente (texto despojado por ahora)
paloma-status-no-recipient = no se puede enviar: falta un destinatario válido
paloma-status-sent = enviado
paloma-status-sent-signed = enviado · firmado (Ed25519)
paloma-placeholder-search = Buscar… ( / )
paloma-btn-compose = ✎ Redactar
paloma-nav-calendar = Calendario
paloma-nav-contacts = Contactos
paloma-nav-soon = pronto
paloma-empty-threads = Bandeja vacía
paloma-empty-search = sin coincidencias
paloma-search-exact = Exacta
paloma-search-semantic = Semántica
paloma-no-subject = (sin asunto)
paloma-placeholder-read = Elegí un hilo para leerlo
paloma-btn-reply = Responder
paloma-btn-forward = Reenviar
paloma-btn-star = Destacar
paloma-btn-starred = Destacado
paloma-btn-mark-unread = Marcar no leído
paloma-btn-mark-read = Marcar leído
paloma-btn-view-rich = Ver HTML enriquecido
paloma-msg-to-label = para
paloma-sig-verified = firmado
paloma-sig-invalid = firma inválida
paloma-compose-new = Mensaje nuevo
paloma-compose-reply-title = Responder
paloma-compose-placeholder-to = Para: nombre <correo@dominio>
paloma-compose-placeholder-cc = Cc: (opcional)
paloma-compose-placeholder-subject = Asunto
paloma-compose-placeholder-body = Escribí tu mensaje…
paloma-compose-sign = Firmar (Ed25519)
paloma-compose-send = Enviar
# === pluma-notebook-llimphi ===
pluma-notebook-fit-all = Ajustar todo
pluma-notebook-center = Centrar
pluma-notebook-zoom-reset = Zoom 100%
# === raymi-llimphi ===
raymi-tab-calendar = Calendario
raymi-tab-contacts = Contactos
raymi-view-month = Mes
raymi-view-week = Semana
raymi-view-day = Día
raymi-btn-new-event = Evento
raymi-btn-today = Hoy
raymi-btn-new-contact = Contacto
raymi-no-events = sin eventos
raymi-all-day = todo el día
raymi-no-contacts = sin contactos
raymi-search-contact-placeholder = 🔍 Buscar contacto…
raymi-select-contact-hint = Elegí un contacto
raymi-title-edit-event = Editar evento
raymi-title-new-event = Nuevo evento
raymi-title-edit-contact = Editar contacto
raymi-title-new-contact = Nuevo contacto
raymi-change-cycle = cambiar
raymi-field-summary = Asunto
raymi-field-all-day = Día completo
raymi-field-apply-to = Aplicar a
raymi-field-calendar = Calendario
raymi-field-date = Fecha
raymi-field-start = Inicio
raymi-field-end = Fin
raymi-field-location = Lugar
raymi-ph-location = Lugar (opcional)
raymi-field-description = Descripción
raymi-ph-description = Notas (opcional)
raymi-field-attendees = Invitados
raymi-ph-invitee = Nombre <correo> · Enter
raymi-field-repeat = Repetir
raymi-field-every = Cada
raymi-field-days = Días
raymi-field-ends = Termina
raymi-field-name = Nombre
raymi-field-emails = Correos
raymi-field-phones = Teléfonos
raymi-field-org = Organización
raymi-field-note = Nota
raymi-ph-full-name = Nombre y apellido
raymi-ph-emails = correo@dominio, otro@…
raymi-ph-phones = +58 412…, …
raymi-ph-org = Empresa (opcional)
raymi-ph-note = Nota (opcional)
raymi-scope-series = Toda la serie
raymi-scope-this-only = Esta instancia
raymi-scope-this-and-future = Esta y siguientes
raymi-repeat-none = No se repite
raymi-repeat-daily = Diariamente
raymi-repeat-weekly = Semanalmente
raymi-repeat-monthly = Mensualmente
raymi-repeat-yearly = Anualmente
raymi-unit-days = día(s)
raymi-unit-weeks = semana(s)
raymi-unit-months = mes(es)
raymi-unit-years = año(s)
raymi-end-never = Sin fin
raymi-end-count = Tras N veces
raymi-end-until = Hasta fecha
raymi-status-no-calendars = no hay calendarios donde crear un evento
raymi-status-no-books = no hay libretas donde crear un contacto
raymi-status-invalid-datetime = fecha u hora inválida (usá AAAA-MM-DD y HH:MM)
raymi-status-contact-needs-name = el contacto necesita un nombre
# === shuma-shell-llimphi ===
shuma-shell-clear-input = Limpiar entrada
shuma-shell-clear-screen = Limpiar pantalla
shuma-shell-cancel-cmd = Cancelar comando
shuma-shell-about = Acerca de shuma
# === supay-app-llimphi ===
supay-hud-health = VIDA
supay-hud-ammo = MUNICION
supay-hud-target = OBJETIVO
supay-action-fire = Disparar
supay-action-reset = Reiniciar partida
supay-menu-play = Jugar
supay-status-game-over = fin de partida
supay-status-victory = victoria
supay-status-dead = MUERTO
supay-hint-space-restart = SPACE para reiniciar
# === wawa-panel-llimphi ===
wawa-panel-status-config-updated = ↻ config actualizada desde el bus
wawa-panel-ctx-refresh-monitor = Refrescar monitor
wawa-panel-autosave-ok = ↻ aplicado
+724
View File
@@ -0,0 +1,724 @@
# rimay-localize — qu-PE (Runasimi, variante sureña).
#
# Nota para el revisor humano: este catálogo es un PUNTO DE PARTIDA
# escrito por un desarrollador no nativo. Las formas elegidas siguen
# fuentes accesibles (AMLQ, Cusqueño escrito) pero piden corrección por
# alguien con dominio del idioma. Pluralización (sufijo -kuna), ergativo
# (-pa, -wan) y cortesía (-yki) son las áreas más sensibles.
# === acciones genéricas ===
save = Waqaychay
load = Apamuy
open = Kichay
close = Wisq'ay
cancel = Saqiy
confirm = Allinmi
yes = Arí
no = Manan
delete = Pichay
edit = Hukchay
new = Musuq
# === estado ===
play = Qallariy
pause = Samay
resume = Kutiy
stop = Sayachiy
# === menús ===
file = Qillqa
view = Qhaway
help = Yanapay
settings = Allichana
exit = Lluqsiy
# === chrome común (reutilizable; PUNTO DE PARTIDA, pide revisión nativa) ===
search = Maskay
language = Rimay
undo = Kutichiy
redo = Kutirichiy
cut = Kuchuy
copy = Iskaychay
paste = Llut'ay
select-all = Llapanta akllay
open-dots = Kichay…
save-as = Wak hina waqaychay…
close-tab = Wisq'ay
find-in-file = Qillqapi maskay
find-in-project = Llapanpi maskay
symbols = Unanchakuna
goto-definition = Sut'ipi riy
terminal = Terminal
command-palette = Kamachiykuna
minimap = Huch'uy mapa
cycle-theme = Rikch'aq tikray
editing = Hukchana
about = Imamanta
refresh = Musuqyachiy
reconnect = Kutillamanta tinkiy
# === nada (qillqa llamk'ana) ===
nada-tagline = Llimphi patapi kamachiq qillqaq
# === niveles de mensaje ===
info = Willay
warning = Yuyaymanay
error = Pantay
success = Allinmi
# === interpolación ===
welcome-user = Allin hamusqaykim, { $name }.
items-count = { $count } imaymana.
# === dominium (chawpi pachapi pukllachiq) ===
dominium-status-running = ● purichkan
dominium-status-paused = ‖ samachkan
dominium-status-line = dominium · chawpi pacha · wiñay { $epoch } · thaski { $tick }
dominium-btn-pause = ‖ Samay
dominium-btn-resume = ▶ Kutiy
dominium-btn-reseed = ↺ Watiq taqraay
dominium-btn-create-concept = ✦ Yuyay ruway
dominium-btn-seed-pack = ✚ Taqra churay
dominium-btn-clear = ✖ Pichay
dominium-btn-save = 💾 Waqaychay
dominium-btn-load-saved = 📂 Waqaychasqa apamuy
dominium-btn-load-named = ✓ «{ $name }» apamuy
dominium-header-sim = [ PUKLLAY ]
dominium-header-conceptos = [ YUYAYKUNA ]
dominium-header-metricas = [ TUPUCHIQKUNA ]
dominium-header-editar = [ HUKCHAY ]
dominium-active-count = { $count } kawsachkan
dominium-stat-population = Runa hunt'ay
dominium-stat-materia = Materia
dominium-stat-oro = Quri
dominium-stat-energia = Kallpa
dominium-stat-epoca = Wiñay
dominium-stat-gini-energia = Gini kallpa
dominium-stat-edad-media = Watayuq chawpi
dominium-stat-var-psi-orden = Var ψ kamachiy
dominium-stat-var-psi-miedo = Var ψ manchakuy
dominium-stat-var-psi-curiosidad = Var ψ tapukuy
dominium-stat-var-psi-corruptib = Var ψ ismuriy
dominium-action-mover = → kuyuy
dominium-action-extraer = → hurquy
dominium-action-sincronizar = → tinkichiy
dominium-action-intercambiar = → chhalaway
dominium-action-replicar = → kikinchay
dominium-action-degradar = → uray
dominium-slider-nombre = suti
dominium-slider-radius = mukmu
dominium-slider-materia = materia
dominium-slider-psique = nuna
dominium-slider-poder = atiy
dominium-slider-oro = quri
dominium-label-hack = hack:
# === cosmos (overlay módulos) ===
cosmos-btn-save-transit = 💾 Purichiqta qispi qillqaman waqaychay
cosmos-btn-save-progressed = 💾 Wiñasqata qispi qillqaman waqaychay
cosmos-btn-save-return = 💾 Kutiqta qispi qillqaman waqaychay
cosmos-header = cosmos · { $title } · Asc { $asc }° · MC { $mc }°
cosmos-demo-title = Qhawanapaq qillqa (Lima)
cosmos-demo-subtitle = cosmos-engine yupan (VSOP2013)
cosmos-status = { $ms } ms · { $layers } qatakuna · { $overlays } overlays · { $aspects } aspectos
cosmos-status-error = pantasqa: { $err }
cosmos-overlay-transit = puriq
cosmos-overlay-progression = wiñay
cosmos-overlay-solar-arc = inti arco
cosmos-overlay-uranian = uraniano
cosmos-overlay-lots = lote
cosmos-overlay-fixed-stars = qulluy
cosmos-overlay-midpoints = chawpi
cosmos-harmonic-label = armónico
cosmos-empty = (manaña)
cosmos-tile-carta = qillqa
cosmos-tile-modulos = módulos
cosmos-tile-armonico = armónico
cosmos-tile-cuerpos = ukhukuna
cosmos-tile-aspectos = aspectos
cosmos-tile-box-graph = aspectarian
cosmos-tile-cualidades = sayaykuna
cosmos-elementos = elementos
cosmos-modalidades = modalidades
cosmos-polaridad = iskaynin
cosmos-elem-fuego = nina
cosmos-elem-tierra = allpa
cosmos-elem-aire = wayra
cosmos-elem-agua = unu
cosmos-mod-cardinal = cardinal
cosmos-mod-fijo = thatkiqnin
cosmos-mod-mutable = mutable
cosmos-pol-yang = yang
cosmos-pol-yin = yin
cosmos-tile-astrocarto = astrocartografía
cosmos-astrocarto-leyenda = MC q'ipi · IC chiqan · Asc/Desc qinqu · • paqarisqa
cosmos-tile-cartas = waqaychasqa qillqakuna
cosmos-cartas-duplicar = + kunan iskayachay
cosmos-cartas-vacio = (chusaq — kunanta iskayachay icha JSON-kunata churay)
cosmos-tile-corpus = corpus
cosmos-tile-lotes = lote
cosmos-tile-estrellas-fijas = qulluy
cosmos-tile-puntos-medios = chawpi
cosmos-corpus-header = { $pasajes } pasajes · { $huecos } pisi · { $total } tinkunakuna
cosmos-corpus-vacio = (mana pasajes — cosmos-corpus/ejemplo.ron qillqay)
cosmos-tile-uraniano = uraniano 90° muyu
cosmos-tile-cross-transit = cross · puriq
cosmos-tile-cross-progression = cross · wiñay
cosmos-tile-cross-solar-arc = cross · inti arco
# === wawa-explorer (Wawa imagen qhawana) ===
wawa-marker-via-aoe = · AoE-pi
wawa-marker-searching = · maskachkan…
wawa-marker-fetch-failed = · fetch pantasqa
wawa-marker-not-in-image = · (mana imagenpi)
wawa-iface-ok = · AoE iface: { $name }
wawa-iface-err = · AoE: mana interfaz
wawa-header-error = wawa-explorer · pantay: { $err }
wawa-header = wawa-explorer · { $source } · { $bytes } bytes · v{ $version } · cursor sector { $cursor } · { $objects } imaymana{ $iface }
wawa-detail-empty = (huk imaymanata akllariy tree-pi)
wawa-detail-title = imaymana { $hash } · { $bytes } bytes · { $children } wawa{ $origen }
wawa-detail-title-missing = imaymana { $hash } · mana kaypi
wawa-detail-payload-header = payload (ñawpaq 256 bytes):
wawa-detail-children-header = wawakuna:
wawa-detail-child-missing = (mana imagenpi)
wawa-detail-searching-aoe-1 = local red AoE-pi maskachkan…
wawa-detail-searching-aoe-2 = broadcast SolicitarObjeto, suyay ProveedorObjeto verified hash-niyuq.
wawa-detail-fetch-error-1 = AoE intento pantasqa:
wawa-detail-fetch-error-2 = kay botón qhipata watiq maskayta atinki.
wawa-detail-needs-fetch-1 = kay imaymana huk tayta-pi nisqa, ichaqa mana local imagen-pi kawsachkan.
wawa-detail-needs-fetch-2 = local red Wawa peer-kuna-mantapis mañakuyta atinki (AoE, iface `{ $iface }`).
wawa-detail-aoe-disabled-1 = kay imaymana huk tayta-pi nisqa, ichaqa mana local imagen-pi kawsachkan.
wawa-detail-aoe-disabled-2 = AoE wisq'asqa: { $why }
wawa-detail-aoe-disabled-3 = CLI iskaynin parlachi-pi `<iface>` churay icha CAP_NET_RAW-wan kachay (`sudo setcap cap_net_raw=eip <binario>`).
wawa-btn-fetch = peer-kuna-manta apamuy
wawa-btn-retry-fetch = peer-kuna-manta watiq apamuy
# hatun menú
wawa-menu-file = Khipu
wawa-menu-reload = Mosoqmanta kichay
wawa-menu-quit = Lloqsiy
wawa-menu-view = Qhaway
wawa-menu-fetch = AoE-wan nodo apamuy
wawa-menu-theme = Tema tikray
wawa-menu-help = Yanapay
wawa-menu-about = Paymanta
# akllasqa nodopi contextual menú
wawa-ctx-select = Akllay
wawa-ctx-expand = Kichariy
wawa-ctx-collapse = Wisqay
wawa-ctx-fetch = AoE-wan apamuy
# === minga-explorer (repo qhawana) ===
minga-header-loaded = Repo: { $path } · watiq apamuy { $ms } ms
minga-header-searching = { $path }-pi repo maskachkan…
minga-error-read = { $path } repo mana ñawinchayta atinichu: { $err }
minga-card-nodes-title = AST Yuyay
minga-card-nodes-desc = código-manta parsesqa fragments
minga-card-attestations-title = Firmasqakuna
minga-card-attestations-desc = nodos hawapi Ed25519 firmakuna
minga-card-mst-title = MST Llaves
minga-card-mst-desc = Merkle Search Tree-pi yaykuq
minga-empty = Ñawpaq refresh suyachkan…
minga-menu-file = Willay
minga-menu-view = Qhaway
minga-menu-help = Yanapay
minga-menu-refresh = Musuqchay
minga-menu-quit = Lluqsiy
minga-menu-theme = Tema tikray
minga-menu-about = Paymanta
minga-menu-context-title = Repo
# === nakui-explorer (event log) ===
nakui-explorer-header = Log: { $path } · { $entries } yaykuq ({ $seeds } seeds, { $morphisms } morphisms) · watiq apamuy { $ms } ms
nakui-explorer-breakdown = rakiy: { $parts }
# === supay (doom) ===
supay-mode-real = MOTOR PAQARIQ
supay-mode-stub = STUB
supay-view-fb = qhaway=FB (F3→3D)
supay-view-3d = qhaway=3D (F3→FB)
supay-header = { $title } · thaski { $tick } · { $mode } · { $view } · { $scene }
supay-stub-title = supay-doom-llimphi STUB modo-pi purichkan
supay-stub-step-1 = doomgeneric-ta apamuy
supay-stub-step-1-cmd = cd 02_ruway/supay/supay-core/vendor && git clone https://github.com/ozkl/doomgeneric.git
supay-stub-step-2 = WAD shareware-ta cwd-man apamuy
supay-stub-step-2-cmd = curl -O https://distro.ibiblio.org/slitaz/sources/packages/d/doom1.wad
supay-stub-step-3 = Watiq kachay
supay-stub-step-3-cmd = cargo run -p supay-doom-llimphi --release
supay-stub-footer = doomgeneric (C) 35 Hz-pi puriy; framebuffer 320×200 ARGB aspect-fit-wan llimpisqa.
supay-controls-hint = WASD · Ctrl tuksiy · Space kichay · Tab mapa · F3 qhaway · F4 ñawi · F5 llantu · F6 HUD · F7 ll-chaki · F8 q'ancha · F9 hark'ay · F10 mobj-k'anchay · F11 maki-k'anchay · F12 lluqsiy
supay-stub-controls-hint = F3 FB/3D tikray · F12 wisq'ay
# === shuma-shell ===
shuma-label-launcher = Launcher
shuma-label-command = Kamachiq
shuma-label-shell = Shell
shuma-label-matilda = Matilda
shuma-label-canvas = Rikukuy
shuma-label-monitors = Qhawaqkuna
shuma-empty-main-incompat = Main yanapakuq mana atinmanchu
shuma-empty-no-tabs = Mana tabs churaqa.
shuma-empty-no-tabs-compat = Kay yanapakuq mana tab kayta atinmanchu.
shuma-empty-no-data-linux = mana willay (¿manachu Linux?)
shuma-empty-no-data = mana willay
shuma-stat-samples = qhawasqakuna: { $have } / { $total }
# === nahual (qhawanakuna) ===
nahual-image-unsupported = mana atisqa formato (kay build-pi PNG/JPEG sapanlla)
# === greeter (mirada login) ===
greeter-subtitle = sesionniykita qallariy
greeter-label-user = sutiyki
greeter-label-password = pakasqa rimay
greeter-placeholder-user = sutiykita churay
greeter-status-authenticating = qhawachkani…
greeter-error-empty-user = sutiyki churay
# === nakui (ERP shell) ===
nakui-header = Nakui · { $count } yanapakuq
nakui-sidebar-modules = Yanapakuqkuna ({ $count })
nakui-sidebar-menu = Akllana
nakui-empty-no-modules = Mana yanapakuq apamusqa
nakui-empty-pick-menu = Akllanata akllariy lateral barrapi
nakui-empty-pick-module = Yanapakuqta akllariy lateral barrapi
nakui-pending-edit = hukchay suyaykuchkan: meta-form Llimphi munakun
nakui-pending-render-detail = qhawachiy suyaykuchkan: meta-form Llimphi munakun
nakui-pending-render-dashboard = qhawachiy suyaykuchkan: dashboard Llimphi munakun
# === pluma (DAG hukchaq) ===
pluma-tone-valid = khuska
pluma-tone-pending = qhawana
pluma-tone-conflict = ch'aqwaypi
# === gioser-edit (qillqa hukchaq) ===
edit-status-find = maskay · Ctrl+G qatiq · Esc wisq'ay
edit-status-goto-def-waiting = goto-def · LSP suyaykuchkan…
edit-status-references-waiting = references · LSP suyaykuchkan…
edit-status-rename-input = sutichay · Enter ruway · Esc saqiy
edit-status-rename-waiting = sutichay → «{ $name }» · LSP suyaykuchkan…
edit-status-rename-error = sutichay · pantay { $path }: { $err }
edit-status-rename-done = sutichay · { $files } qillqa · { $bytes } bytes
edit-status-formatting-waiting = patachay · LSP suyaykuchkan…
edit-status-formatting-done = patachay · churasqa
edit-status-goto-def-at = goto-def · { $path }:{ $line }
edit-status-goto-def-error = goto-def · pantay kichaspa { $path }: { $err }
edit-status-saved = waqaychasqa · { $path }
edit-status-save-error = pantay waqaychaspa: { $err }
edit-header-hint = Ctrl+Shift+P akllana · Ctrl+P qillqakuna · Ctrl+Shift+F maskay
edit-status-position = Ln { $line }, Col { $col } · { $lang }
# === chasqui-explorer (mónadas) ===
chasqui-header = Engine '{ $engine }' · { $count } mónada · socket: { $socket } ({ $src }){ $watching }
chasqui-header-watching = · qhawachkan: { $name }
chasqui-header-searching = Chasqui daemonta maskaspa brahman-brokerwan…
chasqui-field-id = id: { $id }
chasqui-field-watching = qhawachkan: { $name }
chasqui-field-keywords = rimaykuna: { $keywords }
chasqui-field-path = ñan: { $path }
chasqui-field-model = modelo: { $name }
# === wawa-panel (wawa SO panilninkuna) ===
wawa-panel-title = wawa · kamachiy panil
wawa-panel-cat-appearance = Rikch'aynin
wawa-panel-cat-language = Simi
wawa-panel-cat-apps = Llamk'anakuna
wawa-panel-cat-monitor = Qhaway
wawa-panel-cat-modules = T'aqakuna
wawa-panel-cat-about = Imaynan
wawa-panel-section-appearance-hint = Llinphi rikch'ay, tinki ima.
wawa-panel-section-language-hint = Sistemaq simin, pacha rikch'ay ima.
wawa-panel-section-apps-hint = wawaq llamk'ananta kichay.
wawa-panel-section-monitor-hint = Kunan sistemaq munay kawsaynin.
wawa-panel-section-modules-hint = SOq t'aqankunata churay otaq qichuy.
wawa-panel-section-about-hint = Sistemaq willaynin.
wawa-panel-label-variant = Rikch'ay
wawa-panel-label-accent = Tinki
wawa-panel-label-language = Simi
wawa-panel-label-clock = Pacha
wawa-panel-variant-dark = Llanthu
wawa-panel-variant-light = K'anchay
wawa-panel-variant-aurora = Aurora
wawa-panel-variant-sunset = Inti haykuy
wawa-panel-clock-24h = 24 h
wawa-panel-clock-12h = 12 h
wawa-panel-stat-time = Pacha
wawa-panel-stat-uptime = Sayasqa pacha
wawa-panel-stat-mem = Yuyay
wawa-panel-stat-load = Q'ipi
wawa-panel-stat-host = Wasiq
wawa-panel-stat-kernel = Sunqu
wawa-panel-action-launch = Kichay
wawa-panel-action-save = Waqaychay
wawa-panel-action-reset = Kaqmanta churay
wawa-panel-saved = Kamachiy waqaychasqa { $path } nisqapi
wawa-panel-reset = Kamachiy kaqmanta churasqa
wawa-panel-menu-file = Willay
wawa-panel-menu-view = Qhaway
wawa-panel-menu-help = Yanapay
wawa-panel-menu-quit = Lluqsiy
wawa-panel-status-hint = ↑↓ puriy · Enter ruway · Ctrl+S waqaychay · Esc lluqsiy
wawa-panel-about-name = Sistema
wawa-panel-about-version = Mit'a
wawa-panel-about-kernel = Sunqu
wawa-panel-about-toolkit = Llamk'ana qillqana
wawa-panel-about-blurb = wawa kaqmi gioser suiteq sistemaynin. arje sunqu, llimphi llamk'anakuna, huch'uy userland patapi.
wawa-panel-mod-mirada = mirada · wayland kamachiq
wawa-panel-mod-shuma = shuma · q'ipichay, willay ima
wawa-panel-mod-chasqui = chasqui · willasqa, chasqui ima
wawa-panel-mod-akasha = akasha · musuqyachiy ñan
wawa-panel-mod-minga = minga · p2p waqaychana
wawa-panel-mod-agora = agora · llaqta plaza
wawa-panel-mod-on = kasqa
wawa-panel-mod-off = wañusqa
# === mirada-asistente ===
# Llimphi rurana, runa siminchikmanta `mirada-ctl` kamachikunaman tikrachiq,
# LLM-ta tapuspa. Nahual nin, runa hunisqa ruwakun.
asistente-title = carmen · yanapaq
asistente-sub = imatachus ruway munanki nipuway; yanapaq nin, qan hunichinki.
asistente-placeholder = imatachus ruwayta munanki? (Enter tapunapaq, Esc pichanapaq)
asistente-banner-no-llm = LLM mana kanchu: { $motivo }
asistente-status-pensando = yuyaykuspa…
asistente-boton-ejecutar = Ruway
asistente-boton-descartar = Wikch'uy
asistente-ejecutado-ok = ✓ { $accion } ruwasqa
asistente-ejecutado-fallo = ✗ { $accion } pantapun
asistente-error-transporte = apaqniyoq: { $motivo }
asistente-error-sin-llm = LLM mana kallarisqachu
asistente-error-sin-json = JSON mana kapuq kutichiq: { $crudo }
asistente-error-accion-vacia = ruwana mana kanchu chay nisqaqa: { $crudo }
asistente-error-json-invalido = JSON mana riqsisqa: { $crudo }
asistente-error-spawn = paqarichiy pantapun: { $err } (mirada-ctl PATH-pi kachkanchu?)
asistente-cero-salida = (mana kutichiq)
asistente-codigo-salida = lluqsiy yupay { $codigo }
asistente-error-accion-desconocida = LLM mana riqsisqa ruwanata nirqa: { $accion }
# === ayni-llimphi ===
ayni-menu-admitir = Chaskiy aklasqata
ayni-menu-atestar = Reqsichiy aklasqata
ayni-menu-expulsar = Qharquy aklasqata
ayni-menu-enviar-msg = Willayta kachamuy
ayni-menu-adjuntar = Huñichiy willakuyta…
ayni-menu-acuse = Chaskisqata willakuy
ayni-menu-cifrado = Pakasqa kachana E2EE
ayni-menu-recibos = Leeqsisqamanta willakuykuna
ayni-menu-comandos-barra = / barramanta kamachikuna
ayni-label-gente-miembros = RUNAKUNA — ayllukuna
ayni-label-otros-vistos = wakinkuna rikusqakuna
ayni-label-acciones = ruraykuna
ayni-label-elige-alguien = huk runata akllay
ayni-btn-admitir = chaskiy
ayni-btn-atestar = reqsichiy
ayni-btn-expulsar = qharquy
ayni-btn-acuse = chaskisqa
ayni-label-confianza = confiyay (brincaykuna)
ayni-label-sin-atestaciones = — mana reqsichisqachu —
ayni-label-sin-mensajes = — mana willakuykunachu. Uray qillqay (o /ayuda kamachikuymanta). —
ayni-compose-placeholder = willakuyta qillqay, o /adjuntar <ñan>, /atestar <hex> …
ayni-btn-enviar = kachamuy
# === chaka-app-llimphi ===
chaka-menu-run = Ruway
chaka-menu-run-pipeline = Pipeline ruwarina
chaka-tab-output = Lluqsiy
chaka-tab-rust = Rust ruwasqa
chaka-tab-diag = Taripanakuy
chaka-btn-run = Ruway
chaka-corpus-empty = corpus ch'uwa
chaka-corpus-header = CORPUS
chaka-editor-placeholder = corpus nisqamanta huk programata akllay
chaka-no-file = mana archivoyuq
chaka-banner-open-corpus = corpus nisqamanta huk programata lloq'e ladopi kichay
chaka-banner-step-limit = shadow ⚠ hatun takiy tukurirqan (¿tukukunaymanchu muyuriy?)
chaka-banner-pipeline-error = pipeline pantarqan — «Diag» pestaña-pi qhawaychis
chaka-status-no-open-file = mana kicharisqa archivom kan waqaychananpaq
chaka-about-text = chaka · COBOL → Rust tikrasqa · pipeline lex→parse→ir→codegen→shadow
# === chasqui-explorer-llimphi ===
chasqui-explorer-ctx-detail = Qhawarisqa
chasqui-explorer-monad-label = Mónada
chasqui-explorer-monad-stats = { $count } archivos · ent { $entropy } · { $lens }
# === media-app ===
media-settings-tab-audio = Uyariy
media-settings-tab-video = Rikuriy
media-settings-tab-playback = Qhawana
media-settings-tab-bars = Wara
media-settings-tab-controls = Kamachikuy
media-audio-volume = K'aqay
media-audio-eq = Tupuy
media-audio-normalization = Allichakuy
media-audio-lufs-target = LUFS yupay
media-audio-downmix = Iskay qhipa
media-video-color = Riqsinchay
media-video-enable = Qallariy
media-video-brightness = K'anchay
media-video-contrast = Tupay
media-video-gamma = Gamma
media-video-saturation = Hunt'ay
media-video-hue = Killayay
media-video-orientation = Tupuy
media-video-rotation = Muytuy
media-video-rotate-cw = muytuy 90°
media-video-flip-h = Lluqsinchay
media-video-flip-v = Hawaniy
media-action-reset = qallariy
media-action-cycle = muyuy
media-playback-playlist = Takiy lista
media-playback-resume = Kutimuy
media-playback-repeat = Kutichiy
media-playback-shuffle = Ch'aqnay
media-playback-subtitles = Qillqa
media-playback-autoload-sidecar = Kikin maskay
media-playback-sub-delay = Atiy (ms)
media-playback-font-size = Qillqa hatun
media-playback-behavior = Ruway
media-playback-crossfade = Tikray (s)
media-controls-header = Kamachikuy (teclado)
media-controls-hint = controles.ron t'aqay F5 apakuy kachiy.
media-bars-header = Kamachikuy warakuna — clic quichuy
media-bars-bar-label = Wara
media-bars-remove-bar = wara quichuy
media-bars-add-bar = + wara musuq
media-bars-add-items-to = Yaykuchiy:
media-settings-footer = config.ron waqaychakun · Esc wichukuy
media-playlist-header = Takiy lista — clic brinkay
media-playlist-empty = Mana lista kanchu.
media-win-config-title = Churay — media
media-win-playlist-title = Takiy lista — media
media-help-title = media · iskay-kachiy
media-help-group-playback = Qhawana
media-help-toggle = Rikuchiy/pakay yanapay
media-help-close = Wichukuy yanapay
media-help-reload = controles.ron kutimuy
media-menu-capture-frame = Qhawana aysay
media-menu-record = Qillqay / sayay
media-menu-reload-controls = Kamachikuy kutimuy
media-menu-playback = Qhawana
media-menu-play-pause = Qhaway / sayay
media-menu-seek-back = Qipa kutiy
media-menu-seek-fwd = Ñaupay
media-menu-prev-track = Qipa takiy
media-menu-next-track = Ñaupa takiy
media-menu-volume-up = K'aqay huqariy
media-menu-volume-down = K'aqay urmachiy
media-menu-playlist = Takiy lista
media-menu-visualizers = Uyariy rikuchiy
media-menu-shortcuts-help = Iskay-kachiy yanapay
media-ctx-stop-record = Qillqay sayay
media-ctx-record-audio = Uyariy qillqay
# === mirada-app-llimphi ===
mirada-menu-open-window = Tukuypaq qichariña
mirada-menu-open-output = Qhawana qichariña
mirada-menu-close-focused = Qhawasqa wichʼuña
mirada-menu-window = Tukuy
mirada-win-promote = Mama kamachiqman apariña
mirada-win-float = Phawariña / sayachiña
mirada-win-fullscreen = Llapan pantalla
mirada-win-scratchpad = Scratchpadman kachariña
mirada-win-label-fallback = tukuy
mirada-layout-cycle = Churasqata muyuriña
mirada-layout-master-stack = Mama + sarqay
mirada-layout-monocle = Huk ñawi
mirada-layout-grid = Chʼuqicha
mirada-layout-columns = Sayariykuna
mirada-layout-rows = Silaykuna
mirada-layout-centered = Chawpipi mama
mirada-layout-spiral = Muyuq
mirada-layout-shrink = Mamata huchuychariña
mirada-layout-grow = Mamata hatunychariña
mirada-output-next = Qatiq qhawana
mirada-status-body-connected = Cuerpo huñisqa
mirada-status-simulation = simulación — Cuerpo illaq
mirada-status-keymap-reloaded = keymap kutichisqa
mirada-status-keymap-invalid = keymap mana allin
mirada-label-layout = churasqa
mirada-label-focus = qhawasqa
mirada-label-output = lluqsiy
mirada-label-workspace = llamkana
mirada-canvas-empty-hint = llamkana ch'in — n nispa hatarichiña
mirada-win-kind-fullscreen = · llapan pantalla ·
mirada-win-kind-floating = · phawaq tukuy ·
mirada-win-kind-surface = · Cuerpop sawanpi ·
# === mirada-greeter ===
mirada-greeter-menu-session = Yaykuy
mirada-greeter-session-submit = Yaykuy qallariy
mirada-greeter-session-goto-user = Sutiyman ri
mirada-greeter-session-goto-pass = Pasakllavaman ri
mirada-greeter-label-desktop = Llamk'ana
mirada-greeter-btn-submit = Yaykuy
mirada-greeter-btn-submitting = Yaykuchkaspa…
mirada-greeter-hint-nav = ↑/↓: llamk'ana · Enter: yaykuy
mirada-greeter-hint-console = Ctrl+Alt+F1…F12: consola · Ctrl+Alt+⌫: lluqsiy
# === nakui-explorer-llimphi ===
nakui-explorer-menu-refresh-log = Quillqa musuqyachiy
nakui-explorer-ctx-view-detail = Qhaway chikan
nakui-explorer-ctx-refresh-log = Quillqa musuqyachiy
nakui-explorer-ctx-entry-fallback = Yaykuy
# === nakui-sheet-llimphi ===
nakui-sheet-ctx-clear = Chuyayachiy
nakui-sheet-fmt-number = Formato: Yupay
nakui-sheet-fmt-currency = Formato: Qullqi $
nakui-sheet-fmt-percent = Formato: Chunka-chunka
nakui-sheet-fmt-general = Formato: Sapsa
nakui-sheet-freeze-here = Kaypi suyukunata siriychiy
nakui-sheet-unfreeze = Suyukunata kacharpay
nakui-sheet-pivot = Tukuchiy mesa…
nakui-sheet-menu-cell-cut = Celdata kuchuy
nakui-sheet-menu-cell-copy = Celdata rurayta
nakui-sheet-menu-cell-paste = Celdata churay
nakui-sheet-menu-cell-clear = Celdata chuyayachiy
nakui-sheet-menu-bar-cut = Simiyta kuchuy
nakui-sheet-menu-bar-copy = Simiyta rurayta
nakui-sheet-menu-bar-paste = Simiyta churay
nakui-sheet-menu-bar-select-all = Llapan simiyta akllay
nakui-sheet-menu-import-csv = CSV hayquchiy
nakui-sheet-menu-export-csv = CSV lluqsichiy
nakui-sheet-menu-about = Nakui Sheet haqay
nakui-sheet-formula-placeholder = fórmula utaq valorniyuqta qillqay
nakui-sheet-pivot-title = Tukuchiy mesa
nakui-sheet-pivot-close = ✕ Esc
nakui-sheet-pivot-group-by = Huñuy «
nakui-sheet-pivot-over = patapi
nakui-sheet-pivot-with-header = umayuq
nakui-sheet-pivot-no-header = umachiy
nakui-sheet-pivot-more-groups = huñuykuna
nakui-sheet-pivot-total = TUKUY
nakui-sheet-pivot-groups = huñuykuna
nakui-sheet-pivot-rows = saytuqkuna
nakui-sheet-pivot-hint = A ruwana · G huñuy · V chanin · H uma · Esc wisq'ay
# === paloma-llimphi ===
paloma-status-init = paloma · mana tupachisqa
paloma-status-search-semantic = rimay maskay: suyasqam — chiqan maskaywan
paloma-status-view-rich = puriy HTML: suyasqam (kunanmanta llamp'u qillqa)
paloma-status-no-recipient = mana kachayta atikuchu: mana allin chaskiqkuna
paloma-status-sent = kachasqa
paloma-status-sent-signed = kachasqa · firmayuq (Ed25519)
paloma-placeholder-search = Maskay… ( / )
paloma-btn-compose = ✎ Qillqay
paloma-nav-calendar = Killaka
paloma-nav-contacts = Riqsisqakuna
paloma-nav-soon = utqaylla
paloma-empty-threads = Ch'usaq chhawa
paloma-empty-search = mana tupanakuychu
paloma-search-exact = Chiqan
paloma-search-semantic = Rimay ukhunpi
paloma-no-subject = (mana asuntuyuq)
paloma-placeholder-read = Uj hilota akllay leenampaq
paloma-btn-reply = Kutichiy
paloma-btn-forward = Watiqmanta kachay
paloma-btn-star = Ch'askayman churay
paloma-btn-starred = Ch'askayuq
paloma-btn-mark-unread = Mana leesqaña nispa ch'aniyay
paloma-btn-mark-read = Leesqaña nispa ch'aniyay
paloma-btn-view-rich = HTML sumaqta qhaway
paloma-msg-to-label = riqsichiq
paloma-sig-verified = firmayuq
paloma-sig-invalid = mana allin firma
paloma-compose-new = Mosoj qillqa
paloma-compose-reply-title = Kutichiy
paloma-compose-placeholder-to = Riqsichiq: suti <correo@dominio>
paloma-compose-placeholder-cc = Cc: (munasqayki)
paloma-compose-placeholder-subject = Asunto
paloma-compose-placeholder-body = Qillqay willakuyniquita…
paloma-compose-sign = Firmay (Ed25519)
paloma-compose-send = Kachay
# === pluma-notebook-llimphi ===
pluma-notebook-fit-all = Llapallan tupuchiy
pluma-notebook-center = Chawpiman apaykachay
pluma-notebook-zoom-reset = Zoom 100%
# === raymi-llimphi ===
raymi-tab-calendar = Killay qillqa
raymi-tab-contacts = Rimasqakuna
raymi-view-month = Killa
raymi-view-week = Saqra
raymi-view-day = Punchaw
raymi-btn-new-event = Kausay
raymi-btn-today = Kunan punchaw
raymi-btn-new-contact = Rimasqa
raymi-no-events = mana kausaykunachu
raymi-all-day = punchaw tukuy
raymi-no-contacts = mana rimasqachu
raymi-search-contact-placeholder = 🔍 Rimasqa maskhay…
raymi-select-contact-hint = Rimasqa akllay
raymi-title-edit-event = Kausay tikray
raymi-title-new-event = Musuq kausay
raymi-title-edit-contact = Rimasqa tikray
raymi-title-new-contact = Musuq rimasqa
raymi-change-cycle = tikray
raymi-field-summary = Muhu
raymi-field-all-day = Punchaw tukuy
raymi-field-apply-to = Riqsichiy
raymi-field-calendar = Killay qillqa
raymi-field-date = Punchaw killa
raymi-field-start = Qallariy
raymi-field-end = Tukuy
raymi-field-location = Suytu
raymi-ph-location = Suytu (mana wakichisqachu)
raymi-field-description = Willakuy
raymi-ph-description = Qillqakuna (mana wakichisqachu)
raymi-field-attendees = Waqyasqakuna
raymi-ph-invitee = Suti <correo> · Enter
raymi-field-repeat = Kutichiy
raymi-field-every = Sapa
raymi-field-days = Punchaykuna
raymi-field-ends = Tukun
raymi-field-name = Suti
raymi-field-emails = Correos
raymi-field-phones = Qayakuna
raymi-field-org = Llankakuna
raymi-field-note = Qillqa
raymi-ph-full-name = Suti tukuynin
raymi-ph-emails = correo@dominio, sapa@…
raymi-ph-phones = +51 9…, …
raymi-ph-org = Llanka (mana wakichisqachu)
raymi-ph-note = Qillqa (mana wakichisqachu)
raymi-scope-series = Tukuy kutichiy
raymi-scope-this-only = Kay kausay sapan
raymi-scope-this-and-future = Kay kay qhipakuna
raymi-repeat-none = Mana kutichisqachu
raymi-repeat-daily = Sapa punchaw
raymi-repeat-weekly = Sapa saqra
raymi-repeat-monthly = Sapa killa
raymi-repeat-yearly = Sapa wata
raymi-unit-days = punchaw(kuna)
raymi-unit-weeks = saqra(kuna)
raymi-unit-months = killa(kuna)
raymi-unit-years = wata(kuna)
raymi-end-never = Mana tukukuqchu
raymi-end-count = N kutimanta qhipa
raymi-end-until = Punchaw kama
raymi-status-no-calendars = mana killay qillqachu kanchu
raymi-status-no-books = mana qillqa watachu kanchu
raymi-status-invalid-datetime = punchaw utaq hora mana allinchu
raymi-status-contact-needs-name = rimasqaqa sutita munan
# === shuma-shell-llimphi ===
shuma-shell-clear-input = Yaykuna pakay
shuma-shell-clear-screen = Rikuykuna pakay
shuma-shell-cancel-cmd = Kamachiy saqiy
shuma-shell-about = Shuma haqhay
# === supay-app-llimphi ===
supay-hud-health = KAWSAY
supay-hud-ammo = MAQANAKUY
supay-hud-target = QAWAY
supay-action-fire = Aysay
supay-action-reset = Qallarimuy
supay-menu-play = Pukllay
supay-status-game-over = pukllaypi tukuy
supay-status-victory = atiy
supay-status-dead = WAÑUSQA
supay-hint-space-restart = SPACE ninchu qallarimuy
# === wawa-panel-llimphi ===
wawa-panel-status-config-updated = ↻ churasqa huk llaqtamanta
wawa-panel-ctx-refresh-monitor = Mosqoychiy monitor
wawa-panel-autosave-ok = ↻ churasqa
+333
View File
@@ -0,0 +1,333 @@
//! `rimay-localize` — i18n del escritorio gioser sobre Fluent.
//!
//! Disciplina (PLAN.md §6.3):
//!
//! - Los `*-core` agnósticos **no contienen strings de UI**. Emiten
//! identificadores (`MsgId`) que las apps Llimphi resuelven a texto
//! localizado aquí, al renderizar.
//! - Un único catálogo `.ftl` por idioma vive en `locales/{lang}.ftl`,
//! embebido en el binario vía [`include_str!`].
//! - El locale activo es un singleton de proceso. Cambiarlo recarga el
//! bundle pero **no** retransla automáticamente la vista — las apps
//! Llimphi vuelven a llamar a [`t`] en el próximo `view()`.
//!
//! ## API mínima
//!
//! ```no_run
//! use rimay_localize as l10n;
//!
//! // Una vez al inicio de la app: detecta `LANG`/sistema, fallback es-PE.
//! l10n::init();
//!
//! // En cualquier `view()`:
//! let label = l10n::t("save");
//!
//! // Con argumentos posicionales tipo Fluent `{ $name }`:
//! let greet = l10n::t_args("welcome-user", &[("name", "Sergio".into())]);
//! ```
//!
//! ## Por qué Fluent (y no gettext / embeddings)
//!
//! - **Fluent** trae plurales/género/contextos declarativos en el `.ftl`,
//! sin macros de código. Esencial para idiomas aglutinantes (quechua)
//! donde la pluralización no es la binaria one/other del inglés.
//! - **Embeddings** son la herramienta correcta para *búsqueda semántica*
//! (command palette, intent → acción) — ver [`rimay-verbo`]. **No** para
//! strings deterministas de UI.
//!
//! ## Alcance fuera de wawa
//!
//! Este crate requiere `std` y `alloc` (Fluent tira de ambos). El kernel
//! `wawa` es `no_std` y no se localiza: emite **códigos** de error que
//! las apps WASM por encima traducen consultando este catálogo.
#![forbid(unsafe_code)]
use std::borrow::Cow;
use std::collections::HashMap;
use fluent_bundle::concurrent::FluentBundle;
use fluent_bundle::{FluentArgs, FluentResource, FluentValue};
use once_cell::sync::Lazy;
use parking_lot::RwLock;
use thiserror::Error;
use tracing::warn;
use unic_langid::LanguageIdentifier;
// =====================================================================
// Catálogos embebidos
// =====================================================================
/// Lista de catálogos compilada al binario. Para añadir un idioma:
/// 1. Crear `locales/{lang}.ftl`.
/// 2. Añadir la tupla `("{lang}", include_str!(...))` aquí.
///
/// **Orden = prioridad declarada del proyecto**: español primero (es el
/// fallback y la lengua de trabajo), quechua segundo (lengua de la
/// arquitectura del monorepo), inglés tercero (uso técnico). Cambios
/// futuros conservan este orden por convención.
const CATALOGS: &[(&str, &str)] = &[
("es-PE", include_str!("../locales/es.ftl")),
("qu-PE", include_str!("../locales/qu.ftl")),
("en-US", include_str!("../locales/en.ftl")),
];
/// Locale por defecto cuando la detección del sistema falla o pide algo
/// que no tenemos catalogado.
pub const FALLBACK_LOCALE: &str = "es-PE";
// =====================================================================
// Errores
// =====================================================================
#[derive(Debug, Error)]
pub enum LocalizeError {
#[error("locale '{0}' no está catalogado")]
UnknownLocale(String),
#[error("parseando catálogo de '{0}': {1}")]
CatalogParse(String, String),
#[error("identificador de locale inválido '{0}': {1}")]
InvalidLangId(String, String),
}
// =====================================================================
// Estado global
// =====================================================================
struct State {
/// Locale activo (clave de [`CATALOGS`]).
active: String,
/// Un bundle por catálogo embebido. Se construyen perezosamente la
/// primera vez que un locale entra en uso y se cachean.
bundles: HashMap<String, FluentBundle<FluentResource>>,
}
impl State {
fn new() -> Self {
Self {
active: FALLBACK_LOCALE.to_string(),
bundles: HashMap::new(),
}
}
fn ensure_bundle(&mut self, locale: &str) -> Result<(), LocalizeError> {
if self.bundles.contains_key(locale) {
return Ok(());
}
let src = CATALOGS
.iter()
.find(|(l, _)| *l == locale)
.map(|(_, s)| *s)
.ok_or_else(|| LocalizeError::UnknownLocale(locale.to_string()))?;
let langid: LanguageIdentifier = locale
.parse()
.map_err(|e: unic_langid::LanguageIdentifierError| {
LocalizeError::InvalidLangId(locale.to_string(), e.to_string())
})?;
let res = FluentResource::try_new(src.to_string()).map_err(|(_, errs)| {
LocalizeError::CatalogParse(
locale.to_string(),
errs.into_iter()
.map(|e| e.to_string())
.collect::<Vec<_>>()
.join("; "),
)
})?;
let mut bundle = FluentBundle::new_concurrent(vec![langid]);
// Fluent inserta caracteres bidi U+2068/U+2069 alrededor de los
// placeables. En una UI de escritorio que no soporta BIDI complejo
// (Llimphi no lo hace todavía) se ven como ◌. Los desactivamos:
// los catálogos no mezclan RTL/LTR por ahora.
bundle.set_use_isolating(false);
if let Err(errs) = bundle.add_resource(res) {
warn!(target: "rimay-localize", ?errs, "errores al añadir recurso a bundle '{locale}'");
}
self.bundles.insert(locale.to_string(), bundle);
Ok(())
}
}
static STATE: Lazy<RwLock<State>> = Lazy::new(|| RwLock::new(State::new()));
// =====================================================================
// API pública
// =====================================================================
/// Inicializa el localizador detectando el locale del sistema (env
/// `LANG`/`LC_ALL` vía [`sys_locale`]) y eligiendo el más cercano de los
/// catálogos disponibles. Si no hay match, cae en [`FALLBACK_LOCALE`].
///
/// Idempotente — invocaciones sucesivas resetean el locale activo según
/// el sistema actual. Si la app quiere fijar el locale a mano, usar
/// [`set_locale`] después.
pub fn init() {
let detected = sys_locale::get_locale().unwrap_or_else(|| FALLBACK_LOCALE.to_string());
let chosen = best_match(&detected).unwrap_or_else(|| FALLBACK_LOCALE.to_string());
let _ = set_locale(&chosen);
}
/// Cambia el locale activo. Compila el catálogo correspondiente si aún
/// no estaba cargado.
pub fn set_locale(locale: &str) -> Result<(), LocalizeError> {
let mut state = STATE.write();
state.ensure_bundle(locale)?;
state.active = locale.to_string();
Ok(())
}
/// Devuelve el locale activo (clave de [`CATALOGS`]).
pub fn current_locale() -> String {
STATE.read().active.clone()
}
/// Lista de locales disponibles (claves de [`CATALOGS`]).
pub fn available_locales() -> Vec<&'static str> {
CATALOGS.iter().map(|(l, _)| *l).collect()
}
/// Resuelve un mensaje sin argumentos. Si el ID no existe en el catálogo
/// activo, devuelve el propio ID — facilita ver qué falta traducir sin
/// crashear la UI.
pub fn t(id: &str) -> String {
resolve(id, None)
}
/// Resuelve un mensaje con argumentos posicionales tipo Fluent
/// (`{ $name }`). Los valores se convierten a [`FluentValue`] vía la
/// impl `From<Cow<str>>` — números pásalos pre-formateados como string
/// si querés controlar la presentación.
pub fn t_args(id: &str, args: &[(&str, Cow<'_, str>)]) -> String {
let mut fa = FluentArgs::new();
for (k, v) in args {
fa.set(*k, FluentValue::from(v.clone().into_owned()));
}
resolve(id, Some(&fa))
}
// =====================================================================
// Internos
// =====================================================================
fn resolve(id: &str, args: Option<&FluentArgs>) -> String {
// Auto-init lazy: si `t()` se llama sin `init()` previo (típico desde
// librerías como `cosmos-modules` que no ven el `main`), cargamos el
// fallback en ese momento. Es un costo amortizado de una sola vez.
if STATE.read().bundles.is_empty() {
let mut w = STATE.write();
if w.bundles.is_empty() {
let _ = w.ensure_bundle(FALLBACK_LOCALE);
w.active = FALLBACK_LOCALE.to_string();
}
}
let state = STATE.read();
let bundle = match state.bundles.get(&state.active) {
Some(b) => b,
None => return id.to_string(),
};
let Some(msg) = bundle.get_message(id) else {
return id.to_string();
};
let Some(pattern) = msg.value() else {
return id.to_string();
};
let mut errors = vec![];
let s = bundle.format_pattern(pattern, args, &mut errors);
if !errors.is_empty() {
warn!(target: "rimay-localize", ?errors, "errores formateando '{id}' en locale '{}'", state.active);
}
s.into_owned()
}
/// Mejor match entre un locale solicitado y los catalogados.
///
/// 1. Match exacto (`qu-PE` → `qu-PE`).
/// 2. Match por lengua base ignorando región (`es-AR` → `es-PE`,
/// `qu-BO` → `qu-PE`).
/// 3. Sin match → `None`.
fn best_match(requested: &str) -> Option<String> {
if CATALOGS.iter().any(|(l, _)| *l == requested) {
return Some(requested.to_string());
}
let base = requested.split(['-', '_']).next()?;
CATALOGS
.iter()
.find(|(l, _)| l.split('-').next() == Some(base))
.map(|(l, _)| l.to_string())
}
// =====================================================================
// Tests
// =====================================================================
#[cfg(test)]
mod tests {
use super::*;
use std::sync::Mutex;
// Los tests comparten estado global → serialización manual.
static SERIAL: Mutex<()> = Mutex::new(());
#[test]
fn fallback_locale_resolves() {
let _g = SERIAL.lock().unwrap();
set_locale("es-PE").unwrap();
let s = t("save");
assert_eq!(s, "Guardar");
}
#[test]
fn switches_to_english() {
let _g = SERIAL.lock().unwrap();
set_locale("en-US").unwrap();
assert_eq!(t("save"), "Save");
assert_eq!(t("cancel"), "Cancel");
}
#[test]
fn quechua_loads() {
let _g = SERIAL.lock().unwrap();
set_locale("qu-PE").unwrap();
// Solo verificamos que devuelva *algo distinto* del id, no la
// traducción literal — para no acoplar el test al fraseo exacto
// del catálogo (que el revisor de quechua va a ajustar).
let s = t("save");
assert_ne!(s, "save", "qu-PE no resolvió 'save'");
}
#[test]
fn unknown_id_returns_id_as_degradation() {
let _g = SERIAL.lock().unwrap();
set_locale("es-PE").unwrap();
assert_eq!(t("__id_que_no_existe__"), "__id_que_no_existe__");
}
#[test]
fn args_interpolate() {
let _g = SERIAL.lock().unwrap();
set_locale("es-PE").unwrap();
let s = t_args("welcome-user", &[("name", "Sergio".into())]);
assert!(s.contains("Sergio"), "no interpoló name: {s}");
}
#[test]
fn best_match_region_fallback() {
assert_eq!(best_match("es-AR"), Some("es-PE".to_string()));
assert_eq!(best_match("en-GB"), Some("en-US".to_string()));
assert_eq!(best_match("qu-BO"), Some("qu-PE".to_string()));
assert_eq!(best_match("ja-JP"), None);
}
#[test]
fn unknown_locale_errors() {
let err = set_locale("xx-YY").unwrap_err();
assert!(matches!(err, LocalizeError::UnknownLocale(_)));
}
#[test]
fn available_locales_lists_all() {
let v = available_locales();
assert!(v.contains(&"es-PE"));
assert!(v.contains(&"en-US"));
assert!(v.contains(&"qu-PE"));
}
}