Rafael Lopez

treemap

...@@ -106,6 +106,43 @@ ...@@ -106,6 +106,43 @@
106 } 106 }
107 107
108 /* ============================================ 108 /* ============================================
109 + SISTEMA DE TEMAS (LIGHT/DARK MODE)
110 + Para cambiar la paleta, solo modifica estos valores
111 + ============================================ */
112 +
113 +:root {
114 + /* Modo claro (default) - Slate/White */
115 + --theme-body: #fafafa;
116 + --theme-background: #f8fafc;
117 + --theme-titulo: #1a1a1a;
118 + --theme-texto: #64748b;
119 + --theme-fill: #f1f5f9;
120 + --theme-borde: rgba(0, 0, 0, 0.08);
121 + --theme-accent: #c9a751;
122 + --theme-accent-hover: #b8963f;
123 +
124 + /* Superficies alternativas */
125 + --theme-surface: #ffffff;
126 + --theme-surface-hover: #f8fafc;
127 +}
128 +
129 +:root.dark {
130 + /* Modo oscuro */
131 + --theme-body: #0d0d0d;
132 + --theme-background: #1a1a1a;
133 + --theme-titulo: #e8e4d8;
134 + --theme-texto: #b8b3a3;
135 + --theme-fill: #2d2d2d;
136 + --theme-borde: rgba(255, 255, 255, 0.1);
137 + --theme-accent: #c9a751;
138 + --theme-accent-hover: #d4b76a;
139 +
140 + /* Superficies alternativas */
141 + --theme-surface: #1a1a1a;
142 + --theme-surface-hover: #2d2d2d;
143 +}
144 +
145 +/* ============================================
109 ESTILOS BASE 146 ESTILOS BASE
110 ============================================ */ 147 ============================================ */
111 148
...@@ -115,22 +152,51 @@ html { ...@@ -115,22 +152,51 @@ html {
115 152
116 body { 153 body {
117 font-family: var(--font-sans); 154 font-family: var(--font-sans);
118 - color: var(--color-graphite); 155 + color: var(--theme-titulo);
119 - background-color: #FAFAFA; 156 + background-color: var(--theme-body);
120 -webkit-font-smoothing: antialiased; 157 -webkit-font-smoothing: antialiased;
121 -moz-osx-font-smoothing: grayscale; 158 -moz-osx-font-smoothing: grayscale;
159 + transition: background-color 0.2s ease, color 0.2s ease;
122 } 160 }
123 161
124 /* Focus ring consistente con identidad */ 162 /* Focus ring consistente con identidad */
125 *:focus-visible { 163 *:focus-visible {
126 - outline: 2px solid var(--color-gold); 164 + outline: 2px solid var(--theme-accent);
127 outline-offset: 2px; 165 outline-offset: 2px;
128 } 166 }
129 167
130 /* Selección de texto */ 168 /* Selección de texto */
131 ::selection { 169 ::selection {
132 - background-color: var(--color-gold); 170 + background-color: var(--theme-accent);
133 - color: white; 171 + color: var(--theme-body);
172 +}
173 +
174 +/* ============================================
175 + UTILIDADES DE TEMA
176 + ============================================ */
177 +
178 +.theme-bg {
179 + background-color: var(--theme-body);
180 +}
181 +
182 +.theme-surface {
183 + background-color: var(--theme-surface);
184 +}
185 +
186 +.theme-text {
187 + color: var(--theme-titulo);
188 +}
189 +
190 +.theme-text-muted {
191 + color: var(--theme-texto);
192 +}
193 +
194 +.theme-border {
195 + border-color: var(--theme-borde);
196 +}
197 +
198 +.theme-accent {
199 + color: var(--theme-accent);
134 } 200 }
135 201
136 /* ============================================ 202 /* ============================================
......
1 <!doctype html> 1 <!doctype html>
2 -<html lang="en"> 2 +<html lang="es">
3 <head> 3 <head>
4 <meta charset="utf-8" /> 4 <meta charset="utf-8" />
5 <meta name="viewport" content="width=device-width, initial-scale=1" /> 5 <meta name="viewport" content="width=device-width, initial-scale=1" />
6 +
7 + <!-- Theme initialization - ANTES de cargar CSS para evitar flash -->
8 + <script>
9 + (function() {
10 + const savedTheme = localStorage.getItem('theme');
11 + if (savedTheme === 'dark') {
12 + document.documentElement.classList.add('dark');
13 + }
14 + // Por defecto modo claro (no detectar sistema)
15 + })();
16 + </script>
17 +
6 %sveltekit.head% 18 %sveltekit.head%
7 </head> 19 </head>
8 <body data-sveltekit-preload-data="hover"> 20 <body data-sveltekit-preload-data="hover">
......
This diff is collapsed. Click to expand it.
...@@ -10,12 +10,21 @@ ...@@ -10,12 +10,21 @@
10 error, 10 error,
11 selectedIndex, 11 selectedIndex,
12 showResults, 12 showResults,
13 + filterType,
13 initIndex, 14 initIndex,
14 performSearch, 15 performSearch,
15 clearSearch, 16 clearSearch,
16 - navigateResults 17 + navigateResults,
18 + setFilter
17 } from '$lib/stores/searchStore'; 19 } from '$lib/stores/searchStore';
18 20
21 + const filterOptions = [
22 + { value: 'todos', label: 'Todos' },
23 + { value: 'entidad', label: 'Entidades' },
24 + { value: 'objeto_gasto', label: 'Objetos' },
25 + { value: 'rubro', label: 'Rubros' }
26 + ];
27 +
19 let inputRef; 28 let inputRef;
20 let debounceTimer; 29 let debounceTimer;
21 let isFocused = $state(false); 30 let isFocused = $state(false);
...@@ -77,16 +86,28 @@ ...@@ -77,16 +86,28 @@
77 <svelte:window onclick={handleClickOutside} /> 86 <svelte:window onclick={handleClickOutside} />
78 87
79 <div class="search-container relative"> 88 <div class="search-container relative">
89 + <div class="flex gap-2">
80 <input 90 <input
81 bind:this={inputRef} 91 bind:this={inputRef}
82 type="text" 92 type="text"
83 - placeholder={$indexLoaded ? "Buscar entidad, objeto de gasto o rubro..." : "Cargando..."} 93 + placeholder={$indexLoaded ? "Buscar..." : "Cargando..."}
84 disabled={!$indexLoaded} 94 disabled={!$indexLoaded}
85 - class="w-full p-2 border rounded" 95 + class="flex-1 p-2 border rounded"
86 oninput={handleInput} 96 oninput={handleInput}
87 onkeydown={handleKeydown} 97 onkeydown={handleKeydown}
88 onfocus={() => isFocused = true} 98 onfocus={() => isFocused = true}
89 /> 99 />
100 + <select
101 + class="px-3 py-2 border rounded bg-white text-sm text-slate-600 cursor-pointer"
102 + value={$filterType}
103 + onchange={(e) => setFilter(e.target.value)}
104 + disabled={!$indexLoaded}
105 + >
106 + {#each filterOptions as option}
107 + <option value={option.value}>{option.label}</option>
108 + {/each}
109 + </select>
110 + </div>
90 111
91 {#if $isLoading} 112 {#if $isLoading}
92 <span class="absolute right-2 top-2 text-sm text-gray-400">...</span> 113 <span class="absolute right-2 top-2 text-sm text-gray-400">...</span>
......
1 <script> 1 <script>
2 import { goto } from '$app/navigation'; 2 import { goto } from '$app/navigation';
3 - import { clearSearch } from '$lib/stores/searchStore'; 3 + import { clearSearch, filterType } from '$lib/stores/searchStore';
4 4
5 let { results = [], query = '', selectedIndex = -1 } = $props(); 5 let { results = [], query = '', selectedIndex = -1 } = $props();
6 6
...@@ -23,6 +23,9 @@ ...@@ -23,6 +23,9 @@
23 return { entidades, objetos, rubros }; 23 return { entidades, objetos, rubros };
24 }); 24 });
25 25
26 + // Si hay un filtro específico, no mostrar headers de grupo
27 + let showGroupHeaders = $derived($filterType === 'todos');
28 +
26 // Calcular índice global para navegación con teclado 29 // Calcular índice global para navegación con teclado
27 function getGlobalIndex(tipo, localIndex) { 30 function getGlobalIndex(tipo, localIndex) {
28 const g = groupedResults(); 31 const g = groupedResults();
...@@ -39,9 +42,11 @@ ...@@ -39,9 +42,11 @@
39 {#if results.length > 0} 42 {#if results.length > 0}
40 <div class="absolute top-full left-0 right-0 mt-1 bg-white border rounded shadow-lg max-h-80 overflow-y-auto z-50"> 43 <div class="absolute top-full left-0 right-0 mt-1 bg-white border rounded shadow-lg max-h-80 overflow-y-auto z-50">
41 {#if groupedResults().entidades.length > 0} 44 {#if groupedResults().entidades.length > 0}
45 + {#if showGroupHeaders}
42 <div class="px-3 py-1.5 bg-slate-50 border-b"> 46 <div class="px-3 py-1.5 bg-slate-50 border-b">
43 <span class="text-xs font-medium text-slate-500 uppercase tracking-wide">Entidades</span> 47 <span class="text-xs font-medium text-slate-500 uppercase tracking-wide">Entidades</span>
44 </div> 48 </div>
49 + {/if}
45 {#each groupedResults().entidades as item, index} 50 {#each groupedResults().entidades as item, index}
46 {@const globalIdx = getGlobalIndex('entidad', index)} 51 {@const globalIdx = getGlobalIndex('entidad', index)}
47 <button 52 <button
...@@ -61,9 +66,11 @@ ...@@ -61,9 +66,11 @@
61 {/if} 66 {/if}
62 67
63 {#if groupedResults().objetos.length > 0} 68 {#if groupedResults().objetos.length > 0}
69 + {#if showGroupHeaders}
64 <div class="px-3 py-1.5 bg-slate-50 border-b {groupedResults().entidades.length > 0 ? 'border-t' : ''}"> 70 <div class="px-3 py-1.5 bg-slate-50 border-b {groupedResults().entidades.length > 0 ? 'border-t' : ''}">
65 <span class="text-xs font-medium text-slate-500 uppercase tracking-wide">Objetos del Gasto</span> 71 <span class="text-xs font-medium text-slate-500 uppercase tracking-wide">Objetos del Gasto</span>
66 </div> 72 </div>
73 + {/if}
67 {#each groupedResults().objetos as item, index} 74 {#each groupedResults().objetos as item, index}
68 {@const globalIdx = getGlobalIndex('objeto_gasto', index)} 75 {@const globalIdx = getGlobalIndex('objeto_gasto', index)}
69 <button 76 <button
...@@ -81,9 +88,11 @@ ...@@ -81,9 +88,11 @@
81 {/if} 88 {/if}
82 89
83 {#if groupedResults().rubros.length > 0} 90 {#if groupedResults().rubros.length > 0}
91 + {#if showGroupHeaders}
84 <div class="px-3 py-1.5 bg-slate-50 border-b {groupedResults().entidades.length > 0 || groupedResults().objetos.length > 0 ? 'border-t' : ''}"> 92 <div class="px-3 py-1.5 bg-slate-50 border-b {groupedResults().entidades.length > 0 || groupedResults().objetos.length > 0 ? 'border-t' : ''}">
85 <span class="text-xs font-medium text-slate-500 uppercase tracking-wide">Rubros</span> 93 <span class="text-xs font-medium text-slate-500 uppercase tracking-wide">Rubros</span>
86 </div> 94 </div>
95 + {/if}
87 {#each groupedResults().rubros as item, index} 96 {#each groupedResults().rubros as item, index}
88 {@const globalIdx = getGlobalIndex('rubro', index)} 97 {@const globalIdx = getGlobalIndex('rubro', index)}
89 <button 98 <button
......
1 <script> 1 <script>
2 - import { page } from '$app/stores'; 2 + import { onMount } from 'svelte';
3 +
4 + let { onOpenDrawer = () => {} } = $props();
5 +
6 + let isDark = $state(false);
7 +
8 + function toggleTheme() {
9 + isDark = !isDark;
10 + document.documentElement.classList.toggle('dark', isDark);
11 + localStorage.setItem('theme', isDark ? 'dark' : 'light');
12 + }
13 +
14 + onMount(() => {
15 + // Read actual state from document (set by app.html)
16 + isDark = document.documentElement.classList.contains('dark');
17 +
18 + // Listen for theme changes (e.g., from drawer on mobile)
19 + const observer = new MutationObserver(() => {
20 + isDark = document.documentElement.classList.contains('dark');
21 + });
22 + observer.observe(document.documentElement, {
23 + attributes: true,
24 + attributeFilter: ['class']
25 + });
26 +
27 + return () => observer.disconnect();
28 + });
3 </script> 29 </script>
4 30
5 -<nav class="border-b p-4"> 31 +<!-- MÓVIL: Solo hamburguesa arriba a la derecha -->
6 - <div class="max-w-4xl mx-auto flex items-center justify-between"> 32 +<div class="fixed top-4 right-4 z-[110] md:hidden">
7 - <a href="/">Presupuesto Público Bolivia</a> 33 + <button
8 - <div class="flex gap-4 text-sm"> 34 + onclick={onOpenDrawer}
9 - <a href="/">Inicio</a> 35 + class="p-2 rounded-full transition-all flex-shrink-0"
10 - <a href="/clasificadores">Clasificadores</a> 36 + style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
37 + onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
38 + onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
39 + aria-label="Abrir menú"
40 + >
41 + <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
42 + <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/>
43 + </svg>
44 + </button>
45 +</div>
46 +
47 +<!-- DESKTOP: Barra completa con Home + Theme + Menu -->
48 +<div class="hidden md:flex fixed top-6 right-6 z-[110]">
49 + <div class="flex items-center gap-1">
50 +
51 + <!-- BOTÓN HOME (4 cuadrados) -->
52 + <div class="relative group/home">
53 + <a
54 + href="/"
55 + class="p-2 rounded-full transition-all block"
56 + style="background-color: transparent; color: var(--theme-texto);"
57 + onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
58 + onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
59 + >
60 + <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
61 + <rect x="2" y="2" width="7" height="7" rx="1.5"/>
62 + <rect x="11" y="2" width="7" height="7" rx="1.5"/>
63 + <rect x="2" y="11" width="7" height="7" rx="1.5"/>
64 + <rect x="11" y="11" width="7" height="7" rx="1.5"/>
65 + </svg>
66 + </a>
67 + <!-- Tooltip -->
68 + <div class="absolute right-0 top-full mt-2 px-3 py-1.5 bg-gray-900/90 text-white text-xs rounded-lg whitespace-nowrap opacity-0 invisible group-hover/home:opacity-100 group-hover/home:visible transition-all duration-200 pointer-events-none backdrop-blur-sm">
69 + Página principal
70 + <div class="absolute right-3 bottom-full mb-[-4px] w-2 h-2 bg-gray-900/90 rotate-45"></div>
11 </div> 71 </div>
12 </div> 72 </div>
13 -</nav> 73 +
74 + <!-- BOTÓN THEME TOGGLE (Sol/Luna) -->
75 + <div class="relative group/theme">
76 + <button
77 + onclick={toggleTheme}
78 + class="p-2 rounded-full transition-all"
79 + style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
80 + onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
81 + onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
82 + aria-label={isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
83 + >
84 + {#if isDark}
85 + <!-- LUNA (modo oscuro activo) -->
86 + <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
87 + <path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z"/>
88 + </svg>
89 + {:else}
90 + <!-- SOL (modo claro activo) -->
91 + <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
92 + <path fill-rule="evenodd" d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z" clip-rule="evenodd"/>
93 + </svg>
94 + {/if}
95 + </button>
96 + <!-- Tooltip -->
97 + <div class="absolute right-0 top-full mt-2 px-3 py-1.5 bg-gray-900/90 text-white text-xs rounded-lg whitespace-nowrap opacity-0 invisible group-hover/theme:opacity-100 group-hover/theme:visible transition-all duration-200 pointer-events-none backdrop-blur-sm">
98 + {isDark ? 'Cambiar a modo claro' : 'Cambiar a modo oscuro'}
99 + <div class="absolute right-3 bottom-full mb-[-4px] w-2 h-2 bg-gray-900/90 rotate-45"></div>
100 + </div>
101 + </div>
102 +
103 + <!-- BOTÓN MENÚ HAMBURGUESA -->
104 + <div class="relative group/menu">
105 + <button
106 + onclick={onOpenDrawer}
107 + class="p-2 rounded-full transition-all"
108 + style="background-color: transparent; color: var(--theme-texto); cursor: pointer;"
109 + onmouseenter={(e) => e.currentTarget.style.color = 'var(--theme-titulo)'}
110 + onmouseleave={(e) => e.currentTarget.style.color = 'var(--theme-texto)'}
111 + aria-label="Abrir menú"
112 + >
113 + <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24" stroke-width="2">
114 + <path stroke-linecap="round" stroke-linejoin="round" d="M3.75 6.75h16.5M3.75 12h16.5m-16.5 5.25h16.5"/>
115 + </svg>
116 + </button>
117 + <!-- Tooltip -->
118 + <div class="absolute right-0 top-full mt-2 px-3 py-1.5 bg-gray-900/90 text-white text-xs rounded-lg whitespace-nowrap opacity-0 invisible group-hover/menu:opacity-100 group-hover/menu:visible transition-all duration-200 pointer-events-none backdrop-blur-sm">
119 + Menú
120 + <div class="absolute right-3 bottom-full mb-[-4px] w-2 h-2 bg-gray-900/90 rotate-45"></div>
121 + </div>
122 + </div>
123 +
124 + </div>
125 +</div>
......
1 +import { writable } from 'svelte/store';
2 +
3 +export const drawerOpen = writable(false);
4 +
5 +export function openDrawer() {
6 + drawerOpen.set(true);
7 +}
8 +
9 +export function closeDrawer() {
10 + drawerOpen.set(false);
11 +}
12 +
13 +export function toggleDrawer() {
14 + drawerOpen.update(v => !v);
15 +}
1 -import { writable, derived } from 'svelte/store'; 1 +import { writable, derived, get } from 'svelte/store';
2 import { initSearchIndex, search, isIndexReady } from '$lib/services/search'; 2 import { initSearchIndex, search, isIndexReady } from '$lib/services/search';
3 3
4 // Estado del buscador 4 // Estado del buscador
...@@ -8,6 +8,7 @@ export const isLoading = writable(false); ...@@ -8,6 +8,7 @@ export const isLoading = writable(false);
8 export const indexLoaded = writable(false); 8 export const indexLoaded = writable(false);
9 export const error = writable(null); 9 export const error = writable(null);
10 export const selectedIndex = writable(-1); 10 export const selectedIndex = writable(-1);
11 +export const filterType = writable('todos'); // todos, entidad, objeto_gasto, rubro
11 12
12 // Estado derivado: si está mostrando resultados 13 // Estado derivado: si está mostrando resultados
13 export const showResults = derived( 14 export const showResults = derived(
...@@ -41,7 +42,7 @@ export async function initIndex() { ...@@ -41,7 +42,7 @@ export async function initIndex() {
41 /** 42 /**
42 * Realiza la búsqueda 43 * Realiza la búsqueda
43 */ 44 */
44 -export function performSearch(searchQuery) { 45 +export function performSearch(searchQuery, filter = null) {
45 query.set(searchQuery); 46 query.set(searchQuery);
46 selectedIndex.set(-1); 47 selectedIndex.set(-1);
47 48
...@@ -50,8 +51,16 @@ export function performSearch(searchQuery) { ...@@ -50,8 +51,16 @@ export function performSearch(searchQuery) {
50 return; 51 return;
51 } 52 }
52 53
53 - const searchResults = search(searchQuery, 15); 54 + let searchResults = search(searchQuery, 30);
54 - results.set(searchResults); 55 +
56 + // Filtrar por tipo si no es "todos"
57 + const currentFilter = filter !== null ? filter : get(filterType);
58 + if (currentFilter !== 'todos') {
59 + searchResults = searchResults.filter(r => r.tipo === currentFilter);
60 + }
61 +
62 + // Limitar resultados
63 + results.set(searchResults.slice(0, 15));
55 } 64 }
56 65
57 /** 66 /**
...@@ -64,6 +73,18 @@ export function clearSearch() { ...@@ -64,6 +73,18 @@ export function clearSearch() {
64 } 73 }
65 74
66 /** 75 /**
76 + * Cambia el filtro de tipo
77 + */
78 +export function setFilter(type) {
79 + filterType.set(type);
80 + // Re-ejecutar búsqueda con el nuevo filtro
81 + const currentQuery = get(query);
82 + if (currentQuery.length >= 2) {
83 + performSearch(currentQuery, type);
84 + }
85 +}
86 +
87 +/**
67 * Navegación por teclado 88 * Navegación por teclado
68 */ 89 */
69 export function navigateResults(direction, totalResults) { 90 export function navigateResults(direction, totalResults) {
......
1 <script> 1 <script>
2 import '../app.css'; 2 import '../app.css';
3 + import { page } from '$app/stores';
3 import favicon from '$lib/assets/favicon.svg'; 4 import favicon from '$lib/assets/favicon.svg';
4 import Navbar from '$lib/components/ui/Navbar.svelte'; 5 import Navbar from '$lib/components/ui/Navbar.svelte';
6 + import NavigationDrawer from '$lib/components/layout/NavigationDrawer.svelte';
7 + import { openDrawer } from '$lib/stores/drawer.js';
5 8
6 let { children } = $props(); 9 let { children } = $props();
10 +
11 + // Don't show navbar on landing page
12 + let isLanding = $derived($page.url.pathname === '/');
7 </script> 13 </script>
8 14
9 <svelte:head> 15 <svelte:head>
10 <link rel="icon" href={favicon} /> 16 <link rel="icon" href={favicon} />
17 + <link rel="preconnect" href="https://fonts.googleapis.com" />
18 + <link href="https://fonts.googleapis.com/css2?family=DM+Serif+Display:ital@0;1&family=DM+Mono:wght@400;500&family=Instrument+Sans:wght@400;500;600&display=swap" rel="stylesheet" />
11 </svelte:head> 19 </svelte:head>
12 20
13 -<div class="min-h-screen flex flex-col"> 21 +<!-- Navigation Drawer (siempre presente) -->
14 - <Navbar /> 22 +<NavigationDrawer />
15 - <main class="flex-1"> 23 +
24 +<!-- Floating controls bar (fixed position - no afecta el flujo) -->
25 +{#if !isLanding}
26 + <Navbar onOpenDrawer={openDrawer} />
27 +{/if}
28 +
29 +<div class="min-h-screen" style="background-color: var(--theme-body);">
30 + <main>
16 {@render children()} 31 {@render children()}
17 </main> 32 </main>
18 </div> 33 </div>
......
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
This diff is collapsed. Click to expand it.
1 +gestion,objeto,devengado
2 +2025,11100,7010195151.280003
3 +2025,11210,5812831318.110004
4 +2025,11220,3960643633.5099993
5 +2025,11310,477377380.7399999
6 +2025,11321,611358929.5699998
7 +2025,11322,344284069.2800001
8 +2025,11323,8492765.11
9 +2025,11324,119472850.73000005
10 +2025,11331,3741918.29
11 +2025,11332,222831.86
12 +2025,11339,991911009.5900005
13 +2025,11400,2598265843.6899953
14 +2025,11510,115618445.64
15 +2025,11520,3684768.92
16 +2025,11600,347937539.3
17 +2025,11700,16012422722.88999
18 +2025,11810,1897633.19
19 +2025,11820,5236920.13
20 +2025,11910,418427037.15000004
21 +2025,11920,49552831.83999999
22 +2025,11930,141140855.32999998
23 +2025,11940,4603197.24
24 +2025,12100,3204535824.6000023
25 +2025,13110,3901953807.7400007
26 +2025,13120,619414677.6200007
27 +2025,13131,1362025647.0700052
28 +2025,13132,16517337.85
29 +2025,13200,780321050.7899984
30 +2025,14100,1139341529.1000001
31 +2025,15100,0
32 +2025,15200,0
33 +2025,15300,0
34 +2025,15400,4691146.74
35 +2025,21100,18994647.069999997
36 +2025,21200,1185053965.7300012
37 +2025,21300,187133399.53000006
38 +2025,21400,53465476.169999935
39 +2025,21500,32025660.46999999
40 +2025,21600,194624988.81999987
41 +2025,22110,91267157.03
42 +2025,22120,18054096.22
43 +2025,22210,150388054.74000007
44 +2025,22220,34629325.89
45 +2025,22300,1959574229.3100035
46 +2025,22400,2341473.77
47 +2025,22500,701307983.6299998
48 +2025,22600,129774059.36000001
49 +2025,23100,177818037.08
50 +2025,23200,705817678.630001
51 +2025,23300,267332.29
52 +2025,23400,102877216.77999996
53 +2025,24110,347305124.4300007
54 +2025,24120,495875030.0700008
55 +2025,24130,4734068.450000001
56 +2025,24200,186441122.7200001
57 +2025,24300,2640074895.480003
58 +2025,25120,968577449.3700005
59 +2025,25130,48331129.9
60 +2025,25210,124279655.01999998
61 +2025,25220,1788157637.100003
62 +2025,25230,38750297.28
63 +2025,25300,561398734.3999997
64 +2025,25400,878953716.1200004
65 +2025,25500,306587141.63999945
66 +2025,25600,313083444.33000004
67 +2025,25700,6976563.890000001
68 +2025,25810,119466843.19999999
69 +2025,25820,224542509.50000012
70 +2025,25900,237665083.13999984
71 +2025,26200,15655261.7
72 +2025,26300,34604066.51
73 +2025,26610,123238100.68000004
74 +2025,26620,65803840.900000006
75 +2025,26630,5856917.720000001
76 +2025,26640,12578208.32
77 +2025,26700,14848951.62
78 +2025,26910,663385.5700000003
79 +2025,26920,235250
80 +2025,26930,8978735.689999998
81 +2025,26940,66563836.099999994
82 +2025,26990,1503662082.0000036
83 +2025,27110,1825790733.1499996
84 +2025,27120,364659427.3
85 +2025,31110,542443427.4200002
86 +2025,31120,216381918.43999982
87 +2025,31130,664933780.7900007
88 +2025,31140,546467610.53
89 +2025,31150,58934973.47
90 +2025,31200,33094567.35000001
91 +2025,31300,2447995585.1100035
92 +2025,32100,143276681.52000007
93 +2025,32200,132315063.70000002
94 +2025,32300,5561928.509999998
95 +2025,32400,159320
96 +2025,32500,1136682.8700000003
97 +2025,33100,24196989.06
98 +2025,33200,44402437.73000002
99 +2025,33300,140159482.78000006
100 +2025,33400,44503112.73000003
101 +2025,34110,1233206780.699983
102 +2025,34120,22281523272.74
103 +2025,34130,210854679.98
104 +2025,34200,2971103666.2100005
105 +2025,34300,107990911.47999994
106 +2025,34400,7452099.93
107 +2025,34500,643334205.2399997
108 +2025,34600,256516535.3800006
109 +2025,34700,4499642859.289998
110 +2025,34800,31720752.09
111 +2025,34900,3886088.93
112 +2025,39100,110497000.54
113 +2025,39200,48738034.710000016
114 +2025,39300,4137761.2899999996
115 +2025,39400,88709616.89000002
116 +2025,39500,308909532.08000034
117 +2025,39600,13789089.190000001
118 +2025,39700,260527546.88999993
119 +2025,39800,711478491.3899997
120 +2025,39911,25451599.84
121 +2025,39912,229716435.09
122 +2025,39990,85810785.37999989
123 +2025,41100,4018555.16
124 +2025,41200,11738231.740000002
125 +2025,41300,0
126 +2025,42210,2475688.8800000004
127 +2025,42220,5772449.3
128 +2025,42230,3644887583.5699887
129 +2025,42240,119884214.51000004
130 +2025,42310,3262092590.7700067
131 +2025,42320,162411814.5
132 +2025,42400,748574159.99
133 +2025,42500,368399418.97999996
134 +2025,43110,68317124.34
135 +2025,43120,223834030.73999995
136 +2025,43200,145257372.71
137 +2025,43310,18770602.6
138 +2025,43320,7603011.960000001
139 +2025,43330,290260838.97
140 +2025,43340,4231983.279999999
141 +2025,43400,398948895.01000005
142 +2025,43500,328470832.01999986
143 +2025,43600,51696765.46999999
144 +2025,43700,169086594.95000005
145 +2025,46110,125733899.86000003
146 +2025,46120,74691013.75999999
147 +2025,46210,57348534.56999999
148 +2025,46220,9583654.360000001
149 +2025,46310,30831570.299999986
150 +2025,46320,2784494.7899999996
151 +2025,49100,41480273
152 +2025,49300,492862.94999999995
153 +2025,49400,85275
154 +2025,49900,660922.38
155 +2025,51100,0
156 +2025,51200,620015014.37
157 +2025,51600,481042090
158 +2025,51700,29014116.87
159 +2025,53410,52050949.82
160 +2025,53420,351090144.51
161 +2025,53430,3378151.15
162 +2025,53440,25716472.12
163 +2025,54300,77289717.23
164 +2025,54800,632675260.65
165 +2025,55130,0
166 +2025,56100,2147721911.8500004
167 +2025,57100,836275.9
168 +2025,57200,0
169 +2025,61100,70227731033.1
170 +2025,61200,3503973693.6899977
171 +2025,61300,7686201.74
172 +2025,61400,165316.78
173 +2025,61600,4660620766.32
174 +2025,61700,3610015023.1800003
175 +2025,61800,578767.5200000001
176 +2025,61900,560031.13
177 +2025,62100,106585021.14999999
178 +2025,62200,38756619.58
179 +2025,62300,3500499.439999999
180 +2025,62400,405.55
181 +2025,62600,4871024753.510001
182 +2025,62700,3091378138.92
183 +2025,62800,66184743.53000001
184 +2025,62900,236631.16
185 +2025,63100,6480763.82
186 +2025,63200,0
187 +2025,63300,100360.43
188 +2025,63400,462857.7
189 +2025,63500,35529.2
190 +2025,63600,0
191 +2025,63700,2369055.65
192 +2025,63800,0
193 +2025,63900,1087614.1800000002
194 +2025,64100,0
195 +2025,64200,0
196 +2025,65100,586447491.8299999
197 +2025,65210,398987753.5799999
198 +2025,65220,240387686.01999998
199 +2025,65230,132581381.01
200 +2025,65240,0
201 +2025,65300,2444818356.6
202 +2025,65400,644864385.6300001
203 +2025,65500,797927308.79
204 +2025,65600,622100032.9
205 +2025,65800,6897016.98
206 +2025,65900,66705420.480000004
207 +2025,66100,403828926.02000004
208 +2025,66210,2597435653.4000015
209 +2025,66220,1829365908.85
210 +2025,66230,646299428.4800001
211 +2025,66240,80232240.73
212 +2025,66250,209697820.00000003
213 +2025,66300,239921321.82000005
214 +2025,66400,134798065.3299999
215 +2025,66900,1844595842.08
216 +2025,67100,23208064.040000003
217 +2025,68200,230881944.88000008
218 +2025,69100,29581681.77
219 +2025,69200,203500678.33
220 +2025,71100,7630007944.97
221 +2025,71210,2392898.6
222 +2025,71220,322149243.09
223 +2025,71230,4408152.6
224 +2025,71300,26644234.430000003
225 +2025,71610,1883091507.0600004
226 +2025,71630,343800974.93
227 +2025,71700,65080225.449999996
228 +2025,71800,4478984170.690001
229 +2025,72200,2046897058.8299997
230 +2025,72420,316010589.22
231 +2025,72520,7584584602.65001
232 +2025,73100,2664574022.970007
233 +2025,73200,24681254941.659996
234 +2025,73410,4845222515.11
235 +2025,73420,315258596.03999996
236 +2025,73430,4314037.58
237 +2025,73440,1652127
238 +2025,73700,15015040108.359999
239 +2025,73820,1364681.67
240 +2025,75110,0
241 +2025,75120,683772757.9200002
242 +2025,75211,469127620.05
243 +2025,75212,50308009.760000005
244 +2025,75221,11649919.909999998
245 +2025,75222,305831148.79999995
246 +2025,75320,0
247 +2025,77100,346626643.30999994
248 +2025,77200,1783047515.49
249 +2025,77410,154404059.40000007
250 +2025,77440,13005182.149999999
251 +2025,77520,34542653.12
252 +2025,77530,1359464924.2300012
253 +2025,77700,0
254 +2025,77820,42931153.11
255 +2025,78100,346333.4
256 +2025,79100,20183063.04
257 +2025,79200,74336.66
258 +2025,79310,69600
259 +2025,81100,189467352
260 +2025,81200,1327189189.5399992
261 +2025,81300,551652107.6699998
262 +2025,81400,299412884.65
263 +2025,81500,2442434
264 +2025,81600,395569
265 +2025,81950,39137
266 +2025,81960,32790665.14
267 +2025,81990,2007174694.16
268 +2025,82100,879007438.5400001
269 +2025,83110,29113391.8
270 +2025,83120,4240482.35
271 +2025,83210,351070.72
272 +2025,83220,50460
273 +2025,84100,65887753.279999994
274 +2025,84230,394819507.59
275 +2025,84240,723835763.5600002
276 +2025,84250,65803251.14
277 +2025,84900,8503359.91
278 +2025,85100,94254502.63999999
279 +2025,85200,10478575.300000003
280 +2025,85400,6221225.630000003
281 +2025,85500,3581209.3799999994
282 +2025,85900,20640115.529999997
283 +2025,86100,29028844.980000008
284 +2025,91200,512102826.06
285 +2025,92100,0
286 +2025,94100,11526054.86
287 +2025,94200,7279202.82
288 +2025,94300,1551638.3499999999
289 +2025,95100,291453722.56
290 +2025,96100,5934986991.019999
291 +2025,96200,614954091.44
292 +2025,96900,2947311655.2299995
293 +2025,97100,70099589.35000001
294 +2025,98300,125000000
295 +2025,99100,0
296 +2025,99200,0
This diff could not be displayed because it is too large.