From f019c95456cb200d70a2aa64454a2eb6573515cf Mon Sep 17 00:00:00 2001 From: Sergio Date: Thu, 26 Mar 2026 09:06:39 +0100 Subject: [PATCH] Cambios por el userstate --- HerramientaCASA.sln | 4 +- .../Layout/ConfiguracionLayout.razor | 57 +++-- .../Components/Layout/LoginLayout.razor | 62 +++-- .../Components/Layout/MainLayout.razor | 77 ++++-- HerramientaCASA/Components/Pages/Bajas.razor | 4 +- .../Pages/Comun/ClonarDespacho.razor | 4 +- .../Components/Pages/Default.razor | 49 ++++ .../Components/Pages/HerramientaCASAS.razor | 10 +- .../Components/Pages/HerramientaURBAN.razor | 9 +- .../Components/Pages/Licitaciones.razor | 9 +- .../Components/Pages/LicitacionesURBAN.razor | 9 +- .../Pages/Login/ClaveGenerada.razor | 15 +- .../Components/Pages/Login/Denegado.razor | 5 +- .../Components/Pages/Login/Login.razor | 231 +++++++++++------- .../Components/Pages/Login/NuevoAcceso.razor | 11 +- .../Pages/Simulaciones/SimulacionesTabs.razor | 4 +- .../BajasSimulaciones.razor | 2 +- .../HerramURBANSimulacion.razor | 2 +- .../HerramientaSimulacion.razor | 2 +- .../LicitacionesSimulacion.razor | 2 +- .../LicitacionesUrbanSimulacion.razor | 2 +- HerramientaCASA/Model/UserState.cs | 73 ++---- HerramientaCASA/Program.cs | 53 ++-- HerramientaCASA/UtilidadesCASA.cs | 3 + HerramientaCASA/appsettings.json | 8 +- HerramientaCASA/wwwroot/favicon.png | Bin 1148 -> 3314 bytes 26 files changed, 439 insertions(+), 268 deletions(-) create mode 100644 HerramientaCASA/Components/Pages/Default.razor diff --git a/HerramientaCASA.sln b/HerramientaCASA.sln index aa3865f..a1bc9c8 100644 --- a/HerramientaCASA.sln +++ b/HerramientaCASA.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 18 -VisualStudioVersion = 18.1.11312.151 d18.0 +# Visual Studio Version 17 +VisualStudioVersion = 17.14.36915.13 d17.14 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "HerramientaCASA", "HerramientaCASA\HerramientaCASA.csproj", "{60B569DA-FC18-45B9-8ACC-8E29D8C2EA2C}" EndProject diff --git a/HerramientaCASA/Components/Layout/ConfiguracionLayout.razor b/HerramientaCASA/Components/Layout/ConfiguracionLayout.razor index ad2c827..063e32f 100644 --- a/HerramientaCASA/Components/Layout/ConfiguracionLayout.razor +++ b/HerramientaCASA/Components/Layout/ConfiguracionLayout.razor @@ -9,6 +9,7 @@ @inject UserState userState @inject IJSRuntime JS @using bdHerramientaCACOA.db +@using static HerramientaCASA.Components.Layout.LoginLayout @inject UserState UserState @@ -144,24 +145,46 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { - if (firstRender) - { - bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); + if (!firstRender) + return; - urlAnterior = await JS.InvokeAsync("eval", "document.referrer"); - if (!UserState.PuedeAcceder) - { - rutaActual = Navigation.ToBaseRelativePath(Navigation.Uri); - if (!UtilidadesCASA.UrlPermitida(urlAnterior, bd)) - { - Navigation.NavigateTo("/Denegado", true); - } - else if (userState.idUser == 0) - { - Navigation.NavigateTo("/", true); - } - } - StateHasChanged(); + var result = await ProtectedLocalStore.GetAsync("userSession"); + + if (result.Success && result.Value is not null) + { + UserState.idUser = result.Value.idUser; + UserState.EsAdmin = result.Value.EsAdmin; + UserState.PuedeAcceder = result.Value.PuedeAcceder; + UserState.RedireccionValida = result.Value.RedireccionValida; } + else + { + UserState.idUser = 0; + UserState.EsAdmin = false; + UserState.PuedeAcceder = false; + UserState.RedireccionValida = false; + } + + UserState.EstaCargado = true; + + if (userState?.RedireccionValida == false) + { + Navigation.NavigateTo("/"); + return; + } + else + if (userState?.idUser == 0) + { + Navigation.NavigateTo("/Login"); + return; + } + else + if (userState?.EsAdmin == false) + { + Navigation.NavigateTo("/Login"); + return; + } + + StateHasChanged(); } } diff --git a/HerramientaCASA/Components/Layout/LoginLayout.razor b/HerramientaCASA/Components/Layout/LoginLayout.razor index 3d64eb7..e4476d0 100644 --- a/HerramientaCASA/Components/Layout/LoginLayout.razor +++ b/HerramientaCASA/Components/Layout/LoginLayout.razor @@ -1,6 +1,7 @@ @inherits LayoutComponentBase @using BlazorBootstrap; @using HerramientaCASA.Model +@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage @using Microsoft.AspNetCore.Components.Web @inject UserState UserState @inject IHttpContextAccessor HttpContextAccessor @@ -8,7 +9,7 @@ @inject IJSRuntime JS @using bdHerramientaCACOA.db @inject UserState UserState - +@inject ProtectedLocalStorage ProtectedLocalStore @@ -42,28 +43,53 @@ @code{ - string? urlAnterior = ""; - public tsHerramientasCACOA bd; + // string? urlAnterior = ""; + // public tsHerramientasCACOA bd; - bool urlVaida = true; - string rutaActual = ""; + // bool urlVaida = true; + // string rutaActual = ""; - protected override async Task OnAfterRenderAsync(bool firstRender) - { - if (firstRender) + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (!firstRender) + return; + + var result = await ProtectedLocalStore.GetAsync("userSession"); + + if (result.Success && result.Value is not null) { + UserState.idUser = result.Value.idUser; + UserState.EsAdmin = result.Value.EsAdmin; + UserState.PuedeAcceder = result.Value.PuedeAcceder; + UserState.RedireccionValida = result.Value.RedireccionValida; + } + else + { + UserState.idUser = 0; + UserState.EsAdmin = false; + UserState.PuedeAcceder = false; + UserState.RedireccionValida = false; + } - urlAnterior = await JS.InvokeAsync("eval", "document.referrer"); - //urlAnterior = "https://www.cacoa.es"; - bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); - if (!UtilidadesCASA.UrlPermitida(urlAnterior,bd)) - { - Navigation.NavigateTo("/Denegado", true); - } - StateHasChanged(); - } - } + UserState.EstaCargado = true; + + if (UserState?.RedireccionValida == false) + { + Navigation.NavigateTo("/"); + return; + } + + StateHasChanged(); + } + + public class UserSessionData + { + public int idUser { get; set; } + public bool EsAdmin { get; set; } + public bool PuedeAcceder { get; set; } + public bool RedireccionValida { get; set; } + } } diff --git a/HerramientaCASA/Components/Layout/MainLayout.razor b/HerramientaCASA/Components/Layout/MainLayout.razor index 7b74d7f..39c4843 100644 --- a/HerramientaCASA/Components/Layout/MainLayout.razor +++ b/HerramientaCASA/Components/Layout/MainLayout.razor @@ -9,6 +9,7 @@ @inject UserState userState @inject IJSRuntime JS @using bdHerramientaCACOA.db +@using static HerramientaCASA.Components.Layout.LoginLayout @inject UserState UserState @@ -93,7 +94,7 @@
@@ -130,26 +131,66 @@ private byte[] logoColegioArray = []; private string nombreColegio = ""; + // protected override async Task OnAfterRenderAsync(bool firstRender) + // { + // if (firstRender) + // { + // bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); + // if (!UserState.PuedeAcceder) + // { + // urlAnterior = await JS.InvokeAsync("eval", "document.referrer"); + // rutaActual = Navigation.ToBaseRelativePath(Navigation.Uri); + // if (!UtilidadesCASA.UrlPermitida(urlAnterior, bd)) + // { + // Navigation.NavigateTo("/Denegado"); + // } + // else if (userState.idUser == 0) + // { + // Navigation.NavigateTo("/"); + // } + // } + // StateHasChanged(); + // } + // } + + protected override async Task OnAfterRenderAsync(bool firstRender) { - if (firstRender) + if (!firstRender) + return; + + var result = await ProtectedLocalStore.GetAsync("userSession"); + + if (result.Success && result.Value is not null) { - bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); - if (!UserState.PuedeAcceder) - { - urlAnterior = await JS.InvokeAsync("eval", "document.referrer"); - rutaActual = Navigation.ToBaseRelativePath(Navigation.Uri); - if (!UtilidadesCASA.UrlPermitida(urlAnterior, bd)) - { - Navigation.NavigateTo("/Denegado", true); - } - else if (userState.idUser == 0) - { - Navigation.NavigateTo("/", true); - } - } - StateHasChanged(); - } + UserState.idUser = result.Value.idUser; + UserState.EsAdmin = result.Value.EsAdmin; + UserState.PuedeAcceder = result.Value.PuedeAcceder; + UserState.RedireccionValida = result.Value.RedireccionValida; + } + else + { + UserState.idUser = 0; + UserState.EsAdmin = false; + UserState.PuedeAcceder = false; + UserState.RedireccionValida = false; + } + + UserState.EstaCargado = true; + + if (userState?.RedireccionValida == false) + { + Navigation.NavigateTo("/"); + return; + } + else + if (userState?.idUser == 0) + { + Navigation.NavigateTo("/Login"); + return; + } + + StateHasChanged(); } protected override async Task OnInitializedAsync() diff --git a/HerramientaCASA/Components/Pages/Bajas.razor b/HerramientaCASA/Components/Pages/Bajas.razor index 1cf45fa..78aeb93 100644 --- a/HerramientaCASA/Components/Pages/Bajas.razor +++ b/HerramientaCASA/Components/Pages/Bajas.razor @@ -465,7 +465,7 @@ Type = ToastType.Primary, Message = $"Baja creada correctamente.", }); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link); } private void actualizarBaja(string jsonObjeto) { @@ -488,7 +488,7 @@ var link = "/Bajas?idSimulador=" + tsUtilidades.crypt.FEncS(id.ToString(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", 875421649); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link); } public void RefreshState() { diff --git a/HerramientaCASA/Components/Pages/Comun/ClonarDespacho.razor b/HerramientaCASA/Components/Pages/Comun/ClonarDespacho.razor index c93442c..9e01775 100644 --- a/HerramientaCASA/Components/Pages/Comun/ClonarDespacho.razor +++ b/HerramientaCASA/Components/Pages/Comun/ClonarDespacho.razor @@ -81,9 +81,9 @@ private async void cargarListaSimulaciones() { - var idUser = await ProtectedLocalStore.GetAsync("idUsuario"); + var idUser = UserState.idUser; - listadoSimulaciones = bd.simulaciones.Include(x => x.idTipoSimulacionNavigation).Where(x => x.idCodigo == idUser.Value && (x.idTipoSimulacionNavigation.Codigo == "TIPOHERRAMIENTA.CASA" || x.idTipoSimulacionNavigation.Codigo == "TIPOHERRAMIENTA.URBAND") && x.idSimulacion != datosDespachoClonado.idSimulacion).ToList(); + listadoSimulaciones = bd.simulaciones.Include(x => x.idTipoSimulacionNavigation).Where(x => x.idCodigo == idUser && (x.idTipoSimulacionNavigation.Codigo == "TIPOHERRAMIENTA.CASA" || x.idTipoSimulacionNavigation.Codigo == "TIPOHERRAMIENTA.URBAND") && x.idSimulacion != datosDespachoClonado.idSimulacion).ToList(); } public void RefreshState() diff --git a/HerramientaCASA/Components/Pages/Default.razor b/HerramientaCASA/Components/Pages/Default.razor new file mode 100644 index 0000000..5ae2b83 --- /dev/null +++ b/HerramientaCASA/Components/Pages/Default.razor @@ -0,0 +1,49 @@ +@inherits LayoutComponentBase +@page "/" +@layout DenegadoLayout +@inject UserState UserState +@inject IJSRuntime JS +@inject NavigationManager Navigation +@using BlazorBootstrap; +@using HerramientaCASA.Model +@using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage +@using Microsoft.AspNetCore.Components.Web +@using static HerramientaCASA.Components.Layout.LoginLayout +@inject ProtectedLocalStorage pls +@rendermode InteractiveServer +

+ +@code { + string? urlAnterior = ""; + public tsHerramientasCACOA bd; + + protected override async Task OnAfterRenderAsync(bool firstRender) + { + urlAnterior = await JS.InvokeAsync("eval", "document.referrer"); + + bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); + if (!UtilidadesCASA.UrlPermitida(urlAnterior, bd)) + { + Navigation.NavigateTo("/Denegado", false); + } + else + { + UserState.Limpiar(); + UserState.RedireccionValida = true; + await GuardarSesion(); + Navigation.NavigateTo("/Login", false); + } + //StateHasChanged(); + } + private async Task GuardarSesion() + { + await pls.SetAsync("userSession", new UserSessionData + { + idUser = UserState.idUser, + EsAdmin = UserState.EsAdmin, + PuedeAcceder = UserState.PuedeAcceder, + RedireccionValida = UserState.RedireccionValida + }); + } + +} diff --git a/HerramientaCASA/Components/Pages/HerramientaCASAS.razor b/HerramientaCASA/Components/Pages/HerramientaCASAS.razor index 2dece1b..c7e4ee9 100644 --- a/HerramientaCASA/Components/Pages/HerramientaCASAS.razor +++ b/HerramientaCASA/Components/Pages/HerramientaCASAS.razor @@ -12,7 +12,7 @@ @inject ServicioPDF PdfService @rendermode InteractiveServer @inject NavigationManager Navigation - +@inject UserState userState

@@ -183,8 +183,8 @@ nombreOriginal = casa.NombreSimulacion; } - var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); - idUser = obtenerID.Value; + //var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); + idUser = userState.idUser; } catch (Exception ex) { @@ -247,7 +247,7 @@ Message = $"Simulación creada correctamente.", }); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); return idSimulacionCreada; } @@ -273,7 +273,7 @@ var link = "/HerramientaCASAS?idSimulador=" + tsUtilidades.crypt.FEncS(id.ToString(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", 875421649); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); } public void RefreshState() diff --git a/HerramientaCASA/Components/Pages/HerramientaURBAN.razor b/HerramientaCASA/Components/Pages/HerramientaURBAN.razor index df6c763..353eeb8 100644 --- a/HerramientaCASA/Components/Pages/HerramientaURBAN.razor +++ b/HerramientaCASA/Components/Pages/HerramientaURBAN.razor @@ -10,6 +10,7 @@ @inject ProtectedLocalStorage ProtectedLocalStore @inject IJSRuntime JS @inject ServicioPDF PdfService +@inject UserState userState @rendermode InteractiveServer @@ -159,8 +160,8 @@ } - var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); - idUser = obtenerID.Value; + //var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); + idUser = userState.idUser; } catch (Exception ex) { @@ -226,7 +227,7 @@ Message = $"Simulación creada correctamente.", }); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); return idSimulacionCreada; } @@ -251,7 +252,7 @@ var link = "/HerramientaURBAN?idSimulador=" + tsUtilidades.crypt.FEncS(id.ToString(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", 875421649); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); } diff --git a/HerramientaCASA/Components/Pages/Licitaciones.razor b/HerramientaCASA/Components/Pages/Licitaciones.razor index 632f8b9..3dac635 100644 --- a/HerramientaCASA/Components/Pages/Licitaciones.razor +++ b/HerramientaCASA/Components/Pages/Licitaciones.razor @@ -8,6 +8,7 @@ @inject ProtectedLocalStorage ProtectedLocalStore @inject IJSRuntime JS @inject ServicioPDF PdfService +@inject UserState userState @page "/LicitacionCASA" @@ -284,8 +285,8 @@ nombreOriginal = objetoLicitaciones.Descripcion; } - var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); - idUser = obtenerID.Value; + //var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); + idUser = userState.idUser; } catch (Exception ex) { @@ -354,7 +355,7 @@ Type = ToastType.Primary, Message = $"Licitación creada correctamente.", }); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); return idLicitacionCreada; } private void actualizarLicitacion(string jsonObjeto) @@ -379,7 +380,7 @@ var link = "/LicitacionCASA?idSimulador=" + tsUtilidades.crypt.FEncS(id.ToString(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", 875421649); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); } public void RefreshState() diff --git a/HerramientaCASA/Components/Pages/LicitacionesURBAN.razor b/HerramientaCASA/Components/Pages/LicitacionesURBAN.razor index 174a6f2..f997ec2 100644 --- a/HerramientaCASA/Components/Pages/LicitacionesURBAN.razor +++ b/HerramientaCASA/Components/Pages/LicitacionesURBAN.razor @@ -9,6 +9,7 @@ @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage @inject IJSRuntime JS @inject ServicioPDF PdfService +@inject UserState userState @inject ProtectedLocalStorage ProtectedLocalStore @@ -326,8 +327,8 @@ } - var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); - idUser = obtenerID.Value; + //var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); + idUser = userState.idUser; } catch (Exception ex) { @@ -392,7 +393,7 @@ Message = $"Licitación creada correctamente.", }); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); return idSimulacionCreada; } private void actualizarSimulacion(string jsonObjeto) @@ -416,7 +417,7 @@ var link = "/LicitacionesUrban?idSimulador=" + tsUtilidades.crypt.FEncS(id.ToString(), "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890.:/-*", 875421649); - Navigation.NavigateTo(link, true); + Navigation.NavigateTo(link, false); } public async Task CalcularTabla(string idProvincia) diff --git a/HerramientaCASA/Components/Pages/Login/ClaveGenerada.razor b/HerramientaCASA/Components/Pages/Login/ClaveGenerada.razor index 33ee49b..745c0dc 100644 --- a/HerramientaCASA/Components/Pages/Login/ClaveGenerada.razor +++ b/HerramientaCASA/Components/Pages/Login/ClaveGenerada.razor @@ -1,12 +1,14 @@ @page "/ClaveGenerada" @using HerramientaCASA.Components.Layout +@using HerramientaCASA.Model @using bdHerramientaCACOA.db @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage @rendermode InteractiveServer -@layout LoginLayout +@layout DenegadoLayout @inject NavigationManager Navigation @inject ProtectedLocalStorage ProtectedLocalStore +@inject UserState UserState

@@ -34,17 +36,22 @@ bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); logoColegioArray = bd.ficheros.Where(x => x.NombreFichero == "LogoColegio").Select(x => x.Fichero).First(); - var obtenerId = await ProtectedLocalStore.GetAsync("idUsuario"); - claveUsuario = obtenerId.Value; + //var obtenerId = await ProtectedLocalStore.GetAsync("idUsuario"); + claveUsuario = UserState.idUser; if (claveUsuario == 0 || claveUsuario == null) { Navigation.NavigateTo("/", forceLoad: true); + } else + { + UserState.idUser = claveUsuario.Value; + UserState.PuedeAcceder = true; } + } private async Task irPanelControl() { - Navigation.NavigateTo("/PanelControl", forceLoad: true); + Navigation.NavigateTo("/PanelControl", forceLoad: false); } } diff --git a/HerramientaCASA/Components/Pages/Login/Denegado.razor b/HerramientaCASA/Components/Pages/Login/Denegado.razor index f0cd884..2ed0969 100644 --- a/HerramientaCASA/Components/Pages/Login/Denegado.razor +++ b/HerramientaCASA/Components/Pages/Login/Denegado.razor @@ -28,6 +28,7 @@ + Acceso Denegado
@@ -62,9 +63,11 @@ bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); logoColegioArray = bd.ficheros.First(x => x.NombreFichero == "LogoColegio").Fichero; - var datosURL = bd.enumeraciones.First(x => x.Codigo.Contains("CW.URLWEBCOLEGIO")); + var datosURL = bd.enumeraciones.First(x => x.Codigo.Contains("CW.URLWEBCOLEGIO")); urlWeb = datosURL.ValorAlfabetico1; textoURL = datosURL.ValorAlfabetico2; + + UserState.Limpiar(); } } diff --git a/HerramientaCASA/Components/Pages/Login/Login.razor b/HerramientaCASA/Components/Pages/Login/Login.razor index 5857c59..e338224 100644 --- a/HerramientaCASA/Components/Pages/Login/Login.razor +++ b/HerramientaCASA/Components/Pages/Login/Login.razor @@ -1,163 +1,204 @@ -@page "/" +@page "/Login" @using HerramientaCASA.Model @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage -@using Microsoft.EntityFrameworkCore +@using static HerramientaCASA.Components.Layout.LoginLayout @inject ProtectedLocalStorage ProtectedLocalStore @rendermode InteractiveServer @layout LoginLayout -@inject IHttpContextAccessor HttpContextAccessor @inject NavigationManager Navigation @inject UserState UserState -@inject IJSRuntime JS -
-
+
-
-
+
+
- @if(nombreColegio!="CACOA") + @if (nombreColegio != "CACOA") {
} +
+ +

Acceso a la Herramienta

+
+ + + + +
+ + +
-

Acceso a la Herramienta

+
+ +
+ +
+ +
+ +
+ + +
+ +
+ + Si es la primera vez que utiliza la herramienta, + cree una nueva clave de acceso + +
+ +
+

@mensajeError

+
+ + +
- - -
- - - -
-
- -
- -
- -
-
- @* *@ - - -
-
- Si es la primera vez que utiliza la herramienta, cree una nueva clave de acceso -
- -
-

@mensajeError

-
- -
-

Desarrollado por:

-
-
+
+
-@code { - public tsHerramientasCACOA bd; +@code { + public tsHerramientasCACOA bd = default!; private LoginVM login = new LoginVM(); private string mensajeError = ""; private bool recuerda = false; - string? urlAnterior = ""; - string rutaActual = ""; private byte[] logoColegioArray = []; private string nombreColegio = ""; - - protected override async Task OnInitializedAsync() + protected override Task OnInitializedAsync() { bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: false); nombreColegio = bd.enumeraciones.First(x => x.Codigo == "CW.NOMBRECOLEGIO").ValorAlfabetico1; - logoColegioArray = bd.ficheros.Where(x => x.NombreFichero == "LogoColegio").Select(x => x.Fichero).First(); + logoColegioArray = bd.ficheros + .Where(x => x.NombreFichero == "LogoColegio") + .Select(x => x.Fichero) + .First(); - await ProtectedLocalStore.SetAsync("idUsuario", 0); - await ProtectedLocalStore.SetAsync("EsAdmin", false); + return Task.CompletedTask; + } - // Limpiar almacenamiento local o sesión si se está utilizando - if (HttpContextAccessor?.HttpContext?.Session != null) - { - HttpContextAccessor.HttpContext.Session.Clear(); - } + protected override async Task OnAfterRenderAsync(bool firstRender) + { + if (!firstRender) + return; var rec = await ProtectedLocalStore.GetAsync("rec"); - if(rec.Value==true){ + if (rec.Success && rec.Value) + { var usuario = await ProtectedLocalStore.GetAsync("US"); var clave = await ProtectedLocalStore.GetAsync("PS"); - login.codigo = usuario.Value; - login.password = clave.Value; + + if (usuario.Success) + login.codigo = usuario.Value; + + if (clave.Success) + login.password = clave.Value; + recuerda = true; + StateHasChanged(); } - } - - private async void checkCambiado(bool e) + private Task checkCambiado(bool value) { - recuerda = e; + recuerda = value; + return Task.CompletedTask; } + private async Task Acceder() { - var adminUser = bd.enumeraciones.First(x=> x.Codigo=="CW.ADMIN"); + mensajeError = ""; + + var adminUser = bd.enumeraciones.First(x => x.Codigo == "CW.ADMIN"); if (login.codigo == adminUser.ValorNumerico1 && login.password == adminUser.ValorAlfabetico1) { - await ProtectedLocalStore.SetAsync("idUsuario", -1); - await ProtectedLocalStore.SetAsync("EsAdmin", true); - UserState.idUser = -1; - UserState.PuedeAcceder =true; + UserState.EsAdmin = true; + UserState.PuedeAcceder = true; + UserState.RedireccionValida = true; - Navigation.NavigateTo("/PanelControlConf", forceLoad: true); - } - else - { - var usuario = bd.usuarios.FirstOrDefault(x => x.Codigo == login.codigo && x.Contrasena == login.password); + await GuardarSesion(); - if (usuario == null) + if (recuerda) { - mensajeError = "Usuario no encontrado en la base de datos."; + await ProtectedLocalStore.SetAsync("US", login.codigo); + await ProtectedLocalStore.SetAsync("PS", login.password ?? ""); + await ProtectedLocalStore.SetAsync("rec", true); } else { - - await ProtectedLocalStore.SetAsync("idUsuario", usuario.idUsuario); - await ProtectedLocalStore.SetAsync("EsAdmin", false); - - UserState.idUser = usuario.idUsuario; - UserState.PuedeAcceder =true; - - - if (recuerda) - { - await ProtectedLocalStore.SetAsync("US", login.codigo); - await ProtectedLocalStore.SetAsync("PS", login.password); - await ProtectedLocalStore.SetAsync("rec", true); - } - else - { - await ProtectedLocalStore.SetAsync("rec", false); - } - - - Navigation.NavigateTo("/PanelControl", forceLoad: true); + await ProtectedLocalStore.DeleteAsync("US"); + await ProtectedLocalStore.DeleteAsync("PS"); + await ProtectedLocalStore.SetAsync("rec", false); } + + Navigation.NavigateTo("/PanelControlConf"); + return; } + + var usuario = bd.usuarios.FirstOrDefault(x => x.Codigo == login.codigo && x.Contrasena == login.password); + + if (usuario is null) + { + mensajeError = "Usuario no encontrado en la base de datos."; + return; + } + + UserState.idUser = usuario.idUsuario; + UserState.EsAdmin = false; + UserState.PuedeAcceder = true; + UserState.RedireccionValida = true; + + await GuardarSesion(); + + if (recuerda) + { + await ProtectedLocalStore.SetAsync("US", login.codigo); + await ProtectedLocalStore.SetAsync("PS", login.password ?? ""); + await ProtectedLocalStore.SetAsync("rec", true); + } + else + { + await ProtectedLocalStore.DeleteAsync("US"); + await ProtectedLocalStore.DeleteAsync("PS"); + await ProtectedLocalStore.SetAsync("rec", false); + } + + Navigation.NavigateTo("/PanelControl"); + } + + private async Task GuardarSesion() + { + await ProtectedLocalStore.SetAsync("userSession", new UserSessionData + { + idUser = UserState.idUser, + EsAdmin = UserState.EsAdmin, + PuedeAcceder = UserState.PuedeAcceder, + RedireccionValida = UserState.RedireccionValida + }); } } +` \ No newline at end of file diff --git a/HerramientaCASA/Components/Pages/Login/NuevoAcceso.razor b/HerramientaCASA/Components/Pages/Login/NuevoAcceso.razor index 26bb5f4..9e15efb 100644 --- a/HerramientaCASA/Components/Pages/Login/NuevoAcceso.razor +++ b/HerramientaCASA/Components/Pages/Login/NuevoAcceso.razor @@ -1,13 +1,14 @@ @page "/NuevoAcceso" @using HerramientaCASA.Components.Layout +@using HerramientaCASA.Model @using bdHerramientaCACOA.db @using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage @rendermode InteractiveServer -@layout LoginLayout +@layout DenegadoLayout @inject NavigationManager Navigation @inject ProtectedLocalStorage ProtectedLocalStore - +@inject UserState UserState
@@ -64,10 +65,12 @@ nuevoAcceso.Codigo = nuevoAcceso.idUsuario; bd.SaveChanges(); - await ProtectedLocalStore.SetAsync("idUsuario", nuevoAcceso.idUsuario); + //await ProtectedLocalStore.SetAsync("idUsuario", nuevoAcceso.idUsuario); + + //UserState.idUser = nuevoAcceso.idUsuario; - Navigation.NavigateTo("/ClaveGenerada", forceLoad: true); + Navigation.NavigateTo("/Login"); } } } diff --git a/HerramientaCASA/Components/Pages/Simulaciones/SimulacionesTabs.razor b/HerramientaCASA/Components/Pages/Simulaciones/SimulacionesTabs.razor index 4606937..544f9af 100644 --- a/HerramientaCASA/Components/Pages/Simulaciones/SimulacionesTabs.razor +++ b/HerramientaCASA/Components/Pages/Simulaciones/SimulacionesTabs.razor @@ -71,8 +71,8 @@ { bd = tsHerramientasCACOA.NuevoContexto(SoloLectura: true); - var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); - idUser = obtenerID.Value; + //var obtenerID = await ProtectedLocalStore.GetAsync("idUsuario"); + idUser = UserState.idUser; listadoSimulaciones = bd.simulaciones.Include(x => x.idTipoSimulacionNavigation).Include(x => x.idFicheroJSONNavigation).Where(x => x.idCodigo == idUser && x.idTipoSimulacionNavigation.Codigo == "TIPOHERRAMIENTA." + TipoSimulacion).ToList(); } diff --git a/HerramientaCASA/Components/Pages/TablasSimulaciones/BajasSimulaciones.razor b/HerramientaCASA/Components/Pages/TablasSimulaciones/BajasSimulaciones.razor index af9f198..9b92eba 100644 --- a/HerramientaCASA/Components/Pages/TablasSimulaciones/BajasSimulaciones.razor +++ b/HerramientaCASA/Components/Pages/TablasSimulaciones/BajasSimulaciones.razor @@ -35,7 +35,7 @@ private void irNuevaSimulacion() { - Navigation.NavigateTo("/Bajas", true); + Navigation.NavigateTo("/Bajas", false); } } diff --git a/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramURBANSimulacion.razor b/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramURBANSimulacion.razor index faf67ba..70d9e25 100644 --- a/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramURBANSimulacion.razor +++ b/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramURBANSimulacion.razor @@ -36,7 +36,7 @@ private void irNuevaSimulacion() { - Navigation.NavigateTo("/HerramientaURBAN", true); + Navigation.NavigateTo("/HerramientaURBAN", false); } } diff --git a/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramientaSimulacion.razor b/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramientaSimulacion.razor index 5967442..3ee2c0f 100644 --- a/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramientaSimulacion.razor +++ b/HerramientaCASA/Components/Pages/TablasSimulaciones/HerramientaSimulacion.razor @@ -37,7 +37,7 @@ private void irNuevaSimulacion() { - Navigation.NavigateTo("/HerramientaCASAS", true); + Navigation.NavigateTo("/HerramientaCASAS", false); } } diff --git a/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesSimulacion.razor b/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesSimulacion.razor index 6332cd7..75382db 100644 --- a/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesSimulacion.razor +++ b/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesSimulacion.razor @@ -36,7 +36,7 @@ private void irNuevaSimulacion() { - Navigation.NavigateTo("/LicitacionCASA", true); + Navigation.NavigateTo("/LicitacionCASA", false); } } diff --git a/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesUrbanSimulacion.razor b/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesUrbanSimulacion.razor index 9341915..e524cc8 100644 --- a/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesUrbanSimulacion.razor +++ b/HerramientaCASA/Components/Pages/TablasSimulaciones/LicitacionesUrbanSimulacion.razor @@ -36,7 +36,7 @@ private void irNuevaSimulacion() { - Navigation.NavigateTo("/LicitacionesURBAN", true); + Navigation.NavigateTo("/LicitacionesURBAN", false); } } diff --git a/HerramientaCASA/Model/UserState.cs b/HerramientaCASA/Model/UserState.cs index f36024f..6d59a86 100644 --- a/HerramientaCASA/Model/UserState.cs +++ b/HerramientaCASA/Model/UserState.cs @@ -2,64 +2,21 @@ { public class UserState { - private readonly object _lock = new object(); - private int _idUser; - private bool _esAdmin; - private bool _puedeAcceder; - public int idUser + public int idUser { get; set; } + public bool EsAdmin { get; set; } + public bool PuedeAcceder { get; set; } + public bool RedireccionValida { get; set; } + public bool EstaCargado { get; set; } + //public DateTime UltimoAcceso { get; set; } + + public void Limpiar() { - get - { - lock (_lock) - { - return _idUser; - } - } - set - { - lock (_lock) - { - _idUser = value; - } - } + idUser = 0; + EsAdmin = false; + PuedeAcceder = false; + RedireccionValida = false; + EstaCargado = true; + //UltimoAcceso = DateTime.Now; } - - public bool EsAdmin - { - get - { - lock (_lock) - { - return _esAdmin; - } - } - set - { - lock (_lock) - { - _esAdmin = value; - } - } - } - - - public bool PuedeAcceder - { - get - { - lock (_lock) - { - return _puedeAcceder; - } - } - set - { - lock (_lock) - { - _puedeAcceder = value; - } - } - } - } -} +} \ No newline at end of file diff --git a/HerramientaCASA/Program.cs b/HerramientaCASA/Program.cs index dc58f34..fc238f9 100644 --- a/HerramientaCASA/Program.cs +++ b/HerramientaCASA/Program.cs @@ -1,4 +1,5 @@ using bdHerramientaCACOA.dbcontext; +using bdHerramientaCACOA.HerramientaUrban; using DinkToPdf; using DinkToPdf.Contracts; using HerramientaCASA; @@ -7,10 +8,12 @@ using HerramientaCASA.Model; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Components.Server.ProtectedBrowserStorage; using Microsoft.AspNetCore.Mvc; +using Microsoft.EntityFrameworkCore.Metadata.Internal; using System.Globalization; using System.Runtime.InteropServices; using tsUtilidades; + var builder = WebApplication.CreateBuilder(args); @@ -57,7 +60,7 @@ builder.Services.AddSession(options => builder.Services.AddHttpClient(); builder.Services.AddBlazorBootstrap(); builder.Services.AddAntiforgery(); -builder.Services.AddSingleton(); +builder.Services.AddScoped(); builder.Services.AddScoped(); var app = builder.Build(); @@ -94,29 +97,41 @@ app.UseAntiforgery(); app.Use(async (context, next) => { - var userState = context.RequestServices.GetService(); - var path = context.Request.Path; + //var userState = context.RequestServices.GetService(); + //var path = context.Request.Path; - if (path == "/" || - path.StartsWithSegments("/_blazor") || - path.StartsWithSegments("/Content") || - path.StartsWithSegments("/Scripts") || - path.StartsWithSegments("/favicon.ico") || - path.StartsWithSegments("/_framework")) - { - await next(); - return; - } - - //// Redirigir al home si no hay token y la ruta no es pública - //if (userState?.idUser == 0) + //if (path == "/" || + // path == "/Denegado" || + // path.StartsWithSegments("/_blazor") || + // path.StartsWithSegments("/_content") || + // path.StartsWithSegments("/Content") || + // path.StartsWithSegments("/Scripts") || + // path.StartsWithSegments("/favicon.ico") || + // path.StartsWithSegments("/_framework") || + // (path == "/Login" && userState.RedireccionValida == true)) //{ - // Console.WriteLine($"Redirigiendo al home desde: {path}"); - // context.Response.Redirect("/"); + // await next(); // return; //} - // Continuar con la solicitud + + //if (userState?.RedireccionValida == false) + //{ + // Console.WriteLine($"Redirigiendo al home desde: {path}"); + // context.Response.Redirect("/"); + // await next(); + // return; + //} + //else + //if (userState?.idUser == 0) + //{ + // Console.WriteLine($"Redirigiendo al home desde: {path}"); + // context.Response.Redirect("/Login"); + // await next(); + // return; + //} + + ////Continuar con la solicitud await next(); }); diff --git a/HerramientaCASA/UtilidadesCASA.cs b/HerramientaCASA/UtilidadesCASA.cs index 0ab757f..659b216 100644 --- a/HerramientaCASA/UtilidadesCASA.cs +++ b/HerramientaCASA/UtilidadesCASA.cs @@ -5,6 +5,7 @@ using bdHerramientaCACOA.HerramientaURBAN; using BlazorBootstrap; using ClosedXML.Excel; using DocumentFormat.OpenXml.Office2013.Drawing.ChartStyle; +using DocumentFormat.OpenXml.Spreadsheet; using HerramientaCASA.Components.Pages; using HerramientaCASA.Components.Pages.HerramientaCASATabs; using HerramientaCASA.Model; @@ -1513,5 +1514,7 @@ namespace HerramientaCASA return table; } + + //private static } } diff --git a/HerramientaCASA/appsettings.json b/HerramientaCASA/appsettings.json index ef33833..5b91da4 100644 --- a/HerramientaCASA/appsettings.json +++ b/HerramientaCASA/appsettings.json @@ -6,12 +6,12 @@ } }, "ConnectionStrings": { - "WriteConnection": "Server=localhost;Port=22222;Database=herramientascoaaragon;User Id=cacoa;Password=cacoa2018-;", - "ReadOnlyConnection": "Server=localhost;Port=22222;Database=herramientascoaaragon;User Id=cacoa;Password=cacoa2018-;" + //"WriteConnection": "Server=localhost;Port=22222;Database=herramientascacoa;User Id=cacoa;Password=cacoa2018-;", + //"ReadOnlyConnection": "Server=localhost;Port=22222;Database=herramientascacoa;User Id=cacoa;Password=cacoa2018-;" // CONEXIÓN CACOA - //"WriteConnection": "Server=77.229.174.85;Port=22222;Database=herramientascacoa;User Id=cacoa;Password=cacoa2018-;", - //"ReadOnlyConnection": "Server=77.229.174.85;Port=22222;Database=herramientascacoa;User Id=cacoa;Password=cacoa2018-;" + "WriteConnection": "Server=77.229.174.85;Port=22222;Database=herramientascacoa;User Id=cacoa;Password=cacoa2018-;", + "ReadOnlyConnection": "Server=77.229.174.85;Port=22222;Database=herramientascacoa;User Id=cacoa;Password=cacoa2018-;" // CONEXIÓN Herramienta Cacoa Generica //"WriteConnection": "Server=77.229.174.85;Port=22222;Database=herramientascacoagenerica;User Id=cacoa;Password=cacoa2018-;", diff --git a/HerramientaCASA/wwwroot/favicon.png b/HerramientaCASA/wwwroot/favicon.png index 8422b59695935d180d11d5dbe99653e711097819..86934aa17d2e0a3f4bf1f171e0a9bdf8af852ade 100644 GIT binary patch literal 3314 zcmaJ^2~?6<8@9}`u|`{5GEE6bLsJmk05L~F%rVe%YcUf6m6RO?Y|?T%lVW9!+Txbw zN&PjoG?%h;`V}2l&a}CtnV49b8uq)ClK%&4(|^vKpL4k1{qB9<=Y8*epZi`&_9c4$ zptW5~O-=0wuf4bfz;jmlUB4D+kFzGO0}n%<$3dPSGn~gKaj0r;6lNF|xPYhX8o(eL z#RVMXK(HmSu+&J}-Z&1`FOKL>j*B9rC}7t;AdCPF5YVYS5=cOgW^mC07qE&K4fK`6 zFfd33;YGQCmxDS;@C9L+94g2G>S#lT+uMSiP*Av|t-S->8icTgJHc!nV787nws5p9 z5{-a^Rz6_B8;25(K7hlo_yXQsz>z#23k`$u`Ftqf4$9<2z~Cqp3TBIdArLkI!iFnk z@JIq12G?wr0Y~MMIW!iJ#$g~Dm0gOfckeB|A^-L3t3dy0V}FlscFPG#`8 zfG_x0N5DRR1^=TPB`FX&8pkBZD9ycaE?{5;N}*BE2seb2Eeh|3z}aEpa1WF_7LIpE zIKb`f+}!X^aK}|!F9w%KVvwn;wzR)(QUBK#jpa~DJSNAV$&6mjv~MJn$K*ybSs*M{ znOP)=KqAu^$}wdsR-&bHXt7iZp2MVrRC|f0eG@}W3=lv#Dcm89LUFJOBiT`G;BX4b zhD5Q0+feN6C{7M=BqAIh23|3ye6x552NWKTz@duFb7)hE#qPT!=r+H zBePX3pj~D6>!AT&z8*U&12}6O;7}Pa$`7fjt$*u-d zCO%v;db7Er4VrQZeEwM$<J)zg|55G}V3>1SlMv&oG{1H4ka2?Q2}?D?jU8tDdBq`Bl}b>uN%@`^#$WEI=Z4-IkZQ6Q^TzyRKa< zx*f!ccp_TG08C2cm%Hmd!4QBc5BU>&xm|VxOp4h)6*pKy#0pefWuWc5IDE%wyQaAN zV0UTXVgX=wN}76(>#ri2Z!ECOq!AO4!WMS%)NCsJ%7nlQHL2E zZfBS;bXzw?b;CAJHW;FW&Rs)^X2pZqJr!`%StN`QIJ; zykRPR(qgc)^3xp6?~A+}mIWDWN!spYOxtnNeAn%)JK;e)K8d|Lcu zZn1U{GWlrEZS>)rQe?eRw}cs{<9jUI$*I%;wfVQtIydgyPx zB&(Qh`*?#0_Y4>#I9nPu@^7Pc%L!dp z2RZezJHTkr>L&NR^(qM2X<0uBntW{`?%rKHPmot_oz_)4ga!snB8KV zf=~GXY4*u3`O^@|hE5T9A4v#$$b9Elxuz zLtkUvmX2h>UoIfYMJ;i6ac!=JIOxJotf>6Rhm#_Ao~S$+5ZzTD`KH5n;>2r`wLWC~ zqcVz`yhb5i=hrl0g8ZMA)8l9AeJkIyv^7jRmzp~jqKrZPhOP-olBS7&>r|=CFw=5+ zqPHc_O#;1VRZ?-g`xgE3%C!5DgUy z(F>(i)psYZF#KB&dGgQ_9EH^$8Djy|3{k`U_@{`S`cL&bdEEMcZD` zhcACEL-5_&1Af1ZBo?YF$YL@aOq6GAFws`57Nb1m#a_o$y2eSLdUc@Ui#LeE#$no2-5lEgaLo6 zPJK^SW8`1#Cs?D~FG3R^mK|cA3wdN-A9(f4I>MvLEmL$wwVCwgacBu5K8bMRa(p=a zA>Ef(o@tu3t!Ue$=_~myErr}#SKv2jsP;AC}um|x&?)6BO6M1N1z@sfU+)voHI$;S5q zoSG|w5a1!3OuxLprhgt#QLIU>62OhFcU5Bj)n@EVi((hs0w-TVy$Uu*&}Q zk?`Sp87JMksZB2x%hcE~Q?>2`fB9|%YMOpf@Svt{OZ2@_Q3)qm>nC}Hx$&92`OK&3 zrGr&*dGl?R?E6S@(Djm2(x|S0pX61Vtjn;{T7|5_@aLZcaX|f(2l$4z(D zZEWgfsHqg-6^Kb}miN{JdP;45Z2s`nxkXx^EIKK3&U@mqjI?&{9cT^t-CbVAcWR^^ z)YX*v1!E4OMH_~0&VNqhDE%1`r#1BWOYkJ=RcG(bP0IT{ZyqcCQ%BrgR%?|vUwk6d zA>OfY8mD1b_~zTgqP&ikKNHk-6V_%&?q!GK;|)U90)5_1wY9PC QDgT9dc@S}B?xBhQ1@XPVD*ylh literal 1148 zcmV-?1cUpDP)9h26h2-Cs%i*@Moc3?#6qJID|D#|3|2Hn7gTIYEkr|%Xjp);YgvFmB&0#2E2b=| zkVr)lMv9=KqwN&%obTp-$<51T%rx*NCwceh-E+=&e(oLO`@Z~7gybJ#U|^tB2Pai} zRN@5%1qsZ1e@R(XC8n~)nU1S0QdzEYlWPdUpH{wJ2Pd4V8kI3BM=)sG^IkUXF2-j{ zrPTYA6sxpQ`Q1c6mtar~gG~#;lt=s^6_OccmRd>o{*=>)KS=lM zZ!)iG|8G0-9s3VLm`bsa6e ze*TlRxAjXtm^F8V`M1%s5d@tYS>&+_ga#xKGb|!oUBx3uc@mj1%=MaH4GR0tPBG_& z9OZE;->dO@`Q)nr<%dHAsEZRKl zedN6+3+uGHejJp;Q==pskSAcRcyh@6mjm2z-uG;s%dM-u0*u##7OxI7wwyCGpS?4U zBFAr(%GBv5j$jS@@t@iI8?ZqE36I^4t+P^J9D^ELbS5KMtZ z{Qn#JnSd$15nJ$ggkF%I4yUQC+BjDF^}AtB7w348EL>7#sAsLWs}ndp8^DsAcOIL9 zTOO!!0!k2`9BLk25)NeZp7ev>I1Mn={cWI3Yhx2Q#DnAo4IphoV~R^c0x&nw*MoIV zPthX?{6{u}sMS(MxD*dmd5rU(YazQE59b|TsB5Tm)I4a!VaN@HYOR)DwH1U5y(E)z zQqQU*B%MwtRQ$%x&;1p%ANmc|PkoFJZ%<-uq%PX&C!c-7ypis=eP+FCeuv+B@h#{4 zGx1m0PjS~FJt}3mdt4c!lel`1;4W|03kcZRG+DzkTy|7-F~eDsV2Tx!73dM0H0CTh zl)F-YUkE1zEzEW(;JXc|KR5{ox%YTh{$%F$a36JP6Nb<0%#NbSh$dMYF-{ z1_x(Vx)}fs?5_|!5xBTWiiIQHG<%)*e=45Fhjw_tlnmlixq;mUdC$R8v#j( zhQ$9YR-o%i5Uc`S?6EC51!bTRK=Xkyb<18FkCKnS2;o*qlij1YA@-nRpq#OMTX&RbL<^2q@0qja!uIvI;j$6>~k@IMwD42=8$$!+R^@5o6HX(*n~