Rafael Lopez

test done

......@@ -27,3 +27,7 @@ claude.md
# Docs internos
static/ESTILOS_*.md
.Rproj.user
# Data
/data
......
......@@ -32,10 +32,7 @@
<div class="fixed top-4 right-4 z-[110] md:hidden">
<button
onclick={onOpenDrawer}
class="p-2 rounded-full transition-all flex-shrink-0"
style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
class="nav-icon p-2 rounded-full transition-all flex-shrink-0"
aria-label="Abrir menú"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
......@@ -52,10 +49,7 @@
<div class="relative group/home">
<a
href="/"
class="p-2 rounded-full transition-all block"
style="background-color: transparent; color: var(--theme-texto);"
onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
class="nav-icon p-2 rounded-full transition-all block"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<rect x="2" y="2" width="7" height="7" rx="1.5"/>
......@@ -75,10 +69,7 @@
<div class="relative group/theme">
<button
onclick={toggleTheme}
class="p-2 rounded-full transition-all"
style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
class="nav-icon p-2 rounded-full transition-all cursor-pointer"
aria-label={isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
>
{#if isDark}
......@@ -104,10 +95,7 @@
<div class="relative group/menu">
<button
onclick={onOpenDrawer}
class="p-2 rounded-full transition-all"
style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
class="nav-icon p-2 rounded-full transition-all cursor-pointer"
aria-label="Abrir menú"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
......@@ -123,3 +111,23 @@
</div>
</div>
<style>
/* Iconos del navbar */
.nav-icon {
background-color: transparent;
color: #8A8578;
transition: color 0.2s ease;
}
.nav-icon:hover {
color: #F5F0E8;
}
/* Modo claro */
:global(html:not(.dark)) .nav-icon {
color: #333333;
}
:global(html:not(.dark)) .nav-icon:hover {
color: #1A1A18;
}
</style>
......
......@@ -202,15 +202,12 @@
{/if}
<!-- Controles: Theme Toggle + Menú -->
<div class="flex items-center gap-1">
<div class="header-controls">
<!-- Theme Toggle (solo desktop) -->
<div class="relative group/theme hidden md:block">
<button
onclick={toggleTheme}
class="p-2 rounded-full transition-all"
style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
class="nav-icon p-2 rounded-full transition-all"
aria-label={isDarkMode ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
>
{#if isDarkMode}
......@@ -234,10 +231,7 @@
<div class="relative group/menu">
<button
onclick={openDrawer}
class="p-2 rounded-full transition-all"
style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
class="nav-icon p-2 rounded-full transition-all"
aria-label="Abrir menú"
>
<svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
......@@ -465,6 +459,32 @@
}
.mefp-logo:hover { opacity: 1; }
/* Header controls */
.header-controls {
display: flex;
align-items: center;
gap: 4px;
}
/* Nav icon styling - matching Navbar */
.nav-icon {
background-color: transparent;
color: #8A8578;
cursor: pointer;
transition: color 0.2s ease;
}
.nav-icon:hover {
color: #F5F0E8;
}
/* Light mode */
:global(html:not(.dark)) .nav-icon {
color: #333333;
}
:global(html:not(.dark)) .nav-icon:hover {
color: #1A1A18;
}
/* Fade in animation */
.fade-in {
opacity: 0;
......@@ -617,13 +637,33 @@
}
.search-bar {
display: flex; align-items: center;
background: var(--theme-surface); border: 1px solid var(--theme-borde);
background: transparent;
border: none;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 12px; padding: 6px 24px;
transition: all 0.4s cubic-bezier(0.16, 1, 0.3, 1);
}
.search-focused { background: var(--theme-fill); }
.search-bar:hover {
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.15);
}
.search-bar.search-focused,
.search-bar.search-focused:hover {
box-shadow: inset 0 0 0 1px var(--theme-accent);
}
.search-has-results { border-radius: 12px 12px 0 0; }
/* Light mode search bar */
:global(html:not(.dark)) .search-bar {
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
}
:global(html:not(.dark)) .search-bar:hover {
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.15);
}
:global(html:not(.dark)) .search-bar.search-focused,
:global(html:not(.dark)) .search-bar.search-focused:hover {
box-shadow: inset 0 0 0 1px var(--theme-accent);
}
.search-bar input {
flex: 1; background: transparent; border: none; outline: none;
color: var(--theme-titulo); font-size: 16px; font-family: 'DM Sans', sans-serif;
......@@ -643,10 +683,14 @@
.search-loading {
position: absolute; top: 100%; left: 0; right: 0;
background: var(--theme-surface); border: 1px solid var(--theme-borde); border-top: none;
background: var(--theme-body);
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 0 0 14px 14px; padding: 12px 24px;
font-family: 'DM Sans', sans-serif; font-size: 13px; color: var(--theme-texto);
}
:global(html:not(.dark)) .search-loading {
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
}
.search-error {
margin-top: 8px; font-family: 'DM Sans', sans-serif;
......@@ -656,10 +700,14 @@
/* Suggestions / Results */
.suggestions {
position: absolute; top: 100%; left: 0; right: 0;
background: var(--theme-surface); border: 1px solid var(--theme-borde); border-top: none;
background: var(--theme-body);
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 0 0 14px 14px; overflow: hidden; z-index: 100;
max-height: 320px; overflow-y: auto;
}
:global(html:not(.dark)) .suggestions {
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
}
.suggestions.no-results { padding: 16px 24px; }
.no-results-text {
font-family: 'DM Sans', sans-serif; font-size: 14px; color: var(--theme-texto);
......@@ -670,8 +718,11 @@
padding: 12px 24px; display: flex; justify-content: space-between;
align-items: center; cursor: pointer; transition: background 0.2s;
}
.suggestion-item:hover, .suggestion-selected { background: var(--theme-fill); }
.suggestion-border { border-top: 1px solid var(--theme-borde); }
.suggestion-item:hover, .suggestion-selected { background: rgba(255,255,255,0.05); }
.suggestion-border { border-top: 1px solid rgba(255,255,255,0.06); }
:global(html:not(.dark)) .suggestion-item:hover,
:global(html:not(.dark)) .suggestion-selected { background: rgba(0,0,0,0.03); }
:global(html:not(.dark)) .suggestion-border { border-top: 1px solid rgba(0,0,0,0.06); }
.suggestion-main { display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0; }
.suggestion-label {
......
......@@ -34,6 +34,8 @@
let selectedEntity = $state(null); // null = Todo el Estado
let entitySearchQuery = $state('');
let entityDropdownOpen = $state(false);
let levelDropdownOpen = $state(false);
let yearDropdownOpen = $state(false);
// Estado para modo comparar
let compareA = $state({ year: null, entity: null });
......@@ -672,6 +674,12 @@
if (entityDropdownOpen && !e.target.closest('.entity-dropdown-container')) {
entityDropdownOpen = false;
}
if (levelDropdownOpen && !e.target.closest('.level-dropdown-container')) {
levelDropdownOpen = false;
}
if (yearDropdownOpen && !e.target.closest('.year-dropdown-container')) {
yearDropdownOpen = false;
}
if (compareADropdownOpen && !e.target.closest('.compare-a-dropdown')) {
compareADropdownOpen = false;
}
......@@ -969,41 +977,69 @@
{#if viewMode === 'mapa'}
<div class="flex flex-wrap items-center gap-3 flex-shrink-0">
<!-- Selector de nivel -->
<div class="flex items-center gap-2">
<label for="level-select" class="text-xs uppercase tracking-wide" style="font-family: 'DM Mono', monospace; color: var(--theme-texto);">Vista</label>
<select
id="level-select"
bind:value={treemapViewLevel}
class="px-3 py-1.5 text-sm rounded-lg focus:outline-none focus:ring-2 cursor-pointer"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
>
{#each NIVEL_OPTIONS as opt}
<option value={opt.value}>{opt.label}</option>
{/each}
</select>
<div class="flex items-center gap-2 level-dropdown-container">
<label class="text-xs uppercase tracking-wide" style="font-family: 'DM Mono', monospace; color: var(--theme-texto);">Vista</label>
<div class="relative">
<button
class="dropdown-control px-3 py-1.5 text-sm rounded-lg focus:outline-none min-w-[140px] text-left flex items-center justify-between gap-2"
onclick={() => { levelDropdownOpen = !levelDropdownOpen; yearDropdownOpen = false; entityDropdownOpen = false; }}
>
<span class="truncate">{NIVEL_OPTIONS.find(o => o.value === treemapViewLevel)?.label || 'Seleccionar'}</span>
<svg class="w-4 h-4 shrink-0" style="color: var(--theme-texto);" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
{#if levelDropdownOpen}
<div class="dropdown-panel absolute top-full left-0 mt-1 w-52 rounded-lg shadow-lg z-50 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
{#each NIVEL_OPTIONS as opt}
<button
class="w-full text-left px-3 py-2 text-sm hover:bg-black/5 dark:hover:bg-white/5"
style="{treemapViewLevel === opt.value ? `background-color: color-mix(in srgb, var(--theme-accent) 15%, transparent);` : ``} color: var(--theme-titulo);"
onclick={() => { treemapViewLevel = opt.value; levelDropdownOpen = false; }}
>
<span class="font-medium">{opt.label}</span>
<span class="block text-xs mt-0.5" style="color: var(--theme-texto);">{opt.desc}</span>
</button>
{/each}
</div>
{/if}
</div>
</div>
<div class="flex items-center gap-2">
<label for="year-select" class="text-xs uppercase tracking-wide" style="font-family: 'DM Mono', monospace; color: var(--theme-texto);">Año</label>
<select
id="year-select"
bind:value={selectedYear}
class="px-3 py-1.5 text-sm rounded-lg focus:outline-none focus:ring-2 cursor-pointer"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
>
{#each availableYears as year}
<option value={year}>{year}</option>
{/each}
</select>
<div class="flex items-center gap-2 year-dropdown-container">
<label class="text-xs uppercase tracking-wide" style="font-family: 'DM Mono', monospace; color: var(--theme-texto);">Año</label>
<div class="relative">
<button
class="dropdown-control px-3 py-1.5 text-sm rounded-lg focus:outline-none min-w-[80px] text-left flex items-center justify-between gap-2"
onclick={() => { yearDropdownOpen = !yearDropdownOpen; levelDropdownOpen = false; entityDropdownOpen = false; }}
>
<span>{selectedYear || 'Año'}</span>
<svg class="w-4 h-4 shrink-0" style="color: var(--theme-texto);" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7" />
</svg>
</button>
{#if yearDropdownOpen}
<div class="dropdown-panel absolute top-full left-0 mt-1 w-24 rounded-lg shadow-lg z-50 max-h-64 overflow-y-auto" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
{#each availableYears as year}
<button
class="w-full text-left px-3 py-2 text-sm hover:bg-black/5 dark:hover:bg-white/5"
style="{selectedYear === year ? `background-color: color-mix(in srgb, var(--theme-accent) 15%, transparent);` : ``} color: var(--theme-titulo);"
onclick={() => { selectedYear = year; yearDropdownOpen = false; }}
>
{year}
</button>
{/each}
</div>
{/if}
</div>
</div>
<div class="flex items-center gap-2 entity-dropdown-container">
<label class="text-xs uppercase tracking-wide" style="font-family: 'DM Mono', monospace; color: var(--theme-texto);">Entidad</label>
<div class="relative">
<button
class="px-3 py-1.5 text-sm rounded-lg focus:outline-none focus:ring-2 min-w-[180px] text-left flex items-center justify-between gap-2"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
onclick={() => entityDropdownOpen = !entityDropdownOpen}
class="dropdown-control px-3 py-1.5 text-sm rounded-lg focus:outline-none min-w-[180px] text-left flex items-center justify-between gap-2"
onclick={() => { entityDropdownOpen = !entityDropdownOpen; levelDropdownOpen = false; yearDropdownOpen = false; }}
>
<span class="truncate">
{#if selectedEntity}
......@@ -1018,7 +1054,7 @@
</button>
{#if entityDropdownOpen}
<div class="absolute top-full left-0 mt-1 w-80 rounded-lg shadow-lg z-50 max-h-72 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
<div class="dropdown-panel absolute top-full right-0 mt-1 w-80 rounded-lg shadow-lg z-50 max-h-72 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
<div class="p-2 border-b" style="border-color: var(--theme-borde);">
<input
type="text"
......@@ -1703,8 +1739,7 @@
<!-- Año A -->
<select
bind:value={compareA.year}
class="px-3 py-2 text-sm rounded-lg focus:outline-none focus:ring-2 cursor-pointer font-medium"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
class="dropdown-control px-3 py-2 text-sm rounded-lg focus:outline-none cursor-pointer font-medium"
>
{#each availableYears as year}
<option value={year}>{year}</option>
......@@ -1714,8 +1749,7 @@
<!-- Entidad A -->
<div class="relative compare-a-dropdown">
<button
class="px-3 py-2 text-sm rounded-lg focus:outline-none focus:ring-2 min-w-[200px] text-left flex items-center justify-between gap-2"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
class="dropdown-control px-3 py-2 text-sm rounded-lg focus:outline-none min-w-[200px] text-left flex items-center justify-between gap-2"
onclick={() => compareADropdownOpen = !compareADropdownOpen}
>
<span class="truncate font-medium">
......@@ -1731,7 +1765,7 @@
</button>
{#if compareADropdownOpen}
<div class="absolute top-full left-0 mt-1 w-80 rounded-lg shadow-lg z-50 max-h-72 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
<div class="dropdown-panel absolute top-full left-0 mt-1 w-80 rounded-lg shadow-lg z-50 max-h-72 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
<div class="p-2 border-b" style="border-color: var(--theme-borde);">
<input
type="text"
......@@ -1803,8 +1837,7 @@
<!-- Año B -->
<select
bind:value={compareB.year}
class="px-3 py-2 text-sm rounded-lg focus:outline-none focus:ring-2 cursor-pointer font-medium"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
class="dropdown-control px-3 py-2 text-sm rounded-lg focus:outline-none cursor-pointer font-medium"
>
{#each availableYears as year}
<option value={year}>{year}</option>
......@@ -1814,8 +1847,7 @@
<!-- Entidad B -->
<div class="relative compare-b-dropdown">
<button
class="px-3 py-2 text-sm rounded-lg focus:outline-none focus:ring-2 min-w-[200px] text-left flex items-center justify-between gap-2"
style="border: 1px solid var(--theme-borde); background-color: var(--theme-surface); color: var(--theme-titulo);"
class="dropdown-control px-3 py-2 text-sm rounded-lg focus:outline-none min-w-[200px] text-left flex items-center justify-between gap-2"
onclick={() => compareBDropdownOpen = !compareBDropdownOpen}
>
<span class="truncate font-medium">
......@@ -1831,7 +1863,7 @@
</button>
{#if compareBDropdownOpen}
<div class="absolute top-full left-0 mt-1 w-80 rounded-lg shadow-lg z-50 max-h-72 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
<div class="dropdown-panel absolute top-full left-0 mt-1 w-80 rounded-lg shadow-lg z-50 max-h-72 overflow-hidden" style="background-color: var(--theme-surface); border: 1px solid var(--theme-borde);">
<div class="p-2 border-b" style="border-color: var(--theme-borde);">
<input
type="text"
......@@ -1961,6 +1993,41 @@
{/if}
<style>
/* Dropdown controls - tema oscuro por defecto */
.dropdown-control {
border: 1px solid var(--theme-borde);
background-color: var(--theme-surface);
color: var(--theme-titulo);
transition: box-shadow 0.2s ease, border-color 0.2s ease;
}
.dropdown-control:focus {
box-shadow: 0 0 0 2px var(--theme-accent);
}
/* Tema claro: transparente + ring sutil */
:global(.light) .dropdown-control,
:global(html:not(.dark)) .dropdown-control {
background: transparent;
border: none;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
}
:global(.light) .dropdown-control:focus,
:global(html:not(.dark)) .dropdown-control:focus {
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.15);
}
:global(.light) .dropdown-control:hover,
:global(html:not(.dark)) .dropdown-control:hover {
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.12);
}
/* Dropdown panels en tema claro */
:global(.light) .dropdown-panel,
:global(html:not(.dark)) .dropdown-panel {
background: #FAFAF8 !important;
border: none !important;
box-shadow: 0 4px 20px rgba(0,0,0,0.08), inset 0 0 0 1px rgba(0,0,0,0.08) !important;
}
/* Sidebar izquierdo: con fondo en móvil, transparente en desktop */
.sidebar-left {
background-color: var(--theme-surface);
......
......@@ -2,292 +2,384 @@
import { onMount } from 'svelte';
import { tweened } from 'svelte/motion';
import { cubicOut } from 'svelte/easing';
import { supabase } from '$lib/supabase';
// ══════════════════════════════════════════════════════════════
// ESTADO GENERAL
// ══════════════════════════════════════════════════════════════
let mounted = $state(false);
let loading = $state(true);
let hoveredYear = $state(null);
let showInfo = $state(false);
let vista = $state('agregado'); // 'agregado' | 'comparar'
let isDark = $state(true);
// Objeto actual (hardcoded por ahora, luego vendrá de URL)
const objetoCodigo = '10000';
const objetoNivel = 'grupo';
// Info del objeto
let objeto = $state({
codigo: '10000',
nombre: 'Servicios Personales',
nivel: 'Grupo',
años: '2005-2025',
descripcion: 'Gastos por concepto de servicios prestados por el personal permanente y no permanente del sector público.'
});
let mounted = false;
let hoveredYear = null;
let hoveredYearComparar = null;
let showInfo = false;
let vista = 'agregado'; // 'agregado' | 'comparar'
let isDark = true;
let entidadA = 0;
let entidadB = 1;
// ══════════════════════════════════════════════════════════════
// ESTADO SELECTOR DE ENTIDAD
// ══════════════════════════════════════════════════════════════
let entidades = $state([]); // Lista de entidades disponibles
let selectedEntity = $state(null); // null = Todo el Estado
let entitySearchQuery = $state('');
let entityDropdownOpen = $state(false);
// Filtrar entidades por búsqueda
let filteredEntities = $derived.by(() => {
if (!entitySearchQuery || entitySearchQuery.length < 2) {
return entidades.slice(0, 20);
}
const q = entitySearchQuery.toLowerCase();
return entidades
.filter(e =>
e.entidad_desc?.toLowerCase().includes(q) ||
e.entidad?.toString().includes(q)
)
.slice(0, 30);
});
onMount(() => {
setTimeout(() => { mounted = true; }, 50);
function selectEntity(entity) {
selectedEntity = entity;
entityDropdownOpen = false;
entitySearchQuery = '';
loadData();
}
function clearEntity() {
selectedEntity = null;
entityDropdownOpen = false;
entitySearchQuery = '';
loadData();
}
// ══════════════════════════════════════════════════════════════
// DATOS DE SUPABASE
// ══════════════════════════════════════════════════════════════
let datosAnuales = $state([]); // Datos por año
let datosHistorico = $state(null); // Fila con gestion=0
let topEntidadesPorAño = $state({}); // Top 3 por año (solo para Todo el Estado)
// Cargar datos según selección
async function loadData() {
loading = true;
if (selectedEntity) {
// Cargar desde vista_objeto_entidad
const { data, error } = await supabase
.schema('ppto')
.from('vista_objeto_entidad')
.select('*')
.eq('objeto', objetoCodigo)
.eq('nivel', objetoNivel)
.eq('entidad', selectedEntity.entidad)
.order('gestion');
if (data) {
datosHistorico = data.find(d => d.gestion === 0) || null;
datosAnuales = data.filter(d => d.gestion > 0);
topEntidadesPorAño = {}; // No hay top entidades cuando se filtra por entidad
}
} else {
// Cargar desde vista_objeto_estado (Todo el Estado)
const { data, error } = await supabase
.schema('ppto')
.from('vista_objeto_estado')
.select('*')
.eq('objeto', objetoCodigo)
.order('gestion');
if (data) {
datosHistorico = data.find(d => d.gestion === 0) || null;
datosAnuales = data.filter(d => d.gestion > 0);
// Construir top entidades por año
topEntidadesPorAño = {};
datosAnuales.forEach(d => {
topEntidadesPorAño[d.gestion] = [
{ nombre: d.top1_entidad, monto: d.top1_monto, porcentaje: d.top1_pct },
{ nombre: d.top2_entidad, monto: d.top2_monto, porcentaje: d.top2_pct },
{ nombre: d.top3_entidad, monto: d.top3_monto, porcentaje: d.top3_pct },
].filter(e => e.nombre);
});
}
}
// Leer estado del tema
isDark = document.documentElement.classList.contains('dark');
loading = false;
}
// Observar cambios de tema
const observer = new MutationObserver(() => {
isDark = document.documentElement.classList.contains('dark');
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
// Cargar lista de entidades disponibles para este objeto
async function loadEntidades() {
const { data, error } = await supabase
.schema('ppto')
.from('entidades_por_objeto')
.select('entidad, entidad_desc')
.eq('objeto', objetoCodigo)
.eq('nivel', objetoNivel)
.order('entidad_desc');
return () => observer.disconnect();
});
if (data) {
entidades = data;
}
}
// ══════════════════════════════════════════════════════════════
// VALORES DERIVADOS
// ══════════════════════════════════════════════════════════════
// Dummy data
const objeto = {
codigo: '10000',
nombre: 'Servicios Personales',
nivel: 'Grupo',
años: '2005-2024',
descripcion: 'Gastos por concepto de servicios prestados por el personal permanente y no permanente del sector público.',
variaciones: [
{ rango: '2012-2024', texto: 'Gastos por concepto de servicios prestados por el personal permanente y no permanente.' },
{ rango: '2005-2011', texto: 'Retribuciones y complementos al personal permanente y eventual.' }
]
};
// Dummy spending data (in millions Bs, population in millions)
const gastoAnual = [
{ año: 2005, monto: 8200, poblacion: 9.4 },
{ año: 2006, monto: 8900, poblacion: 9.5 },
{ año: 2007, monto: 10200, poblacion: 9.6 },
{ año: 2008, monto: 12400, poblacion: 9.8 },
{ año: 2009, monto: 13100, poblacion: 9.9 },
{ año: 2010, monto: 14800, poblacion: 10.0 },
{ año: 2011, monto: 17200, poblacion: 10.2 },
{ año: 2012, monto: 19500, poblacion: 10.4 },
{ año: 2013, monto: 22800, poblacion: 10.5 },
{ año: 2014, monto: 28400, poblacion: 10.7 },
{ año: 2015, monto: 31200, poblacion: 10.9 },
{ año: 2016, monto: 33100, poblacion: 11.0 },
{ año: 2017, monto: 35600, poblacion: 11.2 },
{ año: 2018, monto: 38200, poblacion: 11.4 },
{ año: 2019, monto: 41500, poblacion: 11.5 },
{ año: 2020, monto: 39800, poblacion: 11.7 },
{ año: 2021, monto: 42100, poblacion: 11.8 },
{ año: 2022, monto: 45600, poblacion: 12.0 },
{ año: 2023, monto: 48900, poblacion: 12.1 },
{ año: 2024, monto: 52300, poblacion: 12.3 },
];
// Datos para el gráfico (monto o per_capita según preferencia)
let gastoPerCapita = $derived(
datosAnuales.map(d => ({
año: d.gestion,
monto: selectedEntity ? d.monto : d.total,
perCapita: d.per_capita
}))
);
// Calculate per capita for each year
const gastoPerCapita = gastoAnual.map(g => ({
...g,
perCapita: Math.round(g.monto / g.poblacion)
}));
// Top entidades por año (dummy data)
const topEntidadesPorAño = {
2020: [
{ nombre: 'Ministerio de Educación', monto: 12500, porcentaje: 31.4 },
{ nombre: 'Ministerio de Salud', monto: 7800, porcentaje: 19.6 },
{ nombre: 'Policía Boliviana', monto: 4200, porcentaje: 10.6 },
],
2021: [
{ nombre: 'Ministerio de Educación', monto: 13200, porcentaje: 31.4 },
{ nombre: 'Ministerio de Salud', monto: 8100, porcentaje: 19.2 },
{ nombre: 'Policía Boliviana', monto: 4600, porcentaje: 10.9 },
],
2022: [
{ nombre: 'Ministerio de Educación', monto: 14800, porcentaje: 32.5 },
{ nombre: 'Ministerio de Salud', monto: 8400, porcentaje: 18.4 },
{ nombre: 'Policía Boliviana', monto: 5100, porcentaje: 11.2 },
],
2023: [
{ nombre: 'Ministerio de Educación', monto: 16200, porcentaje: 33.1 },
{ nombre: 'Ministerio de Salud', monto: 8700, porcentaje: 17.8 },
{ nombre: 'Policía Boliviana', monto: 5700, porcentaje: 11.7 },
],
2024: [
{ nombre: 'Ministerio de Educación', monto: 18200, porcentaje: 34.8 },
{ nombre: 'Ministerio de Salud', monto: 8900, porcentaje: 17.0 },
{ nombre: 'Policía Boliviana', monto: 6200, porcentaje: 11.9 },
],
};
// Total histórico (para cuando no hay hover)
const topEntidadesTotal = [
{ nombre: 'Ministerio de Educación', monto: 74900, porcentaje: 32.6 },
{ nombre: 'Ministerio de Salud', monto: 41900, porcentaje: 18.4 },
{ nombre: 'Policía Boliviana', monto: 25800, porcentaje: 11.3 },
];
let maxPerCapita = $derived(
gastoPerCapita.length > 0 ? Math.max(...gastoPerCapita.map(g => g.perCapita)) : 1
);
// Datos para comparación (dummy)
const entidadesComparables = [
{
id: 0,
nombre: 'Ministerio de Educación',
color: '#E8C547',
datos: [
{ año: 2020, monto: 12500, perCapita: 1068 },
{ año: 2021, monto: 13200, perCapita: 1119 },
{ año: 2022, monto: 14800, perCapita: 1233 },
{ año: 2023, monto: 16200, perCapita: 1339 },
{ año: 2024, monto: 18200, perCapita: 1480 },
],
total: 74900,
promedioPerCapita: 1248,
porcentajeObjeto: 34.8,
ranking: 1
},
{
id: 1,
nombre: 'Ministerio de Salud',
color: '#4A8B6E',
datos: [
{ año: 2020, monto: 6800, perCapita: 581 },
{ año: 2021, monto: 7200, perCapita: 610 },
{ año: 2022, monto: 7900, perCapita: 658 },
{ año: 2023, monto: 8400, perCapita: 694 },
{ año: 2024, monto: 8900, perCapita: 724 },
],
total: 39200,
promedioPerCapita: 653,
porcentajeObjeto: 17.0,
ranking: 2
},
{
id: 2,
nombre: 'Policía Boliviana',
color: '#8B5CF6',
datos: [
{ año: 2020, monto: 4200, perCapita: 359 },
{ año: 2021, monto: 4600, perCapita: 390 },
{ año: 2022, monto: 5100, perCapita: 425 },
{ año: 2023, monto: 5700, perCapita: 471 },
{ año: 2024, monto: 6200, perCapita: 504 },
],
total: 25800,
promedioPerCapita: 430,
porcentajeObjeto: 11.9,
ranking: 3
},
{
id: 3,
nombre: 'Gobierno Autónomo de Santa Cruz',
color: '#F97316',
datos: [
{ año: 2020, monto: 3100, perCapita: 265 },
{ año: 2021, monto: 3400, perCapita: 288 },
{ año: 2022, monto: 3800, perCapita: 317 },
{ año: 2023, monto: 4100, perCapita: 339 },
{ año: 2024, monto: 4500, perCapita: 366 },
],
total: 18900,
promedioPerCapita: 315,
porcentajeObjeto: 8.6,
ranking: 4
// Histórico
let totalHistorico = $derived(datosHistorico ? (selectedEntity ? datosHistorico.monto : datosHistorico.total) : 0);
let promedioPerCapita = $derived(datosHistorico?.per_capita || 0);
let totalPorcentaje = $derived(datosHistorico?.prop || 0);
let ranking = $derived(datosHistorico?.ranking || 0);
let nPares = $derived(datosHistorico?.n_pares || 0);
let nEntidades = $derived(datosHistorico?.n_entidades || 0);
// Número de entidades - cambia según el año seleccionado y la entidad seleccionada
let totalEntidadesHistorico = $derived.by(() => {
if (selectedEntity && datosAnuales.length > 0) {
// Para entidad seleccionada: promedio de n_entidades de los años que tiene esta entidad
// Esto refleja cuántas entidades participaron durante el período de vida de esta entidad
const suma = datosAnuales.reduce((acc, d) => acc + (d.n_entidades || 0), 0);
return Math.round(suma / datosAnuales.length);
}
];
// Para "Todo el Estado": usar la lista del dropdown o el histórico
return entidades.length || nEntidades;
});
// Colores fijos por posición - teal y naranja
$: colorA = '#2a9d8f'; // teal
$: colorB = '#f4a261'; // naranja
let totalEntidades = $derived.by(() => {
if (hoveredYear) {
// Buscar n_entidades del año específico
const añoData = datosAnuales.find(d => d.gestion === hoveredYear);
return añoData?.n_entidades || totalEntidadesHistorico;
}
return totalEntidadesHistorico;
});
$: entA = entidadesComparables[entidadA];
$: entB = entidadesComparables[entidadB];
$: maxComparacion = Math.max(
...entA.datos.map(d => d.perCapita),
...entB.datos.map(d => d.perCapita)
);
$: años = entA.datos.map(d => d.año);
// Para el ranking: valores reactivos según hover
let displayRankingValue = $derived.by(() => {
if (hoveredYear) {
const añoData = datosAnuales.find(d => d.gestion === hoveredYear);
return añoData?.ranking || ranking;
}
return ranking;
});
// Datos de comparación según hover
$: hoveredDataA = hoveredYearComparar
? entA.datos.find(d => d.año === hoveredYearComparar)
: null;
$: hoveredDataB = hoveredYearComparar
? entB.datos.find(d => d.año === hoveredYearComparar)
: null;
let rankingDenominador = $derived.by(() => {
if (selectedEntity) {
// Para entidad: usar n_entidades del año específico o del histórico
if (hoveredYear) {
const añoData = datosAnuales.find(d => d.gestion === hoveredYear);
return añoData?.n_entidades || nEntidades;
}
// Sin hover: usar el n_entidades del histórico (total de entidades únicas del período)
return nEntidades;
}
// Para "Todo el Estado": comparación entre objetos del mismo nivel
return nPares;
});
$: displayMontoA = hoveredDataA ? hoveredDataA.monto : entA.total;
$: displayMontoLabelA = hoveredDataA ? `gasto en ${hoveredYearComparar}` : 'gasto 2020-2024';
$: displayPerCapitaA = hoveredDataA ? hoveredDataA.perCapita : entA.promedioPerCapita;
$: displayPerCapitaLabelA = hoveredDataA ? `por persona en ${hoveredYearComparar}` : 'por persona (prom.)';
// Top entidades histórico (solo para Todo el Estado)
let topEntidadesTotal = $derived(
datosHistorico && !selectedEntity ? [
{ nombre: datosHistorico.top1_entidad, monto: datosHistorico.top1_monto, porcentaje: datosHistorico.top1_pct },
{ nombre: datosHistorico.top2_entidad, monto: datosHistorico.top2_monto, porcentaje: datosHistorico.top2_pct },
{ nombre: datosHistorico.top3_entidad, monto: datosHistorico.top3_monto, porcentaje: datosHistorico.top3_pct },
].filter(e => e.nombre) : []
);
$: displayMontoB = hoveredDataB ? hoveredDataB.monto : entB.total;
$: displayMontoLabelB = hoveredDataB ? `gasto en ${hoveredYearComparar}` : 'gasto 2020-2024';
$: displayPerCapitaB = hoveredDataB ? hoveredDataB.perCapita : entB.promedioPerCapita;
$: displayPerCapitaLabelB = hoveredDataB ? `por persona en ${hoveredYearComparar}` : 'por persona (prom.)';
// Años disponibles
let primerAño = $derived(gastoPerCapita.length > 0 ? gastoPerCapita[0].año : 2005);
let ultimoAño = $derived(gastoPerCapita.length > 0 ? gastoPerCapita[gastoPerCapita.length - 1].año : 2025);
$: displayPeriodoComparar = hoveredYearComparar ? hoveredYearComparar : '2020-2024';
// Current view data (changes on hover)
let currentData = $derived(
hoveredYear ? gastoPerCapita.find(g => g.año === hoveredYear) : null
);
let displayMonto = $derived(currentData ? currentData.monto : totalHistorico);
let displayMontoLabel = $derived(currentData ? `gasto en ${currentData.año}` : `gasto ${primerAño}-${ultimoAño}`);
let displayPerCapita = $derived(currentData ? currentData.perCapita : promedioPerCapita);
let displayPerCapitaLabel = $derived(currentData ? `por persona en ${currentData.año}` : 'por persona (promedio)');
let displayPorcentaje = $derived(
currentData && totalHistorico > 0
? (totalPorcentaje * (currentData.monto / (totalHistorico / gastoPerCapita.length))).toFixed(1)
: totalPorcentaje
);
let displayPorcentajeLabel = $derived(currentData ? `del gasto ${currentData.año}` : 'del gasto total');
let displayPeriodo = $derived(currentData ? currentData.año : `${primerAño}-${ultimoAño}`);
let displayRanking = $derived(`${displayRankingValue} de ${rankingDenominador}`);
let displayRankingLabel = $derived(
selectedEntity
? (currentData ? `entre las que más gastan en ${currentData.año}` : 'entre las que más gastan')
: (currentData ? `ranking en ${currentData.año}` : 'ranking entre grupos')
);
// Top entidades reactivo según hover
$: displayTopEntidades = hoveredYear && topEntidadesPorAño[hoveredYear]
? topEntidadesPorAño[hoveredYear]
: topEntidadesTotal;
$: displayTopLabel = hoveredYear ? `en ${hoveredYear}` : '2005-2024';
// Context data
const totalEntidades = 620;
const totalGrupos = 9; // Total grupos in objeto del gasto
// Calculations
const maxPerCapita = Math.max(...gastoPerCapita.map(g => g.perCapita));
const minPerCapita = Math.min(...gastoPerCapita.map(g => g.perCapita));
const totalHistorico = gastoAnual.reduce((sum, g) => sum + g.monto, 0);
const totalPoblacionAcum = gastoAnual.reduce((sum, g) => sum + g.poblacion, 0);
const promedioPerCapita = Math.round(totalHistorico / totalPoblacionAcum);
const totalPorcentaje = 14.2;
const ranking = 1;
let displayTopEntidades = $derived(
hoveredYear && topEntidadesPorAño[hoveredYear]
? topEntidadesPorAño[hoveredYear]
: topEntidadesTotal
);
let displayTopLabel = $derived(hoveredYear ? `en ${hoveredYear}` : `${primerAño}-${ultimoAño}`);
// Current view data (changes on hover)
$: currentData = hoveredYear
? gastoPerCapita.find(g => g.año === hoveredYear)
: null;
$: displayMonto = currentData ? currentData.monto : totalHistorico;
$: displayMontoLabel = currentData ? `gasto en ${currentData.año}` : 'gasto 2005-2024';
$: displayPerCapita = currentData ? currentData.perCapita : promedioPerCapita;
$: displayPerCapitaLabel = currentData ? `por persona en ${currentData.año}` : 'por persona (promedio)';
$: displayPorcentaje = currentData
? (totalPorcentaje * (currentData.monto / (totalHistorico / gastoAnual.length))).toFixed(1)
: totalPorcentaje;
$: displayPorcentajeLabel = currentData ? `del gasto ${currentData.año}` : 'del gasto total';
$: displayPeriodo = currentData ? currentData.año : '2005-2024';
$: displayRanking = `${ranking} de ${totalGrupos}`;
$: displayRankingLabel = currentData ? `ranking en ${currentData.año}` : 'ranking entre grupos';
// Tweened values para transiciones suaves
// ══════════════════════════════════════════════════════════════
// TWEENED VALUES
// ══════════════════════════════════════════════════════════════
const tweenOptions = { duration: 300, easing: cubicOut };
// Agregado
const twMonto = tweened(totalHistorico, tweenOptions);
const twPerCapita = tweened(promedioPerCapita, tweenOptions);
const twPorcentaje = tweened(totalPorcentaje, tweenOptions);
const twMonto = tweened(0, tweenOptions);
const twPerCapita = tweened(0, tweenOptions);
const twPorcentaje = tweened(0, tweenOptions);
const twTop1 = tweened(0, tweenOptions);
const twTop2 = tweened(0, tweenOptions);
const twTop3 = tweened(0, tweenOptions);
// Comparación
// Comparación (placeholder por ahora - TODO: implementar)
const twMontoA = tweened(0, tweenOptions);
const twMontoB = tweened(0, tweenOptions);
const twPerCapitaA = tweened(0, tweenOptions);
const twPerCapitaB = tweened(0, tweenOptions);
// Top entidades
const twTop1 = tweened(0, tweenOptions);
const twTop2 = tweened(0, tweenOptions);
const twTop3 = tweened(0, tweenOptions);
let hoveredYearComparar = $state(null);
let entidadA = $state(0);
let entidadB = $state(1);
let displayPeriodoComparar = $derived(
hoveredYearComparar ? hoveredYearComparar : `${años[0]}-${años[años.length - 1]}`
);
// Datos dummy para comparación (TODO: conectar a Supabase)
const entidadesComparables = [
{ id: 0, nombre: 'Entidad A', datos: [], porcentajeObjeto: 0, ranking: 1 },
{ id: 1, nombre: 'Entidad B', datos: [], porcentajeObjeto: 0, ranking: 2 }
];
let entA = $derived(entidadesComparables[entidadA] || entidadesComparables[0]);
let entB = $derived(entidadesComparables[entidadB] || entidadesComparables[1]);
let maxComparacion = $state(100);
let años = $state([2020, 2021, 2022, 2023, 2024]);
let colorA = '#2a9d8f';
let colorB = '#f4a261';
// Helper para asegurar que siempre tengamos un número
function toNumber(val) {
const n = parseFloat(val);
return isNaN(n) ? 0 : n;
}
// Actualizar tweened cuando cambian los valores
$: twMonto.set(displayMonto);
$: twPerCapita.set(displayPerCapita);
$: twPorcentaje.set(parseFloat(displayPorcentaje));
// Leemos TODAS las dependencias explícitamente para que el effect se re-ejecute
$effect(() => {
// Leer todas las dependencias primero (para que Svelte las trackee)
const year = hoveredYear;
const datos = gastoPerCapita; // Leer siempre
const histTotal = toNumber(totalHistorico);
const histPerCapita = toNumber(promedioPerCapita);
const histPorcentaje = toNumber(totalPorcentaje);
// Calcular valores
const data = year ? datos.find(g => g.año === year) : null;
const monto = toNumber(data ? data.monto : histTotal);
const perCapita = toNumber(data ? data.perCapita : histPerCapita);
const porcentaje = data && histTotal > 0
? toNumber((histPorcentaje * (data.monto / (histTotal / datos.length))).toFixed(1))
: histPorcentaje;
twMonto.set(monto);
twPerCapita.set(perCapita);
twPorcentaje.set(porcentaje);
});
$effect(() => {
// Leer todas las dependencias primero
const year = hoveredYear;
const topsPorAño = topEntidadesPorAño;
const topsTotal = topEntidadesTotal;
$: twMontoA.set(displayMontoA);
$: twMontoB.set(displayMontoB);
$: twPerCapitaA.set(displayPerCapitaA);
$: twPerCapitaB.set(displayPerCapitaB);
const tops = year && topsPorAño[year] ? topsPorAño[year] : topsTotal;
$: if (displayTopEntidades[0]) twTop1.set(displayTopEntidades[0].porcentaje);
$: if (displayTopEntidades[1]) twTop2.set(displayTopEntidades[1].porcentaje);
$: if (displayTopEntidades[2]) twTop3.set(displayTopEntidades[2].porcentaje);
twTop1.set(toNumber(tops?.[0]?.porcentaje));
twTop2.set(toNumber(tops?.[1]?.porcentaje));
twTop3.set(toNumber(tops?.[2]?.porcentaje));
});
// ══════════════════════════════════════════════════════════════
// MOUNT
// ══════════════════════════════════════════════════════════════
onMount(async () => {
setTimeout(() => { mounted = true; }, 50);
// Leer estado del tema
isDark = document.documentElement.classList.contains('dark');
// Observar cambios de tema
const observer = new MutationObserver(() => {
isDark = document.documentElement.classList.contains('dark');
});
observer.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class']
});
// Cargar datos
await Promise.all([loadData(), loadEntidades()]);
// Cerrar dropdown al hacer click fuera
const handleClickOutside = (e) => {
if (entityDropdownOpen && !e.target.closest('.entity-dropdown-container')) {
entityDropdownOpen = false;
}
};
document.addEventListener('click', handleClickOutside);
return () => {
observer.disconnect();
document.removeEventListener('click', handleClickOutside);
};
});
// ══════════════════════════════════════════════════════════════
// HELPERS
// ══════════════════════════════════════════════════════════════
function formatMonto(m) {
if (m >= 1000000) return (m / 1000000).toFixed(1) + 'B';
if (m >= 1000) return Math.round(m / 1000) + 'K';
return m.toLocaleString();
if (m >= 1e9) return (m / 1e9).toFixed(1) + 'MM';
if (m >= 1e6) return (m / 1e6).toFixed(1) + 'M';
if (m >= 1e3) return Math.round(m / 1e3) + 'K';
return m?.toLocaleString() || '0';
}
function formatMontoLargo(m) {
if (m >= 1000) return (m / 1000).toFixed(1) + 'MM';
return m.toLocaleString() + 'M';
if (m >= 1e9) return Math.round(m / 1e9).toLocaleString('es-BO') + ' mil Mill.';
if (m >= 1e6) return (m / 1e6).toLocaleString('es-BO', { minimumFractionDigits: 1, maximumFractionDigits: 1 }) + ' Mill.';
return m?.toLocaleString('es-BO', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) || '0';
}
function formatPerCapita(n) {
if (n >= 1000) return n.toLocaleString('es-BO', { minimumFractionDigits: 0, maximumFractionDigits: 0 });
if (n >= 10) return n.toLocaleString('es-BO', { minimumFractionDigits: 1, maximumFractionDigits: 1 });
if (n < 1) return n.toLocaleString('es-BO', { minimumFractionDigits: 2, maximumFractionDigits: 2 });
return n.toLocaleString('es-BO', { minimumFractionDigits: 1, maximumFractionDigits: 1 });
}
</script>
......@@ -310,7 +402,7 @@
<span class="codigo">{objeto.codigo}</span>
<h1>
{objeto.nombre}
<button class="help-icon" on:click={() => showInfo = !showInfo} class:active={showInfo}>
<button class="help-icon" onclick={() => showInfo = !showInfo} class:active={showInfo}>
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
<circle cx="12" cy="12" r="10"/>
<path d="M9.5 9a3 3 0 1 1 3.5 2.95c-.5.17-1 .62-1 1.3V15"/>
......@@ -355,14 +447,14 @@
<button
class="toggle-btn"
class:active={vista === 'agregado'}
on:click={() => vista = 'agregado'}
onclick={() => vista = 'agregado'}
>
Agregado
</button>
<button
class="toggle-btn"
class:active={vista === 'comparar'}
on:click={() => vista = 'comparar'}
onclick={() => vista = 'comparar'}
>
Comparar
</button>
......@@ -370,14 +462,60 @@
<!-- Selector de entidad (solo en vista agregado) -->
{#if vista === 'agregado'}
<div class="entity-selector">
<div class="entity-selector entity-dropdown-container">
<span class="selector-label">Viendo</span>
<button class="selector-btn">
Todo el sector público
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M6 9l6 6 6-6"/>
</svg>
</button>
<div class="relative">
<button
class="selector-btn"
onclick={() => entityDropdownOpen = !entityDropdownOpen}
>
<span class="truncate">
{#if selectedEntity}
{selectedEntity.entidad_desc?.slice(0, 30)}{selectedEntity.entidad_desc?.length > 30 ? '...' : ''}
{:else}
Todo el sector público
{/if}
</span>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
<path d="M6 9l6 6 6-6"/>
</svg>
</button>
{#if entityDropdownOpen}
<div class="dropdown-panel">
<div class="dropdown-search">
<input
type="text"
bind:value={entitySearchQuery}
placeholder="Buscar entidad..."
class="search-input"
/>
</div>
<button
class="dropdown-item"
class:active={!selectedEntity}
onclick={() => clearEntity()}
>
<span class="font-medium">Todo el sector público</span>
<span class="text-xs opacity-60 ml-2">({nEntidades} entidades)</span>
</button>
<div class="dropdown-list">
{#each filteredEntities as entity}
<button
class="dropdown-item"
class:active={selectedEntity?.entidad === entity.entidad}
onclick={() => selectEntity(entity)}
>
<span class="entity-code">{entity.entidad}</span>
<span class="truncate">{entity.entidad_desc}</span>
</button>
{/each}
</div>
</div>
{/if}
</div>
<span class="interaction-hint desktop-hint">Pasa el cursor sobre las barras para ver valores por año</span>
<span class="interaction-hint mobile-hint">Toca las barras para ver valores por año</span>
</div>
{/if}
......@@ -392,12 +530,12 @@
</div>
<div class="kpi">
<span class="kpi-value">Bs {Math.round($twPerCapita).toLocaleString()}</span>
<span class="kpi-value">Bs {formatPerCapita($twPerCapita)}</span>
<span class="kpi-label">{displayPerCapitaLabel}</span>
</div>
<div class="kpi">
<span class="kpi-value">{$twPorcentaje.toFixed(1)}%</span>
<span class="kpi-value">{$twPorcentaje.toLocaleString('es-BO', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}%</span>
<span class="kpi-label">{displayPorcentajeLabel}</span>
</div>
......@@ -424,13 +562,13 @@
<div
class="chart"
on:mouseleave={() => hoveredYear = null}
onmouseleave={() => hoveredYear = null}
role="group"
>
{#each gastoPerCapita as g}
<div
class="bar-container"
on:mouseenter={() => hoveredYear = g.año}
onmouseenter={() => hoveredYear = g.año}
role="button"
tabindex="0"
>
......@@ -448,28 +586,30 @@
</div>
</div>
<!-- Top entidades -->
<div class="top-section">
<div class="top-header">
<h3>Mayores ejecutores</h3>
<span class="top-context">{totalEntidades} entidades · {displayTopLabel}</span>
</div>
<!-- Top entidades (solo visible cuando es "Todo el Estado") -->
{#if !selectedEntity}
<div class="top-section">
<div class="top-header">
<h3>Mayores ejecutores</h3>
<span class="top-context">{totalEntidades} entidades · {displayTopLabel}</span>
</div>
<div class="top-list">
{#each displayTopEntidades as ent, i (ent.nombre)}
<div class="top-item">
<span class="top-rank">#{i + 1}</span>
<div class="top-info">
<span class="top-name">{ent.nombre}</span>
<div class="top-bar-bg">
<div class="top-bar" style="width: {((i === 0 ? $twTop1 : i === 1 ? $twTop2 : $twTop3) / $twTop1) * 100}%"></div>
<div class="top-list">
{#each displayTopEntidades as ent, i (ent.nombre)}
<div class="top-item">
<span class="top-rank">#{i + 1}</span>
<div class="top-info">
<span class="top-name">{ent.nombre}</span>
<div class="top-bar-bg">
<div class="top-bar" style="width: {((i === 0 ? $twTop1 : i === 1 ? $twTop2 : $twTop3) / $twTop1) * 100}%"></div>
</div>
</div>
<span class="top-pct">{(i === 0 ? $twTop1 : i === 1 ? $twTop2 : $twTop3).toFixed(1)}%</span>
</div>
<span class="top-pct">{(i === 0 ? $twTop1 : i === 1 ? $twTop2 : $twTop3).toFixed(1)}%</span>
</div>
{/each}
{/each}
</div>
</div>
</div>
{/if}
{:else}
<!-- VISTA COMPARAR -->
......@@ -511,14 +651,14 @@
<div
class="chart chart-comparar"
on:mouseleave={() => hoveredYearComparar = null}
onmouseleave={() => hoveredYearComparar = null}
role="group"
>
{#each años as año, i}
<div
class="bar-group"
class:active={hoveredYearComparar === año}
on:mouseenter={() => hoveredYearComparar = año}
onmouseenter={() => hoveredYearComparar = año}
role="button"
tabindex="0"
>
......@@ -738,6 +878,31 @@
align-items: center;
gap: 0.75rem;
margin-bottom: 0.75rem;
flex-wrap: wrap;
}
.interaction-hint {
font-size: 0.688rem;
color: #5A5650;
font-style: italic;
margin-left: auto;
}
.desktop-hint {
display: inline;
}
.mobile-hint {
display: none;
}
@media (max-width: 640px) {
.desktop-hint {
display: none;
}
.mobile-hint {
display: inline;
}
}
.selector-label {
......@@ -750,8 +915,9 @@
align-items: center;
gap: 0.5rem;
padding: 0.5rem 1rem;
background: #161614;
border: 1px solid #2E2E2C;
background: transparent;
border: none;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 8px;
color: #F5F0E8;
font-size: 0.875rem;
......@@ -759,12 +925,92 @@
transition: all 0.2s;
}
.selector-btn:hover {
border-color: #E8C547;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.15);
}
.selector-btn svg {
color: #5A5650;
}
.relative {
position: relative;
}
.dropdown-panel {
position: absolute;
top: 100%;
left: 0;
margin-top: 0.25rem;
width: min(500px, 90vw);
max-height: 360px;
overflow: hidden;
background: #1A1A18;
border: 1px solid #2E2E2C;
border-radius: 8px;
box-shadow: 0 10px 40px rgba(0,0,0,0.4);
z-index: 50;
}
.dropdown-search {
padding: 0.5rem;
border-bottom: 1px solid #2E2E2C;
}
.search-input {
width: 100%;
padding: 0.5rem 0.75rem;
background: #111110;
border: 1px solid #2E2E2C;
border-radius: 6px;
color: #F5F0E8;
font-size: 0.875rem;
}
.search-input:focus {
outline: none;
border-color: #E8C547;
}
.search-input::placeholder {
color: #5A5650;
}
.dropdown-item {
display: flex;
align-items: center;
gap: 0.5rem;
width: 100%;
padding: 0.625rem 0.75rem;
background: transparent;
border: none;
color: #F5F0E8;
font-size: 0.813rem;
text-align: left;
cursor: pointer;
transition: background 0.15s;
}
.dropdown-item:hover {
background: rgba(255,255,255,0.05);
}
.dropdown-item.active {
background: rgba(232,197,71,0.15);
}
.dropdown-list {
max-height: 240px;
overflow-y: auto;
}
.entity-code {
font-family: 'DM Mono', monospace;
font-size: 0.688rem;
color: #5A5650;
min-width: 2.5rem;
}
.truncate {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
/* Chart */
.chart-section {
margin-bottom: 1rem;
......@@ -868,7 +1114,7 @@
}
.bar.hovered {
background: #264653;
background: #E8C547;
transform: scaleX(1.1);
}
......@@ -891,11 +1137,12 @@
}
.kpi {
background: #131312;
background: transparent;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
padding: 0.75rem 0.75rem;
text-align: center;
border-radius: 8px;
transition: background 0.3s ease;
transition: box-shadow 0.3s ease;
}
.kpi-value {
......@@ -958,8 +1205,14 @@
align-items: center;
gap: 0.75rem;
padding: 0.625rem 0.875rem;
background: #131312;
background: transparent;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 8px;
transition: box-shadow 0.25s ease;
}
.top-item:hover {
box-shadow: inset 0 0 0 1px rgba(201, 167, 81, 0.4);
}
.top-rank {
......@@ -989,9 +1242,13 @@
.top-bar {
height: 100%;
background: #2a9d8f;
background: #C9A751;
border-radius: 2px;
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1);
transition: width 0.35s cubic-bezier(0.4, 0, 0.2, 1), background 0.25s ease;
}
.top-item:hover .top-bar {
background: #E8C547;
}
.top-pct {
......@@ -1025,8 +1282,8 @@
/* Vista Toggle */
.vista-toggle {
display: inline-flex;
background: #131312;
border: 1px solid #2E2E2C;
background: transparent;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 10px;
padding: 4px;
margin-bottom: 0.75rem;
......@@ -1077,8 +1334,9 @@
.selector-group select {
flex: 1;
background: #1A1A18;
border: 1px solid #2E2E2C;
background: transparent;
border: none;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 8px;
padding: 0.5rem 0.75rem;
color: #F5F0E8;
......@@ -1179,7 +1437,8 @@
/* KPIs comparativos - tabla */
.kpis-tabla {
background: #131312;
background: transparent;
box-shadow: inset 0 0 0 1px rgba(255,255,255,0.08);
border-radius: 10px;
padding: 0.5rem 1rem;
}
......@@ -1388,8 +1647,8 @@
}
.tema-claro .vista-toggle {
background: #F0F0EC;
border-color: #E5E5E0;
background: transparent;
box-shadow: inset 0 0 0 1px rgba(0,0,0,0.08);
}
.tema-claro .toggle-btn {
......@@ -1407,6 +1666,10 @@
color: #8A8578;
}
.tema-claro .interaction-hint {
color: #8A8578;
}
.tema-claro .selector-btn {
background: transparent;
border: none;
......@@ -1420,6 +1683,41 @@
color: #8A8578;
}
.tema-claro .dropdown-panel {
background: #FAFAF8;
border-color: #E5E5E0;
}
.tema-claro .dropdown-search {
border-bottom-color: #E5E5E0;
}
.tema-claro .search-input {
background: #F5F5F3;
border-color: #E5E5E0;
color: #1A1A18;
}
.tema-claro .search-input:focus {
border-color: #C9A227;
}
.tema-claro .search-input::placeholder {
color: #8A8578;
}
.tema-claro .dropdown-item {
color: #1A1A18;
}
.tema-claro .dropdown-item:hover {
background: rgba(0,0,0,0.03);
}
.tema-claro .dropdown-item.active {
background: rgba(201,162,39,0.12);
}
.tema-claro .entity-code {
color: #8A8578;
}
.tema-claro .chart-title {
color: #8A8578;
}
......@@ -1441,7 +1739,7 @@
}
.tema-claro .bar-container .bar.hovered {
background: #264653;
background: #C9A751;
}
/* Las barras de comparación mantienen su --bar-color */
......@@ -1497,7 +1795,15 @@
}
.tema-claro .top-bar {
background: #2a9d8f;
background: #C9A751;
}
.tema-claro .top-item:hover {
box-shadow: inset 0 0 0 1px rgba(201, 167, 81, 0.5);
}
.tema-claro .top-item:hover .top-bar {
background: #B8963F;
}
.tema-claro .top-pct {
......
gestion,objeto_grupo,poblacion,top1_entidad_desc_entidad,top2_entidad_desc_entidad,top3_entidad_desc_entidad,top1_monto,top2_monto,top3_monto,top1_per_capita,top2_per_capita,top3_per_capita
2005,1,9475861,Prefectura Del Departamento De La Paz,Ministerio De Defensa Nacional,Prefectura Del Departamento De Santa Cruz,2165989973.2400002,905520472.9100002,783374374.3100002,229,96,83
2005,2,9475861,Municipalidad De La Paz,Servicio Nacional De Caminos,Municipalidad De Santa Cruz De La Sierra,318052922.3799999,262671532.11,239287121.05999997,34,28,25
2005,3,9475861,Yacimientos Petroliferos Fiscales Bolivianos,Ministerio De Gobierno,Ministerio De Defensa Nacional,484404998.67,180713886.04,173790141.18999997,51,19,18
2005,4,9475861,Servicio Nacional De Caminos,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,1602531309.59,426412889.85000026,382531081.14000034,169,45,40
2005,5,9475861,Caja Petrolera De Salud,Secretaría Ejecutiva - Pl 480,Ministerio De Desarrollo Económico,78565985.56999998,54276791.55,40008080,8,6,4
2005,6,9475861,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,Municipalidad De Cochabamba,665938007.79,657951217.52,169294372.42000002,70,69,18
2005,8,9475861,Ministerio De Salud Y Deportes,Ministerio De Gobierno,Ministerio De Asuntos Campesinos Y Agropecuarios,28920132.529999997,22942835.43,20474175.640000004,3,2,2
2005,9,9475861,Municipalidad De Santa Cruz De La Sierra,Ministerio De Hacienda,Ministerio De Salud Y Deportes,32578836.83,28846336.569999993,10778676.76,3,3,1
2006,1,9586372,Prefectura Del Departamento De La Paz,Prefectura Del Departamento De Cochabamba,Ministerio De Defensa Nacional,2521168290.18,1453310487.180001,958445497.76,263,152,100
2006,2,9586372,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,"Ministerio Desarrollo Rural, Agropecuario Y Medio Ambiente",386921568.65,373646357.0700001,335461208.43000007,40,39,35
2006,3,9586372,Yacimientos Petroliferos Fiscales Bolivianos,Ministerio De Gobierno,Ministerio De Defensa Nacional,3688964112.9000006,191526679.58999985,185658779.26999998,385,20,19
2006,4,9586372,Servicio Nacional De Caminos,Prefectura Del Departamento De Cochabamba,Municipalidad De Santa Cruz De La Sierra,1137837735.4099996,968591768.2700002,698595527.3600003,119,101,73
2006,5,9586372,"Ministerio De Obras Públicas, Servicios Y Vivienda",Caja Petrolera De Salud,Municipalidad De Yacuiba,282218297.76,72856150.11,63875244.99,29,8,7
2006,6,9586372,Municipalidad De La Paz,Municipalidad De Cochabamba,Municipalidad De Santa Cruz De La Sierra,462669962.51,288088976.76000005,158705430.61000004,48,30,17
2006,8,9586372,Yacimientos Petroliferos Fiscales Bolivianos,Ministerio De Gobierno,Ministerio De Salud Y Deportes,21867029.55,14706981.85,11468759,2,2,1
2006,9,9586372,Ministerio De Hacienda,Municipalidad De Santa Cruz De La Sierra,Municipalidad De Cochabamba,18617331.94,14999868.350000001,7530275.42,2,2,1
2007,1,9701623,Prefectura Del Departamento De La Paz,Prefectura Del Departamento De Santa Cruz,Prefectura Del Departamento De Cochabamba,2793147580.559999,2142569168.739999,1632277442.7800004,288,221,168
2007,2,9701623,Yacimientos Petrolíferos Fiscales Bolivianos,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,6865924650.49,570437686.4999995,413919119.86999947,708,59,43
2007,3,9701623,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalurgica Vinto - Nacionalizada,Ministerio De Defensa Nacional,7975908085.859999,739852915,299348102.3900001,822,76,31
2007,4,9701623,Prefectura Del Departamento De Tarija,Administradora Boliviana De Carreteras,Municipalidad De Santa Cruz De La Sierra,1754016115.350001,1664453307.4500003,912613170.5799996,181,172,94
2007,5,9701623,Yacimientos Petrolíferos Fiscales Bolivianos,"Ministerio De Obras Públicas, Servicios Y Vivienda",Ministerio De Educación Y Culturas,875200000,323258427.12,293981501.01,90,33,30
2007,6,9701623,Municipalidad De La Paz,Empresa Metalurgica Vinto - Nacionalizada,Municipalidad De Cochabamba,328357628.21,212924215.28,199598641.12,34,22,21
2007,8,9701623,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalurgica Vinto - Nacionalizada,Corporación Minera De Bolivia,6108127707.92,78096547.46,57274853.559999995,630,8,6
2007,9,9701623,Ministerio De Planificación Del Desarrollo,Fondo Nacional De Desarrollo Regional,Universidad Técnica Del Beni Mariscal José Ballivián,23223678.370000005,10374204.82,7515221.790000001,2,1,1
2008,1,9794695,Prefectura Del Departamento De La Paz,Prefectura Del Departamento De Santa Cruz,Prefectura Del Departamento De Cochabamba,3304344591.9199996,2440880970.3999987,1879310925.0499995,337,249,192
2008,2,9794695,Yacimientos Petrolíferos Fiscales Bolivianos,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,10540777751.59,832618443.9699998,486105833.6400003,1076,85,50
2008,3,9794695,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Empresa De Apoyo A La Producción De Alimentos,12750659412.59,553722043.84,323532907.1,1302,57,33
2008,4,9794695,Administradora Boliviana De Carreteras,Municipalidad De Santa Cruz De La Sierra,Prefectura Del Departamento De Tarija,1784228297.3000002,1399548427.8799996,1343000284.6599998,182,143,137
2008,5,9794695,Yacimientos Petrolíferos Fiscales Bolivianos,"Ministerio De Obras Públicas, Servicios Y Vivienda",Ministerio De Educación Y Culturas,971747928.51,510793167.83,375442575.77,99,52,38
2008,6,9794695,Yacimientos Petrolíferos Fiscales Bolivianos,Municipalidad De La Paz,Administradora Boliviana De Carreteras,3224810049.3399997,315244661.84,255818640.30000004,329,32,26
2008,8,9794695,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Ministerio De Gobierno,13519956258.039999,37036040.6,18330223.33,1380,4,2
2008,9,9794695,Administradora Boliviana De Carreteras,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,113603369.12,27399435.18,11836288.28,12,3,1
2009,1,9914126,Prefectura Del Departamento De La Paz,Prefectura Del Departamento De Santa Cruz,Prefectura Del Departamento De Cochabamba,3899616135.439999,2887049199.470001,2235925941.379999,393,291,226
2009,2,9914126,Yacimientos Petrolíferos Fiscales Bolivianos,Municipalidad De Santa Cruz De La Sierra,Municipalidad De La Paz,7564355044.880002,701651121.6799995,580517613.5999999,763,71,59
2009,3,9914126,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Empresa De Apoyo A La Producción De Alimentos,8731254829.150007,925604794.5600002,376708709.00999993,881,93,38
2009,4,9914126,Administradora Boliviana De Carreteras,Municipalidad De Santa Cruz De La Sierra,Prefectura Del Departamento De Tarija,1849296985.0799997,1742795400.2699997,1548134098.3300002,187,176,156
2009,5,9914126,Yacimientos Petrolíferos Fiscales Bolivianos,"Ministerio De Obras Públicas, Servicios Y Vivienda",Ministerio De Educación,1170386094.97,434830717.7,376007546,118,44,38
2009,6,9914126,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Municipalidad De La Paz,9325932684.32,327683508.02,296420207.86,941,33,30
2009,8,9914126,Yacimientos Petrolíferos Fiscales Bolivianos,Insumos Bolivia,Ministerio De Desarrollo Rural Y Tierras,10137117443.170002,52402515.13,41841174.120000005,1022,5,4
2009,9,9914126,"Ministerio De Obras Públicas, Servicios Y Vivienda",Insumos Bolivia,Municipalidad De Santa Cruz De La Sierra,43601631.86000001,37134926.97,28062882.32,4,4,3
2010,1,10076577,Gobierno Autónomo Departamental De La Paz,Gobierno Autónomo Departamental De Santa Cruz,Gobierno Autónomo Departamental De Cochabamba,2810106264.169998,2137233770.1199992,1836796512.7199996,279,212,182
2010,2,10076577,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De La Paz,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,9606702121.769981,676447080.2400005,602260582.9700004,953,67,60
2010,3,10076577,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Caja Nacional De Salud,11529013071.720003,1458247042.1600003,548694335.04,1144,145,54
2010,4,10076577,Administradora Boliviana De Carreteras,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Gobierno Autónomo Municipal De La Paz,1985831172.3600008,1696096057.1899998,1038623520.9000003,197,168,103
2010,5,10076577,"Ministerio De Obras Públicas, Servicios Y Vivienda",Ministerio De Educación,Yacimientos Petrolíferos Fiscales Bolivianos,459994511.27,380911925,340916150,46,38,34
2010,6,10076577,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Gobierno Autónomo Municipal De La Paz,4855770372.599999,1861584187.78,321448950.00000006,482,185,32
2010,8,10076577,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Boliviana De Aviación,12188366174.610003,44830822.26,33681016.910000004,1210,4,3
2010,9,10076577,"Ministerio De Obras Públicas, Servicios Y Vivienda",Servicio Nacional De Caminos Residual,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,58059361,33742361.86,28328004.700000003,6,3,3
2011,1,10245917,Gobierno Autónomo Departamental De La Paz,Gobierno Autónomo Departamental De Santa Cruz,Ministerio De Defensa,1876956964.2700002,1804439437.8100004,1556478749.2300003,183,176,152
2011,2,10245917,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Gobierno Autónomo Municipal De La Paz,13204806505.260015,804986517.4700001,787026639.7400014,1289,79,77
2011,3,10245917,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Caja Nacional De Salud,13780371139.590004,2159717591.2599993,582317617.3299998,1345,211,57
2011,4,10245917,Administradora Boliviana De Carreteras,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Yacimientos Petrolíferos Fiscales Bolivianos,2465488536.6099977,1704115304.1899993,1531693615.8200006,241,166,149
2011,5,10245917,Empresa Nacional De Electricidad,"Ministerio De Obras Públicas, Servicios Y Vivienda",Ministerio De Educación,1510144149.62,901708727.05,385003557,147,88,38
2011,6,10245917,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Gobierno Autónomo Municipal De La Paz,7726615699.2,1290865675.49,375963545.81000006,754,126,37
2011,8,10245917,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Empresa Nacional De Electricidad,15017787489.499998,125388025.87000002,57048585.58,1466,12,6
2011,9,10245917,"Ministerio De Obras Públicas, Servicios Y Vivienda",Caja Nacional De Salud,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,61578780.45,51994601.55,34273741.39,6,5,3
2012,1,10423115,Direc. Dptal. De Educación La Paz,Caja Nacional De Salud,Ministerio De Defensa,2178855137.349999,1925343592.33,1684327813.1800003,209,185,162
2012,2,10423115,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Gobierno Autónomo Municipal De La Paz,17973240238.90001,1311516368.7199996,814786896.2800003,1724,126,78
2012,3,10423115,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Caja Nacional De Salud,19479875947.16001,1521240239.9999998,671854019.02,1869,146,64
2012,4,10423115,Administradora Boliviana De Carreteras,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,3130613069.040002,2822379744.7300005,2049979455.1000009,300,271,197
2012,5,10423115,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Ministerio De Educación,673150100.45,492478179.62,410000000,65,47,39
2012,6,10423115,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Gobierno Autónomo Municipal De La Paz,9572994860.94,1895579903.53,458481402.33000004,918,182,44
2012,8,10423115,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Empresa De Apoyo A La Producción De Alimentos,20916596450.64,131307470.30999999,108596765.45,2007,13,10
2012,9,10423115,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,"Ministerio De Obras Públicas, Servicios Y Vivienda",Boliviana De Aviación,57394472.559999995,38691808.54,35344609.77,6,4,3
2013,1,10594727,Direc. Dptal. De Educación La Paz,Caja Nacional De Salud,Ministerio De Defensa,2465770684.7899985,2102127300.6700006,1841582021.9000006,233,198,174
2013,2,10594727,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Gobierno Autónomo Municipal De La Paz,15222969613.420012,1927333922.0499985,971798623.0599998,1437,182,92
2013,3,10594727,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Empresa De Apoyo A La Producción De Alimentos,18382938405.059982,1558969740.2699997,1097138758.1899996,1735,147,104
2013,4,10594727,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Yacimientos Petrolíferos Fiscales Bolivianos,Administradora Boliviana De Carreteras,3225470030.7300024,3190680164.83,3034059058.33,304,301,286
2013,5,10594727,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Ministerio De Desarrollo Productivo Y Economía Plural,1337786918,799283319.38,691318068,126,75,65
2013,6,10594727,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Gobierno Autónomo Municipal De La Paz,11784575051.26,859275990.37,564119758.4100002,1112,81,53
2013,8,10594727,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Empresa De Apoyo A La Producción De Alimentos,20173943280.710007,194273165.46999997,105063157,1904,18,10
2013,9,10594727,Boliviana De Aviación,Corporación Minera De Bolivia,Banco Central De Bolivia,57684106.2,53791625.059999995,53424591.01,5,5,5
2014,1,10755947,Direc. Dptal. De Educación La Paz,Caja Nacional De Salud,Ministerio De Defensa,2811018706.470001,2304927163.9799995,2035516674.87,261,214,189
2014,2,10755947,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Gobierno Autónomo Municipal De La Paz,21881733206.499973,2047821424.639999,1147577972.3400004,2034,190,107
2014,3,10755947,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Empresa De Apoyo A La Producción De Alimentos,16816252742.549992,1983467373.26,1314485796.1200001,1563,184,122
2014,4,10755947,Administradora Boliviana De Carreteras,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,4471471523.549995,3755573664.629999,3477692771.4199977,416,349,323
2014,5,10755947,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Agencia Estatal De Vivienda,4265946873.46,1462769345.48,818183427.37,397,136,76
2014,6,10755947,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Gobierno Autónomo Municipal De La Paz,11854737861.820002,2781496625.57,544169180.4100001,1102,259,51
2014,8,10755947,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Empresa De Apoyo A La Producción De Alimentos,26673361520.7,214615925.63000003,125756483.42,2480,20,12
2014,9,10755947,Universidad Mayor De San Andrés,Banco Central De Bolivia,Boliviana De Aviación,108160591.77,96364078.23,62332474.08,10,9,6
2015,1,10920682,Direc. Dptal. De Educación La Paz,Caja Nacional De Salud,Direc. Dptal. De Educación Santa Cruz,3196815000.4999995,2738632510.4600005,2271681464.6499996,293,251,208
2015,2,10920682,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Gobierno Autónomo Municipal De La Paz,15225224067.17999,2280195269.949999,1259558084.6999996,1394,209,115
2015,3,10920682,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Caja Nacional De Salud,13962141991.250006,1184540725.5100005,1180563599.2299998,1279,108,108
2015,4,10920682,Administradora Boliviana De Carreteras,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,5283567362.979995,4105956510.9300027,2426933014.4799995,484,376,222
2015,5,10920682,Agencia Estatal De Vivienda,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,1762595577.75,827607758.94,612045786.45,161,76,56
2015,6,10920682,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,11437993835.62,2906358811.79,610331236.6100001,1047,266,56
2015,8,10920682,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Boliviana De Aviación,17929743923.690006,199769833.98,132315787.19,1642,18,12
2015,9,10920682,Banco Central De Bolivia,Caja Nacional De Salud,Boliviana De Aviación,95867427.66,94162422.64,82113934.15000002,9,9,8
2016,1,11083605,Direc. Dptal. De Educación La Paz,Direc. Dptal. De Educación Santa Cruz,Ministerio De Gobierno,3465552656.159999,2449443247.3900003,2330036692.6399994,313,221,210
2016,2,11083605,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Boliviana De Aviación,9415208327.389984,1032000691.63,849049341.5999997,849,93,77
2016,3,11083605,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Empresa Boliviana De Almendras Y Derivados,11995575952.039991,1206341190.64,732246377.3599999,1082,109,66
2016,4,11083605,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Yacimientos Petrolíferos Fiscales Bolivianos,5999681602.410001,5634582638.270006,3098315467.750001,541,508,280
2016,5,11083605,Empresa Nacional De Electricidad,Agencia Estatal De Vivienda,Fondo Nacional De Desarrollo Regional,5261840669.4,1366523942.8099997,972552767.6100001,475,123,88
2016,6,11083605,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Empresa Metalúrgica Vinto - Nacionalizada,7765027451.250001,394791768.53,330332851.33,701,36,30
2016,8,11083605,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Empresa Nacional De Electricidad,9808513908.54,160757331.21000004,147405871.45000002,885,15,13
2016,9,11083605,Boliviana De Aviación,Caja Nacional De Salud,Administradora Boliviana De Carreteras,109840520.94999999,107514545.48,76898776.27,10,10,7
2017,1,11242712,Direc. Dptal. De Educación La Paz,Direc. Dptal. De Educación Santa Cruz,Ministerio De Gobierno,3874606490.6599994,2744823898.3900023,2493300380.2599983,345,244,222
2017,2,11242712,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Boliviana De Aviación,10362979117.190002,984205158.9000002,967109692.0599998,922,88,86
2017,3,11242712,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Boliviana De Aviación,13886105538.840004,1569234959.89,720203230.6099997,1235,140,64
2017,4,11242712,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Yacimientos Petrolíferos Fiscales Bolivianos,7375401157.710002,5045553363.139998,1778189094.459999,656,449,158
2017,5,11242712,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,Agencia Estatal De Vivienda,4282944874.2,1338320661.5,1080172168.1000001,381,119,96
2017,6,11242712,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Gobierno Autónomo Municipal De La Paz,5593851462.229998,486578573.28999996,306025127.0400001,498,43,27
2017,8,11242712,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Boliviana De Aviación,10025830419.640001,256911748.07999998,158304505.88,892,23,14
2017,9,11242712,Boliviana De Aviación,Caja Nacional De Salud,Yacimientos Petrolíferos Fiscales Bolivianos,117635851.57000001,91799962.57999998,64431692.18,10,8,6
2018,1,11386175,Direc. Dptal. De Educación La Paz,Direc. Dptal. De Educación Santa Cruz,Ministerio De Gobierno,4191569716.8,2975066506.47,2706347368.1199985,368,261,238
2018,2,11386175,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Boliviana De Aviación,12124672578.34001,1301082019.210002,966253684.1299998,1065,114,85
2018,3,11386175,Yacimientos Petrolíferos Fiscales Bolivianos,Servicio De Desarrollo De Las Empresas Púb. Productivas,Empresa Metalúrgica Vinto - Nacionalizada,16387061058.159994,1298236513.18,1298030760.4099998,1439,114,114
2018,4,11386175,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,"Ministerio De Obras Públicas, Servicios Y Vivienda",5730403130.989998,3576398449.12,1899554860.9500005,503,314,167
2018,5,11386175,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,Agencia Estatal De Vivienda,2268651016.11,1245671100.6899996,1143026979.1299999,199,109,100
2018,6,11386175,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,5979699985.56,618413095.1300001,271553612.1600001,525,54,24
2018,8,11386175,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Boliviana De Aviación,10863973990.950005,341118744.01,177250112.42,954,30,16
2018,9,11386175,Ministerio De Minería Y Metalurgia,Boliviana De Aviación,Caja Nacional De Salud,292762367.8,123667362.07000001,87580774.85999998,26,11,8
2019,1,11514867,Direc. Dptal. De Educación La Paz,Direc. Dptal. De Educación Santa Cruz,Ministerio De Gobierno,4445368441.799999,3179774881.9200006,2863143021.3999996,386,276,249
2019,2,11514867,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Boliviana De Aviación,12399169775.690004,1149738875.3499997,984473441.33,1077,100,85
2019,3,11514867,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Servicio De Desarrollo De Las Empresas Púb. Productivas,16128293385.159996,1243175128.7700002,1172150575.88,1401,108,102
2019,4,11514867,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,"Ministerio De Obras Públicas, Servicios Y Vivienda",4742184448.900001,2440511194.83,1505655193.4299994,412,212,131
2019,5,11514867,Empresa Nacional De Electricidad,Agencia Estatal De Vivienda,Fondo Nacional De Desarrollo Regional,1385406712.56,1245574650.5099995,994833219.8699995,120,108,86
2019,6,11514867,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,5097730559.569998,808853725.55,343341873.52,443,70,30
2019,8,11514867,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Ministerio De Salud,13676470168.299997,349216136.52,94543209.52000001,1188,30,8
2019,9,11514867,Corporación Minera De Bolivia,Boliviana De Aviación,Caja Nacional De Salud,189732167.96,100038655.35,94859332.39,16,9,8
2020,1,11640016,Direc. Dptal. De Educación La Paz,Ministerio De Gobierno,Direc. Dptal. De Educación Santa Cruz,4429675686.170002,3419104302.1800013,3177788417.15,381,294,273
2020,2,11640016,Yacimientos Petrolíferos Fiscales Bolivianos,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,Boliviana De Aviación,11067634469.870028,813835312.9199992,578725648.1,951,70,50
2020,3,11640016,Yacimientos Petrolíferos Fiscales Bolivianos,Servicio De Desarrollo De Las Empresas Púb. Productivas,Caja Nacional De Salud,12120739599.430012,919302775.8099996,691197545.6700004,1041,79,59
2020,4,11640016,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Agencia De Infraestructura En Salud Y Equipamiento Médico,1487141693.4999998,773611906.3300003,576669319.43,128,66,50
2020,5,11640016,Agencia Estatal De Vivienda,Fondo Nacional De Desarrollo Regional,Ministerio De Planificación Del Desarrollo,1144516445.1899998,781212704.9700003,696917732.38,98,67,60
2020,6,11640016,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,7747696767.070001,932360905.0999999,445927065.0999999,666,80,38
2020,8,11640016,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Ministerio De Gobierno,10404488193.79,441941245.26999986,142071449,894,38,12
2020,9,11640016,Ministerio De Economía Y Finanzas Públicas,Caja Nacional De Salud,Yacimientos Petrolíferos Fiscales Bolivianos,1719605616.72,117836366.7,100171351.09,148,10,9
2021,1,11733918,Direc. Dptal. De Educación La Paz,Ministerio De Gobierno,Direc. Dptal. De Educación Santa Cruz,4564962871.270001,3537614877.54,3285843136.2100024,389,301,280
2021,2,11733918,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,11689007816.880007,895829529.25,779934846.1699996,996,76,66
2021,3,11733918,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Central De Abastecimiento Y Suministros De Salud,18075018944.410007,2160914234.3399997,1462972262.26,1540,184,125
2021,4,11733918,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Empresa Siderúrgica Del Mutún,4190952268.700001,1946375233.7599995,892134155.1199999,357,166,76
2021,5,11733918,Agencia Estatal De Vivienda,Fondo Nacional De Desarrollo Regional,Empresa Nacional De Electricidad,1227901537.4199998,764948406.0900004,712096992,105,65,61
2021,6,11733918,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Gobierno Autónomo Municipal De La Paz,4149112793.8799987,857640236.7900001,332464021.41,354,73,28
2021,8,11733918,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Corporación Minera De Bolivia,11471035531.929996,290929719.37,121814649.52000001,978,25,10
2021,9,11733918,Ministerio De Economía Y Finanzas Públicas,Caja Nacional De Salud,Yacimientos Petrolíferos Fiscales Bolivianos,2994885782.73,116538207.02999997,92378391.36000001,255,10,8
2022,1,11798231,Direc. Dptal. De Educación La Paz,Ministerio De Gobierno,Direc. Dptal. De Educación Santa Cruz,4758751431.880001,3532934303.2099977,3438997772.909999,403,299,291
2022,2,11798231,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,13717458912.900005,1110985098.7200003,955449487.3299994,1163,94,81
2022,3,11798231,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Servicio De Desarrollo De Las Empresas Púb. Productivas,28312956060.750008,1848141879.07,1192873663.4899995,2400,157,101
2022,4,11798231,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Empresa Siderúrgica Del Mutún,3555223496.210001,1337968824.280001,951681893.51,301,113,81
2022,5,11798231,Agencia Estatal De Vivienda,Fondo Nacional De Desarrollo Regional,Ministerio De Planificación Del Desarrollo,1320180516.8000002,601282313.7799997,551926936.63,112,51,47
2022,6,11798231,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,5423504844.51,1410832328.29,579018729.71,460,120,49
2022,8,11798231,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Corporación Minera De Bolivia,14205993480.05,229356840.79999998,104066634.27,1204,19,9
2022,9,11798231,Ministerio De Economía Y Finanzas Públicas,Boliviana De Aviación,Yacimientos Petrolíferos Fiscales Bolivianos,902785870.27,137850755.29,110599063.64999999,77,12,9
2023,1,11872175,Direc. Dptal. De Educación La Paz,Ministerio De Gobierno,Direc. Dptal. De Educación Santa Cruz,4973944023.320004,3688766663.190001,3612275492.66,419,311,304
2023,2,11872175,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,11773261573.190014,1438304348.9699996,963027065.9399998,992,121,81
2023,3,11872175,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Metalúrgica Vinto - Nacionalizada,Empresa De Apoyo A La Producción De Alimentos,25825266301.549976,1564632540.7500002,1488076715.9700003,2175,132,125
2023,4,11872175,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Yacimientos Petrolíferos Fiscales Bolivianos,2379102996.9099994,1022917720.0299999,1020797708.61,200,86,86
2023,5,11872175,Agencia Estatal De Vivienda,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,1358834807.8799996,928522446,502983373.2699999,114,78,42
2023,6,11872175,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Empresa Pública Nacional Estratégica De Yacimientos De Litio Bolivianos,6295789937.63,1502652979.0599997,537055177.3,530,127,45
2023,8,11872175,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Empresa Nacional De Electricidad,13497380795.739998,215762276.84000003,130044604.64,1137,18,11
2023,9,11872175,Ministerio De Economía Y Finanzas Públicas,Banco Central De Bolivia,Boliviana De Aviación,1733803266.3999999,176140756.1,150713617.13,146,15,13
2024,1,11916453,Direc. Dptal. De Educación La Paz,Ministerio De Gobierno,Direc. Dptal. De Educación Santa Cruz,5221331121.370003,3901879569.17,3803816523.320001,438,327,319
2024,2,11916453,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,10545646955.190002,1376143999.17,879273588.7200005,885,115,74
2024,3,11916453,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Empresa Metalúrgica Vinto - Nacionalizada,27468850081.29001,2139035246.8700004,1867921535.0000002,2305,180,157
2024,4,11916453,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Yacimientos Petrolíferos Fiscales Bolivianos,2610044614.9600015,1048343616.21,923019707.7399994,219,88,77
2024,5,11916453,Agencia Estatal De Vivienda,Empresa Nacional De Electricidad,Fondo Nacional De Desarrollo Regional,1401782953.1999996,434716061,392456028.9200001,118,36,33
2024,6,11916453,Yacimientos Petrolíferos Fiscales Bolivianos,Empresa Nacional De Electricidad,Banco Central De Bolivia,5927935075.01,1780339292.0800002,957010270.5400001,497,149,80
2024,8,11916453,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Empresa Nacional De Electricidad,11910441582.309998,253598777.35999998,154447306.18,999,21,13
2024,9,11916453,Banco Central De Bolivia,Caja Nacional De Salud,Boliviana De Aviación,1263368809.8,141667378.23999998,112172417.82,106,12,9
2025,1,11945263,Direc. Dptal. De Educación La Paz,Caja Nacional De Salud,Ministerio De Gobierno,5619472435.389999,5151839169.6900015,4152695264.629999,470,431,348
2025,2,11945263,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Gobierno Autónomo Municipal De Santa Cruz De La Sierra,10022617652.269995,1307238585.7,776894490.02,839,109,65
2025,3,11945263,Yacimientos Petrolíferos Fiscales Bolivianos,Corporación Minera De Bolivia,Caja Nacional De Salud,25440956502.62997,3031843418.9,2453131090.32,2130,254,205
2025,4,11945263,Administradora Boliviana De Carreteras,Empresa Nacional De Electricidad,Gobierno Autónomo Departamental De Potosí,1805588926,1772658039.970001,613522280.5799998,151,148,51
2025,5,11945263,Agencia Estatal De Vivienda,Fondo Nacional De Desarrollo Regional,Ministerio De Planificación Del Desarrollo,1495638952.1900003,584557374.4000002,391180329.65999997,125,49,33
2025,6,11945263,Yacimientos Petrolíferos Fiscales Bolivianos,Banco Central De Bolivia,Empresa Nacional De Electricidad,4459749775.39,3691286335.43,1975389838.2800002,373,309,165
2025,8,11945263,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,Empresa Nacional De Electricidad,7472329158.12,319021370.38000005,200966153.25000003,626,27,17
2025,9,11945263,Banco Central De Bolivia,Yacimientos Petrolíferos Fiscales Bolivianos,Boliviana De Aviación,7846357463.4,6611439447.179998,595725550.83,657,553,50