feat(distro): el censo completo — 152 huecos, y kitty era uno de ellos
El operador preguntó por `kitty` y si «varias populares así faltan». Las dos mitades son ciertas.
**kitty no existe** — ni receta ni intento en toda la historia del repo. Lo único que hay es una
línea del `docs/20` §II.2 que ya lo listaba como «barato» junto a `alacritty`. Y medido, barato era
de verdad: **13 de sus 14 deps ya están en el catálogo** (python3, harfbuzz, fontconfig, freetype,
libpng, lcms2, xxhash, simde, go, wayland, libxkbcommon, openssl, dbus; falta `librsync`, que es
opcional). Lo mismo con los otros cuatro terminales que la gente nombra: **5/5 ausentes**.
El censo pasa de 54 a 170 renglones: terminales, editores, shells, lanzador/notificaciones/bloqueo,
audio de escritorio, capturas, visores de imagen, mensajería, música, video, PDF, notas, gestores
de archivos, lenguajes, depuradores, bluetooth, contraseñas, respaldos, torrent, compositores. Son
**152 huecos** y **12 que ya existen sin viajar en ninguna imagen** — éstos son los más baratos de
todos, porque es declararlos, no escribirlos: `nodejs`, `mako`, `typst`, `uv`, `micro`, `kakoune`,
`elvish`, `gopass`, `valkey`, `wtype`, `kubectl`, `helm`.
Tres hallazgos del barrido que valen más que el recuento:
· **`bob-nvim` existe y neovim NO.** El gestor de versiones de neovim, sin neovim. Es el mismo
patrón que `crun` sin podman y que `cups` sin filtros: el conductor sellado y el motor ausente.
· **`zig` no es una receta.** Vive como artefacto `seed-zig` fuera del catálogo — y es el
compilador de TODO el corpus. No es un hueco de producto, pero que el compilador de la distro no
esté en su propio catálogo merece decirse.
· **`libzip` es biblioteca, no comando.** No hay `unzip`: un .zip adjunto no se abre.
⚠ Y UNA CORRECCIÓN A MI PROPIA MEDICIÓN, la segunda sobre lo mismo. La v1 cantaba huecos falsos
(«falta clang» con `clang18`). Lo arreglé buscando parientes de nombre y sacándolos del recuento, y
eso fue PEOR: escondía huecos reales — `neovim` salía absuelto por `vim`, `man-pages` por `mandoc`
(que es el lector, no el contenido), `patchelf` por `patch`. Ahora **un pariente ANOTA, no
absuelve**: el hueco se cuenta siempre y la pista viaja al lado para que nadie repita la búsqueda.
Las dos formas de mentir tienen el mismo antídoto.
Lo que NO es hueco y queda dicho en el fichero: `gcc` está retenido a propósito (sólo `gcc-libs`),
`clang` es `clang18`, y la suite ArtCraft propia cubre imagen/diseño/ofimática con 12 apps — esos
renglones son los nombres AJENOS que alguien busca, no una capacidad ausente.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
5ebfe46a86ad72e5ecb12fb88070bba6900b1764 · ruwaq Sergio · 2026-10-19T18:28:30Z (2 p'unchaw ñawpaq) · tayta aea7a59f0 · kay commitpi sach'ata qhaway
2 qillqakuna · +1150 −135
diff --git a/docs/state/distro-huecos.json b/docs/state/distro-huecos.json
index 4cf67124..cba5692e 100644
--- a/docs/state/distro-huecos.json
+++ b/docs/state/distro-huecos.json
@@ -30,7 +30,7 @@
"parientes": []
}
],
- "porque": "sin estas fuentes la distro muestra cuadraditos en chino, japonés, coreano, árabe, hindi, tailandés y emoji — o sea para la mayor parte de la humanidad"
+ "porque": "las únicas fuentes del corpus son dejavu y su nerd: sin estas, la distro muestra cuadraditos en chino, japonés, coreano, árabe, hindi, tailandés y emoji"
},
{
"categoria": "escribir en esos idiomas",
@@ -107,279 +107,1193 @@
],
"porque": "sin lector de pantalla ni voz la distro es inusable para quien no ve"
},
+ {
+ "categoria": "terminales populares",
+ "faltan": [
+ "kitty",
+ "alacritty",
+ "wezterm",
+ "ghostty",
+ "xterm"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "kitty",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "alacritty",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "wezterm",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "ghostty",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "xterm",
+ "parientes": []
+ }
+ ],
+ "porque": "`foot` está y alcanza; pero quien llega de otra distro busca el suyo por nombre, y el doc 20 §II.2 ya los listaba como «barato». kitty: 13 de sus 14 deps ya están en el catálogo (falta librsync, opcional)"
+ },
+ {
+ "categoria": "editores",
+ "faltan": [
+ "neovim",
+ "emacs"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "neovim",
+ "parientes": [
+ "vim"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ },
+ {
+ "estado": "falta",
+ "nombre": "emacs",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "micro",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "kakoune",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-y-viaja",
+ "nombre": "nano",
+ "parientes": []
+ }
+ ],
+ "porque": "`vim` y `helix` están. ⚠ Existe `bob-nvim` —el GESTOR DE VERSIONES de neovim— y no existe neovim: el conductor sin el motor, como `crun` sin podman"
+ },
+ {
+ "categoria": "shells",
+ "faltan": [
+ "fish"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "fish",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "elvish",
+ "parientes": []
+ }
+ ],
+ "porque": "bash, zsh y nushell están"
+ },
+ {
+ "categoria": "lanzador, notificaciones y bloqueo",
+ "faltan": [
+ "rofi",
+ "wofi",
+ "bemenu",
+ "tofi",
+ "swaync",
+ "gtklock",
+ "waylock"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "rofi",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "wofi",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-y-viaja",
+ "nombre": "fuzzel",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "bemenu",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "tofi",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "mako",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-y-viaja",
+ "nombre": "dunst",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "swaync",
+ "parientes": [
+ "sway"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ },
+ {
+ "estado": "tiene-y-viaja",
+ "nombre": "swaylock",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "gtklock",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "waylock",
+ "parientes": []
+ }
+ ],
+ "porque": "el esqueleto de un escritorio Wayland que no sea GNOME/KDE: sin lanzador no se abre nada"
+ },
+ {
+ "categoria": "audio de escritorio",
+ "faltan": [
+ "pavucontrol",
+ "pamixer",
+ "playerctl",
+ "easyeffects",
+ "wiremix"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "pavucontrol",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "pamixer",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "playerctl",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "easyeffects",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "wiremix",
+ "parientes": [
+ "wire"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ }
+ ],
+ "porque": "PipeWire suena y no hay con qué subirle el volumen desde una ventana"
+ },
+ {
+ "categoria": "capturas y portapapeles",
+ "faltan": [
+ "satty",
+ "swappy",
+ "flameshot",
+ "kanshi"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "satty",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "swappy",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "flameshot",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "wtype",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "kanshi",
+ "parientes": []
+ }
+ ],
+ "porque": "grim, slurp, wl-clipboard y cliphist ya están"
+ },
+ {
+ "categoria": "visores de imagen",
+ "faltan": [
+ "imv",
+ "nsxiv",
+ "feh",
+ "loupe",
+ "eog"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "imv",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "nsxiv",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "feh",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "loupe",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "eog",
+ "parientes": []
+ }
+ ],
+ "porque": "ninguno: una foto no se abre"
+ },
+ {
+ "categoria": "archivos comprimidos ajenos",
+ "faltan": [
+ "unzip",
+ "zip",
+ "p7zip",
+ "7zip",
+ "unrar"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "unzip",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "zip",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "p7zip",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "7zip",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "unrar",
+ "parientes": []
+ }
+ ],
+ "porque": "no se puede abrir un .zip, un .7z ni un .rar — un adjunto cualquiera queda cerrado. `libzip` es una BIBLIOTECA, no el comando"
+ },
{
"categoria": "imprimir de verdad",
"faltan": [
- "ghostscript",
- "gutenprint",
- "hplip"
+ "cups-filters",
+ "ghostscript",
+ "gutenprint",
+ "hplip"
+ ],
+ "items": [
+ {
+ "estado": "tiene-y-viaja",
+ "nombre": "cups",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "cups-filters",
+ "parientes": [
+ "cups"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ },
+ {
+ "estado": "falta",
+ "nombre": "ghostscript",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "gutenprint",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "hplip",
+ "parientes": []
+ }
+ ],
+ "porque": "cups solo no imprime: los filtros y los drivers son otro paquete"
+ },
+ {
+ "categoria": "escanear",
+ "faltan": [
+ "sane-backends",
+ "simple-scan"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "sane-backends",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "simple-scan",
+ "parientes": [
+ "simple-http-server"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ }
+ ],
+ "porque": "ningún camino hoy"
+ },
+ {
+ "categoria": "documentos técnicos",
+ "faltan": [
+ "texlive",
+ "pandoc",
+ "groff"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "texlive",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "pandoc",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "typst",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "groff",
+ "parientes": []
+ }
+ ],
+ "porque": "nada que componga un PDF desde texto marcado"
+ },
+ {
+ "categoria": "páginas de manual",
+ "faltan": [
+ "man-pages",
+ "texinfo"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "man-pages",
+ "parientes": [
+ "mandoc",
+ "mandown",
+ "mani"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ },
+ {
+ "estado": "falta",
+ "nombre": "texinfo",
+ "parientes": []
+ }
+ ],
+ "porque": "`mandoc` LEE man; falta el CONTENIDO y el formateador de info"
+ },
+ {
+ "categoria": "virtualización",
+ "faltan": [
+ "qemu",
+ "libvirt",
+ "virt-manager"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "qemu",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "libvirt",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "virt-manager",
+ "parientes": []
+ }
+ ],
+ "porque": "ni invitado ni anfitrión: no se puede probar la propia ISO sin salir"
+ },
+ {
+ "categoria": "contenedores",
+ "faltan": [
+ "podman",
+ "docker",
+ "buildah",
+ "flatpak",
+ "distrobox"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "podman",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "docker",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "buildah",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "flatpak",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "distrobox",
+ "parientes": []
+ }
+ ],
+ "porque": "`crun` está (el motor); falta quien lo conduzca"
+ },
+ {
+ "categoria": "java",
+ "faltan": [
+ "openjdk",
+ "jdk",
+ "temurin"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "openjdk",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "jdk",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "temurin",
+ "parientes": []
+ }
+ ],
+ "porque": "un ecosistema entero queda fuera sin una JVM"
+ },
+ {
+ "categoria": "bases de datos de servidor",
+ "faltan": [
+ "postgresql",
+ "mariadb",
+ "redis"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "postgresql",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "mariadb",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "redis",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "valkey",
+ "parientes": []
+ }
+ ],
+ "porque": "sqlite está; un servicio con varios clientes no"
+ },
+ {
+ "categoria": "depurar y medir",
+ "faltan": [
+ "gdb",
+ "lldb",
+ "valgrind",
+ "ltrace",
+ "perf",
+ "patchelf"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "gdb",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "lldb",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "valgrind",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "ltrace",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "perf",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "patchelf",
+ "parientes": [
+ "patch"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ }
+ ],
+ "porque": "se construye la distro entera y no hay con qué mirar un core"
+ },
+ {
+ "categoria": "discos y salud del equipo",
+ "faltan": [
+ "smartmontools",
+ "nvme-cli",
+ "hdparm",
+ "gparted"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "smartmontools",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "nvme-cli",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "hdparm",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "gparted",
+ "parientes": [
+ "parted"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ }
+ ],
+ "porque": "nada que avise de un disco muriéndose"
+ },
+ {
+ "categoria": "otros lenguajes",
+ "faltan": [
+ "deno",
+ "bun",
+ "ruby",
+ "php",
+ "julia",
+ "ghc",
+ "ocaml",
+ "elixir",
+ "erlang"
+ ],
+ "items": [
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "nodejs",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "deno",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "bun",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "ruby",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "php",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "julia",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "ghc",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "ocaml",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "elixir",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "erlang",
+ "parientes": []
+ }
+ ],
+ "porque": "python3, lua, go, rust y perl están. ⚠ `zig` NO es receta: vive como artefacto `seed-zig` fuera del catálogo, y es el compilador de TODO el corpus"
+ },
+ {
+ "categoria": "empaquetadores de python",
+ "faltan": [
+ "pipx",
+ "poetry"
],
"items": [
{
- "estado": "tiene-y-viaja",
- "nombre": "cups",
+ "estado": "falta",
+ "nombre": "pipx",
"parientes": []
},
{
- "estado": "revisar",
- "nombre": "cups-filters",
+ "estado": "tiene-sin-viajar",
+ "nombre": "uv",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "poetry",
+ "parientes": []
+ }
+ ],
+ "porque": "pip no viaja y no hay forma de instalar una herramienta python"
+ },
+ {
+ "categoria": "construcción C clásica",
+ "faltan": [
+ "autoconf",
+ "automake",
+ "ninja"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "autoconf",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "automake",
"parientes": [
- "cups"
- ]
+ "make"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
},
{
"estado": "falta",
- "nombre": "ghostscript",
+ "nombre": "ninja",
+ "parientes": []
+ }
+ ],
+ "porque": "cmake, meson y make existen (sin viajar). ⚠ `gcc` está RETENIDO a propósito (sólo `gcc-libs`) y `clang` existe como `clang18`: eso NO es hueco, es decisión"
+ },
+ {
+ "categoria": "vpn y red gestionada",
+ "faltan": [
+ "openvpn",
+ "iwd",
+ "nmtui",
+ "impala",
+ "mosh",
+ "sshfs"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "openvpn",
"parientes": []
},
{
"estado": "falta",
- "nombre": "gutenprint",
+ "nombre": "iwd",
"parientes": []
},
{
"estado": "falta",
- "nombre": "hplip",
+ "nombre": "nmtui",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "impala",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "mosh",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "sshfs",
"parientes": []
}
],
- "porque": "cups solo no imprime: los filtros y los drivers son otro paquete"
+ "porque": "networkmanager, wireguard-tools y wpa_supplicant están"
},
{
- "categoria": "escanear",
+ "categoria": "bluetooth usable",
"faltan": [
- "sane-backends"
+ "blueman",
+ "bluetuith"
],
"items": [
{
"estado": "falta",
- "nombre": "sane-backends",
+ "nombre": "blueman",
"parientes": []
},
{
- "estado": "revisar",
- "nombre": "simple-scan",
- "parientes": [
- "simple-http-server"
- ]
+ "estado": "falta",
+ "nombre": "bluetuith",
+ "parientes": []
}
],
- "porque": "ningún camino hoy"
+ "porque": "`bluez` viaja; falta con qué emparejar un auricular"
},
{
- "categoria": "java",
+ "categoria": "contraseñas",
"faltan": [
- "openjdk",
- "jdk",
- "temurin"
+ "keepassxc",
+ "pass"
],
"items": [
{
"estado": "falta",
- "nombre": "openjdk",
+ "nombre": "keepassxc",
"parientes": []
},
{
"estado": "falta",
- "nombre": "jdk",
+ "nombre": "pass",
+ "parientes": []
+ },
+ {
+ "estado": "tiene-sin-viajar",
+ "nombre": "gopass",
+ "parientes": []
+ }
+ ],
+ "porque": "nada: la gente guarda sus claves en un .txt o no usa la distro"
+ },
+ {
+ "categoria": "respaldos",
+ "faltan": [
+ "borgbackup",
+ "rsnapshot"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "borgbackup",
"parientes": []
},
{
"estado": "falta",
- "nombre": "temurin",
+ "nombre": "rsnapshot",
"parientes": []
}
],
- "porque": "un ecosistema entero queda fuera sin una JVM"
+ "porque": "restic y rclone están"
},
{
- "categoria": "documentos técnicos",
+ "categoria": "descargas y torrent",
"faltan": [
- "texlive",
- "pandoc"
+ "aria2",
+ "transmission",
+ "qbittorrent"
],
"items": [
{
"estado": "falta",
- "nombre": "texlive",
+ "nombre": "aria2",
"parientes": []
},
{
"estado": "falta",
- "nombre": "pandoc",
+ "nombre": "transmission",
"parientes": []
},
{
- "estado": "tiene-sin-viajar",
- "nombre": "typst",
+ "estado": "falta",
+ "nombre": "qbittorrent",
"parientes": []
}
],
- "porque": "nada que componga un PDF desde texto marcado"
+ "porque": "curl y wget están"
},
{
- "categoria": "bases de datos de servidor",
+ "categoria": "navegadores",
"faltan": [
- "postgresql",
- "mariadb",
- "redis"
+ "chromium",
+ "qutebrowser",
+ "librewolf",
+ "brave"
],
"items": [
{
"estado": "falta",
- "nombre": "postgresql",
+ "nombre": "chromium",
"parientes": []
},
{
"estado": "falta",
- "nombre": "mariadb",
+ "nombre": "qutebrowser",
"parientes": []
},
{
"estado": "falta",
- "nombre": "redis",
+ "nombre": "librewolf",
"parientes": []
},
{
- "estado": "tiene-sin-viajar",
- "nombre": "valkey",
+ "estado": "falta",
+ "nombre": "brave",
"parientes": []
}
],
- "porque": "sqlite está; un servicio con varios clientes no"
+ "porque": "firefox y atuq están; el motor Blink no tiene ningún camino"
},
{
- "categoria": "contenedores",
+ "categoria": "mensajería",
"faltan": [
- "podman",
- "docker",
- "buildah",
- "flatpak"
+ "dino",
+ "gajim",
+ "element-desktop",
+ "telegram-desktop",
+ "signal-desktop"
],
"items": [
{
"estado": "falta",
- "nombre": "podman",
+ "nombre": "dino",
"parientes": []
},
{
"estado": "falta",
- "nombre": "docker",
+ "nombre": "gajim",
"parientes": []
},
{
"estado": "falta",
- "nombre": "buildah",
+ "nombre": "element-desktop",
"parientes": []
},
{
"estado": "falta",
- "nombre": "flatpak",
+ "nombre": "telegram-desktop",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "signal-desktop",
"parientes": []
}
],
- "porque": "`crun` está (el motor); falta quien lo conduzca"
+ "porque": "ningún cliente de chat: ni XMPP, ni Matrix, ni los propietarios"
},
{
- "categoria": "virtualización",
+ "categoria": "música",
"faltan": [
- "qemu",
- "libvirt",
- "virt-manager"
+ "mpd",
+ "ncmpcpp",
+ "rhythmbox",
+ "audacious"
],
"items": [
{
"estado": "falta",
- "nombre": "qemu",
+ "nombre": "mpd",
"parientes": []
},
{
"estado": "falta",
- "nombre": "libvirt",
+ "nombre": "ncmpcpp",
"parientes": []
},
{
"estado": "falta",
- "nombre": "virt-manager",
+ "nombre": "rhythmbox",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "audacious",
"parientes": []
}
],
- "porque": "ni invitado ni anfitrión"
+ "porque": "mpv y cmus están para reproducir un fichero; falta biblioteca y daemon"
},
{
- "categoria": "archivos comprimidos ajenos",
+ "categoria": "video",
"faltan": [
- "unzip",
- "zip",
- "p7zip",
- "7zip",
- "unrar"
+ "vlc",
+ "celluloid",
+ "totem"
],
"items": [
{
"estado": "falta",
- "nombre": "unzip",
+ "nombre": "vlc",
"parientes": []
},
{
"estado": "falta",
- "nombre": "zip",
+ "nombre": "celluloid",
"parientes": []
},
{
"estado": "falta",
- "nombre": "p7zip",
+ "nombre": "totem",
+ "parientes": []
+ }
+ ],
+ "porque": "mpv está"
+ },
+ {
+ "categoria": "imagen y diseño",
+ "faltan": [
+ "gimp",
+ "inkscape",
+ "krita",
+ "darktable"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "gimp",
"parientes": []
},
{
"estado": "falta",
- "nombre": "7zip",
+ "nombre": "inkscape",
"parientes": []
},
{
"estado": "falta",
- "nombre": "unrar",
+ "nombre": "krita",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "darktable",
"parientes": []
}
],
- "porque": "no se puede abrir un .zip, un .7z ni un .rar — un adjunto cualquiera queda cerrado"
+ "porque": "⚠ la suite ArtCraft propia cubre esto con 12 apps (photocraft, vectorcraft, …): estos renglones son los nombres AJENOS que alguien busca, no un hueco de capacidad"
},
{
- "categoria": "vpn y red gestionada",
+ "categoria": "gestores de archivos",
"faltan": [
- "openvpn",
- "iwd"
+ "thunar",
+ "ranger"
],
"items": [
{
- "estado": "tiene-y-viaja",
- "nombre": "networkmanager",
+ "estado": "falta",
+ "nombre": "thunar",
"parientes": []
},
{
- "estado": "tiene-y-viaja",
- "nombre": "wireguard-tools",
+ "estado": "falta",
+ "nombre": "ranger",
+ "parientes": []
+ }
+ ],
+ "porque": "yazi, nnn, lf, broot y dolphin/nautilus están"
+ },
+ {
+ "categoria": "lectores de PDF",
+ "faltan": [
+ "mupdf",
+ "sioyek",
+ "evince"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "mupdf",
"parientes": []
},
{
"estado": "falta",
- "nombre": "openvpn",
+ "nombre": "sioyek",
"parientes": []
},
{
"estado": "falta",
- "nombre": "iwd",
+ "nombre": "evince",
+ "parientes": []
+ }
+ ],
+ "porque": "zathura y okular están"
+ },
+ {
+ "categoria": "notas",
+ "faltan": [
+ "obsidian",
+ "logseq",
+ "joplin",
+ "zettlr"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "obsidian",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "logseq",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "joplin",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "zettlr",
+ "parientes": []
+ }
+ ],
+ "porque": "ninguno"
+ },
+ {
+ "categoria": "otros compositores Wayland",
+ "faltan": [
+ "hyprland",
+ "river",
+ "niri",
+ "labwc",
+ "wayfire"
+ ],
+ "items": [
+ {
+ "estado": "falta",
+ "nombre": "hyprland",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "river",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "niri",
+ "parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "labwc",
+ "parientes": [
+ "lab"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ },
+ {
+ "estado": "falta",
+ "nombre": "wayfire",
"parientes": []
}
],
- "porque": "networkmanager y wireguard están; el resto no"
+ "porque": "hay cinco escritorios (mirada, sway, cosmic, gnome, kde); éstos son los que la gente nombra y no están. Decisión de alcance, no olvido"
},
{
"categoria": "juegos",
"faltan": [
"wine",
+ "steam",
"gamescope",
- "lutris"
+ "lutris",
+ "mangohud"
],
"items": [
{
@@ -388,12 +1302,13 @@
"parientes": []
},
{
- "estado": "revisar",
+ "estado": "falta",
"nombre": "steam",
"parientes": [
"steam-runtime-sniper",
"steampipe"
- ]
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
},
{
"estado": "falta",
@@ -404,44 +1319,56 @@
"estado": "falta",
"nombre": "lutris",
"parientes": []
+ },
+ {
+ "estado": "falta",
+ "nombre": "mangohud",
+ "parientes": []
}
],
- "porque": "decisión abierta, no un olvido"
+ "porque": "decisión abierta: arrastra Vulkan, que la distro hoy no publica"
},
{
- "categoria": "discos y salud del equipo",
+ "categoria": "infra ajena",
"faltan": [
- "smartmontools",
- "nvme-cli",
- "hdparm"
+ "terraform",
+ "ansible"
],
"items": [
{
- "estado": "falta",
- "nombre": "smartmontools",
+ "estado": "tiene-sin-viajar",
+ "nombre": "kubectl",
"parientes": []
},
{
- "estado": "falta",
- "nombre": "nvme-cli",
+ "estado": "tiene-sin-viajar",
+ "nombre": "helm",
"parientes": []
},
{
"estado": "falta",
- "nombre": "hdparm",
+ "nombre": "terraform",
+ "parientes": [
+ "terraform-docs",
+ "terraform-ls"
+ ],
+ "pista": "nombre parecido en el catálogo (verificar, NO es equivalencia)"
+ },
+ {
+ "estado": "falta",
+ "nombre": "ansible",
"parientes": []
}
],
- "porque": "nada que avise de un disco muriéndose"
+ "porque": "decisión abierta: son herramientas de operar OTRA cosa"
}
],
"en_alguna_imagen": 592,
"recetas_alcanzables": 1375,
"resumen": {
- "falta": 45,
- "revisar": 3,
- "tiene-sin-viajar": 2,
- "tiene-y-viaja": 4
+ "falta": 152,
+ "tiene-sin-viajar": 12,
+ "tiene-y-viaja": 6
},
"schema": "takana-censo-distro/1"
}
diff --git a/scripts/censo-distro.py b/scripts/censo-distro.py
index a766584d..13dcd067 100755
--- a/scripts/censo-distro.py
+++ b/scripts/censo-distro.py
@@ -19,11 +19,18 @@ es cada renglón: si hay receta (en el catálogo, en una cola o en `tandas/`) y
imagen. Agregar o quitar un renglón es una decisión de producto; el guion sólo dice en qué estado
está lo que alguien ya decidió que importa.
-⚠ **Y no cuenta un hueco sin antes buscar un PARIENTE de nombre.** Es el error que este censo cometió en su
-primera versión y que ya había costado dos veces el mismo día: decir «falta `clang`» cuando existe
-`clang18`, «falta `rustc`» cuando existe `rust`, «falta `neomutt`» cuando existe `mutt`. Un hueco
-con un pariente cerca sale como `revisar`, nunca como `falta` — porque la diferencia entre las dos
-palabras es la que hace que alguien trabaje de más.
+⚠ **EL PARENTESCO DE NOMBRE ES UNA PISTA, NO UN VEREDICTO — y esto se corrigió DOS VECES.**
+
+La v1 cantaba huecos falsos: «falta `clang`» con `clang18` en el catálogo, «falta `rustc`» con
+`rust`, «falta `neomutt`» con `mutt`. Se arregló buscando un pariente de nombre y sacando esos
+renglones del recuento… y eso fue **peor**, porque entonces el censo escondía huecos REALES:
+`neovim` salía como «revisar → vim» (y neovim falta de verdad: existe `bob-nvim`, su gestor de
+versiones, sin neovim), `swaync` → `sway`, `patchelf` → `patch`, `man-pages` → `mandoc` (que es el
+LECTOR, no el contenido).
+
+⇒ **Un pariente ANOTA, no absuelve.** Un candidato sin receta cuenta como `falta`, siempre; si hay
+un nombre parecido se añade como `pista` para que nadie repita la búsqueda. Las dos formas de
+mentir tienen el mismo antídoto: que la pista viaje al lado del hueco en vez de reemplazarlo.
Uso: censo-distro.py [--json docs/state/distro-huecos.json]
"""
@@ -39,9 +46,10 @@ sys.path.insert(0, os.path.join(RAIZ, 'scripts'))
# Cada entrada: categoría → (por_qué_importa, [nombres candidatos]).
# El «por qué» no es adorno: un renglón sin motivo se discute para siempre.
CHECKLIST = {
+ # ── LO QUE DEJA A GENTE AFUERA ──────────────────────────────────────────────────────────────
'escritura del mundo': (
- 'sin estas fuentes la distro muestra cuadraditos en chino, japonés, coreano, árabe, hindi, '
- 'tailandés y emoji — o sea para la mayor parte de la humanidad',
+ 'las únicas fuentes del corpus son dejavu y su nerd: sin estas, la distro muestra '
+ 'cuadraditos en chino, japonés, coreano, árabe, hindi, tailandés y emoji',
['noto-fonts-cjk', 'noto-fonts-emoji', 'noto-fonts', 'noto-fonts-extra']),
'escribir en esos idiomas': (
'una fuente deja LEER; para ESCRIBIR hace falta un método de entrada',
@@ -49,26 +57,102 @@ CHECKLIST = {
'accesibilidad': (
'sin lector de pantalla ni voz la distro es inusable para quien no ve',
['orca', 'speech-dispatcher', 'espeak-ng', 'brltty']),
- 'imprimir de verdad': (
- 'cups solo no imprime: los filtros y los drivers son otro paquete',
- ['cups', 'cups-filters', 'ghostscript', 'gutenprint', 'hplip']),
+
+ # ── LO QUE ALGUIEN BUSCA EL PRIMER DÍA ──────────────────────────────────────────────────────
+ 'terminales populares': (
+ '`foot` está y alcanza; pero quien llega de otra distro busca el suyo por nombre, y el '
+ 'doc 20 §II.2 ya los listaba como «barato». kitty: 13 de sus 14 deps ya están en el '
+ 'catálogo (falta librsync, opcional)',
+ ['kitty', 'alacritty', 'wezterm', 'ghostty', 'xterm']),
+ 'editores': (
+ '`vim` y `helix` están. ⚠ Existe `bob-nvim` —el GESTOR DE VERSIONES de neovim— y no '
+ 'existe neovim: el conductor sin el motor, como `crun` sin podman',
+ ['neovim', 'emacs', 'micro', 'kakoune', 'nano']),
+ 'shells': ('bash, zsh y nushell están', ['fish', 'elvish']),
+ 'lanzador, notificaciones y bloqueo': (
+ 'el esqueleto de un escritorio Wayland que no sea GNOME/KDE: sin lanzador no se abre nada',
+ ['rofi', 'wofi', 'fuzzel', 'bemenu', 'tofi', 'mako', 'dunst', 'swaync', 'swaylock',
+ 'gtklock', 'waylock']),
+ 'audio de escritorio': (
+ 'PipeWire suena y no hay con qué subirle el volumen desde una ventana',
+ ['pavucontrol', 'pamixer', 'playerctl', 'easyeffects', 'wiremix']),
+ 'capturas y portapapeles': ('grim, slurp, wl-clipboard y cliphist ya están',
+ ['satty', 'swappy', 'flameshot', 'wtype', 'kanshi']),
+ 'visores de imagen': ('ninguno: una foto no se abre',
+ ['imv', 'nsxiv', 'feh', 'loupe', 'eog']),
+
+ # ── CAPACIDADES ENTERAS SIN NINGÚN CAMINO ───────────────────────────────────────────────────
+ 'archivos comprimidos ajenos': (
+ 'no se puede abrir un .zip, un .7z ni un .rar — un adjunto cualquiera queda cerrado. '
+ '`libzip` es una BIBLIOTECA, no el comando',
+ ['unzip', 'zip', 'p7zip', '7zip', 'unrar']),
+ 'imprimir de verdad': ('cups solo no imprime: los filtros y los drivers son otro paquete',
+ ['cups', 'cups-filters', 'ghostscript', 'gutenprint', 'hplip']),
'escanear': ('ningún camino hoy', ['sane-backends', 'simple-scan']),
- 'java': ('un ecosistema entero queda fuera sin una JVM', ['openjdk', 'jdk', 'temurin']),
'documentos técnicos': ('nada que componga un PDF desde texto marcado',
- ['texlive', 'pandoc', 'typst']),
+ ['texlive', 'pandoc', 'typst', 'groff']),
+ 'páginas de manual': ('`mandoc` LEE man; falta el CONTENIDO y el formateador de info',
+ ['man-pages', 'texinfo']),
+ 'virtualización': ('ni invitado ni anfitrión: no se puede probar la propia ISO sin salir',
+ ['qemu', 'libvirt', 'virt-manager']),
+ 'contenedores': ('`crun` está (el motor); falta quien lo conduzca',
+ ['podman', 'docker', 'buildah', 'flatpak', 'distrobox']),
+ 'java': ('un ecosistema entero queda fuera sin una JVM', ['openjdk', 'jdk', 'temurin']),
'bases de datos de servidor': ('sqlite está; un servicio con varios clientes no',
['postgresql', 'mariadb', 'redis', 'valkey']),
- 'contenedores': ('`crun` está (el motor); falta quien lo conduzca',
- ['podman', 'docker', 'buildah', 'flatpak']),
- 'virtualización': ('ni invitado ni anfitrión', ['qemu', 'libvirt', 'virt-manager']),
- 'archivos comprimidos ajenos': ('no se puede abrir un .zip, un .7z ni un .rar — un adjunto '
- 'cualquiera queda cerrado',
- ['unzip', 'zip', 'p7zip', '7zip', 'unrar']),
- 'vpn y red gestionada': ('networkmanager y wireguard están; el resto no',
- ['networkmanager', 'wireguard-tools', 'openvpn', 'iwd']),
- 'juegos': ('decisión abierta, no un olvido', ['wine', 'steam', 'gamescope', 'lutris']),
+ 'depurar y medir': ('se construye la distro entera y no hay con qué mirar un core',
+ ['gdb', 'lldb', 'valgrind', 'ltrace', 'perf', 'patchelf']),
'discos y salud del equipo': ('nada que avise de un disco muriéndose',
- ['smartmontools', 'nvme-cli', 'hdparm']),
+ ['smartmontools', 'nvme-cli', 'hdparm', 'gparted']),
+
+ # ── LENGUAJES Y HERRAMIENTAS DE CONSTRUCCIÓN ────────────────────────────────────────────────
+ 'otros lenguajes': (
+ 'python3, lua, go, rust y perl están. ⚠ `zig` NO es receta: vive como artefacto '
+ '`seed-zig` fuera del catálogo, y es el compilador de TODO el corpus',
+ ['nodejs', 'deno', 'bun', 'ruby', 'php', 'julia', 'ghc', 'ocaml', 'elixir', 'erlang']),
+ 'empaquetadores de python': ('pip no viaja y no hay forma de instalar una herramienta python',
+ ['pipx', 'uv', 'poetry']),
+ 'construcción C clásica': (
+ 'cmake, meson y make existen (sin viajar). ⚠ `gcc` está RETENIDO a propósito (sólo '
+ '`gcc-libs`) y `clang` existe como `clang18`: eso NO es hueco, es decisión',
+ ['autoconf', 'automake', 'ninja']),
+
+ # ── RED, SEGURIDAD, DATOS ───────────────────────────────────────────────────────────────────
+ 'vpn y red gestionada': ('networkmanager, wireguard-tools y wpa_supplicant están',
+ ['openvpn', 'iwd', 'nmtui', 'impala', 'mosh', 'sshfs']),
+ 'bluetooth usable': ('`bluez` viaja; falta con qué emparejar un auricular',
+ ['blueman', 'bluetuith']),
+ 'contraseñas': ('nada: la gente guarda sus claves en un .txt o no usa la distro',
+ ['keepassxc', 'pass', 'gopass']),
+ 'respaldos': ('restic y rclone están', ['borgbackup', 'rsnapshot']),
+ 'descargas y torrent': ('curl y wget están', ['aria2', 'transmission', 'qbittorrent']),
+
+ # ── APLICACIONES DE ESCRITORIO ──────────────────────────────────────────────────────────────
+ 'navegadores': ('firefox y atuq están; el motor Blink no tiene ningún camino',
+ ['chromium', 'qutebrowser', 'librewolf', 'brave']),
+ 'mensajería': ('ningún cliente de chat: ni XMPP, ni Matrix, ni los propietarios',
+ ['dino', 'gajim', 'element-desktop', 'telegram-desktop', 'signal-desktop']),
+ 'música': ('mpv y cmus están para reproducir un fichero; falta biblioteca y daemon',
+ ['mpd', 'ncmpcpp', 'rhythmbox', 'audacious']),
+ 'video': ('mpv está', ['vlc', 'celluloid', 'totem']),
+ 'imagen y diseño': (
+ '⚠ la suite ArtCraft propia cubre esto con 12 apps (photocraft, vectorcraft, …): estos '
+ 'renglones son los nombres AJENOS que alguien busca, no un hueco de capacidad',
+ ['gimp', 'inkscape', 'krita', 'darktable']),
+ 'gestores de archivos': ('yazi, nnn, lf, broot y dolphin/nautilus están',
+ ['thunar', 'ranger']),
+ 'lectores de PDF': ('zathura y okular están', ['mupdf', 'sioyek', 'evince']),
+ 'notas': ('ninguno', ['obsidian', 'logseq', 'joplin', 'zettlr']),
+
+ # ── DECISIONES ABIERTAS, NO OLVIDOS ─────────────────────────────────────────────────────────
+ 'otros compositores Wayland': (
+ 'hay cinco escritorios (mirada, sway, cosmic, gnome, kde); éstos son los que la gente '
+ 'nombra y no están. Decisión de alcance, no olvido',
+ ['hyprland', 'river', 'niri', 'labwc', 'wayfire']),
+ 'juegos': ('decisión abierta: arrastra Vulkan, que la distro hoy no publica',
+ ['wine', 'steam', 'gamescope', 'lutris', 'mangohud']),
+ 'infra ajena': ('decisión abierta: son herramientas de operar OTRA cosa',
+ ['kubectl', 'helm', 'terraform', 'ansible']),
}
@@ -85,7 +169,7 @@ def nombres_conocidos():
def clasificar(cand, conocidos, en_imagen):
- """`tiene` (y si viaja) · `revisar` (hay un pariente) · `falta` (ni por subcadena)."""
+ """`tiene-y-viaja` · `tiene-sin-viajar` · `falta` (+ pistas de nombre parecido, que NO absuelven)."""
if cand in conocidos:
return ('tiene-y-viaja' if cand in en_imagen else 'tiene-sin-viajar'), []
raiz = cand.split('-')[0]
@@ -98,7 +182,7 @@ def clasificar(cand, conocidos, en_imagen):
cerca = sorted(x for x in conocidos
if (len(raiz) >= 3 and x.startswith(raiz))
or (len(x) >= 3 and (cand.startswith(x) or cand.endswith(x))))
- return ('revisar' if cerca else 'falta'), cerca[:4]
+ return 'falta', cerca[:4]
def main():
@@ -110,7 +194,7 @@ def main():
conocidos = nombres_conocidos()
en_imagen = {n for (c, n) in yupana.membresia_imagen() if c != 'wanted'}
- filas, resumen = [], {'tiene-y-viaja': 0, 'tiene-sin-viajar': 0, 'revisar': 0, 'falta': 0}
+ filas, resumen = [], {'tiene-y-viaja': 0, 'tiene-sin-viajar': 0, 'falta': 0}
for cat, (porque, cands) in CHECKLIST.items():
items = []
for c in cands:
@@ -119,6 +203,9 @@ def main():
items.append({'nombre': c, 'estado': estado, 'parientes': cerca})
filas.append({'categoria': cat, 'porque': porque, 'items': items,
'faltan': [i['nombre'] for i in items if i['estado'] == 'falta']})
+ for i in items:
+ if i['estado'] == 'falta' and i['parientes']:
+ i['pista'] = 'nombre parecido en el catálogo (verificar, NO es equivalencia)'
print('== qué le falta a la distro para usarse (checklist de JUICIO, estado MEDIDO) ==')
print(' recetas alcanzables: %d · de ellas en alguna imagen: %d'
@@ -128,11 +215,12 @@ def main():
print(' %s %-28s %d/%d falta%s' % (marca, f['categoria'], len(f['faltan']),
len(f['items']),
': ' + ', '.join(f['faltan']) if f['faltan'] else 'n'))
- rev = [(i['nombre'], i['parientes']) for f in filas for i in f['items'] if i['estado'] == 'revisar']
+ rev = [(i['nombre'], i['parientes']) for f in filas for i in f['items']
+ if i['estado'] == 'falta' and i['parientes']]
if rev:
- print(' — a REVISAR (hay un pariente, no se cuentan como hueco):')
+ print(' — PISTAS: falta, pero hay un nombre parecido (verificar; NO es equivalencia):')
for n, p in rev:
- print(' %-20s → %s' % (n, ', '.join(p)))
+ print(' %-20s ~ %s' % (n, ', '.join(p)))
print(' resumen: %s' % json.dumps(resumen, ensure_ascii=False))
if a.json: