Feat Selector Modo Tabla
This commit is contained in:
		| @@ -2,9 +2,20 @@ import { useState, useMemo, useEffect } from 'react'; | |||||||
| import { useQuery } from '@tanstack/react-query'; | import { useQuery } from '@tanstack/react-query'; | ||||||
| import Select from 'react-select'; | import Select from 'react-select'; | ||||||
| import { getSeccionesElectorales, getRankingMunicipiosPorSeccion } from '../apiService'; | import { getSeccionesElectorales, getRankingMunicipiosPorSeccion } from '../apiService'; | ||||||
| import type { MunicipioSimple, ApiResponseRankingMunicipio } from '../types/types'; | import type { MunicipioSimple, ApiResponseRankingMunicipio, RankingPartido } from '../types/types'; | ||||||
| import './ResultadosTablaSeccionWidget.css'; // Reutilizamos el mismo estilo | import './ResultadosTablaSeccionWidget.css';  | ||||||
| import React from 'react'; |  | ||||||
|  | type DisplayMode = 'porcentaje' | 'votos' | 'ambos'; | ||||||
|  | type DisplayOption = { | ||||||
|  |     value: DisplayMode; | ||||||
|  |     label: string; | ||||||
|  | }; | ||||||
|  |  | ||||||
|  | const displayModeOptions: readonly DisplayOption[] = [ | ||||||
|  |     { value: 'porcentaje', label: 'Ver Porcentajes' }, | ||||||
|  |     { value: 'votos', label: 'Ver Votos' }, | ||||||
|  |     { value: 'ambos', label: 'Ver Ambos' }, | ||||||
|  | ]; | ||||||
|  |  | ||||||
| const customSelectStyles = { | const customSelectStyles = { | ||||||
|   control: (base: any) => ({ ...base, minWidth: '200px', border: '1px solid #ced4da', boxShadow: 'none', '&:hover': { borderColor: '#86b7fe' } }), |   control: (base: any) => ({ ...base, minWidth: '200px', border: '1px solid #ced4da', boxShadow: 'none', '&:hover': { borderColor: '#86b7fe' } }), | ||||||
| @@ -12,10 +23,36 @@ const customSelectStyles = { | |||||||
| }; | }; | ||||||
|  |  | ||||||
| const formatPercent = (porcentaje: number) => `${porcentaje.toFixed(2).replace('.', ',')}%`; | const formatPercent = (porcentaje: number) => `${porcentaje.toFixed(2).replace('.', ',')}%`; | ||||||
|  | // Nueva función para formatear votos con separador de miles | ||||||
|  | const formatVotos = (votos: number) => votos.toLocaleString('es-AR'); | ||||||
|  |  | ||||||
|  | // --- NUEVO COMPONENTE HELPER PARA RENDERIZAR CELDAS --- | ||||||
|  | const CellRenderer = ({ partido, mode }: { partido?: RankingPartido, mode: DisplayMode }) => { | ||||||
|  |     if (!partido) { | ||||||
|  |         return <span>-</span>; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     switch (mode) { | ||||||
|  |         case 'votos': | ||||||
|  |             return <span>{formatVotos(partido.votos)}</span>; | ||||||
|  |         case 'ambos': | ||||||
|  |             return ( | ||||||
|  |                 <div className="cell-ambos"> | ||||||
|  |                     <span>{formatVotos(partido.votos)}</span> | ||||||
|  |                     <small>{formatPercent(partido.porcentaje)}</small> | ||||||
|  |                 </div> | ||||||
|  |             ); | ||||||
|  |         case 'porcentaje': | ||||||
|  |         default: | ||||||
|  |             return <span>{formatPercent(partido.porcentaje)}</span>; | ||||||
|  |     } | ||||||
|  | }; | ||||||
|  |  | ||||||
|  |  | ||||||
| export const ResultadosRankingMunicipioWidget = () => { | export const ResultadosRankingMunicipioWidget = () => { | ||||||
|   const [secciones, setSecciones] = useState<MunicipioSimple[]>([]); |   const [secciones, setSecciones] = useState<MunicipioSimple[]>([]); | ||||||
|   const [selectedSeccion, setSelectedSeccion] = useState<{ value: string; label: string } | null>(null); |   const [selectedSeccion, setSelectedSeccion] = useState<{ value: string; label: string } | null>(null); | ||||||
|  |   const [displayMode, setDisplayMode] = useState<DisplayOption>(displayModeOptions[0]); | ||||||
|  |  | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     const fetchSecciones = async () => { |     const fetchSecciones = async () => { | ||||||
| @@ -48,91 +85,79 @@ export const ResultadosRankingMunicipioWidget = () => { | |||||||
|   }); |   }); | ||||||
|  |  | ||||||
|   return ( |   return ( | ||||||
|     <div className="tabla-resultados-widget"> |         <div className="tabla-resultados-widget"> | ||||||
|       <div className="tabla-header"> |             <div className="tabla-header"> | ||||||
|         <h3>Resultados por Municipio</h3> |                 <h3>Resultados por Municipio</h3> | ||||||
|         <Select |                 <div className="header-filters"> | ||||||
|           options={seccionOptions} |                     <Select | ||||||
|           value={selectedSeccion} |                         options={displayModeOptions} | ||||||
|           onChange={(option) => setSelectedSeccion(option)} |                         value={displayMode} | ||||||
|           isLoading={secciones.length === 0} |                          | ||||||
|           styles={customSelectStyles} |                         // --- CORRECCIÓN EN ONCHANGE --- | ||||||
|           isSearchable={false} |                         // 'option' ahora es del tipo correcto, por lo que no necesitamos aserción. | ||||||
|         /> |                         onChange={(option) => setDisplayMode(option as DisplayOption)} | ||||||
|       </div> |                          | ||||||
|  |                         styles={customSelectStyles} | ||||||
|  |                         isSearchable={false} | ||||||
|  |                     /> | ||||||
|  |                     <Select | ||||||
|  |                         options={seccionOptions} | ||||||
|  |                         value={selectedSeccion} | ||||||
|  |                         onChange={(option) => setSelectedSeccion(option)} | ||||||
|  |                         isLoading={secciones.length === 0} | ||||||
|  |                         styles={customSelectStyles} | ||||||
|  |                         isSearchable={false} | ||||||
|  |                     /> | ||||||
|  |                 </div> | ||||||
|  |             </div> | ||||||
|  |  | ||||||
|       <div className="tabla-container"> |             <div className="tabla-container"> | ||||||
|         {isLoading ? <p>Cargando...</p> : !rankingData || rankingData.categorias.length === 0 ? <p>No hay datos.</p> : ( |                 {isLoading ? <p>Cargando...</p> : !rankingData || rankingData.categorias.length === 0 ? <p>No hay datos.</p> : ( | ||||||
|           <table> |                     <table> | ||||||
|             <thead> |                         <thead> | ||||||
|               {/* --- Fila 1: Nombres de Categorías --- */} |                             <tr> | ||||||
|               <tr> |                                 <th rowSpan={2} className="sticky-col municipio-header">Municipio</th> | ||||||
|                 <th rowSpan={2} className="sticky-col municipio-header">Municipio</th> |                                 {rankingData.categorias.map(cat => ( | ||||||
|                 {rankingData.categorias.map(cat => ( |                                     <th key={cat.id} colSpan={2} className="categoria-header">{cat.nombre}</th> | ||||||
|                   // Cada categoría ahora ocupa 4 columnas (1° Partido, 1° %, 2° Partido, 2° %) |                                 ))} | ||||||
|                   <th key={cat.id} colSpan={4} className="categoria-header"> |                             </tr> | ||||||
|                     {cat.nombre} |                             <tr> | ||||||
|                   </th> |                                 {rankingData.categorias.flatMap(cat => [ | ||||||
|                 ))} |                                     <th key={`${cat.id}-1`} className="partido-header">1° Puesto</th>, | ||||||
|               </tr> |                                     <th key={`${cat.id}-2`} className="partido-header category-divider-header">2° Puesto</th> | ||||||
|               {/* --- Fila 2: Puestos y % --- */} |                                 ])} | ||||||
|               <tr> |                             </tr> | ||||||
|                 {rankingData.categorias.flatMap(cat => [ |                         </thead> | ||||||
|                   <th key={`${cat.id}-p1`} colSpan={2} className="puesto-header">1° Puesto</th>, |                         <tbody> | ||||||
|                   <th key={`${cat.id}-p2`} colSpan={2} className="puesto-header category-divider-header">2° Puesto</th> |                             {rankingData.resultados.map(municipio => ( | ||||||
|                 ])} |                                 <tr key={municipio.municipioId}> | ||||||
|               </tr> |                                     <td className="sticky-col">{municipio.municipioNombre}</td> | ||||||
|               {/* Fila 3: Sub-cabeceras (Partido, %) */} |                                     {rankingData.categorias.flatMap(cat => { | ||||||
|               <tr> |                                         const resCategoria = municipio.resultadosPorCategoria[cat.id]; | ||||||
|                 <th  className="sub-header-init" /> |                                         const primerPuesto = resCategoria?.ranking[0]; | ||||||
|                 { |                                         const segundoPuesto = resCategoria?.ranking[1]; | ||||||
|                   // Usamos un bucle map simple en lugar de flatMap. |  | ||||||
|                   // React manejará la creación de un array de nodos sin problemas. |  | ||||||
|                   rankingData.categorias.map(cat => ( |  | ||||||
|                     // Usamos un Fragmento (<>) para agrupar los 4 <th> de cada categoría |  | ||||||
|                     // sin añadir un nodo extra al DOM. |  | ||||||
|                     <React.Fragment key={`subheaders-${cat.id}`}> |  | ||||||
|                       <th className="sub-header">Partido</th> |  | ||||||
|                       <th className="sub-header">%</th> |  | ||||||
|                       <th className="sub-header category-divider-header">Partido</th> |  | ||||||
|                       <th className="sub-header">%</th> |  | ||||||
|                     </React.Fragment> |  | ||||||
|                   )) |  | ||||||
|                 } |  | ||||||
|               </tr> |  | ||||||
|             </thead> |  | ||||||
|             <tbody> |  | ||||||
|               {rankingData.resultados.map(municipio => ( |  | ||||||
|                 <tr key={municipio.municipioId}> |  | ||||||
|                   <td className="sticky-col">{municipio.municipioNombre}</td> |  | ||||||
|                   {rankingData.categorias.flatMap(cat => { |  | ||||||
|                     const resCategoria = municipio.resultadosPorCategoria[cat.id]; |  | ||||||
|                     const primerPuesto = resCategoria?.ranking[0]; |  | ||||||
|                     const segundoPuesto = resCategoria?.ranking[1]; |  | ||||||
|  |  | ||||||
|                     return [ |                                         return [ | ||||||
|                       // --- Celdas para el 1° Puesto --- |                                             <td key={`${municipio.municipioId}-${cat.id}-1`} className="category-divider"> | ||||||
|                       <td key={`${municipio.municipioId}-${cat.id}-p1-partido`} className="cell-partido"> |                                                 <div className="cell-content"> | ||||||
|                         {primerPuesto?.nombreCorto || '-'} |                                                     <span className="cell-partido-nombre">{primerPuesto?.nombreCorto || '-'}</span> | ||||||
|                       </td>, |                                                     <CellRenderer partido={primerPuesto} mode={displayMode.value} /> | ||||||
|                       <td key={`${municipio.municipioId}-${cat.id}-p1-porc`} className="cell-porcentaje"> |                                                 </div> | ||||||
|                         {primerPuesto ? formatPercent(primerPuesto.porcentaje) : '-'} |                                             </td>, | ||||||
|                       </td>, |                                             <td key={`${municipio.municipioId}-${cat.id}-2`}> | ||||||
|                       // --- Celdas para el 2° Puesto --- |                                                 <div className="cell-content"> | ||||||
|                       <td key={`${municipio.municipioId}-${cat.id}-p2-partido`} className="cell-partido category-divider"> |                                                     <span className="cell-partido-nombre">{segundoPuesto?.nombreCorto || '-'}</span> | ||||||
|                         {segundoPuesto?.nombreCorto || '-'} |                                                     <CellRenderer partido={segundoPuesto} mode={displayMode.value} /> | ||||||
|                       </td>, |                                                 </div> | ||||||
|                       <td key={`${municipio.municipioId}-${cat.id}-p2-porc`} className="cell-porcentaje"> |                                             </td> | ||||||
|                         {segundoPuesto ? formatPercent(segundoPuesto.porcentaje) : '-'} |                                         ]; | ||||||
|                       </td> |                                     })} | ||||||
|                     ]; |                                 </tr> | ||||||
|                   })} |                             ))} | ||||||
|                 </tr> |                         </tbody> | ||||||
|               ))} |                     </table> | ||||||
|             </tbody> |                 )} | ||||||
|           </table> |             </div> | ||||||
|         )} |         </div> | ||||||
|       </div> |     ); | ||||||
|     </div> |  | ||||||
|   ); |  | ||||||
| }; | }; | ||||||
| @@ -23,6 +23,11 @@ | |||||||
|     border-bottom: 1px solid #dee2e6; |     border-bottom: 1px solid #dee2e6; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | .header-filters { | ||||||
|  |     display: flex; | ||||||
|  |     gap: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
| .tabla-header h3 { | .tabla-header h3 { | ||||||
|     margin: 0; |     margin: 0; | ||||||
|     font-size: 1.25rem; |     font-size: 1.25rem; | ||||||
| @@ -173,4 +178,32 @@ | |||||||
| } | } | ||||||
| .tabla-container tbody tr:nth-of-type(even) td.sticky-col { | .tabla-container tbody tr:nth-of-type(even) td.sticky-col { | ||||||
|     background-color: #f8f9fa; /* Para que coincida con el fondo de la fila */ |     background-color: #f8f9fa; /* Para que coincida con el fondo de la fila */ | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Contenedor principal de la celda para alinear contenido */ | ||||||
|  | .cell-content { | ||||||
|  |     display: flex; | ||||||
|  |     justify-content: space-between; | ||||||
|  |     align-items: baseline; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Nombre del partido dentro de la celda */ | ||||||
|  | .cell-partido-nombre { | ||||||
|  |     text-align: left; | ||||||
|  |     font-size: 0.85rem; | ||||||
|  |     padding-right: 1rem; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | /* Contenedor para la vista "ambos" (votos y porcentaje) */ | ||||||
|  | .cell-ambos { | ||||||
|  |     display: flex; | ||||||
|  |     flex-direction: column; | ||||||
|  |     align-items: flex-end; | ||||||
|  |     text-align: right; | ||||||
|  |     line-height: 1.2; | ||||||
|  | } | ||||||
|  |  | ||||||
|  | .cell-ambos small { | ||||||
|  |     font-size: 0.8em; | ||||||
|  |     color: #6c757d; | ||||||
| } | } | ||||||
| @@ -188,6 +188,7 @@ export interface TablaDetalladaResultadoMunicipio { | |||||||
| export interface RankingPartido { | export interface RankingPartido { | ||||||
|   nombreCorto: string; |   nombreCorto: string; | ||||||
|   porcentaje: number; |   porcentaje: number; | ||||||
|  |   votos: number; | ||||||
| } | } | ||||||
|  |  | ||||||
| export interface RankingCategoria { | export interface RankingCategoria { | ||||||
|   | |||||||
| @@ -965,43 +965,37 @@ public class ResultadosController : ControllerBase | |||||||
|  |  | ||||||
|         // 3. Procesar los datos por cada municipio |         // 3. Procesar los datos por cada municipio | ||||||
|         var resultadosPorMunicipio = municipios.Select(municipio => |         var resultadosPorMunicipio = municipios.Select(municipio => | ||||||
|         { |     { | ||||||
|             // Filtramos los resultados solo para el municipio actual |         var resultadosDelMunicipio = resultadosCrudos.Where(r => r.AmbitoGeograficoId == municipio.Id); | ||||||
|             var resultadosDelMunicipio = resultadosCrudos.Where(r => r.AmbitoGeograficoId == municipio.Id); |  | ||||||
|  |  | ||||||
|             // Agrupamos por categoría (Senadores, Concejales, etc.) |         var resultadosPorCategoria = resultadosDelMunicipio | ||||||
|             var resultadosPorCategoria = resultadosDelMunicipio |             .GroupBy(r => r.CategoriaId) | ||||||
|                 .GroupBy(r => r.CategoriaId) |             .Select(g => | ||||||
|                 .Select(g => |  | ||||||
|                 { |  | ||||||
|                     var totalVotosCategoria = (decimal)g.Sum(r => r.CantidadVotos); |  | ||||||
|  |  | ||||||
|                     // Obtenemos los 2 partidos con más votos para esta categoría EN ESTE MUNICIPIO |  | ||||||
|                     var ranking = g |  | ||||||
|                         .OrderByDescending(r => r.CantidadVotos) |  | ||||||
|                         .Take(2) |  | ||||||
|                         .Select(r => new |  | ||||||
|                         { |  | ||||||
|                             NombreCorto = r.AgrupacionPolitica.NombreCorto ?? r.AgrupacionPolitica.Nombre, |  | ||||||
|                             Porcentaje = totalVotosCategoria > 0 ? (r.CantidadVotos / totalVotosCategoria) * 100 : 0 |  | ||||||
|                         }) |  | ||||||
|                         .ToList(); |  | ||||||
|  |  | ||||||
|                     return new |  | ||||||
|                     { |  | ||||||
|                         CategoriaId = g.Key, |  | ||||||
|                         Ranking = ranking |  | ||||||
|                     }; |  | ||||||
|                 }) |  | ||||||
|                 .ToDictionary(r => r.CategoriaId); // Lo convertimos a diccionario para fácil acceso |  | ||||||
|  |  | ||||||
|             return new |  | ||||||
|             { |             { | ||||||
|                 MunicipioId = municipio.Id, |                 var totalVotosCategoria = (decimal)g.Sum(r => r.CantidadVotos); | ||||||
|                 MunicipioNombre = municipio.Nombre, |  | ||||||
|                 ResultadosPorCategoria = resultadosPorCategoria |                 var ranking = g | ||||||
|             }; |                     .OrderByDescending(r => r.CantidadVotos) | ||||||
|         }).ToList(); |                     .Take(2) | ||||||
|  |                     .Select(r => new | ||||||
|  |                     { | ||||||
|  |                         NombreCorto = r.AgrupacionPolitica.NombreCorto ?? r.AgrupacionPolitica.Nombre, | ||||||
|  |                         Porcentaje = totalVotosCategoria > 0 ? (r.CantidadVotos / totalVotosCategoria) * 100 : 0, | ||||||
|  |                         Votos = r.CantidadVotos // <-- AÑADIR ESTE CAMPO | ||||||
|  |                     }) | ||||||
|  |                     .ToList(); | ||||||
|  |  | ||||||
|  |                 return new { CategoriaId = g.Key, Ranking = ranking }; | ||||||
|  |             }) | ||||||
|  |             .ToDictionary(r => r.CategoriaId); // Lo convertimos a diccionario para fácil acceso | ||||||
|  |  | ||||||
|  |         return new | ||||||
|  |         { | ||||||
|  |             MunicipioId = municipio.Id, | ||||||
|  |             MunicipioNombre = municipio.Nombre, | ||||||
|  |             ResultadosPorCategoria = resultadosPorCategoria | ||||||
|  |         }; | ||||||
|  |     }).ToList(); | ||||||
|  |  | ||||||
|         // Devolvemos las categorías que tuvieron resultados en esta sección para construir la cabecera |         // Devolvemos las categorías que tuvieron resultados en esta sección para construir la cabecera | ||||||
|         var categoriasMap = await _dbContext.CategoriasElectorales.AsNoTracking().ToDictionaryAsync(c => c.Id); |         var categoriasMap = await _dbContext.CategoriasElectorales.AsNoTracking().ToDictionaryAsync(c => c.Id); | ||||||
|   | |||||||
| @@ -14,7 +14,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Api")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Api")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+c105106f3b420a1c1c19b125cdf5c31e59bfbe3b")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d5168e1d175a8b1944d6009066d13f9b99cba1d0")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Api")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Api")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Api")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Api")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -1 +1 @@ | |||||||
| {"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["TyIJk/eQMWjmB5LsDE\u002BZIJC9P9ciVxd7bnzRiTZsGt4=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","TEsXImnzxFKTIq2f5fiDu7i6Ar/cbecW5MZ3z8Wb/a4=","5WogJu\u002BUPlF\u002BE5mq/ILtDXpVwqwmhHtsEB13nmT5JJk=","dcHQRkttjMjo2dvhL7hA9t4Pg\u002B7OnjZpkFmakT4QR9U=","Of8nTYw5l\u002BgiAJo7z6XYIntG2tUtCFcILzHbTiiXn\u002Bw=","PDy\u002BTiayvNAoXXBEgwC/kCojpgOOMI6RQOIoSXs3LJc=","ePXrkee3hv3wHUr8S7aYmRVvXUTxQf76zApKGv3/l3o=","Mo7tdPQiZw6/WSnll8t7xy4SU1EoFW4N6EN7JftvBYs=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","eix/dR870pRbtIGVeoF7YpZlG47M4PrBntvgxdO1oDM="],"CachedAssets":{},"CachedCopyCandidates":{}} | {"GlobalPropertiesHash":"b5T/+ta4fUd8qpIzUTm3KyEwAYYUsU5ASo+CSFM3ByE=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["TyIJk/eQMWjmB5LsDE\u002BZIJC9P9ciVxd7bnzRiTZsGt4=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","TEsXImnzxFKTIq2f5fiDu7i6Ar/cbecW5MZ3z8Wb/a4=","5WogJu\u002BUPlF\u002BE5mq/ILtDXpVwqwmhHtsEB13nmT5JJk=","dcHQRkttjMjo2dvhL7hA9t4Pg\u002B7OnjZpkFmakT4QR9U=","Of8nTYw5l\u002BgiAJo7z6XYIntG2tUtCFcILzHbTiiXn\u002Bw=","PDy\u002BTiayvNAoXXBEgwC/kCojpgOOMI6RQOIoSXs3LJc=","ePXrkee3hv3wHUr8S7aYmRVvXUTxQf76zApKGv3/l3o=","DJ3OEGlGm0XqehqAshsJPdHddx35xQrKqTYPlJ\u002BmgK0=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","VC4RrsY3drpYvDr8ENTx68n\u002BklPRBIIs4arkXFsPT3E="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||||
| @@ -1 +1 @@ | |||||||
| {"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["TyIJk/eQMWjmB5LsDE\u002BZIJC9P9ciVxd7bnzRiTZsGt4=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","TEsXImnzxFKTIq2f5fiDu7i6Ar/cbecW5MZ3z8Wb/a4=","5WogJu\u002BUPlF\u002BE5mq/ILtDXpVwqwmhHtsEB13nmT5JJk=","dcHQRkttjMjo2dvhL7hA9t4Pg\u002B7OnjZpkFmakT4QR9U=","Of8nTYw5l\u002BgiAJo7z6XYIntG2tUtCFcILzHbTiiXn\u002Bw=","PDy\u002BTiayvNAoXXBEgwC/kCojpgOOMI6RQOIoSXs3LJc=","ePXrkee3hv3wHUr8S7aYmRVvXUTxQf76zApKGv3/l3o=","Mo7tdPQiZw6/WSnll8t7xy4SU1EoFW4N6EN7JftvBYs=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","eix/dR870pRbtIGVeoF7YpZlG47M4PrBntvgxdO1oDM="],"CachedAssets":{},"CachedCopyCandidates":{}} | {"GlobalPropertiesHash":"tJTBjV/i0Ihkc6XuOu69wxL8PBac9c9Kak6srMso4pU=","FingerprintPatternsHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","PropertyOverridesHash":"8ZRc1sGeVrPBx4lD717BgRaQekyh78QKV9SKsdt638U=","InputHashes":["TyIJk/eQMWjmB5LsDE\u002BZIJC9P9ciVxd7bnzRiTZsGt4=","t631p0kaOa0gMRIcaPzz1ZVPZ1kuq4pq4kYPWQgoPcM=","PA/Beu9jJpOBY5r5Y1CiSyqrARA2j7LHeWYUnEZpQO8=","E2ODTAlJxzsXY1iP1eB/02NIUK\u002BnQveGlWAOHY1cpgA=","6WTvWQ72AaZBYOVSmaxaci9tc1dW5p7IK9Kscjj2cb0=","vAy46VJ9Gp8QqG/Px4J1mj8jL6ws4/A01UKRmMYfYek=","cdgbHR/E4DJsddPc\u002BTpzoUMOVNaFJZm33Pw7AxU9Ees=","4r4JGR4hS5m4rsLfuCSZxzrknTBxKFkLQDXc\u002B2KbqTU=","yVoZ4UnBcSOapsJIi046hnn7ylD3jAcEBUxQ\u002Brkvj/4=","/GfbpJthEWmsuz0uFx1QLHM7gyM1wLLeQgAIl4SzUD4=","i5\u002B5LcfxQD8meRAkQbVf4wMvjxSE4\u002BjCd2/FdPtMpms=","AvSkxVPIg0GjnB1RJ4hDNyo9p9GONrzDs8uVuixH\u002BOE=","IgT9pOgRnK37qfILj2QcjFoBZ180HMt\u002BScgje2iYOo4=","ezUlOMzNZmyKDIe1wwXqvX\u002BvhwfB992xNVts7r2zcTc=","y2BV4WpkQuLfqQhfOQBtmuzh940c3s4LAopGKfztfTE=","lHTUEsMkDu8nqXtfTwl7FRfgocyyc7RI5O/edTHN1\u002B0=","A7nz7qgOtQ1CwZZLvNnr0b5QZB3fTi3y4i6y7rBIcxQ=","znnuRi2tsk7AACuYo4WSgj7NcLriG4PKVaF4L35SvDk=","GelE32odx/vTului267wqi6zL3abBnF9yvwC2Q66LoM=","TEsXImnzxFKTIq2f5fiDu7i6Ar/cbecW5MZ3z8Wb/a4=","5WogJu\u002BUPlF\u002BE5mq/ILtDXpVwqwmhHtsEB13nmT5JJk=","dcHQRkttjMjo2dvhL7hA9t4Pg\u002B7OnjZpkFmakT4QR9U=","Of8nTYw5l\u002BgiAJo7z6XYIntG2tUtCFcILzHbTiiXn\u002Bw=","PDy\u002BTiayvNAoXXBEgwC/kCojpgOOMI6RQOIoSXs3LJc=","ePXrkee3hv3wHUr8S7aYmRVvXUTxQf76zApKGv3/l3o=","DJ3OEGlGm0XqehqAshsJPdHddx35xQrKqTYPlJ\u002BmgK0=","P8JRhYPpULTLMAydvl3Ky\u002B92/tYDIjui0l66En4aXuQ=","VC4RrsY3drpYvDr8ENTx68n\u002BklPRBIIs4arkXFsPT3E="],"CachedAssets":{},"CachedCopyCandidates":{}} | ||||||
| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Core")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Core")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+c105106f3b420a1c1c19b125cdf5c31e59bfbe3b")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d5168e1d175a8b1944d6009066d13f9b99cba1d0")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Core")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Core")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Core")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Core")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Database")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Database")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+c105106f3b420a1c1c19b125cdf5c31e59bfbe3b")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d5168e1d175a8b1944d6009066d13f9b99cba1d0")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Database")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Database")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Database")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Database")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
| @@ -13,7 +13,7 @@ using System.Reflection; | |||||||
| [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")] | [assembly: System.Reflection.AssemblyCompanyAttribute("Elecciones.Infrastructure")] | ||||||
| [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] | ||||||
| [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyFileVersionAttribute("1.0.0.0")] | ||||||
| [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+c105106f3b420a1c1c19b125cdf5c31e59bfbe3b")] | [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0+d5168e1d175a8b1944d6009066d13f9b99cba1d0")] | ||||||
| [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")] | [assembly: System.Reflection.AssemblyProductAttribute("Elecciones.Infrastructure")] | ||||||
| [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")] | [assembly: System.Reflection.AssemblyTitleAttribute("Elecciones.Infrastructure")] | ||||||
| [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | [assembly: System.Reflection.AssemblyVersionAttribute("1.0.0.0")] | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user