From f10beece4e29ab497156a575313f2fbbff5fec0b Mon Sep 17 00:00:00 2001 From: GiuseppeS Date: Tue, 23 Sep 2025 18:45:31 +0200 Subject: [PATCH] Rimosse risorse inutilizzate e migliorata Login page --- .../Layout/AuthLayout.razor | 99 +++++++++ .../Layout/MainLayout.razor | 86 +++++++- .../Layout/NavMenu.razor | 38 ++-- .../Pages/Dashboard.razor | 34 +-- ...omponentsEndpointRouteBuilderExtensions.cs | 119 ++-------- .../Account/IdentityNoOpEmailSender.cs | 21 -- .../Account/Pages/AccessDenied.razor | 14 +- .../Account/Pages/ConfirmEmail.razor | 48 ---- .../Account/Pages/ConfirmEmailChange.razor | 68 ------ .../Account/Pages/ExternalLogin.razor | 205 ------------------ .../Account/Pages/ForgotPassword.razor | 68 ------ .../Pages/ForgotPasswordConfirmation.razor | 7 - .../Account/Pages/InvalidPasswordReset.razor | 8 - .../Components/Account/Pages/Lockout.razor | 8 - .../Components/Account/Pages/Login.razor | 108 +++++---- .../Account/Pages/LoginWith2fa.razor | 101 --------- .../Account/Pages/LoginWithRecoveryCode.razor | 85 -------- .../Account/Pages/Manage/ChangePassword.razor | 98 --------- .../Pages/Manage/DeletePersonalData.razor | 86 -------- .../Account/Pages/Manage/Disable2fa.razor | 64 ------ .../Account/Pages/Manage/Email.razor | 122 ----------- .../Pages/Manage/EnableAuthenticator.razor | 178 --------------- .../Account/Pages/Manage/ExternalLogins.razor | 140 ------------ .../Pages/Manage/GenerateRecoveryCodes.razor | 68 ------ .../Pages/Manage/ResetAuthenticator.razor | 52 ----- .../Account/Pages/Manage/SetPassword.razor | 87 -------- .../Manage/TwoFactorAuthentication.razor | 110 ---------- .../Components/Account/Pages/Register.razor | 146 ------------- .../Account/Pages/RegisterConfirmation.razor | 68 ------ .../Pages/ResendEmailConfirmation.razor | 70 ------ .../Account/Pages/ResetPassword.razor | 103 --------- .../Pages/ResetPasswordConfirmation.razor | 7 - .../IntegryControlPanel/Components/App.razor | 2 +- .../IntegryControlPanel/Program.cs | 2 - .../wwwroot/images/background.png | Bin 0 -> 1987419 bytes 35 files changed, 287 insertions(+), 2233 deletions(-) create mode 100644 IntegryControlPanel/IntegryControlPanel.Client/Layout/AuthLayout.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityNoOpEmailSender.cs delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmail.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmailChange.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ExternalLogin.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPassword.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPasswordConfirmation.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/InvalidPasswordReset.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Lockout.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWith2fa.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWithRecoveryCode.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ChangePassword.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/DeletePersonalData.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Disable2fa.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Email.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/EnableAuthenticator.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ExternalLogins.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ResetAuthenticator.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/SetPassword.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/TwoFactorAuthentication.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Register.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/RegisterConfirmation.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResendEmailConfirmation.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPassword.razor delete mode 100644 IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPasswordConfirmation.razor create mode 100644 IntegryControlPanel/IntegryControlPanel/wwwroot/images/background.png diff --git a/IntegryControlPanel/IntegryControlPanel.Client/Layout/AuthLayout.razor b/IntegryControlPanel/IntegryControlPanel.Client/Layout/AuthLayout.razor new file mode 100644 index 0000000..98ee0bb --- /dev/null +++ b/IntegryControlPanel/IntegryControlPanel.Client/Layout/AuthLayout.razor @@ -0,0 +1,99 @@ +@inherits LayoutComponentBase + + + + + + + + + @* + Integry Control Panel + + *@ + + + + @Body + + + + +
+ An unhandled error has occurred. + Reload + ?? +
+ +@code { + MudTheme MyCustomTheme = new MudTheme() + { + PaletteLight = new PaletteLight() + { + Primary = "#4CAF50", // Verde Material (puoi usare anche #43A047 o #2E7D32 per più scuro) + Secondary = "#00BFA5", // Verde acqua moderno + Tertiary = "#8BC34A", // Verde lime di supporto + Background = "#FDFDFD", + Surface = "#FFFFFF", + AppbarBackground = "#FFFFFF", + AppbarText = "#212121", + DrawerBackground = "#F9F9F9", + DrawerText = "#212121", + DrawerIcon = "#4CAF50", + TextPrimary = "#212121", + TextSecondary = "#616161", + ActionDefault = "#4CAF50", + ActionDisabled = "#BDBDBD", + Divider = "#E0E0E0", + LinesDefault = "#E0E0E0", + TableLines = "#E0E0E0" + }, + Typography = new Typography() + { + Default = new DefaultTypography() + { + FontFamily = ["Montserrat", "Roboto", "Helvetica", "Arial", "sans-serif"], + FontSize = ".95rem", + FontWeight = "400", + LineHeight = "1.5" + }, + H6 = new H6Typography() + { + FontSize = "1.1rem", + FontWeight = "500", + LetterSpacing = ".0156em" + }, + Button = new ButtonTypography() + { + TextTransform = "none", + FontWeight = "500" + } + }, + LayoutProperties = new LayoutProperties() + { + DefaultBorderRadius = "16px" // Flat ma leggermente smussato (stile Material You) + }, + Shadows = new Shadow() + { + + Elevation = + [ + + "none", // 0 + "0px 1px 2px rgba(0,0,0,0.05)", // 1 + "0px 2px 4px rgba(0,0,0,0.08)", // 2 + "0px 4px 8px rgba(0,0,0,0.1)", // 3 + "0px 8px 16px rgba(0,0,0,0.12)",// 4 + "0px 12px 24px rgba(0,0,0,0.14)",// 5 + // dal 6 al 24 puoi riciclare o tenere "none" + "none","none","none","none","none", + "none","none","none","none","none", + "none","none","none","none","none", + "none","none","none","none","none" + ] + } + }; +} \ No newline at end of file diff --git a/IntegryControlPanel/IntegryControlPanel.Client/Layout/MainLayout.razor b/IntegryControlPanel/IntegryControlPanel.Client/Layout/MainLayout.razor index 3e9bc61..aadf2ab 100644 --- a/IntegryControlPanel/IntegryControlPanel.Client/Layout/MainLayout.razor +++ b/IntegryControlPanel/IntegryControlPanel.Client/Layout/MainLayout.razor @@ -1,16 +1,16 @@ @inherits LayoutComponentBase - - - - + + + + - + Integry Control Panel - + @@ -18,10 +18,10 @@ - + - + @Body @@ -37,6 +37,74 @@ @code { private bool _drawerOpen = true; -} + MudTheme MyCustomTheme = new MudTheme() + { + PaletteLight = new PaletteLight() + { + Primary = "#4CAF50", // Verde Material (puoi usare anche #43A047 o #2E7D32 per più scuro) + Secondary = "#00BFA5", // Verde acqua moderno + Tertiary = "#8BC34A", // Verde lime di supporto + Background = "#FDFDFD", + Surface = "#FFFFFF", + AppbarBackground = "#FFFFFF", + AppbarText = "#212121", + DrawerBackground = "#F9F9F9", + DrawerText = "#212121", + DrawerIcon = "#4CAF50", + TextPrimary = "#212121", + TextSecondary = "#616161", + ActionDefault = "#4CAF50", + ActionDisabled = "#BDBDBD", + Divider = "#E0E0E0", + LinesDefault = "#E0E0E0", + TableLines = "#E0E0E0" + }, + Typography = new Typography() + { + Default = new DefaultTypography() + { + FontFamily = ["Roboto", "Helvetica", "Arial", "sans-serif"], + FontSize = ".95rem", + FontWeight = "400", + LineHeight = "1.5" + }, + H6 = new H6Typography() + { + FontSize = "1.1rem", + FontWeight = "500", + LetterSpacing = ".0156em" + }, + Button = new ButtonTypography() + { + TextTransform = "none", + FontWeight = "500" + } + }, + LayoutProperties = new LayoutProperties() + { + DefaultBorderRadius = "12px" // Flat ma leggermente smussato (stile Material You) + }, + Shadows = new Shadow() + { + + Elevation = + [ + + "none", // 0 + "0px 1px 2px rgba(0,0,0,0.05)", // 1 + "0px 2px 4px rgba(0,0,0,0.08)", // 2 + "0px 4px 8px rgba(0,0,0,0.1)", // 3 + "0px 8px 16px rgba(0,0,0,0.12)",// 4 + "0px 12px 24px rgba(0,0,0,0.14)",// 5 + // dal 6 al 24 puoi riciclare o tenere "none" + "none","none","none","none","none", + "none","none","none","none","none", + "none","none","none","none","none", + "none","none","none","none","none" + ] + } + }; + +} \ No newline at end of file diff --git a/IntegryControlPanel/IntegryControlPanel.Client/Layout/NavMenu.razor b/IntegryControlPanel/IntegryControlPanel.Client/Layout/NavMenu.razor index 1137a67..efa7e3a 100644 --- a/IntegryControlPanel/IntegryControlPanel.Client/Layout/NavMenu.razor +++ b/IntegryControlPanel/IntegryControlPanel.Client/Layout/NavMenu.razor @@ -6,31 +6,19 @@ Dashboard - - - Server - Client - Servizi - - - Counter - Weather - Auth Required - - - - Profilo (@context.User.Identity?.Name) - - Logout - - + + + Server + Client + Servizi + + + + Logout + - - Login - Register - @@ -54,5 +42,5 @@ { NavigationManager.LocationChanged -= OnLocationChanged; } -} +} \ No newline at end of file diff --git a/IntegryControlPanel/IntegryControlPanel.Client/Pages/Dashboard.razor b/IntegryControlPanel/IntegryControlPanel.Client/Pages/Dashboard.razor index 5c3cc8e..3e0203b 100644 --- a/IntegryControlPanel/IntegryControlPanel.Client/Pages/Dashboard.razor +++ b/IntegryControlPanel/IntegryControlPanel.Client/Pages/Dashboard.razor @@ -8,13 +8,13 @@ Dashboard - + @* Benvenuto, @context.User.Identity?.Name! - + *@ @@ -129,35 +129,7 @@ - - - - - - Informazioni Sistema - - - - -
- - Versione: 1.0.0 - -
-
- - Database: Connesso - -
-
- - LDAP: Connesso - -
-
-
-
-
+
diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs b/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs index b9c0ddf..e1a19dd 100644 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs +++ b/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityComponentsEndpointRouteBuilderExtensions.cs @@ -17,107 +17,30 @@ namespace Microsoft.AspNetCore.Routing // These endpoints are required by the Identity Razor components defined in the /Components/Account/Pages directory of this project. public static IEndpointConventionBuilder MapAdditionalIdentityEndpoints(this IEndpointRouteBuilder endpoints) { - ArgumentNullException.ThrowIfNull(endpoints); + ArgumentNullException.ThrowIfNull(endpoints); - var accountGroup = endpoints.MapGroup("/Account"); + var accountGroup = endpoints.MapGroup("/Account"); - accountGroup.MapPost("/PerformExternalLogin", ( - HttpContext context, - [FromServices] SignInManager signInManager, - [FromForm] string provider, - [FromForm] string returnUrl) => - { - IEnumerable> query = [ - new("ReturnUrl", returnUrl), - new("Action", ExternalLogin.LoginCallbackAction)]; + accountGroup.MapPost("/Logout", async ( + ClaimsPrincipal user, + [FromServices] SignInManager signInManager, + [FromForm] string returnUrl) => + { + await signInManager.SignOutAsync(); + return TypedResults.LocalRedirect($"~/{returnUrl}"); + }); - var redirectUrl = UriHelper.BuildRelative( - context.Request.PathBase, - "/Account/ExternalLogin", - QueryString.Create(query)); + // Add GET endpoint for logout to handle navigation from WebAssembly client + accountGroup.MapGet("/Logout", async ( + ClaimsPrincipal user, + [FromServices] SignInManager signInManager, + [FromQuery] string? returnUrl) => + { + await signInManager.SignOutAsync(); + return TypedResults.LocalRedirect($"~/{returnUrl ?? "Account/Login"}"); + }); - var properties = signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl); - return TypedResults.Challenge(properties, [provider]); - }); - - accountGroup.MapPost("/Logout", async ( - ClaimsPrincipal user, - [FromServices] SignInManager signInManager, - [FromForm] string returnUrl) => - { - await signInManager.SignOutAsync(); - return TypedResults.LocalRedirect($"~/{returnUrl}"); - }); - - // Add GET endpoint for logout to handle navigation from WebAssembly client - accountGroup.MapGet("/Logout", async ( - ClaimsPrincipal user, - [FromServices] SignInManager signInManager, - [FromQuery] string? returnUrl) => - { - await signInManager.SignOutAsync(); - return TypedResults.LocalRedirect($"~/{returnUrl ?? "Account/Login"}"); - }); - - var manageGroup = accountGroup.MapGroup("/Manage").RequireAuthorization(); - - manageGroup.MapPost("/LinkExternalLogin", async ( - HttpContext context, - [FromServices] SignInManager signInManager, - [FromForm] string provider) => - { - // Clear the existing external cookie to ensure a clean login process - await context.SignOutAsync(IdentityConstants.ExternalScheme); - - var redirectUrl = UriHelper.BuildRelative( - context.Request.PathBase, - "/Account/Manage/ExternalLogins", - QueryString.Create("Action", ExternalLogins.LinkLoginCallbackAction)); - - var properties = signInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl, signInManager.UserManager.GetUserId(context.User)); - return TypedResults.Challenge(properties, [provider]); - }); - - var loggerFactory = endpoints.ServiceProvider.GetRequiredService(); - var downloadLogger = loggerFactory.CreateLogger("DownloadPersonalData"); - - manageGroup.MapPost("/DownloadPersonalData", async ( - HttpContext context, - [FromServices] UserManager userManager, - [FromServices] AuthenticationStateProvider authenticationStateProvider) => - { - var user = await userManager.GetUserAsync(context.User); - if (user is null) - { - return Results.NotFound($"Unable to load user with ID '{userManager.GetUserId(context.User)}'."); - } - - var userId = await userManager.GetUserIdAsync(user); - downloadLogger.LogInformation("User with ID '{UserId}' asked for their personal data.", userId); - - // Only include personal data for download - var personalData = new Dictionary(); - var personalDataProps = typeof(ApplicationUser).GetProperties().Where( - prop => Attribute.IsDefined(prop, typeof(PersonalDataAttribute))); - foreach (var p in personalDataProps) - { - personalData.Add(p.Name, p.GetValue(user)?.ToString() ?? "null"); - } - - var logins = await userManager.GetLoginsAsync(user); - foreach (var l in logins) - { - personalData.Add($"{l.LoginProvider} external login provider key", l.ProviderKey); - } - - personalData.Add("Authenticator Key", (await userManager.GetAuthenticatorKeyAsync(user))!); - var fileBytes = JsonSerializer.SerializeToUtf8Bytes(personalData); - - context.Response.Headers.TryAdd("Content-Disposition", "attachment; filename=PersonalData.json"); - return TypedResults.File(fileBytes, contentType: "application/json", fileDownloadName: "PersonalData.json"); - }); - - return accountGroup; - } + return accountGroup; + } } } diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityNoOpEmailSender.cs b/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityNoOpEmailSender.cs deleted file mode 100644 index 51f48b1..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/IdentityNoOpEmailSender.cs +++ /dev/null @@ -1,21 +0,0 @@ -using IntegryControlPanel.Data; -using Microsoft.AspNetCore.Identity; -using Microsoft.AspNetCore.Identity.UI.Services; - -namespace IntegryControlPanel.Components.Account -{ - // Remove the "else if (EmailSender is IdentityNoOpEmailSender)" block from RegisterConfirmation.razor after updating with a real implementation. - internal sealed class IdentityNoOpEmailSender : IEmailSender - { - private readonly IEmailSender emailSender = new NoOpEmailSender(); - - public Task SendConfirmationLinkAsync(ApplicationUser user, string email, string confirmationLink) => - emailSender.SendEmailAsync(email, "Confirm your email", $"Please confirm your account by clicking here."); - - public Task SendPasswordResetLinkAsync(ApplicationUser user, string email, string resetLink) => - emailSender.SendEmailAsync(email, "Reset your password", $"Please reset your password by clicking here."); - - public Task SendPasswordResetCodeAsync(ApplicationUser user, string email, string resetCode) => - emailSender.SendEmailAsync(email, "Reset your password", $"Please reset your password using the following code: {resetCode}"); - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/AccessDenied.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/AccessDenied.razor index db67a6f..13ac9ea 100644 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/AccessDenied.razor +++ b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/AccessDenied.razor @@ -1,5 +1,15 @@ @page "/Account/AccessDenied" +@layout IntegryControlPanel.Client.Layout.AuthLayout -Access denied +Accesso negato -You do not have access to this resource. + + Accesso negato + Non hai i permessi necessari per accedere a questa risorsa. + + + + + Torna alla home + + diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmail.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmail.razor deleted file mode 100644 index dcfe8f3..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmail.razor +++ /dev/null @@ -1,48 +0,0 @@ -@page "/Account/ConfirmEmail" - -@using System.Text -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IdentityRedirectManager RedirectManager - -Confirm email - -

Confirm email

- - -@code { - private string? statusMessage; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromQuery] - private string? UserId { get; set; } - - [SupplyParameterFromQuery] - private string? Code { get; set; } - - protected override async Task OnInitializedAsync() - { - if (UserId is null || Code is null) - { - RedirectManager.RedirectTo(""); - } - - var user = await UserManager.FindByIdAsync(UserId); - if (user is null) - { - HttpContext.Response.StatusCode = StatusCodes.Status404NotFound; - statusMessage = $"Error loading user with ID {UserId}"; - } - else - { - var code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(Code)); - var result = await UserManager.ConfirmEmailAsync(user, code); - statusMessage = result.Succeeded ? "Thank you for confirming your email." : "Error confirming your email."; - } - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmailChange.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmailChange.razor deleted file mode 100644 index 3b76728..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ConfirmEmailChange.razor +++ /dev/null @@ -1,68 +0,0 @@ -@page "/Account/ConfirmEmailChange" - -@using System.Text -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityRedirectManager RedirectManager - -Confirm email change - -

Confirm email change

- - - -@code { - private string? message; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromQuery] - private string? UserId { get; set; } - - [SupplyParameterFromQuery] - private string? Email { get; set; } - - [SupplyParameterFromQuery] - private string? Code { get; set; } - - protected override async Task OnInitializedAsync() - { - if (UserId is null || Email is null || Code is null) - { - RedirectManager.RedirectToWithStatus( - "Account/Login", "Error: Invalid email change confirmation link.", HttpContext); - } - - var user = await UserManager.FindByIdAsync(UserId); - if (user is null) - { - message = "Unable to find user with Id '{userId}'"; - return; - } - - var code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(Code)); - var result = await UserManager.ChangeEmailAsync(user, Email, code); - if (!result.Succeeded) - { - message = "Error changing email."; - return; - } - - // In our UI email and user name are one and the same, so when we update the email - // we need to update the user name. - var setUserNameResult = await UserManager.SetUserNameAsync(user, Email); - if (!setUserNameResult.Succeeded) - { - message = "Error changing user name."; - return; - } - - await SignInManager.RefreshSignInAsync(user); - message = "Thank you for confirming your email change."; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ExternalLogin.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ExternalLogin.razor deleted file mode 100644 index cdcba73..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ExternalLogin.razor +++ /dev/null @@ -1,205 +0,0 @@ -@page "/Account/ExternalLogin" - -@using System.ComponentModel.DataAnnotations -@using System.Security.Claims -@using System.Text -@using System.Text.Encodings.Web -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject SignInManager SignInManager -@inject UserManager UserManager -@inject IUserStore UserStore -@inject IEmailSender EmailSender -@inject NavigationManager NavigationManager -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Register - - -

Register

-

Associate your @ProviderDisplayName account.

- - -
- You've successfully authenticated with @ProviderDisplayName. - Please enter an email address for this site below and click the Register button to finish - logging in. -
- -
-
- - - -
- - - -
- -
-
-
- -@code { - public const string LoginCallbackAction = "LoginCallback"; - - private string? message; - private ExternalLoginInfo? externalLoginInfo; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - [SupplyParameterFromQuery] - private string? RemoteError { get; set; } - - [SupplyParameterFromQuery] - private string? ReturnUrl { get; set; } - - [SupplyParameterFromQuery] - private string? Action { get; set; } - - private string? ProviderDisplayName => externalLoginInfo?.ProviderDisplayName; - - protected override async Task OnInitializedAsync() - { - if (RemoteError is not null) - { - RedirectManager.RedirectToWithStatus("Account/Login", $"Error from external provider: {RemoteError}", HttpContext); - } - - var info = await SignInManager.GetExternalLoginInfoAsync(); - if (info is null) - { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); - } - - externalLoginInfo = info; - - if (HttpMethods.IsGet(HttpContext.Request.Method)) - { - if (Action == LoginCallbackAction) - { - await OnLoginCallbackAsync(); - return; - } - - // We should only reach this page via the login callback, so redirect back to - // the login page if we get here some other way. - RedirectManager.RedirectTo("Account/Login"); - } - } - - private async Task OnLoginCallbackAsync() - { - if (externalLoginInfo is null) - { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information.", HttpContext); - } - - // Sign in the user with this external login provider if the user already has a login. - var result = await SignInManager.ExternalLoginSignInAsync( - externalLoginInfo!.LoginProvider, - externalLoginInfo!.ProviderKey, - isPersistent: false, - bypassTwoFactor: true); - - if (result.Succeeded) - { - Logger.LogInformation( - "{Name} logged in with {LoginProvider} provider.", - externalLoginInfo.Principal.Identity?.Name, - externalLoginInfo.LoginProvider); - RedirectManager.RedirectTo(ReturnUrl); - } - else if (result.IsLockedOut) - { - RedirectManager.RedirectTo("Account/Lockout"); - } - - // If the user does not have an account, then ask the user to create an account. - if (externalLoginInfo.Principal.HasClaim(c => c.Type == ClaimTypes.Email)) - { - Input.Email = externalLoginInfo.Principal.FindFirstValue(ClaimTypes.Email) ?? ""; - } - } - - private async Task OnValidSubmitAsync() - { - if (externalLoginInfo is null) - { - RedirectManager.RedirectToWithStatus("Account/Login", "Error loading external login information during confirmation.", HttpContext); - } - - var emailStore = GetEmailStore(); - var user = CreateUser(); - - await UserStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); - await emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); - - var result = await UserManager.CreateAsync(user); - if (result.Succeeded) - { - result = await UserManager.AddLoginAsync(user, externalLoginInfo); - if (result.Succeeded) - { - Logger.LogInformation("User created an account using {Name} provider.", externalLoginInfo.LoginProvider); - - var userId = await UserManager.GetUserIdAsync(user); - var code = await UserManager.GenerateEmailConfirmationTokenAsync(user); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - - var callbackUrl = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri, - new Dictionary { ["userId"] = userId, ["code"] = code }); - await EmailSender.SendConfirmationLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl)); - - // If account confirmation is required, we need to show the link if we don't have a real email sender - if (UserManager.Options.SignIn.RequireConfirmedAccount) - { - RedirectManager.RedirectTo("Account/RegisterConfirmation", new() { ["email"] = Input.Email }); - } - - await SignInManager.SignInAsync(user, isPersistent: false, externalLoginInfo.LoginProvider); - RedirectManager.RedirectTo(ReturnUrl); - } - } - - message = $"Error: {string.Join(",", result.Errors.Select(error => error.Description))}"; - } - - private static ApplicationUser CreateUser() - { - try - { - return Activator.CreateInstance(); - } - catch - { - throw new InvalidOperationException($"Can't create an instance of '{nameof(ApplicationUser)}'. " + - $"Ensure that '{nameof(ApplicationUser)}' is not an abstract class and has a parameterless constructor"); - } - } - - private IUserEmailStore GetEmailStore() - { - if (!UserManager.SupportsUserEmail) - { - throw new NotSupportedException("The default UI requires a user store with email support."); - } - return (IUserEmailStore)UserStore; - } - - private sealed class InputModel - { - [Required] - [EmailAddress] - public string Email { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPassword.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPassword.razor deleted file mode 100644 index 4c5fe48..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPassword.razor +++ /dev/null @@ -1,68 +0,0 @@ -@page "/Account/ForgotPassword" - -@using System.ComponentModel.DataAnnotations -@using System.Text -@using System.Text.Encodings.Web -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IEmailSender EmailSender -@inject NavigationManager NavigationManager -@inject IdentityRedirectManager RedirectManager - -Forgot your password? - -Forgot your password? -Enter your email. - - - - - - - - - - - Reset password - - - - -@code { - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - private async Task OnValidSubmitAsync() - { - var user = await UserManager.FindByEmailAsync(Input.Email); - if (user is null || !(await UserManager.IsEmailConfirmedAsync(user))) - { - // Don't reveal that the user does not exist or is not confirmed - RedirectManager.RedirectTo("Account/ForgotPasswordConfirmation"); - } - - // For more information on how to enable account confirmation and password reset please - // visit https://go.microsoft.com/fwlink/?LinkID=532713 - var code = await UserManager.GeneratePasswordResetTokenAsync(user); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - var callbackUrl = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ResetPassword").AbsoluteUri, - new Dictionary { ["code"] = code }); - - await EmailSender.SendPasswordResetLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl)); - - RedirectManager.RedirectTo("Account/ForgotPasswordConfirmation"); - } - - private sealed class InputModel - { - [Required] - [EmailAddress] - public string Email { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPasswordConfirmation.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPasswordConfirmation.razor deleted file mode 100644 index 31f70ce..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ForgotPasswordConfirmation.razor +++ /dev/null @@ -1,7 +0,0 @@ -@page "/Account/ForgotPasswordConfirmation" - -Forgot password confirmation - -Forgot password confirmation - -Please check your email to reset your password. diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/InvalidPasswordReset.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/InvalidPasswordReset.razor deleted file mode 100644 index 561b651..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/InvalidPasswordReset.razor +++ /dev/null @@ -1,8 +0,0 @@ -@page "/Account/InvalidPasswordReset" - -Invalid password reset - -

Invalid password reset

-

- The password reset link is invalid. -

diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Lockout.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Lockout.razor deleted file mode 100644 index 017e31d..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Lockout.razor +++ /dev/null @@ -1,8 +0,0 @@ -@page "/Account/Lockout" - -Locked out - -
-

Locked out

- -
diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Login.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Login.razor index 30def34..54599f2 100644 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Login.razor +++ b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Login.razor @@ -1,4 +1,5 @@ @page "/Account/Login" +@layout IntegryControlPanel.Client.Layout.AuthLayout @using System.ComponentModel.DataAnnotations @using Microsoft.AspNetCore.Authentication @@ -10,64 +11,77 @@ @inject NavigationManager NavigationManager @inject IdentityRedirectManager RedirectManager -Log in +@* Log in *@ -Log in + - - - - - + - Use a local account to log in. + - - - - - - - - - Remember me - - - Log in - - - + Accedi al tuo account - - - Forgot your password?
- { ["ReturnUrl"] = ReturnUrl }))">Register as a new user
- Resend email confirmation -
-
-
- - Use another service to log in. + - + + + + + + + + + + + + @* + Ricordami + *@ + + + Accedi + + + + + + + @* *@ + + @* + + Non hai ancora un account? + { ["ReturnUrl"] = ReturnUrl }))" + Color="Color.Primary"> + Registrati qui + + + *@ + + @* Commented out links for now + + + Forgot your password?
+ Resend email confirmation
+*@ +
@code { private string? errorMessage; - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; + [CascadingParameter] private HttpContext HttpContext { get; set; } = default!; - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); + [SupplyParameterFromForm] private InputModel Input { get; set; } = new(); - [SupplyParameterFromQuery] - private string? ReturnUrl { get; set; } + [SupplyParameterFromQuery] private string? ReturnUrl { get; set; } protected override async Task OnInitializedAsync() { @@ -115,7 +129,7 @@ [DataType(DataType.Password)] public string Password { get; set; } = ""; - [Display(Name = "Remember me?")] - public bool RememberMe { get; set; } + [Display(Name = "Remember me?")] public bool RememberMe { get; set; } } -} + +} \ No newline at end of file diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWith2fa.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWith2fa.razor deleted file mode 100644 index ad9ee2d..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWith2fa.razor +++ /dev/null @@ -1,101 +0,0 @@ -@page "/Account/LoginWith2fa" - -@using System.ComponentModel.DataAnnotations -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject SignInManager SignInManager -@inject UserManager UserManager -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Two-factor authentication - -

Two-factor authentication

- - -

Your login is protected with an authenticator app. Enter your authenticator code below.

-
-
- - - - - -
- - - -
-
- -
-
- -
-
-
-
-

- Don't have access to your authenticator device? You can - log in with a recovery code. -

- -@code { - private string? message; - private ApplicationUser user = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - [SupplyParameterFromQuery] - private string? ReturnUrl { get; set; } - - [SupplyParameterFromQuery] - private bool RememberMe { get; set; } - - protected override async Task OnInitializedAsync() - { - // Ensure the user has gone through the username & password screen first - user = await SignInManager.GetTwoFactorAuthenticationUserAsync() ?? - throw new InvalidOperationException("Unable to load two-factor authentication user."); - } - - private async Task OnValidSubmitAsync() - { - var authenticatorCode = Input.TwoFactorCode!.Replace(" ", string.Empty).Replace("-", string.Empty); - var result = await SignInManager.TwoFactorAuthenticatorSignInAsync(authenticatorCode, RememberMe, Input.RememberMachine); - var userId = await UserManager.GetUserIdAsync(user); - - if (result.Succeeded) - { - Logger.LogInformation("User with ID '{UserId}' logged in with 2fa.", userId); - RedirectManager.RedirectTo(ReturnUrl); - } - else if (result.IsLockedOut) - { - Logger.LogWarning("User with ID '{UserId}' account locked out.", userId); - RedirectManager.RedirectTo("Account/Lockout"); - } - else - { - Logger.LogWarning("Invalid authenticator code entered for user with ID '{UserId}'.", userId); - message = "Error: Invalid authenticator code."; - } - } - - private sealed class InputModel - { - [Required] - [StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Text)] - [Display(Name = "Authenticator code")] - public string? TwoFactorCode { get; set; } - - [Display(Name = "Remember this machine")] - public bool RememberMachine { get; set; } - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWithRecoveryCode.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWithRecoveryCode.razor deleted file mode 100644 index 51fff5f..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/LoginWithRecoveryCode.razor +++ /dev/null @@ -1,85 +0,0 @@ -@page "/Account/LoginWithRecoveryCode" - -@using System.ComponentModel.DataAnnotations -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject SignInManager SignInManager -@inject UserManager UserManager -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Recovery code verification - -

Recovery code verification

- - -

- You have requested to log in with a recovery code. This login will not be remembered until you provide - an authenticator app code at log in or disable 2FA and log in again. -

-
-
- - - -
- - - -
- -
-
-
- -@code { - private string? message; - private ApplicationUser user = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - [SupplyParameterFromQuery] - private string? ReturnUrl { get; set; } - - protected override async Task OnInitializedAsync() - { - // Ensure the user has gone through the username & password screen first - user = await SignInManager.GetTwoFactorAuthenticationUserAsync() ?? - throw new InvalidOperationException("Unable to load two-factor authentication user."); - } - - private async Task OnValidSubmitAsync() - { - var recoveryCode = Input.RecoveryCode.Replace(" ", string.Empty); - - var result = await SignInManager.TwoFactorRecoveryCodeSignInAsync(recoveryCode); - - var userId = await UserManager.GetUserIdAsync(user); - - if (result.Succeeded) - { - Logger.LogInformation("User with ID '{UserId}' logged in with a recovery code.", userId); - RedirectManager.RedirectTo(ReturnUrl); - } - else if (result.IsLockedOut) - { - Logger.LogWarning("User account locked out."); - RedirectManager.RedirectTo("Account/Lockout"); - } - else - { - Logger.LogWarning("Invalid recovery code entered for user with ID '{UserId}' ", userId); - message = "Error: Invalid recovery code entered."; - } - } - - private sealed class InputModel - { - [Required] - [DataType(DataType.Text)] - [Display(Name = "Recovery Code")] - public string RecoveryCode { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ChangePassword.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ChangePassword.razor deleted file mode 100644 index 05e2f95..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ChangePassword.razor +++ /dev/null @@ -1,98 +0,0 @@ -@page "/Account/Manage/ChangePassword" - -@using System.ComponentModel.DataAnnotations -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Change password - -Change password - - - - - - - - - - - - - - - - - - Update password - - - - -@code { - private string? message; - private ApplicationUser user = default!; - private bool hasPassword; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - hasPassword = await UserManager.HasPasswordAsync(user); - if (!hasPassword) - { - RedirectManager.RedirectTo("Account/Manage/SetPassword"); - } - } - - private async Task OnValidSubmitAsync() - { - var changePasswordResult = await UserManager.ChangePasswordAsync(user, Input.OldPassword, Input.NewPassword); - if (!changePasswordResult.Succeeded) - { - message = $"Error: {string.Join(",", changePasswordResult.Errors.Select(error => error.Description))}"; - return; - } - - await SignInManager.RefreshSignInAsync(user); - Logger.LogInformation("User changed their password successfully."); - - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been changed", HttpContext); - } - - private sealed class InputModel - { - [Required] - [DataType(DataType.Password)] - [Display(Name = "Current password")] - public string OldPassword { get; set; } = ""; - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string NewPassword { get; set; } = ""; - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/DeletePersonalData.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/DeletePersonalData.razor deleted file mode 100644 index b506639..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/DeletePersonalData.razor +++ /dev/null @@ -1,86 +0,0 @@ -@page "/Account/Manage/DeletePersonalData" - -@using System.ComponentModel.DataAnnotations -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Delete Personal Data - -Delete personal data - - - - - Deleting this data will permanently remove your account, and this cannot be recovered. - - - - - - - @if (requirePassword) - { - - - - } - - Delete data and close my account - - - - -@code { - private string? message; - private ApplicationUser user = default!; - private bool requirePassword; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - protected override async Task OnInitializedAsync() - { - Input ??= new(); - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - requirePassword = await UserManager.HasPasswordAsync(user); - } - - private async Task OnValidSubmitAsync() - { - if (requirePassword && !await UserManager.CheckPasswordAsync(user, Input.Password)) - { - message = "Error: Incorrect password."; - return; - } - - var result = await UserManager.DeleteAsync(user); - if (!result.Succeeded) - { - throw new InvalidOperationException("Unexpected error occurred deleting user."); - } - - await SignInManager.SignOutAsync(); - - var userId = await UserManager.GetUserIdAsync(user); - Logger.LogInformation("User with ID '{UserId}' deleted themselves.", userId); - - RedirectManager.RedirectToCurrentPage(); - } - - private sealed class InputModel - { - [DataType(DataType.Password)] - public string Password { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Disable2fa.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Disable2fa.razor deleted file mode 100644 index d515f06..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Disable2fa.razor +++ /dev/null @@ -1,64 +0,0 @@ -@page "/Account/Manage/Disable2fa" - -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Disable two-factor authentication (2FA) - - -

Disable two-factor authentication (2FA)

- - - -
-
- - - -
- -@code { - private ApplicationUser user = default!; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - - if (HttpMethods.IsGet(HttpContext.Request.Method) && !await UserManager.GetTwoFactorEnabledAsync(user)) - { - throw new InvalidOperationException("Cannot disable 2FA for user as it's not currently enabled."); - } - } - - private async Task OnSubmitAsync() - { - var disable2faResult = await UserManager.SetTwoFactorEnabledAsync(user, false); - if (!disable2faResult.Succeeded) - { - throw new InvalidOperationException("Unexpected error occurred disabling 2FA."); - } - - var userId = await UserManager.GetUserIdAsync(user); - Logger.LogInformation("User with ID '{UserId}' has disabled 2fa.", userId); - RedirectManager.RedirectToWithStatus( - "Account/Manage/TwoFactorAuthentication", - "2fa has been disabled. You can reenable 2fa when you setup an authenticator app", - HttpContext); - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Email.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Email.razor deleted file mode 100644 index 23823dd..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/Email.razor +++ /dev/null @@ -1,122 +0,0 @@ -@page "/Account/Manage/Email" - -@using System.ComponentModel.DataAnnotations -@using System.Text -@using System.Text.Encodings.Web -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IEmailSender EmailSender -@inject IdentityUserAccessor UserAccessor -@inject NavigationManager NavigationManager - -Manage email - -Manage email - - - -
- - - - - - - - @if (isEmailConfirmed) - { - - - - } - else - { - - - - - Send verification email - - } - - - - - - - Change email - - - - -@code { - private string? message; - private ApplicationUser user = default!; - private string? email; - private bool isEmailConfirmed; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm(FormName = "change-email")] - private InputModel Input { get; set; } = new(); - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - email = await UserManager.GetEmailAsync(user); - isEmailConfirmed = await UserManager.IsEmailConfirmedAsync(user); - - Input.NewEmail ??= email; - } - - private async Task OnValidSubmitAsync() - { - if (Input.NewEmail is null || Input.NewEmail == email) - { - message = "Your email is unchanged."; - return; - } - - var userId = await UserManager.GetUserIdAsync(user); - var code = await UserManager.GenerateChangeEmailTokenAsync(user, Input.NewEmail); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - var callbackUrl = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ConfirmEmailChange").AbsoluteUri, - new Dictionary { ["userId"] = userId, ["email"] = Input.NewEmail, ["code"] = code }); - - await EmailSender.SendConfirmationLinkAsync(user, Input.NewEmail, HtmlEncoder.Default.Encode(callbackUrl)); - - message = "Confirmation link to change email sent. Please check your email."; - } - - private async Task OnSendEmailVerificationAsync() - { - if (email is null) - { - return; - } - - var userId = await UserManager.GetUserIdAsync(user); - var code = await UserManager.GenerateEmailConfirmationTokenAsync(user); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - var callbackUrl = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri, - new Dictionary { ["userId"] = userId, ["code"] = code }); - - await EmailSender.SendConfirmationLinkAsync(user, email, HtmlEncoder.Default.Encode(callbackUrl)); - - message = "Verification email sent. Please check your email."; - } - - private sealed class InputModel - { - [Required] - [EmailAddress] - [Display(Name = "New email")] - public string? NewEmail { get; set; } - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/EnableAuthenticator.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/EnableAuthenticator.razor deleted file mode 100644 index 2a7c9d0..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/EnableAuthenticator.razor +++ /dev/null @@ -1,178 +0,0 @@ -@page "/Account/Manage/EnableAuthenticator" - -@using System.ComponentModel.DataAnnotations -@using System.Globalization -@using System.Text -@using System.Text.Encodings.Web -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IdentityUserAccessor UserAccessor -@inject UrlEncoder UrlEncoder -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Configure authenticator app - -@if (recoveryCodes is not null) -{ - -} -else -{ - Configure authenticator app - - - - To use an authenticator app go through the following steps: - -
    -
  1. - - Download a two-factor authenticator app like Microsoft Authenticator for - Android and - iOS or - Google Authenticator for - Android and - iOS. - -
  2. -
  3. - - Scan the QR Code or enter this key into your two factor authenticator app. Spaces and casing do not matter: - - - @sharedKey - - - Learn how to enable QR code generation. - - -
    -
  4. -
  5. - - Once you have scanned the QR code or input the key above, your two factor authentication app will provide you - with a unique code. Enter the code in the confirmation box below. - - - - - - - - - - Verify - - - -
  6. -
-} - -@code { - private const string AuthenticatorUriFormat = "otpauth://totp/{0}:{1}?secret={2}&issuer={0}&digits=6"; - - private string? message; - private ApplicationUser user = default!; - private string? sharedKey; - private string? authenticatorUri; - private IEnumerable? recoveryCodes; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - - await LoadSharedKeyAndQrCodeUriAsync(user); - } - - private async Task OnValidSubmitAsync() - { - // Strip spaces and hyphens - var verificationCode = Input.Code.Replace(" ", string.Empty).Replace("-", string.Empty); - - var is2faTokenValid = await UserManager.VerifyTwoFactorTokenAsync( - user, UserManager.Options.Tokens.AuthenticatorTokenProvider, verificationCode); - - if (!is2faTokenValid) - { - message = "Error: Verification code is invalid."; - return; - } - - await UserManager.SetTwoFactorEnabledAsync(user, true); - var userId = await UserManager.GetUserIdAsync(user); - Logger.LogInformation("User with ID '{UserId}' has enabled 2FA with an authenticator app.", userId); - - message = "Your authenticator app has been verified."; - - if (await UserManager.CountRecoveryCodesAsync(user) == 0) - { - recoveryCodes = await UserManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10); - } - else - { - RedirectManager.RedirectToWithStatus("Account/Manage/TwoFactorAuthentication", message, HttpContext); - } - } - - private async ValueTask LoadSharedKeyAndQrCodeUriAsync(ApplicationUser user) - { - // Load the authenticator key & QR code URI to display on the form - var unformattedKey = await UserManager.GetAuthenticatorKeyAsync(user); - if (string.IsNullOrEmpty(unformattedKey)) - { - await UserManager.ResetAuthenticatorKeyAsync(user); - unformattedKey = await UserManager.GetAuthenticatorKeyAsync(user); - } - - sharedKey = FormatKey(unformattedKey!); - - var email = await UserManager.GetEmailAsync(user); - authenticatorUri = GenerateQrCodeUri(email!, unformattedKey!); - } - - private string FormatKey(string unformattedKey) - { - var result = new StringBuilder(); - int currentPosition = 0; - while (currentPosition + 4 < unformattedKey.Length) - { - result.Append(unformattedKey.AsSpan(currentPosition, 4)).Append(' '); - currentPosition += 4; - } - if (currentPosition < unformattedKey.Length) - { - result.Append(unformattedKey.AsSpan(currentPosition)); - } - - return result.ToString().ToLowerInvariant(); - } - - private string GenerateQrCodeUri(string email, string unformattedKey) - { - return string.Format( - CultureInfo.InvariantCulture, - AuthenticatorUriFormat, - UrlEncoder.Encode("Microsoft.AspNetCore.Identity.UI"), - UrlEncoder.Encode(email), - unformattedKey); - } - - private sealed class InputModel - { - [Required] - [StringLength(7, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Text)] - [Display(Name = "Verification Code")] - public string Code { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ExternalLogins.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ExternalLogins.razor deleted file mode 100644 index eb8cc63..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ExternalLogins.razor +++ /dev/null @@ -1,140 +0,0 @@ -@page "/Account/Manage/ExternalLogins" - -@using Microsoft.AspNetCore.Authentication -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor -@inject IUserStore UserStore -@inject IdentityRedirectManager RedirectManager - -Manage your external logins - - -@if (currentLogins?.Count > 0) -{ -

Registered Logins

- - - @foreach (var login in currentLogins) - { - - - - - } - -
@login.ProviderDisplayName - @if (showRemoveButton) - { -
- -
- - - -
- - } - else - { - @:   - } -
-} -@if (otherLogins?.Count > 0) -{ -

Add another service to log in.

- -
- -
-

- @foreach (var provider in otherLogins) - { - - } -

-
- -} - -@code { - public const string LinkLoginCallbackAction = "LinkLoginCallback"; - - private ApplicationUser user = default!; - private IList? currentLogins; - private IList? otherLogins; - private bool showRemoveButton; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm] - private string? LoginProvider { get; set; } - - [SupplyParameterFromForm] - private string? ProviderKey { get; set; } - - [SupplyParameterFromQuery] - private string? Action { get; set; } - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - currentLogins = await UserManager.GetLoginsAsync(user); - otherLogins = (await SignInManager.GetExternalAuthenticationSchemesAsync()) - .Where(auth => currentLogins.All(ul => auth.Name != ul.LoginProvider)) - .ToList(); - - string? passwordHash = null; - if (UserStore is IUserPasswordStore userPasswordStore) - { - passwordHash = await userPasswordStore.GetPasswordHashAsync(user, HttpContext.RequestAborted); - } - - showRemoveButton = passwordHash is not null || currentLogins.Count > 1; - - if (HttpMethods.IsGet(HttpContext.Request.Method) && Action == LinkLoginCallbackAction) - { - await OnGetLinkLoginCallbackAsync(); - } - } - - private async Task OnSubmitAsync() - { - var result = await UserManager.RemoveLoginAsync(user, LoginProvider!, ProviderKey!); - if (!result.Succeeded) - { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not removed.", HttpContext); - } - - await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("The external login was removed.", HttpContext); - } - - private async Task OnGetLinkLoginCallbackAsync() - { - var userId = await UserManager.GetUserIdAsync(user); - var info = await SignInManager.GetExternalLoginInfoAsync(userId); - if (info is null) - { - RedirectManager.RedirectToCurrentPageWithStatus("Error: Could not load external login info.", HttpContext); - } - - var result = await UserManager.AddLoginAsync(user, info); - if (!result.Succeeded) - { - RedirectManager.RedirectToCurrentPageWithStatus("Error: The external login was not added. External logins can only be associated with one account.", HttpContext); - } - - // Clear the existing external cookie to ensure a clean login process - await HttpContext.SignOutAsync(IdentityConstants.ExternalScheme); - - RedirectManager.RedirectToCurrentPageWithStatus("The external login was added.", HttpContext); - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor deleted file mode 100644 index 89ba031..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/GenerateRecoveryCodes.razor +++ /dev/null @@ -1,68 +0,0 @@ -@page "/Account/Manage/GenerateRecoveryCodes" - -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Generate two-factor authentication (2FA) recovery codes - -@if (recoveryCodes is not null) -{ - -} -else -{ -

Generate two-factor authentication (2FA) recovery codes

- -
-
- - - -
-} - -@code { - private string? message; - private ApplicationUser user = default!; - private IEnumerable? recoveryCodes; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - - var isTwoFactorEnabled = await UserManager.GetTwoFactorEnabledAsync(user); - if (!isTwoFactorEnabled) - { - throw new InvalidOperationException("Cannot generate recovery codes for user because they do not have 2FA enabled."); - } - } - - private async Task OnSubmitAsync() - { - var userId = await UserManager.GetUserIdAsync(user); - recoveryCodes = await UserManager.GenerateNewTwoFactorRecoveryCodesAsync(user, 10); - message = "You have generated new recovery codes."; - - Logger.LogInformation("User with ID '{UserId}' has generated new 2FA recovery codes.", userId); - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ResetAuthenticator.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ResetAuthenticator.razor deleted file mode 100644 index bc8eb7e..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/ResetAuthenticator.razor +++ /dev/null @@ -1,52 +0,0 @@ -@page "/Account/Manage/ResetAuthenticator" - -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager -@inject ILogger Logger - -Reset authenticator key - -Reset authenticator key - - - - - If you reset your authenticator key your authenticator app will not work until you reconfigure it. - - - - This process disables 2FA until you verify your authenticator app. - If you do not complete your authenticator app configuration you may lose access to your account. - - -
- - - Reset authenticator key - - -@code { - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - private async Task OnSubmitAsync() - { - var user = await UserAccessor.GetRequiredUserAsync(HttpContext); - await UserManager.SetTwoFactorEnabledAsync(user, false); - await UserManager.ResetAuthenticatorKeyAsync(user); - var userId = await UserManager.GetUserIdAsync(user); - Logger.LogInformation("User with ID '{UserId}' has reset their authentication app key.", userId); - - await SignInManager.RefreshSignInAsync(user); - - RedirectManager.RedirectToWithStatus( - "Account/Manage/EnableAuthenticator", - "Your authenticator app key has been reset, you will need to configure your authenticator app using the new key.", - HttpContext); - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/SetPassword.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/SetPassword.razor deleted file mode 100644 index 5453106..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/SetPassword.razor +++ /dev/null @@ -1,87 +0,0 @@ -@page "/Account/Manage/SetPassword" - -@using System.ComponentModel.DataAnnotations -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager - -Set password - -

Set your password

- -

- You do not have a local username/password for this site. Add a local - account so you can log in without an external login. -

-
-
- - - -
- - - -
-
- - - -
- -
-
-
- -@code { - private string? message; - private ApplicationUser user = default!; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - protected override async Task OnInitializedAsync() - { - user = await UserAccessor.GetRequiredUserAsync(HttpContext); - - var hasPassword = await UserManager.HasPasswordAsync(user); - if (hasPassword) - { - RedirectManager.RedirectTo("Account/Manage/ChangePassword"); - } - } - - private async Task OnValidSubmitAsync() - { - var addPasswordResult = await UserManager.AddPasswordAsync(user, Input.NewPassword!); - if (!addPasswordResult.Succeeded) - { - message = $"Error: {string.Join(",", addPasswordResult.Errors.Select(error => error.Description))}"; - return; - } - - await SignInManager.RefreshSignInAsync(user); - RedirectManager.RedirectToCurrentPageWithStatus("Your password has been set.", HttpContext); - } - - private sealed class InputModel - { - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "New password")] - public string? NewPassword { get; set; } - - [DataType(DataType.Password)] - [Display(Name = "Confirm new password")] - [Compare("NewPassword", ErrorMessage = "The new password and confirmation password do not match.")] - public string? ConfirmPassword { get; set; } - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/TwoFactorAuthentication.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/TwoFactorAuthentication.razor deleted file mode 100644 index 8351ca3..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Manage/TwoFactorAuthentication.razor +++ /dev/null @@ -1,110 +0,0 @@ -@page "/Account/Manage/TwoFactorAuthentication" - -@using Microsoft.AspNetCore.Http.Features -@using Microsoft.AspNetCore.Identity -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject SignInManager SignInManager -@inject IdentityUserAccessor UserAccessor -@inject IdentityRedirectManager RedirectManager - -Two-factor authentication (2FA) - -Two-factor authentication (2FA) - - - -@if (canTrack) -{ - if (is2faEnabled) - { - if (recoveryCodesLeft == 0) - { - You have no recovery codes left. - - - You must generate a new set of recovery codes - before you can log in with a recovery code. - - } - else if (recoveryCodesLeft == 1) - { - You have 1 recovery code left. - - - You can generate a new set of recovery codes. - - } - else if (recoveryCodesLeft <= 3) - { - You have @recoveryCodesLeft recovery codes left. - - - You should generate a new set of recovery codes. - - } - - if (isMachineRemembered) - { -
- - - Forget this browser - - } - - Disable 2FA
- Reset recovery codes - } - - Authenticator app - - @if (!hasAuthenticator) - { - Add authenticator app
- } - else - { - Set up authenticator app
- Reset authenticator app - } -} -else -{ - Privacy and cookie policy have not been accepted. - - - You must accept the policy before you can enable two factor authentication. - -} - -@code { - private bool canTrack; - private bool hasAuthenticator; - private int recoveryCodesLeft; - private bool is2faEnabled; - private bool isMachineRemembered; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - protected override async Task OnInitializedAsync() - { - var user = await UserAccessor.GetRequiredUserAsync(HttpContext); - canTrack = HttpContext.Features.Get()?.CanTrack ?? true; - hasAuthenticator = await UserManager.GetAuthenticatorKeyAsync(user) is not null; - is2faEnabled = await UserManager.GetTwoFactorEnabledAsync(user); - isMachineRemembered = await SignInManager.IsTwoFactorClientRememberedAsync(user); - recoveryCodesLeft = await UserManager.CountRecoveryCodesAsync(user); - } - - private async Task OnSubmitForgetBrowserAsync() - { - await SignInManager.ForgetTwoFactorClientAsync(); - - RedirectManager.RedirectToCurrentPageWithStatus( - "The current browser has been forgotten. When you login again from this browser you will be prompted for your 2fa code.", - HttpContext); - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Register.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Register.razor deleted file mode 100644 index 4e6a001..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/Register.razor +++ /dev/null @@ -1,146 +0,0 @@ -@page "/Account/Register" - -@using System.ComponentModel.DataAnnotations -@using System.Text -@using System.Text.Encodings.Web -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IUserStore UserStore -@inject SignInManager SignInManager -@inject IEmailSender EmailSender -@inject ILogger Logger -@inject NavigationManager NavigationManager -@inject IdentityRedirectManager RedirectManager - -Register - -Register - - - - - - - - Create a new account. - - - - - - - - - - - - - Register - - - - - - Use another service to register. - - - - -@code { - private IEnumerable? identityErrors; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - [SupplyParameterFromQuery] - private string? ReturnUrl { get; set; } - - private string? Message => identityErrors is null ? null : $"Error: {string.Join(", ", identityErrors.Select(error => error.Description))}"; - - public async Task RegisterUser(EditContext editContext) - { - var user = CreateUser(); - - await UserStore.SetUserNameAsync(user, Input.Email, CancellationToken.None); - var emailStore = GetEmailStore(); - await emailStore.SetEmailAsync(user, Input.Email, CancellationToken.None); - var result = await UserManager.CreateAsync(user, Input.Password); - - if (!result.Succeeded) - { - identityErrors = result.Errors; - return; - } - - Logger.LogInformation("User created a new account with password."); - - var userId = await UserManager.GetUserIdAsync(user); - var code = await UserManager.GenerateEmailConfirmationTokenAsync(user); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - var callbackUrl = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri, - new Dictionary { ["userId"] = userId, ["code"] = code, ["returnUrl"] = ReturnUrl }); - - await EmailSender.SendConfirmationLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl)); - - if (UserManager.Options.SignIn.RequireConfirmedAccount) - { - RedirectManager.RedirectTo( - "Account/RegisterConfirmation", - new() { ["email"] = Input.Email, ["returnUrl"] = ReturnUrl }); - } - - await SignInManager.SignInAsync(user, isPersistent: false); - RedirectManager.RedirectTo(ReturnUrl); - } - - private static ApplicationUser CreateUser() - { - try - { - return Activator.CreateInstance(); - } - catch - { - throw new InvalidOperationException($"Can't create an instance of '{nameof(ApplicationUser)}'. " + - $"Ensure that '{nameof(ApplicationUser)}' is not an abstract class and has a parameterless constructor."); - } - } - - private IUserEmailStore GetEmailStore() - { - if (!UserManager.SupportsUserEmail) - { - throw new NotSupportedException("The default UI requires a user store with email support."); - } - return (IUserEmailStore)UserStore; - } - - private sealed class InputModel - { - [Required] - [EmailAddress] - [Display(Name = "Email")] - public string Email { get; set; } = ""; - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - [Display(Name = "Password")] - public string Password { get; set; } = ""; - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/RegisterConfirmation.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/RegisterConfirmation.razor deleted file mode 100644 index dde3906..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/RegisterConfirmation.razor +++ /dev/null @@ -1,68 +0,0 @@ -@page "/Account/RegisterConfirmation" - -@using System.Text -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IEmailSender EmailSender -@inject NavigationManager NavigationManager -@inject IdentityRedirectManager RedirectManager - -Register confirmation - -

Register confirmation

- - - -@if (emailConfirmationLink is not null) -{ -

- This app does not currently have a real email sender registered, see these docs for how to configure a real email sender. - Normally this would be emailed: Click here to confirm your account -

-} -else -{ -

Please check your email to confirm your account.

-} - -@code { - private string? emailConfirmationLink; - private string? statusMessage; - - [CascadingParameter] - private HttpContext HttpContext { get; set; } = default!; - - [SupplyParameterFromQuery] - private string? Email { get; set; } - - [SupplyParameterFromQuery] - private string? ReturnUrl { get; set; } - - protected override async Task OnInitializedAsync() - { - if (Email is null) - { - RedirectManager.RedirectTo(""); - } - - var user = await UserManager.FindByEmailAsync(Email); - if (user is null) - { - HttpContext.Response.StatusCode = StatusCodes.Status404NotFound; - statusMessage = "Error finding user for unspecified email"; - } - else if (EmailSender is IdentityNoOpEmailSender) - { - // Once you add a real email sender, you should remove this code that lets you confirm the account - var userId = await UserManager.GetUserIdAsync(user); - var code = await UserManager.GenerateEmailConfirmationTokenAsync(user); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - emailConfirmationLink = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri, - new Dictionary { ["userId"] = userId, ["code"] = code, ["returnUrl"] = ReturnUrl }); - } - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResendEmailConfirmation.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResendEmailConfirmation.razor deleted file mode 100644 index cd48367..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResendEmailConfirmation.razor +++ /dev/null @@ -1,70 +0,0 @@ -@page "/Account/ResendEmailConfirmation" - -@using System.ComponentModel.DataAnnotations -@using System.Text -@using System.Text.Encodings.Web -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject UserManager UserManager -@inject IEmailSender EmailSender -@inject NavigationManager NavigationManager -@inject IdentityRedirectManager RedirectManager - -Resend email confirmation - -Resend email confirmation - -Enter your email. - - - - - - - - - - - - Resend - - - - -@code { - private string? message; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - private async Task OnValidSubmitAsync() - { - var user = await UserManager.FindByEmailAsync(Input.Email!); - if (user is null) - { - message = "Verification email sent. Please check your email."; - return; - } - - var userId = await UserManager.GetUserIdAsync(user); - var code = await UserManager.GenerateEmailConfirmationTokenAsync(user); - code = WebEncoders.Base64UrlEncode(Encoding.UTF8.GetBytes(code)); - var callbackUrl = NavigationManager.GetUriWithQueryParameters( - NavigationManager.ToAbsoluteUri("Account/ConfirmEmail").AbsoluteUri, - new Dictionary { ["userId"] = userId, ["code"] = code }); - await EmailSender.SendConfirmationLinkAsync(user, Input.Email, HtmlEncoder.Default.Encode(callbackUrl)); - - message = "Verification email sent. Please check your email."; - } - - private sealed class InputModel - { - [Required] - [EmailAddress] - public string Email { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPassword.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPassword.razor deleted file mode 100644 index cf353b1..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPassword.razor +++ /dev/null @@ -1,103 +0,0 @@ -@page "/Account/ResetPassword" - -@using System.ComponentModel.DataAnnotations -@using System.Text -@using Microsoft.AspNetCore.Identity -@using Microsoft.AspNetCore.WebUtilities -@using IntegryControlPanel.Data - -@inject IdentityRedirectManager RedirectManager -@inject UserManager UserManager - -Reset password - -

Reset password

-

Reset your password.

- -
-
- - - - - - -
- - - -
-
- - - -
-
- - - -
- -
-
-
- -@code { - private IEnumerable? identityErrors; - - [SupplyParameterFromForm] - private InputModel Input { get; set; } = new(); - - [SupplyParameterFromQuery] - private string? Code { get; set; } - - private string? Message => identityErrors is null ? null : $"Error: {string.Join(", ", identityErrors.Select(error => error.Description))}"; - - protected override void OnInitialized() - { - if (Code is null) - { - RedirectManager.RedirectTo("Account/InvalidPasswordReset"); - } - - Input.Code = Encoding.UTF8.GetString(WebEncoders.Base64UrlDecode(Code)); - } - - private async Task OnValidSubmitAsync() - { - var user = await UserManager.FindByEmailAsync(Input.Email); - if (user is null) - { - // Don't reveal that the user does not exist - RedirectManager.RedirectTo("Account/ResetPasswordConfirmation"); - } - - var result = await UserManager.ResetPasswordAsync(user, Input.Code, Input.Password); - if (result.Succeeded) - { - RedirectManager.RedirectTo("Account/ResetPasswordConfirmation"); - } - - identityErrors = result.Errors; - } - - private sealed class InputModel - { - [Required] - [EmailAddress] - public string Email { get; set; } = ""; - - [Required] - [StringLength(100, ErrorMessage = "The {0} must be at least {2} and at max {1} characters long.", MinimumLength = 6)] - [DataType(DataType.Password)] - public string Password { get; set; } = ""; - - [DataType(DataType.Password)] - [Display(Name = "Confirm password")] - [Compare("Password", ErrorMessage = "The password and confirmation password do not match.")] - public string ConfirmPassword { get; set; } = ""; - - [Required] - public string Code { get; set; } = ""; - } -} diff --git a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPasswordConfirmation.razor b/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPasswordConfirmation.razor deleted file mode 100644 index 2554ddb..0000000 --- a/IntegryControlPanel/IntegryControlPanel/Components/Account/Pages/ResetPasswordConfirmation.razor +++ /dev/null @@ -1,7 +0,0 @@ -@page "/Account/ResetPasswordConfirmation" -Reset password confirmation - -

Reset password confirmation

-

- Your password has been reset. Please click here to log in. -

diff --git a/IntegryControlPanel/IntegryControlPanel/Components/App.razor b/IntegryControlPanel/IntegryControlPanel/Components/App.razor index a4ec36a..571bc27 100644 --- a/IntegryControlPanel/IntegryControlPanel/Components/App.razor +++ b/IntegryControlPanel/IntegryControlPanel/Components/App.razor @@ -5,7 +5,7 @@ - + diff --git a/IntegryControlPanel/IntegryControlPanel/Program.cs b/IntegryControlPanel/IntegryControlPanel/Program.cs index f6eb3f2..c6673a3 100644 --- a/IntegryControlPanel/IntegryControlPanel/Program.cs +++ b/IntegryControlPanel/IntegryControlPanel/Program.cs @@ -71,8 +71,6 @@ builder.Services.AddScoped(); // Registra il servizio per gestire il database esistente builder.Services.AddScoped(); -builder.Services.AddSingleton, IdentityNoOpEmailSender>(); - var app = builder.Build(); // Configure the HTTP request pipeline. diff --git a/IntegryControlPanel/IntegryControlPanel/wwwroot/images/background.png b/IntegryControlPanel/IntegryControlPanel/wwwroot/images/background.png new file mode 100644 index 0000000000000000000000000000000000000000..209a2c8c42cfbae00ae167456e7ee3648c210b09 GIT binary patch literal 1987419 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℞2+SiekH9b(o{dP~iaSCHVacMd`>JxaEZ)7|126S%XJffGy3lcE`yrwBjKx?ae@C&$ zM2QJy@v+ZN8DP@C5 zw5sM|@l`Y{f~w@hSVkNHtBz$f8CaSo9JUx8*=1T7H;B3N4&f@&s& zvs8AGiEZgVk+;NhX)e**STkqp*VI_T-J*(m#sE}A{SCpeX=n@QZnwk zG1;ovkRMAx4MNjhi0*{%IpYpotT4|i`-sf~@h^JT*x=wi-fIp9n`HT2k|zo|s|RA2 zX!+!$kc^8L>+cO&n3%FSY%J>ogxk28|+IN!KjfS4uUMHz=9NI zB;zRoM=wXB^PUgIEEE&D*+4oZllFdWnh|$MlHqq*1S>fcV)}N>%9#+Fl|Wv(G^J5} zft31Dh%CkU=$0JJ!1Rk|SZPE*SCT@;*Hh_VOqVJw_%NupWq5>`z2lieHr=!7R%&cJ zPaN_wSbu*h!D?_p+ACKvk;?VyyY-EV8x-Du86xK9+++QE_B!lDm#||u=3C$@l4nA0 zYc)S9>YXmxPT6~RBuCED8Xu(_B0zhOB@QSFAJ`>`96 zQ=^|aJP{j9;+VK+#=yfBrHsp2uYS(v_Rwd@B)&q@JG`4x~-W86SlBU+WsYetBVxHLv-5WF{Redq!d}1Zd zoEI^TDVI`k_;N)}#?q5bBp{tHs!GM-ieynR~ z@g5PdAfq&LQyy7@@a1@%XT6gQ;^COaOqguIgp)5LxSvKLC$o(;D{Gx0q;m9!nBPz$-P)2We<-ujDE*v*1`pXp305yy@aabC@iu8Sv@)LH({Q=I^y*cUz-_41 ztk=)p*6b7)QJns~(8e(=@xIno54Jds4xaGe?l=?Bp}7;c$2BIRx@I>@R9u3 zD@J%+L33em<|3q(>_3C?-hZy|$2`|?LS7K`(+d$vvhGJ9++Vo?20XFh@&Tz+r~1~ zROKaA_Pv#CD_G?25$o{feBiK`mdAV6-X~jw41)>r=_y`>9L&Pa~*k7c>#_YGG`rP)}0UVeFlqA3DPK0+S)#b9eS zq}M|eG1M%Ea@eE1{@zTg&+8FuOe)V)GG(ZGQxP zGy9=*5i_oOpN0Jr@u6cR>ijE<4`Td1icmjaRSWYh9jVqzIb1CHu3zT!a_^gj&lbVa z#tyg|nOaKdpq*W(CgJB&{0qjzR_6n?drud)+$kP(Pq0H0kEI|Tr!ohhJokL(u}4L= z5bM5_@|hya`RZ;q^~U$f+l-gz-ugv}6Z43^U-Z85GJ~RDz4#Pc)o<7nd9=}F$Va{Y z$m6uvLVihEN6Foj$D@H!fvoB!AbbQ9$B{I!8mU z9FDb$@}bBjuMZkQ0Z`sX|_z>P469_ejl+sr3szoos@gA-$e>jY;L!g zgt{E8*Ia?ORU|a@ua~gY88(YZir@6m;}hy;I#a!Y`t<9a*K2IHt=TN&9*i!N&lVR6 z_-Ls#T=sm+Q3SQ7-~B_D@|C_uua8^o8yeLs+;`UH8+Dcn6Db3ym&A!S5&F&3`fYp< ze38*yHP9S2x&t#%Ueg}8(f9ja=eI#F2J~#*ZK9q1+QCm3r&=UX?@bcgcSWHMzoms8 zAFE^qH0|n6&Do@er45HXP>&^(JoNdMW8|bygKAktmoj5t=q)K1i;cIHFzY3dynP3Q z+V(mLxn=7~-Hk%TN}93hEt;ueFMk|g)aFS#rd9n!>OkeU&zNF$NtM7nb@^A*hn|mZ zK=~88?5^_@%I^vp2dkS?#;ejNcEskXMRD?(MmcLc-TubOkC(ACEd}GwlWxE%YUeK z&XV|4`}px1dMK8H(8{jvA5~W0#=|i^4dN|x)oDlh`kggPCx`9wNcpdnF_okF9{4-` z8<+}>QPLsL0~!!4Ya0Zid-~mtrI7Uig5$NFpz=Q9^~SC0C#54URG2^g)RQ%``_zj^ zOQH$K%y1EXdp9xUY~Btr)o^#P?+lep-Ro^`?pMu7Rlr~VQfm@2T-l`!@q*0XoRbK- zoXaWiAG`j=yRczDrLbL3nwcov^6gO<74;;s)@|3c@C1&OYRO_yWL_$$8}@G9>hVdf zBFXXLH6>z+DL#G6jrO#sS;XdE;WeTnsG-kePn0GxqSvG1$J@Ohq%hl@DsSPkvctPn zFRpz3@PR?|qpGD6Y~HSzU$rH%4$Z0JOQE;J`yWI_9k$_5X%^>t628(s^V13o$0XCJ>Drw@BZR74h!wB9&pIl5tGDn!R$V1L+1EY4spVcHpw z)fSmqTl!0eeAmL_F_-i$RmK-mQs1tbpdyie`e(lEN@Mz9P!ZyZNn3^FWL1Z@cqO~$ z?GQaOC6v^3NWr?$!ua|jYs^U2Q`PZxBKt(DLu~cm%`nPO){i}EfA-^#mQ(K|2JS)& z(Q0gMFK+P3O46Xnm+whOg;KbE>PFTd@d>;75wvBIXd~OvAg$;iWs;h-((sYR+3oql z;SaapyylqRp~sO}FSAhd>S0DcZdjulFQ@NOcc0m)4LOu>z!G;CBz>>*Z=k5xl098w*$StwMdv!a zWN#_6+!=Su%`LXJI*YH$-XwLR6(2`r$S|RacQNv@<<=6iw`qtipDF{t{H(hw+rx0& ztN)_J^+2Tc{;0YzUlRT_R#X^0nl z%ZLg4lMGi#oT;;D8E`8%d{ed@@$wF4?4YJ6GrjwD@*sgw@kO&BnQxx(bZ5EgMKW0- zgSW(pAj;jdWcZ}y+DeqLdH4m)t@^=T6&|mW&$mw3tRmZz?p(BeFX5_}o1NRtdHU#Q znRbr0meglSX@YO3s!4jO#iy0Z*S|*Tfanb}@^V6}k{TJY0JE`t>DB#+;l2G)IYSB9P^a@1?@bR4g@yX&`PR=Dr&XdRy=3$2pX4{ ziPU)<8M;(|yXw}(tO4;G!;g-e@Lb-U96x(4MXU{DT`?NSzAoxGt(n$xU#rV=y-jB! zD|Wno-}7w=B8daca9VCFNyP5!m=CLbeE*Lt6Jl~ou7wI8NjEQ|mDvXB2WpCoY)FgR z6IBl0p9x&0Xp_)P#2x9Z$(*QL^2hBjcaB!u`cH46*xG!!dWKlPtH|GqBC~pHNS1Pl z>h9Xb${!skO6X&aYms&z=!R;km7dLN%SN-a$V4xVH)b=g_6y?GYq!O}{=xQ@-dy;G zl9YNVUqr_A+7W|zrSd3~&5y}DCJ&ur+Nk9l=x15xJxo>T!cN`|Un1}4q1qB;lY}&# z%)L5Z{2}uDdKtU;T}M~a3}y8PmLXSf=3E@E$lbqbRa=(%fo6>kba@Z!nryN(G5M|( z!Rzc$)xKLkTAFn#Z$lPfHmDpc?bsS3D&-1Qp2|HXY0KL&HB}oF_+XM~>~;F^x{wof z9~TwZM_<-}rq!ZOI(Ls9A8o($?ntdhlEeDZ1II+D0n|(AB|?_Yo_Fq^^k9B}RU?U( zl2+qA*lB&G`Vi&bK;7-JC$*)S{3Y9!Ur6H;$rUMQh|#7y_w3{pvZ};yk0nIMWaG9k zXD+$2^l;Of-TPMDdE8+#CKj&sbMlpiqT<1%>q$;Y{BWPFdP&pAx3ZKq-pU>xWwcue zxBa{@E*X&C`OU0YN;3WYofOoop5%6|>Md)(&coCWdV;Ut#Qy9p)ZNyD!s;gJ1FL#Wbc+}6lKh~M7jd*RGU6VA`7-e0d z70VG@q~6_Wrimki1GsQ*!OZ=bzq?7R_WAW!`>;Y~?3X#tEt($FpA&<9lAiV{%htOx-mE^Gd-1Az+TJFXskQ@} zI$8=z##ik(m1rF4vgzvV$&0;sdO4T>nT*!HQtf+&s z%KO;Z)BVPy>e<6%M*Xh~7a4>TScDjrT;kyM2B)Ga-rg<_d(ji}s+S^r>@#snDPcCP z-5W^C((BMo!F_dKnQPY{&HnLt@9oa_N?UFijyo)=dwuM=;SXDD)jvLTyQ{IGc#|d>OC)^ zn_u*GE_r(1X&0`I4b$pW^cdbOAuSucZh3Mri9qdZw4_XPU`ZJeYM%{cT%tG8boxj}GQuKJOhZ^P` zl3ZP~!dQqh6{YcdlXYGB#Cp*yeK|osZPxD%N+K}otJY-`id#Bkd)@l4b zMq+L)JR_5+_IcufOJIra*LQNhCbF?ot2XX3dHK3wg`(Cy{N2J=H`JPWLkT(ePTEL! z*yiM*HE9vrk*_X`#TR!vuIo=%w!4C`R^v{@@YIaZQo_~a zjmd|ih}OJ-h83SLB~~~dQNrVhR$+Q&UNM%}UzF|aIwxU!&|&7w+4XlCvfOW|pPIar z^J*&Q=<4`L`8R7m&xnV~9xAx>$I}rLw|gEsT;T0VL`^aANZt%h4x36-Cd(RTp)H} z<*R#mtyPB2h4IY=+^zauAuljeFY_mJ!$mc{d_u#`KRI19F09=u>gJt#Rzp^jt9PNL z-4TnA+@kD$ptn;@G%U%vM!E{s^GX@v5hmhWqWq;1(K;5hcjob%mHk(dHFfTT?JqBE zKh$@*)Gq(c$eM6EHQ82ihOt7pBu4tD$H0`M&mb11emH^j_$|k7sC?{TR7^RkRCNTE zE82X%unrgMD=&WdQo=~eZm;Rq`@9DeM*^%XC4}}~-5hDlG_5T#6><7exG+&9FfgvB z??rDGRFRoDCb7xj;`49Mn{tGHVw>-Ldv_YrI(Y-LlyjcA2z$cu+?^HHS=QbMgZ@|% zf8^>brcAI@I_;#he%&GQfpZ6Kb807ovbWw9j@!NSEARB1g}mmG!Z4EZ8O1+_oa!4! z5ZX^4C$zgLTT1Mu-*HuNchYYUPLf!+9z{34)%_r0jJ{^m4b}bZP1lSwf?wr_y;Nw~ zmTE5hURZN{wMo|J^?UCLpL>Mwk>6StZM-{5Ci%+J%{js%yYGIJTvR-hhNO%tsNDRX z@JPKVETMYhk!f3G-O$dBpDb4J^2xmTq1&BH*YI379oKo%KD{ey;yGSa{KMD}t0703 zX^;A`nr(%)yg}1PV>mT+pQbkt4p3S(e1k@+Oj7C&%TVsQ-X4j%TYWMOYN@G_tuK#1 z_I$O!i`dxv>@%yAUcB8hRf5}nuG6g7!ti`mx0iv7G1@FFDDG6IR+cr+blvM?lZ$3h z?fxN7St=FH*$txf(+Ndvyy@3(qeELdo33?>ckN&_ZhE`&hBh%f-sJJFv1iDJ=u*V- zSXWVOG|p41!D4ln=pFp0ACqCN{U7?&*B#q2N+AB2P+5^;se+0Ba*eEB7pbp?I{El} zw?Z~|w4(am5Tm}Ekub3IWzo9}h4<8}r&i{*bs65B+&l9MpT>T-WrM<&5xe_i%~9Ly zOfq+E&ePa(+Wy`e{+rN@Eu+Wkc1_3iDZFu1;*)O2hT}>Ve_ESc9kgs^O8eL~MGUAv zyzLX7eSN8+AxB9Q)js~TH?{QFI!jc_)ZL18LSyEJ=3%831Uup9mcgAPg&E^jh_8>7 zpE0|k%g$oH$1!Cpt{vWG2d)A72%DMIlC_fiw+oL3-`8|J_SjwM{M)-Xq;;({RayGeOY4g=rTR*r zt==Kx`A`S($0l*qoi5ZOrRKco@#$#=xi3*$#!VJix^)gw~~UXo({MXnyOJ-L)6oKYAQDONz0U4=f5_-&UWR(X3=0y&&Zxs{4+w zS6uXtt-LE_yTck+7ilLqJ|=Vc6k$lm5CuieOjTzS0bt|yB)Xwj%OB)m& z%7W-0R4*J_`f1F`CdTEO{oB+>yH)S4{)0XGjI`)DF4+3r_uU@GODJU?&0#O6_a6M= z{as0Uc-O^OB)`O|IhaMQ3feMgaa-h+I_dT!}^b<=LVTw%bDhLIn;okP4PUOrAc!mC`^>Dw!D z|H0k&4)5s?YJS!p?`__2_EBGj{05{#j_lN>pWWYbKb#oeV)KluqCfUXtoa_~u6^YE z!2X3MLOSMm7v-Ka{rv5^?cKYQraKdKqSJJFNg+;eCseeE@h6fd#a3R}iav$WNl@xM zlzwH$<>_6CuWm30Doro?V|?36*GmTKN=EFP+Q84ead_RH16S6KHxTwjDY##=5?a!K zL*CMuN4=iux_TpZG(%eFssJyjo@`ds_|zRjuCXZA~8O?x_{Sz3Z7 zUKKv+R&b4qwpJDii*!;SK2@fke}}pIO}N3uz7Lxw`)=NyUYo4c|9Gr2Js{fd_y=W4 z<&JOZNt&y5i!+7a2j-~1dtCJ)`$YXr3ZwUsPT}|S_7gejo^L;wtM#M|BN?|>-!k)% zND$hnkbT=A3g-m9HPF0!&u|6nT}_U!)`FcAk7{bnM;#5(Uw>|1_8e2!UT63D$cc@} zt?v%o2E5yXF-2E@<&b^F-9xSX-y|-oDUsXI^o{byD(Tyg{aEE?)*qEWFT8X2?v9_S zL9!+_pMG9hc&o_fOy;pL(%`3Vt5cHaaXhsj-x#Y@O(Ngz+`MDo{gs!- z&wBmLE!z40``S@&y*BN6s^P`VZpJraRI_S6QQN794 zPkY&8Gsm}?HOD^h(X@ypO{ekYH@n~))ZD<-HXX;a;PkM`x-OGuc^#jAhpT=75`{xzcRS!))D&Kuaa(C1Q1%1nj?bjW8(Z|eJ zUT=?>n6$#%rM~(6dD|a@KZd@(Q+d5&MKZnq8~UrrdKBT?R?iQ6*WAtD`D$jgU|++5 zc1EKcqoAy~Q)v6-yP55iX*R_&yBey4-c9?jI+=;9Y<@XhW)?~E_va1*-d|=hpyfgCo;Kelh*}n9JC{*e4Uu~5 zA2${xGD8?wGxueD^;CIy_3ff#sWCTVUwgH`Xv|RkSQl)xW2rAmzPT4WO)a~i>Wo=J>ay>fC%C;$rUo}&7a9kGCCdRyKE7E4~c;7_-hpY?(WodoX_fe{duDVFu z_~F+vQBzn|UCw3T@M^@epkA!CE&Tu1a@*hG~Bf6@U7)8UQdnKSz5bQEoZ zU~J%m!66R~Utg(W-Kk>unIS4$B1$|m*R_$D!n}_=bOm%ttSseG9!TSRW5rSnMROPTQNHSZj$wS-#f*B z08~tI9CCBx4fb##*_4c^-UEf1uFWcMOySk0si zPwEEpy+oCxS6|x+tSJQJx?(2|8V$nGxSI>Wf3YCO`hp`Cw=L;NK6+S$LI@swMUl+NiFy8W&NMm8G3T2P1us-xKMBm4dBhU0tzc&I=Dsn$oDjjv)2yPkdsY+; z2XoFDGSFU&rl`R=Gkr46uqe1=WM2SvesYeEW;AnZ`2Qm!^_)t#Tno3e;v-5;NIdg! zo;g!}xj3pg4u6gm+dDev`2l$YFYdqB_MFpGt{Dv^+GYP6+2UZO!>J$Nq*o4k*l!9PL|Qf#P^rKmhH&mFF2`Ns2t=oTqk-VkdXuuz4WLA51bOKNXG}T2+7f98HF7z6J3`y{5w7t$UHzS>Im}G-&#MexRDwvcBHy z1%8|yP?EER#i#VuC-77>Ly6~TRCJ&@b~jkBH)Osp!ToR}@ZK9QNPBw(3r+z{tOu;x z)(RwmV*%1XLK^8n0*%BwEwiM31PV=zERJ%Xl5?pmkJ)%JqV#j-d46UN!Y>(0gP9pM z9Yi|N>}`$>_uXWjo4Wn)It%ZuSOz0zc(eX9o@WB+eLcoZ z)R0%+QR4w3;I;2(5nqgd=tby#BqE>BC}3+1z>ya;W^_oH&;cT5bQ)h|f9}i~Z8_if zGSr!x27lj`YOl}p&rev*n2*A~W=&c(hdA^6=$WEp$+C@t%{z5Zu#t0h3GdoRQN`tN z2;U{6a$nCJO_@B`EISyTgD>qQx50;-`tAkJR|yQd*FgMBrgKd`2&7-Z_%x?CC5@X< zNjC8bWk&eEm*eN>{PUlGDg(da-i!DzO7;feVWr=i*3vRG2<*2?^pL!-nGG5fggNzW zf4GR9k2*M~uhu8s_U(m88<=~!_YPGf{R{bBux9i?3H^Wl^K(YkCGY*+;Qn6kFC4&| zU8)e++GK-nbOg1-5qmgx@4nk)q^)R(W%bbrNdm|~y{mr{8vPQ(* z@XWyzr(XCop9-$BIzl|3l4T?bRfC_IGpd`od0kW(-}g=Y{=V)Esc^8V6X(UaSK_+9 z_vXTz;=9mHhM4R4UL;gA z5i^_X-Fu~;)Oam?)G(N#Hu-CXtE)C{ISy3s#&BXli_| z=|(jexRmkcsBy^z&v`162d6$y(AG3<$BrE!Z5$3H%q76n7|=46ZJd#^xd&qVGaY>q zM0@Z4u1>j<+Nu}L1D`->45=8VNy=fRe@B$vyPvT5dCq(Sfr>vJTyOl|}Xk;Gn7^cTcJIPv?gYi?z2fH3yZm4g-OY65}1-|Hjrhy>3>d34e@zcbZeBq1T( zC2}+do!5;MgGV_W9`cC6(%yX_hNtH@$*$K7k2I7@X;5iSM0M)KA)jaFnU9ajTWJLW z+*J?qdw1Oi(l>~~p{4H8h=Y%Tu86A%)63w7d16&Mle3_oWWeIfV&c*^?zhJtuh(X_$eyY37ZlOCSY zNm11q1bhAI-rxrMcn$0OgLZ|=6>oJC*DJu=?6m6_)2S?_A|T8&Q`oI~hqp#YkaI#X znas_ea>G~+2YybTGosda?@d*@5S~+A4O5{Im6E#^cgq*+f9o|*5JkvhLGX+aC>!=N zaFcB-uA(H(qsC|34adeC1b~pfZp7|W(6}`ipka~W8=09in3;}Ozd&f5djcwy0 zK-W>(yH+umDg+FLEYcj-UM?}hU<#Qdgm=Ck7wz||cKuNuTkvapbGxq~cej`*2y)Id zxY|XxEnNfr@;}5_sq zcVE9tDe5gYQM?y)(fq_qUz^T4xxe+8?3)`iNzTW?4W_!IzvLUk_wFOP{JgXHoKkai zO=52qiXz8rJ)EIDX43<|xd~Y|$kSdzGgFJ7*J^-ZjC=Fi5clrusD7ClZux+M8@s#N ziFtq5=FA~88g*2rp<`d^c}n#zO3oae2!Nza6E1pFbI5b|cefJ$?Y#;GB2^n+Mv{&@ z59m~Mn&#Uda}+Z(4U@A~>KDPH~l?%rETDG-T`Xo9mzz%v}7 zc7fe}G@mn>!(g(+q|)?yLQLdCz6wzc`8fqtrC1tv-MlSlMN8OwmwTSNzhN{da#)im znN_dRB+gNC*N(q#JHd1tN%gN6;PW$IGR02Y3VXL-Blu-GsQQ%Q(W9#V)S5t08N`ZW zpKzk{bI>%?W(a&_WnxAC-GF170tJfa=#jbEf+^K`KBq$yG^Xy_(Rycu=T!0$iyDny zd!#@H=g+>w0lMcv2Jq6ViG*^J-7ZCVW;h(3I%fG_cMo=&l@!$S*q~febVf&zw-t)7 zY0as6(2DJw!@5@X;biSxBH!Q?exAy#_u6R#Kt!ErcuI={x&K~?KR?fU|C=B*nx98= zczr+kB@Ks)vUM@s^t5bdZ7dhFRpJJHTCb55E8|93uq1t_wlWZ^O*Wf0%DeG($jQV5uPi5T| zi21^ZR0D0Y41^Ov{-okz6HPwtc%ADYG>;`UAa;nmtOa&~>%7>_!qf2TSp73frd~Ju zmrTCONYo>gc)`iHyh>`O9ZW{QHFyV~>3;^J)PyzyF79KGdA^^EB2y=Q$v2IOPm>>cW}o`c!b zMP``zUPF3!y{rwUZ|R)zw@08WF-Jw8mxpZRIL{$R6xIW+6V%yMiO9Jrwemb z8k_?nq=R@#pK}QA*3{1Xd-rbE&mUbHG}24`3y&y?=lpJV12pq-z&QVO_hta?vh}j;d3-+IARuGg5JX~*^}OKG_WT3_b)uB6*AtE z!UJhEQN1~TMkncupoMg1o(H7LeFx2$5YILEr@eweVte0^YgQ14h^x0 zJoj$`sfjkor&DH!Q6S?jYJMpw9bh(hhfIy_Ry)M|HgZm0EO(v}nKK+Y#(}n)tihpU z5|{)ZX+ z@Ta?oIUIeW00Mlsnapj%47c=y)Bn%&MHj-6fUY%r2vCvUc$?M3^3Bk`Xe2r z8Aj6KI=I2Ewy8>l$&_Fp%jvL-Nn8`Kyzk#rlP&65R90Z-ll>U^=WkR{O+4_-SK;03NLE@ zqon6N{Fx9W8$ME{y1ju0hmx;jxS1l~lDm+~BvE|dd-VQkYn_lcL%6k|`0q!|(Z3ZvizPg7+>HRr~9b;_zJPqIL-JZ;%e+a%+X@u9vmuTDY;mv-kF$n1z9mkH2!nmv}>iSs31B>Bx z>@UQP)S2gC-hc0VE#KF#_w6el}38q&p#*p zOf3!ZfB2A`nVbFn_hm3=7`DyhJV)%_tj|(E%I-2<*5+O36#$m68N_b3`!s{XZ)|UX z^)HDFJA2<-ZH>KOcXRzsK*Bfj&$k8drhe;^gk>D7Z>XDizpZ35^JR#U9ADdert|I6 zyz3yj*?axofYP~011hqWL!c1H9C3rY`trfiyX(=j%z+1&)Tio4sp6zhC|Xrs%& zxci6OQKafzhq8BO5-fb&|dw=(4@&y6$b1fpN1%lUYn81`W>7bYEz=xdm6__IG zsk?lz^~PiG%kZ2h*>6#w@a~)BjWayYe7+Zk!<>eAHx+c&xZb;K_+f>n)jKv+-OTqh zcN;gNHw(JkdaNNaBPZ|urHIDegYUJ2rb-!G2fhFP$1XjgdvE!%a^a=r@Tb833?LkT z54)Uv5Qm>Kp-b!6O|wZYoE3XH#&ProgYwI^>lP3MJ9>Ty2=(B_+jz_MthdNqD$VRT zerEo#o*{DajrvG+4M5W#4}qHc&$o61-s}Ax{WVlG5a1i|i}&vP2IMw=sKZn{vp^gk z1na!<7qJS6I;yh=Wa4d@X)&TXUH=Tyc6SLC9$oJhdOsq_y&${GkHg_S&v``3lZ1W? ziUpsOrmhV8=93?~zX&<%KMg5yy~SbyN|fVYG>rmHg$TJqes^Q*s7h8wl9)k5G;36C z+6!18R{0}Ltyg}Y^4Z`#8s+uftByUxyMHMcq5e67dJqGK*qiz(&wQ(P&nQ2TsH5ny z{qMi`!I|?BaWH0vIyj*4GtX!mc&bq;2I6@8q8#afo;lB%E?Vod0+yvN_^zO#qxVCb z!>#I7GY3;?^Yi>X|9J@9Z6g!?oT=kIs#t_`W~AUY@10$xjE;H{3y0M&)^`OpwH{`q>BV@_wA)*czy5a-3J24DU^C~7>}sfNQ&BK9 zbMG4x4O36!{i=*Dn2HL!bGjF8jpaF0nVkrCnZlY4WSukZX4EX9z%=OnWw!c+uImw} zxp>`fR5`A1Ta^U>9g-v87}+p3clRri*^<$I8?_aF^;Jw}WGqMqw^Mt0`%iI2eew3^ zOvAak**6(J34$#QxaB9FXEGgwpAt+txJHt_*fcvP%>LeYui;L2j?Y)D4$e@gqf*KW zbR)wDvVMV|aN~xj(azPHHI=U5Jwp2<1%L?*e#csEz()7}d$I3ZAD>ybZ=)s??@Mgy zgEQxAQgX>|x3g-_-^4f_pL3fH)a|m$ArG*7EltQ84My`klypWv&zX7V2&87dos5_w z0N>`ZnhgMSV+O`01G32Rx$&%ya_z#(janHg}yvZcXOA z-$*vp46|1{f!}q)=QQ3MyQxe}qY%@OIf&3v+viO@`tZ}e3mCUa;CMzedi06^0M@9- zPnEokhC)|BfM70A<_Jd#zYw5u1=9@$LhaONa*peSoT(>aK%M7|uv~CR@2*4e9En31 zQ$EReV zlAx-?Yv12rJNx^BLOwG92vwxEav6_r0k%r;YAl zywsPQtWa2dV{C_}pj1b_a|m;4KzsM@-TQ_Jkh649EzxlNRxQzJ2#h@9-LnE-BX zLd%=I+pw=}Oa1+Jmr$C+ue$7d@wu}jVBr^w{RnAv$27B{3o<#23lcoyBN5)D>#~sU zf7bUW((1a4B*6Q!(b;F_XY$1gf5e@jqes)Fj>CBOr64^zvsf|Sx7P&8ITNMZeaWt% z#rfhg=f)n8$6k&#T_`G%3okMpJts)FS$qv;BB&8yU%a8Z6(|dA6%t58!x$Iu!W-5l@{U&zXTxay?H1}-utr>Bb(GvRknW2m!<=Q29hu`Xs%;1)P z;ZXiEIq}7rv_nb!muqAA`FXlJv&#El+jHUu9<8L`-9t!v8fPD{D@KM)etwQL1x_nW zzP-T8xOS&I_D6H(0og}cnMMl?0AlJ!@?BKfg0KK_eeqfcZ0eONWJe+n2W0RvuSiftL91~w?H$M}S;oQ5Lr<;d{ z0mbFd86EkHqFrxv)Xq_@j0BIc=Ok34r*=Ku2ggIyXnlo+wG8*P;7Du99kS; zvMX18Vn$Q17`;t`}VF{dTv7j~dCv;LidG{#nf;oA<+y(GP% z#pn{F>A|kIe9m;3;e3VIUBeN|hojAz(6VgcBcth9Lf|OnS zD#jmwh0)YV=6q{)65d7Zx?KAru%9Y><`54xzyJPXSq7%t<0=Wl&fV_%!SL}HFEx!r zdm>1|k`oM^`@Z*m2d+XwJ1xEmuD9y-xPZGh?=4HvgU z3=h{4rr|g<(tN1Gx?TXSR^%LxermF)MgYxcVpB0#4N*O;5*!ShHqHq9ugBw?(e$U(=tB<>YSg4UkJy>Jm=SM zO+=NO?|Y@_h^=}zzSm7Buh|fUA|BxEzsqkXqYH91ArR*l<&hU4R`7?36IV7i3N$<- z@b107scbA{mpgTSs9WEB|NWngce`FLoK!y`N=>2jHI$3HTe-dOUBbDQ5mM>$gtro| zgS`pxg-$~{;($%7qX^tMnN1@4VTI*~Vpp*V7}|T&HI`&}Z=N}WvxKrbCm33W05$NJ zV3;Zw8}uYr`lR?}rCgqDK9-uM^d_htsN}~}MOE{rRi9GDbb$G!s|s^31!|-TbK4H* zwhMA7PQuvFnJ>7cK_2hs&CeWxG7EVZKd_9_&I(+@@sQUJ;vLPSy ziBs+M8~&~F3aUg(E>ug-rX(QFbcM-uns;@!VH$h!9LBlu@B1k$N}U(1@?Ejo)%DOx z24zr{ytw%ruip3Hyw{2$>RZQr$Yh<>Cs2nMj5TtIS=27lVc~9=+^$Vv1mAy?JKy4k zi*G3=Tq3&pQ7rAB%j6&dM>7* zN$+t;!{H{t_%}DnhaxauE&T3Z?u63p<9i*5+G=HO1Zzj^iYn^^tZ&;7gfqpT<6PfO zxEO}RFJiPSR|N;CrF%*W(g8SEVrM9cZ#Tg4G~tgE&QnDySr0?rT=KZf_dtW!;6(&yfH^}QEY!xP6bq`LbwDjAZ_l(%FZdg$3m(PzW1$1mGn)w+%SpXUxvHU(ZW@+ z{chDipXi|}^MyAPgONdOGYSA8wihGdP;tz-IxGs?09isai5g#$0pM#&IEOVH+%;$Z zd1iF3NmBC|2Oj7BeP262bC4X)8U386>g-O(nnTe_oy#|spKa5B#Dr~VzHDT|E-u+X zg$v6LKS_8k1V{RSG%3ORdz%e*_kM}MHBmESIGt44=IYbs|A0i^(7u#J@KY5~&)YOv!oiZgkG+xfCIe8NkNH z0v;lVyZU+RJ>k3SyNJ~!vTPZ)E>zXhjs}&xW_`r-QIyHE-8^g ze+A+kX$}J4_1=89TM*1SoF5R)i2l!WDw+50y<6@uud{jg{cmLCLc;}c_U523P~61^1Z(h=rru52Xcg;X*5leD^_;6{MrPeWEWclWGdrfIJH_pe&xC9;#&S;travoK;@ePRGhB1S1yIw&js9}K_%+vjg_4=`C zKBOMaBh8s}PO0f2G(NCBz(9KDIqStje4MwH-RppcH&Crk306HIUo0ge$l$LXAEtrH z_}>Nd;CW7hBplVFI|mIPGxoIdf9k|)bCJoJPp+8VzqQ|LDm)LJ1p%(H5GXFb?F
v98(ROv_G;WiF;azC7)IjznEe-QMCQ8}Gc7yPDr^EEdBWyM=>~k90 zn(B1kc&>o3 z$Q7)<_d7ZDh_NYY-JJ>0yf=$mE!&^2*s`G`rrDM=ry1!S>YLR&2y1XY2fD3i%$FpD zy=!7>V`kr^-Q8-b@w<8?&U%5idY{Ugb(5o;Y83kJ?emRc&76ngW-AQ@G{Xal;k{mS zX4en(oa(FSz``>Rp9h4q2TjcrYu18T`PegycYQzHDF4gaQ(xu@ZUnwq9Xy(&FX^}1 zsY<2eggQDKkh|V9l3&1p zj^_OOer_!`@FgOUmUW(g{(*CTsF~!;g=l%Nn+KyX5bQ|Ia&4b9zO z2u)=mR#m~Bhs52>!Hho93z97E%hZ^FB$_iv?|nCp&1uG*y#~}Rv*gKnzLe4K-yN6% zWn!}*GPM`--pn~&A~s@1R33nbJcnYwtt*na@5|4mz_zRcivA0@Nwl>Tj79lL$B?Q%W)O{Nwy9s@hI+8#6gulpuUBc;}_eEoLyk7e++8YQz zOb5+Wc33$XdBjlzija7J@4xZ3wLHN{jqcHRytRKDCzHfJ`a*9hn(}^IOW6G(hK@vT zQlYwLj>g2_g4Wb;_r7~+G#gvC`6bH;tjqX=~Ll=7w1Qecql-HbQq{8an4{;uV3u_ta(zP%gloYVBh zKSr=etj2@9?~5E?m;ihv{p>fZJ@P5r=voCIq(%>xYgMu1~a`y7#7*@A(J6cgOEQRogI?)|nh zD{2Y~&p~dl#xrMfAj#wqFt%!g9N{^qo8cAcPv{TcKJ-H#DMOqyjoJR%*=>8usv*6k za2ElDXJ*bUon7UE+;8V@Ftx;z6r2dxx2S*DSIr@n++SSYp-AVq!g)J+U!sa&(~)86 zIn#X!Kl60iCD-=)16XFx5A-DlHa8XFB>OF$efy0WsS*A&K*Va+fq1sK6*$o#nI;VOMRZouY zmECtpA~THH{o_VUW(p$qZ98W);QE)dx4LXW*u zrD{fhcM`-~2OpJyW+NCq1DZ7r1#XlVVp>z^$|7_3y|0^RHearIF)4~S_;x*Xd#Cf4 zcz_po*B4AUI&JjmCfTfn_0FRqu2;MFx`nbG5Iv22aHAw`f32R>MAhJ&e+JWtgYx(L zNh6Xlxrd}4g85qkd*6FTw4z|B13e%?V%$$1fkyx?#H{r*)R#=d@1fz47dt>cw2kLE z|L5nYmvl2UzMQMzUc@BgZ5{nD9-gJf@G?=W))QeyARlyyCECbhpe_A~(Id>usjVt^ju z3+3z@!NgaiyH*eUhNN-VzVCi3>V#)TBVZ=#ev`5obChUPi9Ec!NLQ&eWM2ZK`56h_ z<6tyvPhHHpnwT&U2=VpBl>D%arVO`P$;tf!i%)#Bc_|=;dQIGS-`xDn&q&cSA)cohlK=(ty>AU-lAdQ^czx}zWOLpo zPNc7b)ITIkg79bFHmf&kyl0rHpYc@G}@}?q*pys7X%OO(^rG2N%H6JacCF@BL+> zj&d{g%vK0JIN0@F0+)3BZC)C+9jICId=e?mOzihx2lBhB0>246fig*>kfo>LGC+aR ztN_dijN)A*cMY;GA%11pL^ERZ{By{9E;OTIzw=_u_&HBJuFL_dJh?e~=ZxkA*xkJ^ zyM@MI9p3DPxzT~tw2l2aKk5ec3el0Gws-y2-CS1W0j1z8*Ef-BF+mKAD~|s2jCiWC z-7X4T0hZ2Az66QCIPu6`v{yurA8xn~+C|?F?0XRJ`|HgMuNTGyGyK$O3Z>*?hVw%{ zwNvyC&fX?S_;!E-u|NNL_;aEPJ1^{s!^M|NQq>f@^-(tDL!6%<;)t;8Z`IxngQGsl z&jKkun%m%+`KP@O7}Gionya9{6Y(WwbTS0|#iM~~i{0#j#Q_gbNjSknEF9x!X3j%! zhKld*Tdo_t*R8&e(Twu=FTp|vqN#*mVCdbw*EM+~OW|g-(I@5{+rPQU1;@>{p$_Gn zH*R^yU$!*A8f*f)0E#oLh}t`_Z3=3*i}iLB-#Moia)IkN^B0-Ul+gY|UK*REct4k` z0i$utQPZRfxJwg3;gc`1G2Y6ma^|S@mkscG^q1iD7p&6O3Ln+T8j_Ut^);JR#`>Y% z;o!{CGc(PNz)Z-7^hXjO7#rMO@Bg5>e}G)rr5U~^8hTX1{|7Xkl)|ye4Nn$dUVd=!=!%tx0*>*xzn(xSPko*qE|x= z{*ibp%D>(>7bN8syg3?76-waD{PRyQnDkrg2J7MTb24Y&U!b!{H;tk%-StkTuTJ)} z1%J|+&{%kH!L?Dc61_`@wf`G1bCoX;U*EFM-a#Xgvf(t5y^hWXW8Qm1!PPkZS)=+LZn$Z1vatt5 zQ80_o40q=2U56aq-@E_QRgE>Zk2qfpGgzfpp-t5DDeCKf$ja}U{w>a&ZD64K-Qo+1 z2T@qo5LsWGhU^x5@X*Cf+Y7KsTi<4YQHN?UM;Zn6M_D4+NX>3&v>dwCw5!l~_AYWc z{&{}poF(GD-c$(z=N9|cCAdxw!d-24aRFv{W*&iOMvpR_L&|GP?jfMM3CY)0;HhbQ zpYi}qgGJ`%-k4dGxrzkJ!ndgj13o`f5$BnC9_?Q^<8EJsp#}S!s2;gB zVX{fx{pK(f+pa=Y#6-G|pBQ3yt?iJCz^_Ubw3#?elZyJg=)fZq^~A%sKe8 zOCVT(Yu%mpO}*%$Q!x`7ng{&tK(bNNlu(_YyYy7*@Vm8M{<-$fV5HQjoou0Fr^X2H zI{VRy#b1#E)qB-TG3Znr!oi2dcTvkac6s|!+kd&N{6s^Qk;Jj{IVZjWfTxhPhx1{n zr@YP+Y37-FA*O~EKS$s8v1Bt{hXzc|d8hd}&W(Pg^E`~6XR5h>Z#@sdF9+nAmL_pt zx2XVtF0U^S>wLPu8^Pw8BW8_~h@axiS#OFdgvtGudt`>3u`9x;^r6|}ee0xYL^qK@ z6KXV{wCP(kKrCyXYidRVo`z5d3_u7?v)x!a;yb9_D#FkB3=l@wDVQv` zWhc%ygy_*jBA-b#(Fwjd=*0j0{NQwC&0m0cfRjux_ulTFyWV>*kkAqapmcxp@BjP{ zJL+)m>qYL~`=JK)wAhJ_p>FQog`{(iMp854B#w?gu*m_Zu}3v31->`$tKn%%uy6Pc zbc2RGqOvSvLSy$DdjYshtSLSZ4}ffT_xG1=FW@6(^G(!JmxX8$baPWkz59Ew8?Voy zcKnEj@8N{!z&UjHE}qc5=ksU3l+G<-_;Bw^$w-aU|{D2=CnlPl_B% zAQpbzb6@@xf1zLZb#cEV-kU$GVD(_8cxG_Os38V6c^BJ`f=O_pqc|Gki%b3N256HW z2e`j)r(^pK+f=oSGI*1G9U7}*z^)M-&E3UT*;9*oEBKP~P&y-W&X79)kq&`%x&d(s zGz(UtntS!fWP&)-BS}0pY9Uy5BkTXm)E{Kok{r9*7y$Fg;v0_Inz06`$I5U6)IcPE z-NnXTs}75Ka>w>CHvk`e&Z!8I_uj0ZGu_Znb$Jrlhesjb4fbD$KvR8D7~b9cE*1SW zgoU9y>?5@S&SDQwPwQ4|sYzHgtar0HfvU|nlifu~d_avdL#UWspqbo8^R&sF11Ul) zKpA!}Z;C!`TBuLD9e-5 zG+F8X?&5Wp*_ej=-suBdT4uQ&4zbxU*IJPaK>Q9yXHtAMmEH3U;#Ti8-+|I%_`NA> zcKvcyx3$?&WUCy8c7>6nM}?tA{W#Ptu7h>%u5Dq-bfMa{y+5{@4MQ2$-e1#t6QzlR z8}0=9+a~dglj{sfPxy6ph2ZndXcI!ChX=cCBh2R(+TArQku*-4Gk$mu;JcT&5w}NF zu6LXG85|_B-}mn*DT&q-M(1>+(XK&$F6u9R_&m>Ze$KQ;;te+Sa^G&9*ur(Lcz%us z4mhR=MA%8wlZnySsuOryX*6e3&XnrTNH`jZ3j};vc}0sqNPE!VUf5-q!eU}K$gcN( zT<2(RF|PFkcsCev!+-Z?OY_q(YQdu>4Q;4&qU(qy31&8eX z?Ax)4B;h=mPV3bz_NE4W_X3E%j@2pdZ+TPZ7eRjJqOURzjdE?97k1&aC#EmdPG;4H zfqY9_f3eM=VjSns7BTu9GKqaVn7}CM-%Z1SWDYkD zmZdrX4P{~%r>T+diOEqmb)wcibr*Gya2j?z$BheuXl%9&&4hWp;Umyuevaa3x!U1Cbz=)QoW z#Je|X>oU~PT*%_lNkQ{7=TyC(qtj4I-QmfM&hyNi;Gsrmo-bj5?NVImerHASyJm}c zZ0FwnedENkH(4g{y{#woU($f&jOy83*slSBGZ(4^BWbgHui68jZ}}t?wC^%{cb8wIfRfzCf^Z#iz8z!jR{`e_5r4`|u2Y;Oe$Jza>e69E z|FzKEFZfP5hClmE-Adp#5)449p)THTemBMe=J`reyIn!Rg+DU~0f@)?MiJmsvny4j-J!0^1#Jyv&U-Rt_?dhK)PN8tAcf=hDF+!kTmx8^w{2 z6VZGn$kKO=B(6mS|n4A&4J#>f8 z-m4!C&+hh~@4M@e9OENSh~G=39up0YK?r@~2yannMr7SJwt|F2X-1q=mSOSmxEjtp z#9Z&b`|dBKL)i`Lv<1e`bB1Rm1pYRRJJg&rbE+%!I+a4t&_F&B?p?p{d;d*nTxUVo z(X+dk1}V(0G(QChKj)ti8f zd?x~LviBUFUfhe#-8(SPB>D1aVJVA-^_}xZT>X~IFApk8*}`u5dGzo7za16d5{d#` zmwgm}0y-k$39BFObI$opb=>Ul-uptx{OIRrz=8}vgwtCRr3pj8KrP|{Bt_4e^ZaxE zIcJ7E*y}4@T#?TEJ z1^fdnF_Yw)et)q`et{Baxy$g+2K1dL;~os?%Nf0MQ9tLz2zSGHTj)7ugQMV!W}I&B zCAq=7|Nh=za}1PS*kmh~o7+`h5-i4Z0z}8&edipu|CgiB!_4gd?z=aXxDrAf#Bbgp z_jdKL0X)UIKSF>jo5s(}v^U-?!6OMKA=&Zu<*`q};^y@XQIxD)vO;V(#1& zR}&z~!`>lP!#o2RM-#{gU5Ld{MNmkbYrxxyxV*?Y4>fhq9O!7=A8T1oZILyh7g#Xj znb9^T6hiapoS%S=jOp{M)Mq{1RAf9jU^n zyvNtsG$M{TP+4~bPDX;}y}68&`~LQ-+3uUXAwJ6;)0vF@7Ud%g^6Snz?SN1(U!8PG zN5B?dq21eb27CQ&Se6I}N94hLWE_s*Yzcds=gTs=d(s%xe5c!y6JMtj4I({XKeY2B zx|*vE?oC>GE^5v=+t{4HH~#-3$nBFRyuvwW@?E=B&T-Zho|qc-L!1$K?|t`%X(`of zgYzRH8Ma=7S|Eqd(FgWw02BE(9ZjUtzrMRmlrQmSNyK2%M>WfK2ll(@c*FO7i$2(d z_UP=lQQCOx6r+%~>-^c~*FnS!^LDu5O8Y-OUs$3#OeK8`mo>jqOtdb(!wQ=JP_Dw!eg~pj=4D z9|Gq?F~&7CWzh&z%%h{9fB2*J>&0l9N-L_@y$e@DPr_}8(_X@9f7EJl(o;OgYE$2 zsGYASufU!-*s#exxWio0WCe*BDZnop~&c@ zCq@|6JeL-x4N%pu5*yg%%QG_vmA^tC9tgCM3rZXwjUH;SKHwr1X91_yQOP<0Z$Oa0 zG56QR|M*593kO5>e#ttw@`W0N=nN)bj}g?3{gG_bD(%&-4-0FPdS>d}`Sz2Nk++w5 zjX*my6b?W5UCsQVyVxY6hm9k`oupE;TbX5V`^_LRSSck^c$e}dYeK6V~rLW|M~@$M~EGSDGIu3xlz zn8ILr{hRZr+3>RodWDSJ|+YjQ1@}H@07fW}(|4XTrP@y5ch`)eN z3yu$T?_2Ss(6SGvknFuiFygQwG5x3}%Jtd_aBai@jVn?!&zxG3HV~^D|BbK zjR1k8aX?Q`!GqCx1f{a-6v9Qb$mIpL*7$c5XY-M)V0iI+-44{(Tl`S-OZdur-3vdo z4I7m;FrqT~!x*+8aWD|BSEJ`S!wi*(`r6+ZIQy;mnfIge1SQl*2-EYa8>!g4iGi_= zB)RwZ!tn0hedhdUevS@n9B5nRy9_njh1XpB2Hw=POf?8~IJhab1Zzr~qYoNI)*J*% zv@?`p@9vv|V_5a<-X2$sHn?}|QrP(3tC{59-?tI2yZK|$VCEsZB6<-2-rqlzk4mF8 z3}12p%RpanDI7BmKv@Wp24*NODL>$8Elu?!PQ7&!_Qt z%jV0!|NXBQzBlcw|I%P(joo}zK@rc-{OI|{Br=B>YQ4Bv$o0v={@jB+HCl1LUvB*E zjIzK5Lt@;0c$^FDy6ShML6eVzzqe6&U*F%f`U}!1ZD69#X_=7tt?22!RmE!E8cvAc z`|ob_P)E~1I zu;IlSh7Ft7uG>r_ehqIk7=6i?;RmdsH1&P>-rrWGb+t44Ud7C$*{Un4 z+r(%*CGXTrbZayfLSNXM8#S8JvpWG&Dn>BRNRM<1Pdq#wS&?5Dg%NoDaTDuYSbF^~ zictjWksrsL4>QM!W@-ot?05HGlz=+}m?S}ayTda`9Z=VoNr9Frynyfx(o#O#x8AG5 zS!bTX;qZJl(28`ZFSipnG!dlTKImtHK4FnK0|4!iGsOjy+w7e_`o))Y&1SD_O*FFK za_BC~+pl&0ul@q_qfwr7TE#dckO`|CAoY6e&4uc%=nn9X=v{z^6Ex{6d_GD;#wf|* zIp_I`Pg>AD@bz>Na=xsy@lBDnYxh_Bt`!U+@_~r;8dw~v8Zej4Q0I(x)VALqV@?Ku786jK%2DSe@^Ec*l0q={%=H1}+H6}!WGoQWy1|KpgdEc)u0K0)&mw9xVcRMOWSM=tHxutNSY*>)ZLi}$9^Zu< z3DI*{9OtIx*PqbT>+$<`XCeWVFl*g=0mAfq*(`3I8yhM|u-D&&!@cgLp((g5!>=@t zB%Wq8zyA@pz>8#{HE-ijsq0)LNEHA{416?m&ceAt%V0xB9s~x@(P-63({$u>ZBH%M zRl7*8*Kesbi^SQHU|mA}$$+k>xk@kY!9)H$XP$W9HR5X+pO}mCqsyr?RhE2?sMcBhBGC^X+Xgn_w>s@cZVa#&_Cs{&6h;b+@3p3xIVcqAq!c$!uQOwivw9?4%0f7KVOc;SxM67|$DJb(2>S)z@8>hAXU z_x(fYWCrJaq2Va8wF20?!B z4PYz00JfCrEX`h=7LKD}snE|kt#Fq2ba34iFq@5-ku+tV2pD8Jm~cNk1b`&f#kdHuX6{;^z5vo6Bg3Kd0^0f^Yw>WLt+ftN z%%j$zlp>z@eP7>tzuJ%U_IjqkJUY7pIl#R(4B+U%A0Js1)n!a;+5tCW+D#v$(lr5C zligPc&qUsR3Egd(PwS-{BIhC~2TIRd?=Q^}&oQtC??xit{Mx@N3=g=s%JG*LViY$- zc-G$En@mt7hPo-ecJdOq@BYP&jV?Ew3==xp-<#X&XvSXzB71kQ_;jv45a1eVYLly7 zW#d4DIi~>tH=qG5`vRHseu_oDuwjxqTf?zH2b)bBszB(-pC#%?g7qR;`pmQdWExg) zRjO0hS2ZNt&Mxj}9B2?f@ophDH4~WCOi0%PY%ZwT?{NY@Frt&&upelv(`1wmPqB9??mC6$W{7=r<|GIzg>~r| z!lNLkAE+HVd%xM2jpzQ=0N0B^A{e6+;fx+>aHxhkH(R%D=j!Q+WGuZiBWiC~iFog? zs2&Z4^0fUh*U)l`&M$Hg{;aE*FApbh;5>RlVsfDTFLHX&T@^_NwAWu`hQ}bXhiZ%gB>3kSwY;r^=_GULFN2H_@m&iW4Q3>; z9EKpkzW-uBI>2-_0*2&8^6}g5TF-g@^G__a9r9Y=!1(ED!4k)my|>0IBkvo3^9B>j zX0A8!Ifrw+f$!Z$*urA+FO+*`$P><-1M&vvqi!9hF|&~8VSoi)mv8TQk~aM6Rq%DV z5M*!sBnP44a(i3OJ!I3WK>VC}4!t$<+~f-8NQckiO>CcG>nfdM|G$r}&W$r;1X#MK zJ*_7H z#fD01@zF^tYBa2*+b|7I$Q!fW9qV96Ge@M_ObSq-?NO6Mits=I?oBea*mq61=@f`< zQkWo5)O-P_(=IH|GtU`@IZeg?-b5zWB?rBQiGYVwufjT+XNUwAnn`dSfbVu&%=p#_XhNBvJ*!`w%c-jmlCqRR;Q6IBj8+LGDqMjR(J|j-n%Lu z4Y}9Z;KOwBEl=ypi+$g|@($KHZ{QNV(5rJBOpa;+S zLx!}?y>`;igghoSC$>M#!WZwEX5qp2Ucc|={{H*^-d}qan;xz-JZNbrgjNq>Ml)az zzg1q*`sQqQ5*hl@w@aXxJ zYA<{j?Fbg^R&&z*EldROe4I?I%8jen;iCeL&I$QE(~_8)W^!+2jr3sgepG}n`r-`E zJjwKQXR-Ie^#{Zudl>=Z_NKKOA&KqbKg}9l1R%rg#`o4IXB&CF>G(!pFE)4gqE~NK zjZH*TnqUHM(FaM&Penu!Vms*zX4Cp3L<~pS*EYyWqUIKpT2am!p4tzbDHkl+xCJ$wngr3dNrEoL)!o-=DeO84?GZT>H)E z=Sm8^s@5$C%r$DTz+|)kIU3FS1wVgzL77qz?9#^fHyhyX4g6~~o`-e*8#ifr$_HzJ zPu3dfOx8yqvX&vB2HIUQTL0YOY#U4gW5vNzx$J)*yOIRnAqbXaO@^--tTIh&fR zFp9oO>+q}Qk)ZAGry#3*H&{lL22%%Vb|Fz?xU=~+hS3>)wMi-daeWbv;=$kuY7}x> z1o+8@M%QMMxp}>?bYQ&s0?E^6lLe4w`3bgb1)~=Hq4oxA1IiO8{;M1@xD7V)aKIx3 zWeXPiBw#-H7ZG_83{;oXrSE8<-reBDp3xugm`M(%CF(?qy!$*A5I>vQtewMDVIKRIZDa4QJU;TaJ;^D{FzaAIpE5V}D$3k-*9X3BY{Gz&>aHjcyZqfR5f#KT-d9U>yzX}}Z zFrVib0rQ0v74}5_9M#DOg-<5|F=vYL8}O2bl&qY|QX*z%LZS|IO|C zNBUNpgA?>aOAclbe7GY3``-!2zm}E92PIr|fsr70!0PgqwizsTD zggigz6ipzx##@azIHOPWojHe2M)Pyd%v=+&Ds<-Nj5J^*1nBI^Hv)@b1lh^H+slj~$dKnh0ZJY4t@Ggf=VD z!6@>TC1ONHg}5*%%mJS|US4MbTg~0Gckc$}G*z`DbVbv{51j=t_wx6B*T2}PL7HLW ze|JmaEt<2{v7goa`NHV)lt@ydHUSws=+=d0aMrYk_OfgoOz`0s5oRkTH)KDWsUZZ` z9MEl{s|wkd-w-oTQ~HgJ1hbn%nk#TJh;2U-nO5>NE|+0!Jm5&(ZjN$T!6!OvXwK2G z`R+YBd+*)rbL4_1aLW(wK(~FiVD+?Me!43NnI@q`ABA*4S%IYOW(@C}n`wAl*Ls^2c8MnIXAf zSZH1@m>Do!k=tHw7wHz1w)1s~d}Ks_?gxO#rZmmcb0FXP+OUZ4d+2YSsPboL1}pS6 ziA{{5&OAKBFH>v8)uV)tkojK0zeLggtpu}+mSsH86DfCZ);5F*!o@_S4zFMGi@%Oa z_&9+kweUL(&R+#bM<2v@gNT}$b57MPAHH5A94IYZoNl+J!}Dl(ex^zZG|zvY{xzPT z((7v~Y)@P@OOPKuig2La1!FGfoagX>Vp|G}|DX9J_6yED;3#VChgxQdevj@@$VWKY zy{X|#{C>y&bijFL?Y&oNNFU~U^UO&E;Y>p#cJ6L8z3u6Fen!*c-Ql|7wC?3q99$Iq zdw<{B2x5t{Fl0snxV^Q4cx~5nE0;1Me(!uC{NiP7kgg7Ej>w%edHBUAZc=2-kTY|h zpPwIqfpF$|PEEM8jXMnHNDSPjwk2+GL?rzQhU$L#3yP%*-^C)0H|gy9-l9SUFAx&m z+gE=H4IJcTG+YY{sUWKN-~YQ?U*UDEXL9DlWE3HQyuN6)3N~cu$W4VnxQ%&b55j{1 zURSAEsH2g1#!%IKvyut@#}AFuiWp*DSwc;tZH#qg%Ctf}+<9tz&)p+>J?LOMCs z!-tPlsceRZjFdfZ^8Fg#8$Gf2CH#TWnFQ}{X4ORRR2hN5G4yeqm;bN-&;NVFf6jUD zmC*fK*2~lcd4v_{4;k#%l>yDYf(uhZaVlMDOENB63{VsjtG@yx-1oiKnQx6geSMJ0 zb958mNSO2Ne*eG#gRRZZ!HjX+ce#mlYICAOsly<+H##7P_DZowpS4p=UGV((|NDRa zZsx!)L}c`VbP3vY_L*b*P@A34&EMQK^4;XrALRLY?%n^#y^Bgh=+dGkCN(ymbAI37 zXAYplIL=G_F#T_23 z7M{dxl=``OI|vFGus4yL z5V*S(yBgc|N3*`s`JAVqkgxe$O?%bgvjqf9fH}a&LLM5It^|VX4E9F+AC<5bl#@au zls9{D<|t;+)7BuSg`=$llMcBYIs}$cw74o>mDLWu^uN7SmvZR%x1XCn<@=#cIic;g z1=TqW_3_f(%fF++AK=q4G117*;Mn&P1Ro$r_rAjHt|Cm%`Ptlk@9BIH`=*jv6%_N^ zde{uoUZD4`=1{pe&2Ke{dE>H9h#}L8Q*YsO`Tjld-Hb&0wHwP|}uw}|6T{(fJq4sck4ewq9MrJS`gdv z-cbCRpPP4Wf*dvZptcsy19*bFkpLY6oD6ld@9#dGtM}nEqxan=BZoDnvWtl$jr3-R z$meMNr~r;r z{`ci)bIP^x42>xed!D1c+wzSXJ(d{~ne~p4*vTUi^X~Ra-#li+!3_&klwIvWSe(PV zpTnBKVAgNY<<4pTD>2D+GzSZ5{XsG_%cZH0tQ)0)0PcjgJm>Lxa~bi|QQA54MVGq- z{o7#Ftri}11%HnGt~dJOZXPk3e50jOpq_rjN(^bO z#O~n}aeeCv2ld`xW*%{abIK=FLa7`aA=_HxdtU}iOxV%lhRL4i>HCeE++4StX@Y&g zKMDA=1BMtrM0OWk@TW`28!K{f2Hu#Q(=Lmah(hcsR19i)XRIY{fM{})3Bv(y>%g=1 zBJAE^>hi!sxR{^)2qL0@&DB29g$O1uQU!x+92p<1$unn$_c~6zVBIwQmT@)2RjLFK z7(N{0gV1ziSBIY{a)LecS?~-7i>-P(Be&RVlS4i3o$s?^V`ZG|Q7ws`%_lzvA=Ofb@%MZJWXmqNj zk-Wz9qjfsPY^*=;20tqj9C70N%>g%=f$z>a*Zzc=BDZJgeY0bQ9v%Cx_vnF?U5!9e zMe-=Z$E=9I9XyQCF%OuD9g#N+_7a%VhvSkL(wgM8KLmcQS&VOQTP>U|~P*2or<-z0a}alM!xu~7fx$%N4$pbi_z?9=UbJM3iVkN)bv=pqn}NL zH+gDbi#`16-GDZIq-K=*H|TTm`(aK92r1MI2L}zvtavPAzYyQ=*7Y5)IJb_fziAcn za8L*E5*4|U=VwH%4Wu&OTHziI*B6d`&hze73L6QltHOV?0;-J^2k<4h9V^2r$+hai z^&T?0{W=%hU+^Zo-%3Ab&otiZ|0yr2<-7?ln!C5#7?kE-k`DmzFopiIjwjOxbd^O) z-bC4Jai)A#Tw#nVk?}3XgIG)Rz8AzfBC*YqBr_-Ox$-%lQZpD*x_RRBbMnI6BLZ`O zZ;rT8kbyzvrUBDGtZ6ZX!o|S z4h!IGg(_C>{rx>(aj=mr^-NvT3w9Wjv!qf6H#noL&GN;pNBt;PnU+H9fVuaM`0Yih zWZTxJv^~PR7n~o>_PWQjiua{4=j`>r_nt>c$Vu)OJtlqk-}gN~!$Msk$opDS4vzJ{ zcZNCin;%V#OPBC^bf%d9eD9Ay#P;Y1faT>^J5@TG}#x+{iHSpY^MZ9o?t-;ybzg%0CGYkMSJHX4SPGSueZ8Qvt}s;HB%fW}=t10W!1^vz z;eqWc-LB%+0nX6=od+2y zjq@6Posll1@!n)LPo*<)7PqoAq+pTZG%rIy*MI*K1tZ@D5O8L=H+69nAa8O+kb?s{ z8h=v?_~k*7w(5eQVQ#EYr<47}si$9j;ZXC%dy)76zh6d>>e4DOIZg;1izjwI6E{uS zhVAC-D~`En zy-6^00^?rN;z>OG%xQTe;x{j&^MT3gI1@$to&oUSqcfYyweuahKS9_%rt9m^(a*pB z9rxzO^E|Ega8ZEi60jG`8S1|8(J>U!s;BbC+Uy?eMWENn%r z;OXtwzy|Y-y#ty&WFUKonGqCRKF_Jm^8XJ%nr|~r&78e&D9GYqYfYKUo9uZnKryWZQ{e$$j|J)qi5;7(DSZ4dLJEbj~#R}WEzdA{fSB<#c^eYP$DnyG&Ui? ztPy@rL$o*;#|Vab5chr;Eu9fyddIdG}v2_X7iQ1MGL?K{e2!D)EwB5cNVWC?pGM zH`M+8J?Ci~i6S@Bf*5TAFRr?CX_w~}8{8M=%zwh$f3{iTcxHAt6uDk>TOOrmbpTZA zAjaR?b(niOqpu;=Fm&X-Y|I4T*+ia^>~}QZ*00}=gKV(=$p6MI%bkO?qwWWrR$WTV zFIm^unTFcA_pbKT1Q~j$o0m|6XC}0GYWe4I_Z5y|G!W9ZYsk2Hd7c_2>jtaE+cR_` z&wZm0m%BB$`clYEh9hD(CZ2QdyYKt5w+{)<@F#z+B+%$9XP|;r2mk2U7faBaVi?5a z=V!t{ze5A#C7IOf{0U;8p|Yq7WcL**2aHui6nTS(g!Ei+y2c2}$hXWg@lZF?brHF&-q57vInq(lGM!bk#26c(=~Zie-M&u)lkv6&X)&Yr+KTKv#sDL(bhfAuTjH5{FJ^e} z;yjbQ*PS~=clHYN$BYw$^=m2jym<(aRBw^b%tH=Ea3Zk-NY@nj~%MJrv0It^tYv`8gLfGE#8{Y+oO2 zV00R&1oP|dANl!t?(gEveq^%5P~(V@`z}lA^u%y_VI^Z^<{A<-XJ&rl?~se=)=tn( z$WRBNI3k?PgU^t%3C5yX=VYB`G%aYyXnLGUJNbO^Ilq99CK6Usp&|_9^(|B#Nb13j zcbyL3y{aa7t88R5Wvi;i5I;`=b&y#WAbw0s1pv-j``W%kVnS%Ym^veS* zyWnMV!s6NOy9!?%DbbOX?APtc4TjG{G^rLb zIFfmPo+Hxxnz6Mv`0|YQLL|@OoN@uV*aa92+DT%09<&J8_pXginM3L+ z!r**TYe20{PvSRU5r@;25u(NZk>tzZ91v{)^^vf2a`%cvCw)udwEH)W50ahnHSMYc zh=ZUeV0Z23Mf9n0&PP_JZ|(NYYkS{NNFT%rx}%Z(=7xK}WBCla18s&F<*VxYx45J0 zrRdFj%?mv9^(m8o>GL3Nu43;+qDQC9k=|_K;$w=^ZEkJ7MW{ma#iTm9OpXSe1Yuen z{h3)x{h&3^Lmg9(VvXAO^kv`rKxI8Mz4_=o1=ct^-MAK5hydT%gBqRVDWXk=j3rKy z?LvRA9chS+;CS!1!A(QO-LnnXePdGH1!ZdJE9Q%kbVT4uk2UZ-1rfcq%@WtS6QJda z$%!016H(G37$Md=IzN>5bwXnN-bNWfY+Vs3BCR9A;9E-XW`WkcbF|bBqN6PCzI#1~ zKQq2KPtyPeVT;1iPnLI=$~n^q+AIYPJZGkc>De{_;)0hbEj-t50Cxe5FxY(kIq!Y( zh{N5_xObiT8E;gsq_!+X^aRJ|mNeIfJvU}t>nEc_iN&zAKBXW2s>j5as63M*PN1oW z-B|FbS2#|2B)PwifzJZpZ9~pc!+K%Dyze{7p*Yx&(RKQ%^`iUb1>XgUuCG&tltcaQ ziaeY%T-Gh_r0o`D$x{SA<_c`G`TU+E}-4@X!>%2A-3|8=hnK*TvckMV9E9Uc*! zhpAI-RFI$qe_hAJ)`e?=nIoxVHg_*OD=IpFnWqpNe>?z&bDeP6{7^N8_7#}HJRcsS zUU6Vh2=;Gys0SHD4V)nq4%yQ@20yuB#tlfHWy^m`>sbH384Di~m`qJSGayKOFYoui zck@wu(E{iOXomB&NpH?M&me>6h#Jlu5{b@{<}YF|Q1>EtN0nrlX0=d|L#iU4^Yy$H z+|kD+o4cVnXNPEu918Fr7rR2!?0|-Fgie zW9mQ6uz^kBd|0KJeP0a;{`{+5?^2b+j+7ZQB_nde8zmyA%`KeO-qH6>Zik~g%}(vX_$ zirJ~ zIMNxyU8SU&-E{X3q&@&AZ=I4!_Px7(wDj}ykDi}la<^tnFTY-R4?|s%|Z^nf0gV)z<0O#irh`=rqzCK)c@iHn!YQS6o#w-|lt3%<0(q-EB8Bx%sNHz43;JX(qnmcWF4C<%Geo zW=rpWfYzq!9Tsm@@BY4_b8kC9gZ#el zhEu$VcU>O&0=)6A^*sH)D4Zr`d)lt5$uY#$qvsjr%_FVt;h}nELsZ_$8^4WZlqD^Y z_@VSO5ca*s644NLWmUr)?Drz?XCjbOh*LMDZI?`)A&mKPyekJeTj~!?FaEl%TS2dS zJMa-SF!^7pThp=qDUt?~HYV@hjekyY+utpX!^3kVf~GSFLmZgZ?flaF?%m$4)0WKZ zN*CNP6&4V*IXNGMw591B)cY5?i1WuS`!O1Su;qdtg-uB*N)_ne%k93OJ;5MJ59Pa{!kq8Pww4`Cra#L~|>5wI7;Eej)g_cl3r za~tenYdi(obLRPZu%<|zu5&x&*a@aAC2!6%;@qBY()R{vJ0EPbN@a(dd$IT3H4yKY z5GTKS?{fw%!W2?75MZe#Xh=ZLVaC#cx%Ty{gR%mteL)G9nfYl`4M-Tc-!>bYVNuC2 za*&fYgH5a01rse|8rOIunv-qf+XnBoZNVp4YqPj_V*=07NF$0%_i}=kXb8;RIBFo{ z=?UEF4FK+?O=PyWUkr$AX(day zrc`EH$72{(K1&E8%j36SS#Mn{Jf-n)i-Gm%E1 z+Uc6$E9CSFl9tkzNtEjC2W)|XhQRau(@p?#x-rVI*2zBMBccU~bC^6c zwVhOJWoN&K-MRNr2{Sd(p6Q<)4XA+eGV*JZM_;i?j4nz7wJ3`oM{ik6D3H}WQ{z>y ztNt*<#C|K$02;7)hfi<-lg)c?>(-S_$X_qLjcaW<;EOCFmqo&V<|i0;Y$RRwz~0u^ zg1 z1|2v*uR9vBfXL^3E~+%uGNPWo2oY7lLOjn`d2Rc>u(wDkdG5XM`!C@ZVlURbKhFRX zr}pt`O=vyY$XS6$=L7I{F-3uAajH{kVm+!FO2bP?0fbL(#FHKSz~)J%GA$MM>}gc6$3KQm`SgnRSG(U~q^&-sTS z$vNi(IQO6mvItuHw*vQH1H@rTVt@sM`wUsri`C%pptOWSv?zXvT570lc721JD`P>9 zp3cxoHuu`^-E6eq#jlSR*3Op#1q|}w58EG}^QelLE2%QZqZV63BkIXDGc2TOA5D{k)9v^xfKymUv{|NS!H|4P)lU64o=OId2}>Du0b_86wQq6TwniI zLM056XF?9i4S8^WemJsr_coW0yB!(&WZv@60m+=qoPM|r2)y@mOc#g<^#()@_vU8F zq_uVMciB^shTCB|O>j93^r+izQls&7g=P|;5qttLW zM`xruG#Wdp%P8x~uw}SWV2uiPLsKm=x#!H!KR=r#Z@=z=j6gWWVWwqxlg}UiGkmBK zIseQYP35({``!^60Nv1a>CTdva}G7swG01jO=n48(FxZ<)`53-jq?xA^8<1Tzxn-L zuG2*BBTV~i7+L?z`w#)Wp9p1?-aGU zqZ>?pJZMgoF|jhUO(hjwiaDb!MjVs4EOm3&d+)Ub&GRh{{$6s2Bhg551-e~D!AR%l zXr`-(#0di|w+GbjD{W_yzzWlmE`UDaBp@=s#&#mnlu+jVl_=)$M;(i5cM<=+_Rt)E zzS9I5o}%JQtNju&h=vWnXmtLW`>x^2w4={122xQBM1$GS9dka4O3*j6IVpup~6v^MKB;@7>#9_GMcF~&%nF7xc9f_Ru8x1q@-A#vtnVE8N{yZ`|-#4uP zjm5@*`2N1PfzQp~gak6SnK71MRvfK2$f_2NYnxZkh^5qDWP^_#!4wGX-~IKywPwNi zT3}-xh2KUB@rUxOhM1srhj;INMdq{XFZPOpuuPeYYSFtEmdJ%EEHxMphabV6;I!6S5) zQ|?4(=)LY|#vGo}cbt3ozP{5s+M^c#c|Yk6QdYyK?JS>TKk{A8(bQw3_r9U8w^5s( zIStK(Y=<+nu|e@swPUP*?{*acV*TB|N!1vY7O()Xi^nv7&dg8l!kaUvmv4S>ruPpk z8kZc6`SK|C>s4A(T9?{aJ=@KO01mO*eR;HzFGt>OgUz>*6nOJ~G3=YLwOL?|P9X51 z4SxY9yHsDv{T~Rf->#jo!hn@u%)=9c(k_2*2o z8vv!)VinNi4F_1N;C}9TY7FKSQM>_mr03_^o8SAMx?#_QdkO4DI_^#5Z;K{=ILfSGq|gRHDRs- zglFPx7q!%NCrji#g=ZdR7F#Grl^!Fi z%#HI|me>8?bjUYmfmlFty#?34UEMbw!VW0V zvxxj*v}LZz79tqo!UVbmueE^~iSKVSo2d6{f8QJ-qI;aq&&=<>*Vas$Lm~=3SBU#^ zC^Ukcuamxk5UKr|<;C@y(m|X41n;$3tmzZ%mxtlNCJde}jcs4+u%N7&`h->@jm4hK zFHCDlZ=2E^kQ`BWzYKM;%v{*vA=Lt-%g-jH{k=y&0(71<;Ar^smwk3$?Bb(u6Yvaf z4WXnuiCmP=L~u#C0%JJ3w!?FVZA#$yE&03aGB)@)AlKX8xTt^6S zoLumUKP(GGdIMeHC+UKto1r>n0J6`S%naGm-Zm=4E6nr5)@=ce1f#YEQq~eO);Bs` z+%&O@4ZQa`59;A;stsLzWc1ie&9&p`AvSj{)|b~qm`8l?#Syku7^s!jX=B7wl|IBl zm%{q%(dJ<6mr_I#HzDbz;LMMAAyTuurwor9st6{GX3J2Q&ZrFtqZ54Q+^QS9zxso@ zgly7p_I7bg1mfO1KR;CKsY0}r_=Y^KxA7%Z_E&$#bpDb)PE$}{?Nm}p6&*-vUTKPInHW0P4tYpBdw<)d*&80H z?C!zfr+!uj70&3HMc zmCkokzLYhPLAKIL2lF;qlI&cc=S)2!OC~whxn_%Y)o=T=lV{9&5J!y zbUxlSsGEqw9;LE*q*my#Qi1fR>~&Vo06! zc9-qFUj_kR?B5CTWo4^!%o#X%eo)^JoBIYqO7~v8|D`7P>dbWKs@eNygTZ8s`_Us< z_G~cv7;}5iG&%O|_jmpL=V&(}g3U7enR&Cxo*9@kM8*y8qK(l&X7?>DsUHhatim^; ze!!IGfByJk0i;8lBfJY`ba1x_w&5^7XR;q;NWF8Id)@LlZaz%CyFQ!EigZ1ZM$HLZ z(|&Diw0xa|q#?&nAfAKzaJ3C_cPOSBw5&fALPC3#A>VeK}kG@iH^ z0enM)&?E^UUJmiK$snNWI1myf{5fiAh|Ac==bIWi#Fq9d6fcZEIkgh9f0L$~J z?~dS0>!K})vbR91A->#{%}V8U78E_FVDQ1Fz$sc7T>y*pUKr=$^hFqIKIDcI%10wI z-uc7bksJ;eXTE)J66Y<)ZTC$uqjrHEY4UB;g^j{*U6dh@roxt>o7~C=-FM#f7Ee$( zV0?Y68AdqHrd)Q`^4;G7?6vfCtBWAi#wca+HUJfop# z@BUs$=S$Yv@fN|toS$*NcD*VFE#U+}bK0-FUvEQA0YA@#42j8xd419RtYOo{0xF_R zEE3o?A!yF2H>4)???cD;f3@tG`)&N!c5beLkJ>=sre%%-bWUcX+~0bA{pSsZ`@?i2 zgeY=ao#$u7na@a`K4R*tMg%tBq#lwP4Mx&1T=!oE zHJMU)=NU&E-QB;K3(tAZ6uTjEmMbhpQPT_MNa7;v<@`TZy*Y!xw`SZ(oI?(k<9taz zb99a}dvotgz*L#GWJU+(Z*FLzUDk4WIai{f<44h8-){^amqlt-c-`_RXimGMM6|fjD!@+%*jy`FK)QFgRpK=o86G;m@7@b$ZFA0uqcivz;_vST zZl#RV6;eYXd(mc#d`Reo^ccayxlfLfHk^34Tlq)N9H|w9?Q6pVNJgI@U*x7WdSEYk zjnADfxE7?SZ*g5>JtxB6SHNjWO4ka2xA#J)MF0lokeGQm5G9^^l5K|g=XvxslwfZS zeYa>RBN z;~`2%EgRGYwj$X#0&mYzM80k%mWJPwT-}BQP~^A+EK{PKOn`eDiG*>Q2AebUjjbGF z|4Qic9VC4-i8CQgMcb6u)}_puL^yhL7fbqkA~EHq%~CGQq93o%;T(Wsw!wia=_1Mb zy$eno0>Ur;klm8!3w@3-QprriNl!D^DZ*UZyzlS({x?@MdfykhfH+JWS(Dfe73w^o z$YR|M-$qm93?Qs#+9Fk(lFT}IoYiNBrcE1Z)9YT zhGJU;z9~0}d(qByiy{Pl@hyZsO#{z|AH$>PyH5~J83Dlw#eK^wXJ^}^?&`N_TP_&h zy}re&fyANka{|`)`M&G;Ysp1I57b_6%>nbhdwpa0-r?z_MCj*vW{&;-f#RxyouB9b z40+=rapWOc_@e&(z0+7Jk;OBoNA5kxA6aT`(}19pQZfW< z`;RDLv<1{FyL2G{c|eB0jMst>N1Zr}J_G)Je-mCCSj`W;&gN?Z!M(Q#JPrRjKfpAv zik?lQI_(yShTjI0c5Z%yUB5=x!ZmAE-B{YWw|*{v?z`vf29N6||KX8T2QU88#N9O< z&5V#Nm1+@jvV>^U_P$+DH`XO##N8X*P7x^mwlmc{wTUV-O;?Q`JRJc+;$|Cx2Jkty zK%IZuy8#ixihVO~-39?!B`(O9C)O7f0d?Ov?hU^bkw?^Xb{(TOHri0rK!6ax`Koe) zWY=Cyc#bxo``l}++kP{EMm!I{_%`pmjc5ShU|X62KX_w3A4nlq5$j-b;?Ir0u$k;j zu`OWT#a5Lpm-Cx|i&Mr9NDgxR7atX{zID2`BB35z{9RYqn|RKVIOj|3o*94~h!&a1 zEmj*%BOZ0&WIpQ-#p@L3SBgoO9o2~?s-d3HvHjj(FnMpE$0GqxKLIM5g3O}uTlqB> z;_yazYE4ZgA#t7|)km_%_icnwJO_uxk2Zv=FxL^NKW`SF8tSnPn*en_A03W9*2&;S zJ6>x;Tg2?4Kbns(-lY`3y6mF{!o|tG1c_-T+eUijI63DOoD&&d4QZgwC;ZKah^le% z^X~KsL%=FNAHn+`&b@D($UxTkdMfLjKN7Rq-2@qF<^dq$*Bc`3HmKMB$jM!YS6_ib z%WN=`_k$k!zV|L#de>U`&Y;by)au<`29*f6Bh|)x^D!3wdFISNyKwS61q>7=c+=Su z+xvyAI4lQdfr3q;uvI)|%Jkg?W1C>@EDfN(?HS;(7m2jY`JeNDo<~RaHN&GhCmSmF zt_#xv@B4mb(>#q3b`jI{&45%@>PUdK$+R41UjRyHCjgS>d0M>YF4+~BtETb=iPARk zQiO3ccx$i>jtZ09mMbpYyDs;|^%W>;_rl>eIM3$?j}+(k-jr#2&S$2o`PyAE{vA>o z>8Xw7%v83@(8OzHao^32UWyL<1#Y=;6^i2+Xe zSlDewht00)e=R&3P`LZvHi6bzyNlZ%5;iPG&WM;J{Vje@O+$Ov+b|2IgsrF?EzuG- zQVsde(cUUKz!OT}o2AtBWuycp_J7coUD|vQ2lv7(P6OWpYa0{M=PM6+*8Bc@fxNqt zN28f6t~a^C$|=U@nL4?_HM=KnW72@?jzYG<<#RHFWD;EjOTZuZh6rcQd7kTg;|YJ} zIX}}5%gzJ`1fij*SRWn`h6xi>ZoVX zB+dX6k}Uv3n8hW%-%oeC0&=ZpmM1aT~CHxAEf^VH7h%tHkk`xo)3ExAYs z`OP`PC;sgF`Y&Qxq-NheK69vs81+1-l)3ce6f1ci4a?3YZN$dUXpj!^X-B?(w(eXp-Yww;*3IAa#4lW+R%? zVbJN4WKoW>|BdmkH21!}mbdT1f%j!_?bp9?`&7U$?qS2IBuT4l#8KM+dc;PLHpPm~ z=$!d>v}Mpp$Zc6F)JUyHgIRF^v8q{_P7B7)O7e}f{X0fg4!pO?m#=5(Kw#z3D!$s? zyIbPrkKCaV&kWRD3_o4+Z z&^Fgb6Um?8l}|`GT<2aR&VHy=LCt3t*+-JL9%(X%*RRtWgq&x(Ep_hxz5~siqr-`S zY+f5K!lPhauEUC@ws$Em>uT$@qz)Yk=Hgc(frnwJ;Ge7Rb*L5XGfIyj*#UId!^aE`xWAGh@Yp7oP|qSjvWzmrpJD`=Ny)yfgIl8qGax} zZi(gYzJ9wf#pd1nA`T7aR2P4*Sm|%?diU;Kl6V9!G@8RrH@3I-nr^Q89gMLJ;}Br$ z!WfzgxOeAyfN#31i@?mip*iG{>fQMM-nmJ7?Nmx>AThgF^JgkamhzSqb-=SX`Fpoc zyHZl=w>QwPiw7U1>lZ92Z!3en_ul$aJ}$@pg|DDT(Re?Kb(ICQm7I(4UWb2{N-@Te z=R8fm{`T|8**Q*o$)lMbovyQ`jJeqgK&FvED9nnR+50v)K&tCG1lo<91UgV z&mxKcQzV}w~ zUfd~wH#z6~>N;5WI*)A>MkqY`{5$$KGmPtm$wHM@87z0!c0bDn?Dovy4? zkFwuuU*mpQz`(5Irjy<<8~8RqKBd^kxfj8lNn~#mnM+tlqZyr<6&$CL%*gDfWp5xI z4zIV4h}~vOO#vo~Kstx@`v&{w?mALjd6tzk|ja3(2y^uCz-gLvy@tm3JSgP@F z46Nx5qF{$y@BJjpJM%Vs0Gfw0I*l_isLI9`?8@7o+j-_V3zsv3#5s`EH$Di*?|vSf z8h5*Zt(cutl^a05jP{VqNBd_+^Ydt?tHrdTv)Hnxuh0|&$Tl&2k|plF z7VK0falFpH_ueRqm){ng`JAPp@VmRYxs0tT?M2!Bvj}#f7U`6BGzSdX z&w^~EzUTL_*Exi15a#YhW}c(Za!Z=|>#;pYsHtVUTNb1HIY43?o%ptCr`WvAMV zCXo2uJ0?OtJe-5^vJMvF1JU&z@`$H3Ikl)#HqO`Hi-ID6Z*SG?3-oSS*Tbude-*jDjAg!^ND-e47zR0%iOaGyt@)yq!-ThEZxw>knVI}=i2dfHtqs_& z@chi_s>1*Nd#_)(BD-@w4(Oc!wXV(+TcE8A-j`xYS5?Phj=&Ses zzx4)}`ur;;d@YdNIS(Q4>RV^R-!knr?c0|I-o+I5FbC%$;@whS_I@UDv;^4o6wSwN zX%1<`;O<_RH`v)f;`WXIo>i%n6hqT=@&Xff_X z&KV8n!Ek+(o9sDrf48JgczH&Y27YguzEKqjyc?rDcV}ihsSsJ1Myv5cIwo#6o$YB| zWBrIcXQ6O7r&ralyCL)^nFnAGu6oViU3O^LR0R#9`8o5{pcEj^{4a4(x5evZC8ygn zx$D;r?)^;**p&~OW&d8^n}OFiFe@c$5^W1!RxPHhgZ{2H-v+I|sY5M%^stO=BFZ_B zZC~%ZSqM4b5acizw2KOL0oCxI0$*H+VAl+YIcFDMjOrKWb50dFut*<$bFVk|ewozz z_-Gx)-&daY)b3JyS!6i({$+3U{4BsiclI0DBkdtDWSiTbbQ<6a)#wt~TD**&E(l%-`GRwtiZEe^!Jj zH%(7b+M0Wb{oRDm9Q!M#!Z-4Aeg^nv^{_tNeg~S&jHFHWFG{v2>mmqpCSRg%^8s2mkzx4-iz#07XuKG2@R`10U%wcTsNQYzI4`|mj+}XW#wBNpj{Apah)4J?;9RiuV{!(3E zXyjny`38&jL^z7pE?%nmiw{eJW!=W#Ry_Oyz9K2I`(LnGVM zqKQYejTIT`x9K*)ng1VA|B_@&lI&W709e%gKBAgT_G`p7zofcuDhy-;YM#A_@HofK z_Er_)53o>4;2b$P|2!4o0C}Dxo-!U-<1nQ&n-s+AZYjihI1OX-{X&_bAuD7c1v8ge zWnW_%jml{=L;3#h%kUdJ`FG1&2z^WRsH`P(zP|GL`Ny#H660kWvhtt9aQ+mpR$l+! z>-U{#jv&v^(dpJQ-n_TVd?_Mj^BK}OM+)zIcNfZDd+BWoo5hGreo%4(aR%Avd!?WHQo%76LQDY=6-@;Mo z`k&4@6-e~Q`x|=~k^@Y^hoDrBY5U2A*)s66Rz!2c*td}9>z>R5@+~VTt_DFLjP(^{ zQb!2MrDmzz`|Dd8^fLYbTzCpQHs(x&Gr!f`eY4=ndJVd~@&uHLc<~X~!#}lP_SOS4 z)Zvge-1SDncdrsLWWy>?7Ch}%M^Uir%gXbeT~-!58XCu(Lx06G5E~ib?%Sh<4>?5Y z=Qgqyb=n@C&zU`1_zM&ZUMx>7SI*}$0x4g=c5yR!G6}Y0;w*jF0?!OiIhxemE`6?1^F<|f#Tg=VEE^G%06`F=JWk=;AZBQLwgV=19S(8;{2JSYJh0x(f#38%Y4z^apxChXuzDc=8`4(>5w}sT4*H^*}HhzAderTQJBU}?a z5O&{>;z|@O*k%RNl7X4~27vc>r`iq0#+#Kwtwu-z_fB%J<9m~DzXSfhzDHWqS*SuNwgG|SeGpw?~T{1*e~d{95}qndd4zW4X@LNe!&gMxy7{c8%lVdE%@ zeoMgXy#6#udVqu1S6?t3N$gGSg+~mC-czx2o3*?#;OgM^6UUCfXUGol`o^58Sx=yl z!Nw`X79`^R*S;?*%yF57U4x$A_ZO*;lIfA@CC}akRaRt&(E|AZ3yYt8$eXw({gDhN zQKoW!M=?w6sxqz${P+VO98O|Q=J_e7d~en-C_Rq>ctt>uNXMA3@(|_8?m|0*L-nfp zlUQ?R^h`?NN=A>n)JKf0qemePz8#5jocsR!OO4}NR`+kJ9IiP>GmY`9mwlo+p8dUV z0lRz-4?A>wdCe#t*zo=?<4U3zM6^YgS7{y?S97QV6Qp(H!ucp<&zuRaBIu+RS^yn` zwGQ{^F#N#b=q}jrjmJ|8RH)o7ZH(D`mlxl3(F=I(pbNe}Q%(CI36mYSEYuDU`66E;qH5lqNZQulq z^7~?eCBavNnbRA6#VQbyZ-@}=@8YhjV9@CR4N3Mc88i5+`B}l@Ijj5WPCu*lB-wkd zZNf}PKF~j(K_QbVWEJzHZ^YjGBv4Y ze+@s=Q+4!1*R6DLo-@t-`qvy~5Hy|&VR&%Zcr=B~RK9!~I{dr84DI{+w>aJqk~$V9NrH2qM=#r6_o;#6b(3>d7MztnGdwPJ98@ghoYHsOp+wt*dh4& zF}CyjDk!I`z4f=6weOX_R8rgaySD&}v^NRzoa4HUK9EQ#hll%nNs)7O1{>f0uA0dgT>xl~2FW~g z_$>ClzhS7e4EGhRGiNlMTRXtseV2gOa75ZmT&Edmn^aZ@iahN?Iu&@9xcegHCKt&4 zGXXrRZD&*t#kHft+rxy^k$%oOOoyKu>gf6Tha&^;@2xY1AN59W8D9k-L-cmhLK|Lm zp{*9Xp65wHzI>V*K>Q7xS;pcc{p{V}``-0Ucz3=H_}<+&?m)1>_=+-mb6X$fTBLoQ z-TiFe-5QHW#6!!dk1`WeBUY=)2CBkWCs(+hFI-LfXNJo!lT0PCf>Wj^E zD|BvfMX4V|9N$`~3vn5ib@~na&Y6C-K;nx(aZ8~9J@hduSE;%P@c^LrlbL&*rki3Q z|E@|pW}J*Ax_Jk8yH6lULOjjbsVL_1bEbm?KKUx>VgxEtsc@K;lM~W8#jZ0IE6uuO zq96cGT2V)e5WqQ{Eu2r1@<{Gbdt%}9=JAlbx3tenz&toDX$LUNan=wea&*1r|JErm zjC)@qvDyUZ6aTc_u!2iqCdThBaD~U^ew44n1UlmIpc!R2kEAaZcZVJ16~S*U3V=o> z6Mx`y+#s;=dg~B~I!>+UUF4^)=nn_@j5tTYuF;2tx#^_1tPTdppuI9EP`8e+wb6!v z#9qJu{^nIa)yB0Cz<6J8+@-2WB+pUF6#C?)!;ki*M+Y|q*=b7+A-3PU-Y*`a!mi(oj?lx5C*?N;@I~)ec>y;{FGByN!ckRm6=Wiba(h{}) zhJT1-dxHb2*USJ*@~G<_aDZL!-H+wDu7bdD?h3dKY7OQbed?PHBhB#qEtqAo7TnKC z3^=-y=sY`0MnLq6wFDrNoSFlURq2=KajP%~iqt9{Em1;;|^!_ow$io=S zd>d*e+XjlFd+inV0g!qA5o+@x$`149bOzi1MSqkk=iS|cbVhT|^U(2tebYOREsj87 z`(<&Zv0vgOdH3Dis@L~3MA^L0`I$&CJUD{C8`XiW59~LAjPg{ZIX@L;y=%i7@vGrX z`R4k=VW3VZVdfn7)C*?RxnU^yZT27>4yaR+F^T*70?4wgiS6%;niTP949<}2SDIgoTeT;WVb0X_wMb!ew3Jda4~RKm2umj8|qs-0&9 z){d+O5!B@O4ZeFPr<1^XxxlJMZ3NfZy!2Y_&!p0`ZE{f{+9j5q8GKgq&&;j+W0lErdorfiK}7E4oGBCv3JPLavi z!b?h2dY0q6$aYce6^>?*Ca6Lxz=+f!{#?_=N@+RqdhdP>Z1!6&B9-cYF619%j%Fki zx$ZcUAnKxl_({V)D8e_xMLnA@sc(zzc<+0+4xGBS0SY zf5REAdk!>ZDEYS7ftGGe5NlM?G+Z0Klzr6&h_eD}-|h?}VcAO-S3> zoi4T6-WbNAjtDC{Khs^;F4k9dCqnvT!viE=r|a8yLMjH{yJ<>^acw;#=^B~yiBs!u zjb{1@fACrd``Y&VzW?{{`+GN<zt<{6@l9cxAd-WB;#f0rbbv8&T8Lr=!$g8-60PjUnM zm;vt3) z@x{WGMsC>q+O0L?-~;n)riPnyK2883*VqfA*=Ob{?C|cpk}%A`pSKgd{u7jSCNA(( z@wh5qyf^uDQZP02UEkZP@K5MO^7L#`Xzpi$jz=?deBXC->eW1HAQWtswX$6^mm23) z>Mdg6Y_F!k43}FIN0p7u>+`x+)2!7s>4=Ws-1ib$zwfTyv=!s}F!dA|;4uU2K*}1# z&HnuJ%+S|)uLJm8a^sRjL=}7RHH9l1b8vJNdW=7Y{kDS--J{>s|K}tf##wU$5=$%css1LSdkZcVA!oBF&rw$pvWTHSVY@ z0RDwdQgu-wh)3|8y+O3Mw6z4z8t7Kg2`*es2Gcu+@n^qGZWlizmJOP!09y2L4$pS` z3i=b*6>(}&n%jb`Z}!rtg}@z_U9;M-0-Ix06}KGqxocI0fVV`vBn}k z(PMs8OjQc?C6p+$25VBXQxNoPV7}b+XND8*$74yfckec!Yk>ZJGW~6ZW9cIva06kw znXy3?P8=a-jsM9yT6b#)B+=hkLGhjIE;GF zwXh|CP$Hr@?&6RI*;P7-LH)FK=P1JN?ptOt4N!OZXk?pfdygj6?#9mDDvNh-ywU;7 z>U1Ue#@5ASr=NfGj^qk|S6%m7`mglBYI%p-CrD4TUGh|oVrh1S*FyFh$f)K;4@LmfWPceZuYpMr?z zi>`LU`HwzW1dL{WG|&5c^U3K!bW4FCzgb)p^C1{2i53zMGx;m}$(i%_JrWS?n7Ktz zW^KRDUYrsY+N+2>t&4LF4u%~lq9f!o|94%v#bR;)B0>4F53G){W*U{yErh7HX2Yrh zeS7PA^IpI2*2G-+)Gsrf6V+qZ*|vf|x#9pvE`Y z6(={ocQ3@d$Zv|@;u#r;&2T7ZU%piWte2xHdg7^OJ zTgegtjGFSJlFN6mI!oXuBL13G_%r9AqrSVo_$=|HGni_rU}A3-Y}4$5Ij1qK6=m;! zg2>^VlRtyIfHM-$X8Fee$L1@0yh(jI6-U30vHcMo;3LKGUgZ9rAjaPJJ^Vw4kvemz z4{eT1xDzVqbm}WH*C5KM`m{3`Fb|I?My^LdJ@=|!kOxLz|8IC zfJ(Rg0X<6p<%gM?8HzLdy|)v~Fr0y*HuGU#Hezi_o&HtSD77lK76ZM_&s^? z`P9VPdD&Ll&7rb84Ml2+&^;$H)XzCE5)^9o=kDE3dW_I+{Pxdj>RYGO3pDep|2@-; zJQ+tn-y;6k*V+4N7Xt)?AgJ0H;TR0>yUlA6Rs2mTdYBA$~bEAQeI2xhmGSR@n zCo_*CsB;j1DOOiV7fyc=wnkG=6>1C<)x%b?|8UMXbjE&?ucF&>MgiwXEs$(~WUpa| z5(nhFXAWWTGi;zSfE}gZk47`k!|$_U)RPDI-kW{SflAMGQYK^0)M66fF>I85i01=fP(UC7b+vZx-Iq+S;(qLQYfs^VeFm87ODg6lcyqGetxJ zX?Ngc*ZL?K*n16x-u1h#;^(fBJemt64D%4(+WbJ+aIQ zf6k$17sluLtv^SIqT(%&vB9BYJNtZ#K9xMafNdbz)H-^1i7z_+Lp^v&J81@?muqr; zki6an_Onmi+p(Y=U)R)++!oN;b>2MlbWfybnn}&b?}yGx*&>rOhlkj+Hin|^uY0Lr zP6;Ild#N)J4#IdZHo&gmN)9C;s^sS92O4CLejJ}8cu-S`+|}>LNRa>fAn)e7+h@-| zPc1@wU%ziHV_%0@eCtPQHLA|Bo#d{V_kFpV^L)XmH?eZc=X&nlL|IT1VVlNWwMCTR zOInx?w9^y6Glw&CCeP8&943b`f$6{fB?R-MPV{vM2U>H=by9(ZB2n@K(xK&0cqMK ze#+g4+-e8F`TzWb-q6TJp5hW#%(M_jHOK(y&)nYHbe?C<(d2S>V^p>&&6lMM*xDBqk0 zYvm)-O_aW{>K8ejPX)s|$ENbVAvk(KW^+k}@r{HZHGW0Xsj{N)Vdzg341G}fV3ha1 zfm3p;8dr(r8g-mi|A$J;;r=<4^iZ_k=dbWC7))3(bMe@kXf%(|s1^2)Q{TnhQ4+g8 z((irm-WPZGzVE&F0=vP?=_(xFpf37a%4_t+Iz)XWC2%wLeHUs@Suu>YSbjx@B%S#= zKj)n7dYf?UFNd6=Kue88{o9L7*>?tX3hn&Uc6HlY`i&@%-e0o@B$0N5GKjErj8;tD zNd^JrFav>p_wL5`p67w%yCUZNRHsi3o)NxD)1f%$=+uP-nDrgWU*urAApb^f-B9_y z0i14152c57w$}Bls=dN!KA=Ji7z&PWwjz&1if3jDl4q69->ABZ1__vR=4Z;7Or{E; zW+aU!>w$2pude@);^;X>-WQ+F<8L)yontdcTcN@oJdwjW=g}}H0HN#^N$Q-V^AK#j zy#XW&a5pJxASCDKoaf<8g+LsS@-aW08{fU15@-lx&SCRx>-wooVfsj+DUT>zI>-za z4JvkOz-|Yl_uX~g8lfFgd4bd?qfayee6c4sa;w)cl5P#~1;Wg$9uGkGjs<=3yh? z?t6Fdfh=(5(V(5o9~dpyoA?7)e=g~nNwBrvdUiuj)uU}wHg!*^y%fp!{TIZXFXat5 z1amLQcp-QgNk>X$7NQ<@@DPr4&g`0hbMyu>fm6w0pnLC!KO5T(TA;w;Ln|y_1$`lqWSCVOtiUi4@dY%u^owH7{1eKbUWuXi+tGTNIVUjHBq~%V2_alX z)HE5BVGTX&?aFcOH7>9QG;lvo7uMmnfvt4!e%hQunA%}pR0@|v%!$ib%lUccD^1Sx zJSTCKfx#H}{VhzlP96a3Wj7_v(ZlFiXUKC{&9%VwnVD1J(Rg3hgTPPu51VSfN>V-! z3axOrHcvN#t@D;3bPmP1vona|1Q18(9CvcnlD~QuGdTCA1_D-J?vTS+k1o8);;pB* z9*GDfMkfoVg40oi;m`b3VN21OVNi}ge;)rLFK!fQn%YRsA1{6p-HuHLScf>DBAdXAT7m@au3p&2s?Xm)d!YQe0 z4o`u?<&;+Y#<)L?-6a|rKEs8nb~E>0ueJW2X+CkMjaCQKY|O$S;PVV-C>&uPU^VCH z_}wiRggoa617DVd%+E`|xb|m|AZr;9tIX+MJPc-ynKSwVRlO)}ez)P`OEy_sV&!PR zoB@&&FWG(@tyB-%e$qOgT!u2t9S$XhWxmz_x0wI-@X#wXAYjqgAnKU<$e2+e{id0_$Bxd_3Z|* zW*#22Xg6|ZT&vdW+@!W!7|WpyDFWmXwRmswIS}8#gQAH5- zr4#7aet&-vWBwz$L=?f_|NXu9e=qWz+rX7@oZWW~Y)Ku+49MJfH~Y^S&AB(B0blg1 z*GJ3jmTpI!d49gpO+B5FJSKYa=o8PUH>=vUBJ($lHNMMQbtk9cAgqD)Zee&LSlj0Q z#(PKS;nW86oTm?8+g0E6oo5Azv1a4I(nBj!sKnbS$-t;EOy4s^P`O4Y^9#{RtGK)Ny(2inU||0Y!AfVy3n zZqtVTQot-MKWy5QzNHc19@P$}oZU2fX5aVj-b7W`1b#%2-pjHlKPe;w;WmVe7K3nD zKAG!GRGjKp+&mqI0-CEn$n_fvINwS-afr`~Tj6gdjup?QE2V|bF!1iG8NIwu2aBL5 zPK8iQ?DcoqTNFogG>6dP!>%T@?5vdIce5;AtFJ)Atk(bj-rWWg!Tyv`wfOfaq2MI- zKeyPg%x8Tazm9%}(3|yMP~p-nR=xAab!}^5*U0UezAn(!NmVYUqwtflCqcG5#0ikC zcKUBV1vAf?mTunaue*=EwXX?4_}!FDU<a=L>5{eF##wC!A_!i$MIKRh=l-)gN}7@hOw%42mfdH&>GQ zy}4VNM4x%i$lr`?B$h!BAcXv8nZ5UJ++@K7@LOq8zx+rshUvgY2FHy%+UwsYAM^Wv zx5AD_;)LcP2lf6oRi|xM2k*${-i3J1tP0xpyH2&YxbX$?{B(Bxr9UIl^OvJk+5Smq z#PBwp-tfJPU@9=&B9E(j9#vb)&2VNUayZlk#f)hV<KdjBkwN(vm8B;1GZIlr575o&HVKYvZdi=>Z&klFN=|o4D&5tziEjniRZ~^nRTahN z4HMdz9k->>P<_6{oQ^|lZhpIBsdt8?PCd2fG#gZ{GJ42ISc~_I!6}d>{Rgd=8?u`U z_L?bNZnu~F$DiPwFK063-W#tF7fB9nq-oL*y5s3grn2=kMHk@mkApv7JW;7HTa!zF zjE3c9K3!)Q5TCuF(wlWY^RN4Pl`a55sXcYSj0vhlp0kTnc!CY-OVa|iX{ycLUwoUL z?`m#ML^o?Ae=PtDdVeteT|1CSxZd3xAN?sHay!Don!r_>Pr^h@@kZSk&OAKQIUJ&y zYdS-W$T@R#fIX*61?vkp3M#8l*A6log=?xoOPyDn!VtXqvc!O@U}jV=NcA-ed>c87 zH(7Yrr6Xrf}RibsyX$S)l{Slf;IQ$ZQah8V2^Pn`<%2f#r=Nx@a z>8Gy>G&;m=FA@ODMV5K(w=o=EY8$xvIfz-kWWE{_@LqR{M9cvx-`l46JfCtcCCX3r z8w81zgg!IP=fdGs{O@mY0Tp5ihI!L$yId^ZDF!#MPkp_Ci^Xb2k-L^f-q8S0%j=`PaZsAaH z+#Znh-h>t>ivedC;3iQDGDGSf#M&H;CVF?>c@Ps#^sx0Egvz=}Vv16qVqn@X?8d7#tI5y5af$N zM&pj~ONe>jG&dBm_ucioQ*)nlS_w!xHH#3JULQO(HI)4P^FN>hR#udbC(-D)?f~bA z7}+;>D<)CpioLj_U;{L&&-7;K~JP_~)?})YZ`aI7$gQ{R3>2x;Z=~Qf;&Gd%{ z5D^#v%A2(dbLx-)l;(&9I8ay37?th5V^bW z?;YxGmY#f(-ReCEabeW*beeUrjUCT3TN4Ty4W_>c?X>r1 zq}Z=N&gf!3k`%DDrWpAOse%BVP4`v+B^GTOfzMN=Ju6ka)wfrQ0!;Ohg^dz3pSStv z=Z8A(JZ3#&G+CE(VldHq{Z(qIU|Z7Y=z}C^B-o z%c1!cGw0z_N%! zIxue4wz-qA%fp~M#s5~0<_uMDDw4>{{QhpUUxD*8dLHV`ZIcF7TO~;-@p6ui*M~>n z%9ZnoDk^Slcf-7_*$%t^OYG@FAUqQ2``&whzjJbWU6^FFUxU=A(j`4r@4&58n?|zN z=9E@2fjHN`e%;xShLlE_X&=VsV{idy>Srz^7y)33s-o-847_>Q%gCXlF90ua^&wwWM zGv_=_$I56vO~aASCk`i}Bsb8UGXg7n_BLkw9*HTZGB7mCDA)Whv(U}9cVv*KCrKxN zN7=v`i8@K}5hyZ1RcfT}z58p9AkJa1@%^+Tiim$^Buc_J=WTFZF#6UM)f0Yn5j~=_ zUBgyk=z!VzlfGC@8Vca^v4Y@%Mnj@7wGD=hg-^cT>wu%>=McL7WxomL@cE07WB1@> z_yio$eJ3VUPHFW8y)8m~-~PT#iv%h2`M$C29IQisLPz4~HFQ_|1aYe*C8o?nxBqRl zEO4*Azw8@WoyvY3|5CA3YAr$%XdW*&sXjb|R3R24SIqBC$?*@TbjUg%6Pb`EJrJnI zw=fh7lpB1JLff7)UG?|^p6uUHw3Amz?mTcnbO|B zU?gJ7#X73$L?V9XuPSSk-=Y-(f6fs@LpesLB6R!RHn^N61^I)4m6AUhzbi}kgc>%4nE!j<2a zou!_WO3vk#2^nLMow;U;ergm$||2{_A3ZE9NOA~CbIklW?-r8z}}l{ zi86J<`5AQpG`j z_qM+MR3F5Rv(QZD8T|xbI~nJw0{w_u-w*Uwp9plzQqXDDD(TGy_HVcpHnoad*(YsL z=Me6`@ek6m4h5-MiBIUeAJ0+oO!ZYXs&hXxL1$_bH9b(3z&i;+@qtE7!|cwW?d_Cn zySeLZFFEI4hmp~SwHkm=@0QaYd2VVVzIXRtA|fA6M}ftzKSz?v^}qG~1r;OT5b}Q0 z{KnlEC~h>EGYPQvIrX?iHXR-)Y>@bN{*6D5?GHImZ3`g-NFzN3P+;K(ybZg%R3}eh z`N955*Nk+ibEeM0>rzi(BiCKg#dpp*Xa4!;h+JoXZ}(Pv8(vobL4i?#Q}3Ibn*(59#O2+F4i*j~-**#KUu&^qFd&ZB=wkTYkD>vZQnA^&;)2|-QvB3sL*fix8^%SdyeUbu^3 zPN9o&^S|j@6~8C59uWW% fIAV06F@i(bUgRN?O$_Cb!Ct>Q!#Rq-D3POsd~b2Pz^ZI2EM7LqMi`v%ndy*4%+DuI z-!dJ))`ee-So!~O46iK>M*)62C^4T0gE9874L!Z?<&}tkpWS5yoM(cgPRp2r&Gt6} z&NR%|#TQ8x1PA$}wf%u2_U3*LS^KNYA;ZtlkGBS7kB&why`h>Q!)I%@D+d6$ zdppVDekmvR7cnFg!cbvI4a6hW&L8Lu%`VI(PPgqJ6f)~drcEreV{4?4quZc4_cF!a zwOUZpaTu-_2oH-knyQBlTef7{(B4HLE4>c zH@3D9b{-1#hgoV#-O=kKiKj46z!obhkeM;fY%Qc^aEPWQlf;*{pxzAJ-Hv|>@0qVQ z-t{_aTzvyW7;m`S`ID-vEXTm+H{s&-#bMM2v2Q{y$TLHb!_jP(DI_TK9DKRogS$ZfCc2F|C6eY=`fifL=BsP%Vd@zP{Hfc? z!8dej)KPi56$-L~hhX>iXTZ?VjJ_j~ZPXHP(fo(NzMqTd!(kzNiG|?1b4KTUzVHen z10Dd0#y9V;@9*UYm!A&8>PDkj8y}i6m)+Wd&WL*NJJQ2vMgVj`i@$sA8ll2>uaPt~ zfH1UK@A|%39DWYNTaVvpP22b0%E;mxsRX2{vKemk!ZhcQ3MZ%(YIDVda74PdkWMC%;!9+M;>tl7|!GSCT5_6HofzR zL+Cp->&@Y#XIQCT={)>q%s|_>ZEglJIipzqaG}`Ey9T!pM~Bw`zSp^tFPvu8C!1|# z9>AhmB^*t6W$o^0-t|VW6T&ow^>toIjq>>tcs89)gBWHMooACF?=_{nxlO7}r5u6A z8~Qt!rvZPzuZ?7(;JstqHIZsTEUul;o(~QNvv1oA&J5PR+W@r+Iz-hzjX7wKysJv1 z)O;=?+0D%^JkwabvzAj6;b947pFOwJhKPzSXSWCl8ENpPs9nEVk!2)$xA-oK=ckD& zxWznrrN-ZZGcuUJWFH}?7W#4?hhdAT+&vtOFc2$ErgY{!e^Qh9z6>Vc=J`nT40*^y zlfrYpsaxuEUx3li!Ne6AGwe!2D)amka#Y1n@tnL)ayV6!A=7Y`QDz33AlTY}fM!(Z zZ%1P-!zzP|dnHQXb{vT+!Y84M=pwbg_WG?nslI)1l60tgJH)OPaKtln8YH1%z$zS; zZv4~y!3ia_3FAjANX2AH*br2Q7G_cdE+SZ%&;#7k^Y9SzxLhePj99iz(Dk^tHyyT&C_$hMm;gW?W9uA z1Cr}$j#}5wa|UHId{bs;W`;^Nbnovg9P$gc^4^GO;uI^nGLR8a$WOwBRL+5W?2uV* z3{2u2PRQN&8P)G`UA+VkKNf~1GscjbBc4>0Hj1u|hp9jp$oS*X* z#?zns@N)n`a4VkE`5IE#({_ve)7Jc3a*RHWe|&vckp13WD*VO=h~1!@Oe1^?{l#>J z-y^1OJLtyVcjHfW!~SxZj`pv0hBL)jibq}M^=%B7Tg;W3dy(v2Y~|}|Mswn&rCh)F z^I~E~$NCQ9F9wbzT{$Rv7xE&f%0S^cKNLqNZ?!a^;?$tu{bYB7(D1*Mg%@hq_YW)@ z37Y)fgA9?~IL>Xys?$|kf8FXmqyz>!AEE8{zK23|-#6jKa#TtKyPQ?gH^*`QMQ+8J zAEm2Z?6;##=X|CctlD~CKj(zW`aEUyRSf3MMju!=-f{!Z!5lIn>#X1R)=ek4Y2rER zdT|0>=SzSF*hs@<9nPFN=bRTnGIQp9TBEzUZzxMi1(&rE_tUXo2mDO_`>v`>2A~uc z++Lni2igQrL-+0lQO8XnN%zIO3tr!9rf!^%;)>6)bmIiR>ukbguiuu>NMmC1)*>5A zhth)g-gRSR1CH@=ihyBoba3?Vk=L-xqRc^CR8F`Jn6M zUq(o^!(PNUxNp?mU>Dh57&G5cpmB8zzj@JFSaHp1B4gm)M(QS16-e1sja6SX+E1wn4C zFNEYgK=E-q&tP=-g{`R~8UNm2Ue%{@_>q5oEr^=U79w7m4=Ciq-VM3+@^>0t6;NP- zd|2XIT_qLDfF^U!NpAPFi)C3M*93IL=b*bO@8621wzr&fx_KQAe0!Hi5a&yB%6Ev) znR9+p;kcr22^4$JA7TcbL)sriA;3@!$$fuwh|+65BpLUjWV&+>?JAWG3kzfKTL6z9 zN%M0GXgr#!6d8YMuFxmMD;wkW0{*tiQ+$3NojH%nA9dhM_tK3<8`GYd)|2Nve_I*H zfAnF-@Ihc}rdK$F`$a_J-XN=Jq#51K@B0GNZPd2L@#pC*TdPITaicac4+uQdQ!Ew5 z^x)uBkJaRuW_W*-#2SLZa8$AqN65L?c{dy1Tf61E>)jyOh|{I*$6g`UMgCvHY|sqN zHo8gcka>Q7PLIucC2Q0||JD(ik}?G7d7dLBzP#u2lMi+NlS~24M>Nd5@fXpyE7j)9$8~_OTnL0F+;xmknybr%noUa3NLaz7S%jg_RIFOEN zWIzPtw<7Qm$-Z|eoMVN+X~-%JWjJ;y&Cer#Ia1XNv>gVp24C01JU#84tfwS&gu?u- z)&c4a&fLA%;KIWIr{kdV=(3CsMss)f-+NghGjK)+D&CR@=dioDzy!Tf#@`_TN5D#UA4$`yxn^x!15~|gTxzczch{G`+9#n?2Vm9%ys{U2b@y_5U~FBT~l~w zyzl*e;hs*9P-W>l+fn5i9i7rLLh#Jb^JM^4!yIF;^Ky4#|EQSLY zfU4ri?tGYbiBB(kSf6aYAuj76&}v{~k?wIM>jU+UGUdVUCdeGKAoFhaHpIvZcOoD^ zKMz?mU?qNpJkNuCKMK|$mTq&O+e|q$28{dpvr`S?nLnx`%Rb;R*fpF>ohIEx`s{Aq z((hjX-jb1qTV#o5n=HtfyNgREU^Y|L^E`U|`S^5W2YWXQEM{sZ!+Y0W5Q7X4MDMMW zhXg(ZM=Cw~&qeAc&+LWb8&Jym^r85W*T$E6L7)P=afVNMXG}UBLV}RP1+aB$6pOG) z;3cZveye7#R_P0~PR%RA(?%HEoF(zhb4Znb)aaq04mm>1?!G;myx!mc|Jp}Gdi_2i z$eSd8CVHqsZhlrhAW^-PBo3^xKRT}s(^CQ|Jd~0XE5^smjJ>~K2m?6KAx7pm-+P`P zod;Vyem!>{bohaJ&;smZ70%3QAjWpjT*)rQ%&@oS*O;v?J28SVg61YkkR$vxQpJjI=TG$je-5KTfA0Od?@h1xr#w3jQ0g=BrZ*J#hqcim6x>Hg5M$k^LXtRDpUu+JR0bfRyCsfBoWj| zT>2Akr)Xt(N zpPeIh@Z?29-f~9tzl??pb<1hruy1;vsx(BX{-8 zsMk$pzt!)rZ(=drFQUWuedRoJ&S{2q&XJ^>TjlRlRm6WIx{8Uzk-oo+yw{)ukA2_O znQE89trA>A@>DfZFKd4TeONIf^6TH<*LK9+>)qs*`|xS#?4SQRPZbKAy}!!P%<4x! z0Q>9V;?d7P=b7Rkjf(gje~!Z7M~s6CE@~_$k`;#Avylj075EJ>QRisesW%FOSqzlD zes8{_$@;syl@*lyB7NFwaLU2?xNp+Fdtv@x|G)n)AjrVrYfOk6J^WLA{Uu$>jd;47 z6U}oj?ucvOdj~&gW<&O9+!RdfhLTMVwKlwS>Qr=fu$`DYEoh|C-OGA^sKiw_baHEK z-b$dQfxSAX%QV#nSG666Cx~(vf`<1`vK&C)bKu|rn}nlH9!@>HK_v$4^USy~>oyrYy*o=8 z(O{yxJDkox`uZGB{7NQMFtr zc}wc^-aJ*PA!f4k%r_fS$|uv&zMg@eoQF;v(wyP#y9VGpbr4{_ zxG2^Bwco;^(8DSmyJ;t}@L-ZW(j}c8J=N-K@KMEuWGbL%dur3Eydr9{48H~lzt>NM zS=XeE8RC8%p$#M+JiG6%OGRIRwuJqpnf#{kGiMeHBJLW;bv0cWJ{UI#BY`(1!|wY#XC&Rtc?QOfLCZAoGh=4&&T|Cb zx6%=4DCvFg!?^@Dpv^oVvm-iVFix|Ws83+^zBllr`F=`HA=aH(RvXc-6`$3Yh#{TP zd-q73vsnR^&1cOo4sh}*;IUr9)Ho22bL*=srp~e8Hl{Sgh=aPAgMZF!$0`!B$plcF ze{8%Jk{WHW6Q1wb-1p!A`_;$g#yL&a;(D7xS|F^{1i3G@=6dy|@S2G`*e#I^$yy1d zhKM^rw(h};#TWHgf_dFA`FYN6_mL9>_{%!1*@KCpLthK@LPW;ukTo<{9A6W)YH8*R zF(B%|2$0ZNLz6(dj7{D(O-(fn!o@sDz*#Qi}B2K-Ds@Pm&AXM7;kAyAEb2O2}El6f@A>P~0 zhM~QB1lKT_Zkj38hu;_O!a~k@x}@;6H2DvRBgHP|=bQ)R-dCr-=_*bnB+|93rpR9E zB=>F|xJ|M$p_@H|!*hgAeQ=~ddv#}{Gu0&87d4uA?!M$wPl4~RYrHNJK%owc3Maie zQ>sho%1wKxbEETkU9l286Jy|OblfiZO=<{O+SMvwP>%>E?MV^&HT&u4}bg z&G9$Ika2M@=Yg8VxkFs|=($^67DRQ07sN!9)=lj1b}Md(v%|BlwlJ5O;eqb{5)*#1 z_yO*X<_V4aVxB2E&z_k?$d+b89fIaENR9Ury!;ai?^1&X$S{Q9%`iG=Z)Tq0w<%qp zn?rPyyYRhg0|&CxBcfcn>j0}6F4s4jA(MRaW^u38s)_`-K>fgA&J0o?uGq~`a!>B#>?uwC4oV&mCGg#d9XsD39Yfqj$ zb!WmWo^(VCqzi3M`)OFa=Ir29M%?0{PDRfS|7lAkR`Ga1grAw{Q3zhMcD5PW-d%|vOR7*Eahff(*4o~c8;ZAOjP#S?V0%rWb1wY?xt9pw+r~3GVegj}hZ?DYEWv zob3I|GoFt^7>|CcEHHyrTEFj&hB1ar1ts6eapI1U<}%O7>+Ov3Of~%aXrVk)v*ON7 z8j+AvLp{_L@R~F6w>RsS`|M05_e9OsX`*>*}QvZ6#8yw; z>L|IfG+gXNeSoV{;C$u{d*^4mC6}h9P(_&}v*0jJw6h}T^6dsXyL@JEN+=An!9ZPX zDBm<6y>50@4#v0p|Cn_63&uHT0NwWmqVqInEc``+ZtlQkz)sdho?a6nqdwp3Wox1`T~?O>iE+KQF+Ba+-w zfe-+zU*0a>ay^e6ytxC_f{A6~Gir|E2jj?Puv_kO9mY)*5?-(0%nW$f=RC<0K&G6) zAbV55Yk+ru&pe&dh$p{SfX*55wB%B^??*%!cl)0ErXmg4o5Lv_%e(KtyPJojgLAn1 z;`8+4f;p=HP9HX7>z0TwhwrYdBZX%k%>lKsF!MY!GRnzqx4oe2{(?A19oc$!eFxgO zQ8xJ-wo!<9jrZ=C6&X*Z_(3@4rr--SmpqFV%<0sP{1H#m7B9q1o^`VC&F0K}9!}oZ z3`!g8TK><>{x+oax$7*vTO2C&^jdz}h*mECEzo7JwFCHd7F5;+=88?09L@}3#MRf5 z04}CqT-TzmD=q6&yFNEH=YJ_?tcDt*DR>%Bz*^s%c4Sy^Xx#hzTgBz;w-PKf>r4d| z?^cG)qvx4mZm0M(!%{*SB(blQ#w8kZpK=TWECJ?AO)0~76SF7C2*`7UYK-l+2j`17 zB7z;RjWk|n*In4@`5}l6m{T(1`dhM2z}utT*+3D`oW`0m2{DzWGBRqM`Cjq!JkRrl z@cp845_nO0eBwEk-V>SvoI1Iwe!+L&-}P>D7mDud{WKW5q3_2dWva{)&Uq#Xu?CJy zg^XBT;iL+Q23UnW4Klj~H+%29{w0y7z?C+JZFHA->N@rZaT~h*I?znFU9TSv!XQT! zMu$fHYjmUd*ErPx(s3yh*#$rd@@q5oMSon0&KS8Coe}k%gQWN6gK^b&&Mrai^}Z`ITnbxDFnPbtIYFpJa4(9xADwC!NX41I z|1KD%dr=oEMd%DRi{@Wcm--C>KY~g}A~U^j!OYINT#McetRHkp6OJt^Gm2d6KTKn$+w`G>abxq=N^0C z{LzNd8F0L}8lK#Dv4QxA1UJ4mc1O~A@Qq3)s) zGz=9Z((fWzV17nJ&1oa$D(v@Cs0*9)?{DQ5zV{8c1dMNVCUI(RnjpB0z&xA-KoWNE z|Nbk0wN9LRe-x6LbIyJ#diV3k^pn+BQ+@E?GKbnm?@Dv;z3|NX3ZS&25(#&&! z@(+{sH$j|_(7zG#V%Ne5EXO+EeIMwI&hs z7Oa?c;R$vmbk!OB-nRlqO_$78m8%~zcwi#7FDR;#6Fz+AJkz;yf>`{>$(O~{QP65iMhD|S0-t%z2&XuV4_XGjYk}esfFbyuyZBx?+Jzy) z=;76dV>xK=`WlIurs?cD(cT+pDP)ZzD>iS#Hn|kJwd5$Zz4@bNKLp_yjQV#)p`5>SF&ER=p>Vq;amKQ+6~@ zBYw1dhDSp^TeXg)o-!RqqZ~W7Fs_!M*%?5nqG0~BzKfx+_jhfl-drjl?8e@`h7%6W z&lNWViWaONcU1I6my}zj+yxB|+l+RQL>wNHU$`F-H_8Qsx)t8bB{_O?F%X7_#Kq_t zokmI^lt1CFGt@%hV04}bv4@J3>Beibw`_xOHzMm{Kj--w1-LgK?14lv#qpuOnj`uw ze0?XR!yrNr3KUgGe_o0Tu+*KFrr#x87dmHA;>BA7Vvu_;cl8C?!U+1lK{J{eLc6!B z90y$N?o9u_7OVWUbsuPRS>V6pmLfB#lvh&sO4-rz^o)*$YGfIT%;I|SZr5nY@|iQ=45Wr-IiLHdKq@fTHiU6$YrFBT z_j{XiN`M$Rs2!a+BxZ0*i~8l=+yGJvf}Ej*iE1i)InX&6eaI`J@K8nXzt^#d`I2>! zzQ7e|sypT{bNAuZO zGv%YX0zTfB0hCt>7`XCCS4tqWHeFo#@5IfIK$!KIiu$! zbGgh2z;7c+h26cs5Yabqgaji^A2JXrA`#B|m58V5NCdSuZ?d)_AO562Kl<2 z#oZp$;B>O|Kj*>BKj$acYcDdSJ4p&*mNxR|Jw!1ywQlX@-Bf+V7BXma*neZS`n`-% zZ+C*t#J3PiZ)dUQjHD58&TlT`24(3ePy;gcg>|_N0O0jC7@ZG-XJTfabLM%Q^#P*h^E>~A=fjyk^&m>j{X4(NG&67LNbf&QRk;3oHX?d34a zdDM9`NPY<8f%y80k`BoFxA@HypNIoNZOg~XCzn0P%5KEop%Qtqp1a)T7cbU5RzaA9J5n<&1t9x zFcyd@Cbl5`Zy&gRMqZ${aB#ElTWPvNe4w;CyV*E#r=XBs)`)Xvnx^?#XRt{fAvi&zsr@bTZD$ck6&KlxB3=-U5*M5;I z1VAr3!7GfmjG-ut@|!>B@$>vMKmX7IQbAKpMuGOT#=xES1^yf}612&D#`B(L`I^O` z9sK!Y0SYZjDVN2mrxOaX$pU+KM#C@*VaRMeW0wEFs6xIM%M zi}&Ff%Dkl-AE7T8!u8U(&>17n9Rl>617)UGE8ewtt6!MsP}qCFM(-Rn$xKVJr8H3~ zY2ZDNo>4Z+1aq@Q2B$G}^=y(PF*;QJr28izt&*{1ICXmDMNj#LGTRPw<`4~7DZE)pu(Y?vN;Vh}#r<9|-a1DS=$ zo|pJ<}9`r_X0RR9=L_t)PG}1s7Y!Xry*~D3}8|m?v{Wf#*wWgP> z=S9QNt&9SGfI{S?6f2Ti(6(QdJ}m z=%($BZ?1RC0CY&n0F2>?Ytt7wBY$S3AuFotVx|;j&UE}fN7MYdz@NFST2y?J- z#1Vd;pAoi0JCPZZ!1k6bNzv<$FX%Y)S-smMq!UPTARgm>#A|;ggL6lXQyZ23k{aq`R!AV!&K%)kyL+agKz_IIaur4piE8!!L_0J~1`wnNiyU0U=IxXIq%f8X5}nhkyAIY%?89su^Tn(W%} z^4Ik#x_?ZJ*?a$<@HxsHR3FXCfB8M0Vbx|mHBD`g1%R-cCS6%KY>lDQB(HS0cvxGi*0sj!i zWI*Mn@!Q|PpbTALch7kQynC~VklVgKAUIrKJjWaY27DvJyL>c9U_L1^an2cOo`bTP zp>^(Vg>EhN%cA*&bw;Qr`vBQrcb3c$jW|ZudDjn*%A=A1DueiUuM4)?s+Qg?lTw3v z?^b3gA?t4yCxgG)H6?IVEwL@o-tLP&A-%gDaVb=#e5`lQIp={8R;?-KLWcwdPR%`M znu7o~ni_8*ICGqj@it=&3UC=L6sQ5TDxmZ3mMh;nqd4!4ld+rXyq#A62~(!qC==dr z#&CUF-5UCCk9-t*&4>&6zNTK+i~rWew_pcyy%2 zW;>k(ZSdaK1SWJiJm5(4$X0c5mcITE?O1Bz0P=HWpt*gO)HDF3Bv1v)30L+beQh-TLc^PKvr4dZ>^u!Ai-`*Z`Q@3ZrE1-qX#1FkEz z?F|6(wypQAb6{GB>P*dEXd4YmlY!wM$J)fAP$iRrpCDLAOMvp_w9C;Yn>?*F>y-i_|Cf^D7GEN=!RX1otDdDGis!(Qq z?=>6YT~|VEPMVikbtW48G5>TylsH>Aofsr^fk1ct$Ar4cAhHsWQTTyDud{ne{G1s~ zGK%&uI*~lPD}sfr_H@xlK^XnG;u>UncLHag%GpGc<0Nask``#u*4D+zJV)o$&~f|v zNm6B`-@1GG$9;ni$u(Yg2`s{X*MZ-AUvLLUQ@?{F6=_p(=_+1UPe^<-(goc|A`PiH z?d_@2c@pq0l72azIvt%slfTeyPXT$U6OR$kepBl789(}`gX;B8)KjCm(Vd<`q@8T_ z^UZ!jsE1HpMGYbMTWX*LMkX$j3Mk=0UXQ}5bBF7bJi=y;yTfoAGBE|xw? zGMnG#IY5KJzWk15RYoOg0%5LycMJ8Ngtq~dmy9PR;!!g?x~0zoE9c$HN}2C7pAv#T zW_5%`2&1vefY}>9QD2-|ID{F9G7-)-!c^CBlrs-`m~QKDu@`g3@Ee<{bd}!q%T$^% z0eu6tcHFc;)E_1UY4}!sOpE#maHd-hBu@6?#vjl7tMKdi_8ggv7pxgw3^V*mrnR96;Ib2hH(DY3dKWvJ*p zC8)1cXb)z(D4PxN!nbj4DT)q|K%EdJaDA%F z!`y(tPB3eSau((@=lneNN3HQks0FylaMKI+c%;2)v zbZ?4CV%nniU@CzX%J5sZ1shNU!`^#$cU$6O>E#S|7qVw!Wr;-}Fm zId8Z??SF>5P9{Q|Vh$gTtP!MqKq5pWu({f*YQUDl4*on;^L;qZ2D#R%QN0ks@4Q0s z={Q29d_#ua%j71c?(a1@GjpCnD9-4EX1WJfb9ni1&d)(10Dw1>!6t#ufq^za=E{die~WBhEQ|&bRL_pHISK9sf+D5x>uRj-nNa zE8lCc^I{jnYwosWHjqGu|NZ?p@p(?b>f@D(R08IyC7zh`LngkZbdnm*=@td!G6XeG z=hyQv)4QkZ1y_iH5vba!&gdiTi8ME#cF_s$ZL};;hch$Hji?kSKo>Iuw7hn%8zo$G z<6UR(FTDSZ;6)aWBGe@JM^cWxHBh0`=BcW99fvPt#(R;iFKq7xygh5H3EaEB+=!EH ze1<9+x3gK}i;5$d4Un5Ry9oVz&(EAxYaIfOSFJuNe+wOKkUtVFEeTVh6UZvx0x<=A zs|MPP=-p4^%167}rREi2E_c}I!#cGOCbFxi<5+>|XAlUI1A&C;n=ew3R|KbxU zy4nO}|EMKY_mibT=c{b_No_ZG8GQQZZ$Io&Bd@Ev6B_HRZ?>!Rsd>M(Yg%QmFa+-| z2lwA!3o{aOetrNY@6U72^OMEeYxa2(*6${_RGK2qK6|eCjS(xqL1mDLKcNYw&FoMT4ao`V?pPo>sX#kaQYo*$=kh=kx;+4`hVq5reD7rBExRSZc@ zzKJ;{4#aNwhbA)rn7IL{$=bWvPvp?a@^U}#N6)8Iy$CSCm(Nb~`=;XeCaB%4TQJD# zP0_4tZpY1aP*!J-t|CX%aYon*i|Ag?Epq=5pPMYMBr0=eKkCc3FEq(um?mCLO)J%t zs1168{PUd3B4EAM3p^ChX7vSE73HwY5SS6XyTJ0Bz?WZV^vZe82~1^J@WVE&7b6y( z3x9Avy!ZFL_X^(YIggQjcS$w>J$hykS2Z)wdFGTLX@}}Bhfq92m*H zx1Gw7rb1*1cn&dicTh7>f5EOPq(NKaGFQJzu*RFcD8JT8aaYcD* zaW_Hki|3sGc_!<4Da5M(51E*s5ld?DWEBlP)8~N0K<^v$ITQu0^r_z7*j_9p_vRk$ z-qT(W45OKO9*KDiA#i--+u3ivL7Uu|v{UUzl{cRpH(wubUtpKuJSdXBG|1HTDWG}5 zUV+byakc*MS-Q3;+}~7j4G}s&KlAfo>sCF}{Q-y4^v4Up+!$O}cGy(|yAK$h2a^wV zjN2=oXXzeNA`NeVMb=g2Z)*hh1gj1A?$R+0zGWFYl})J5?(ZeHZ?O(Bak~LKTmv#S z4_i&b5xqn1UTl@djg>gYcGz7(GN73gi0L3k3^$8u#I@2KpGJv9aL#kk^u_sP!Sx0o zp;1xL2_HaTWN-kuEQ~aUr5UYk9s>3^NHjkj#B>^MeMx?zPRIG(`))XG1-esd1c|Ty zj@y2qLJkQ;67=|QU0Z{ahRvID$nPC&7~Z6m+UYiPiYn)|w~DSx_Q6aa2TAqSruUv( zi2rWTKaJpN&?|RHBKN+ryuO>gtv`1IWO*^CSn1l#0Kv+wUj`c|8!$8I&#MpILEnoa z>yj|9Z(EdyERw-AGOr_zXY?FN4Nea3%($UB__`X3#%bShhDQapd@Cj2Z!5!Zpio#q z&ODB}NOm~QXe}TLNyFZejK5J|$7Or(=6)4xEO7ntg6pdL(U~(pI%=F7+vFB?H|Nn% z=aXhKL8?_vHRE3l(DbHu`0XF?ZJeD$$*c7g7=^DU|AB~GHV>q~eRet|0%~N#=;)9Y ziwCL`idI%+rMOke=WgW#JUWUX`&K-79pZ1hB0#!#^PL|?`0L#ZObqOPWcYku?e>xQ z`ZvgSZryDPzFPg>-<0%W#|4*gjz*om=kCHw6&J8ik16=rey4E7`T$en3x77VEot3CgsH>>D1jNi*DQ@AdWidL2m5IipV%^*#4&f*ApO z`A6y9qL{2KnM+bk9jV>%aWwPj(ED=ENas8i{|Vrr3RwI!htWs++--_&O833k&@knD zbGx2ov60X&{QofZcRRKu$*wL&(mb+y>tzJ#R)C<_6>y$T7e}iz+(=z8vbKPQUWM+7 znweunxZ4l;(Lh#?sm%G2%evqs52tqvF#B!npXceOo{d0nW`OTqZ!afFU=?2Z25`ds z!!Tck=w0i-clRxdX0xHT=Ftti_KTWnBjo#_zqmuc^ng&8HL3hgAsS8-LmpSJC&$UiZsZBu%j=G*O#* zMG#SZhXVEU96eLLCe24j9cXv*5db0|0uLVmPIYnj-KD>5q#o7`yu9g|vILW27um$| zd+WE;=nRML{60=ib4MTFb}kAgmA*1W9(}`_sg@~qH3=lenfX+U3q^st<-CZdRnld5 z5u|YXcT9$K8vdjla-&7WY(n?s-p`RTCmJB{+t6|bGKPSuMe3VI)73F&=w))lXpp>> zY}Zh9ckg|_v)8%rj#SUpQw#7M1l$TXOj0|}-lk%;C&um6S`y zEDEJD{k!k)y}$2eGI|y@#wxWgC5Ok(?&l(jBXE5?gQ+p@^Ct_MLrhRRo^LZ0vLu-^ z!Qn@CX;n@fd%v-v)E|#-zCy(ER&gDL@LaIwBB8g zfXv6zkp0Dk-y|RWIlF%E@2A6@M;J)LtaSIS_U<|39=W>%appWkv{=n)-Q??5lELn~ zn~SYli0+ttyWqpx_cgi=5hnl2;{EO~Bj8xjOh`TB>wW9D?5B}-Pc_5(Tiyl1&rDTM z)wi+07HD7Z*2({VbeQk4)Oi%J9f_n)E+}qWyfYpWTS+G3U^>aMu#4;0rR~hnlu=|r zRq0c31KfKE;jQ`1t$h-u(B!SI?Z8s z)}7HY8;=swe~gU>F*E<+_g}iCxARQxt=`ZMG9s4iJ>*m2 z?+7<=p}Y3GN8i|<`nyQtQQmlWi+%R)M;0P0An2~!$$<5TbOPU@T3j<)CAXngl^M0W;kA#bSZ!3N%MJ`k@ z>VeAnlp2FSOiyc@>2jlFuvh;Gf^|XClMlAK!_<}!$>}L=D7L-s~m8=kfFek!k zY9@?*uh$ztujbR}+z~W1r6)-|PN@Dm+qPCL@gZ_8<|gzm`v|6?eMsE5CW~ zTQVM!0vVb!!1@8Efw$eRS*HfAbn^IS`(t~>Dn zn9pY{2DMQcV1Dm%AwK4(Etn>6aljhM6%fky5d`f|H#L@r1MiJm=1$5WkA<&Go=t%9W&!aPs=7-Gfhs#;V*{O2BPlAM{-`vV~ zj3nornLINP_Igbg>gDU;IV_8%Qk&YQP(u_IwTpZr%nwgcXgrwT-~akX0)CEyb0o%h zx%9=Hr(sY6D4f%@tgSAFtqKA`N27^7z1r&;s@n1lb)GIni|^4K`usd2aPeU@d059L z8$%{b7>uaOc_`c-Kh2L~=2397|EO!lQj=y*KGbxMm3ZpNMpfvSw%)wKW zTA0PXKFXWv{5%OT zr#LaP(X*z)L(LiS;goMuDg$-G@8f;%rnY#gEv{GVj7~MuYxv$@Ux^1w+zr2Njn16d zB0CZOdH$JmaC$+tAT=5n4bv)?1|V_&2E|!0_PzVJUfm>3D{hHXr{2Ezy>GG6eIWmN zPKedND})93{5<6Gem?p8IcYZd)6whn39i~p)ZQvvZ%~^JMa=nPB>4=%w=yQ)IjT5M zqjL`1b)YL`Z<9XXD`@S+=}R;1fG`03*_anEycuYOYjN7;cb|CozSr-)1B%se;=b>NG0X*$ z9Q~W+aZPfH_sjle7vof3#^BmtOH+PwLRdAwkmuC;7t|e)ztRMCJf;MQyI)tYGY}t^ z;n<6lPKO_1Ob>l_LQ9BKrC%3);@J|uK9f}x!0<-jNCHrYq=~Qe4C!Fb|DIdig4F>@#`roH znPeEZ48QkQ?KPi3df*;O0#N7|-d#*rdwXUW0?6j|0%>=n%atFqot4%InzPIMYmT@7Zd;~IrxM~e!{=6Ic5{$ULQX(~haPtD&1DI-5m zH6q*wD3A#Gz>#X%1#zA?84>=XdRny+VhwSc+D|&))Mp$F!-9+MEjrU0K4%&j$xwJS zVkT6Fe`|WLxua$VWAA^RO%pO&zAQqIbj}awlP%Py$5#1H0$^?yggErY*q@M+ubGs2 zT8N3!ft@dGg0Kc+AYh6DI!C1K|NK02=H?4+n%d@f`8T!}KuAYRrz%3X;3RI1>%V?q z&73p%(J6+N*@kAB#Oy6|fu(;pWui!$x~lBuscvYq*PGYZfM4VC!)J~^mz7Ck4qGwD zYAnQzIPfmBL8gdPcUBsvvn>Er=0Kh3=3Vc?pKPf*&})Nh#+$w7^z0gM5g?@)`OQ zl7gHN^%#!MDbu7=8;O{N3yWmBk|%ipY6i*mesWazo&pdhl592|>Zx#Y6Iz3NKbFMT zb!WZi-r9LZ{mTUf*|~fanEvm6JM=&p0P1)BMbAPLafq$*@@F2Bm~Y(_Yy-c`A^C*! z;Fzr3YB(Asfrp`<=jV_gOfpcAi|V01I&_^-?u4n+bmiu(23tyQ}t`ccl}#F!S-kPG}5X+Yjah{3qFUGq`SA{uMV!e(q~dw zVVS#4x~WW!4Fs?W9O>Voa+!!aLj3MFF+*YAMNN9pI_++M&OyePwMa=k`svcH*yNc( z(MS#mfqI^>d?#a=2`fAsQ36m z_E852s%!aLr( zxz5EG(uazH*UXK-Kqz;l56W5JMhg*@OZCeBD3k824fu-%ciU-J9uHC9=*6{I+X?63 zTdCCSnGRb?1>-y&-_^K-FRn#OgwM?L zbYjrKZ{>jK!OK6#IjVV4v1P=Jchyq^@LKcvwmLcPZaL6&D|x;3M!4v{wXy$W^LFbA zV9pQ3XlB6~uC}iey}qe!Zqvdsy3hOCD)E#YoT5$B2qS zzt?B@GgIB#spPCn6;bQ5Ab>8hJKqb5y@l_6z%LXqNp??<(YyQp?s^&g?scF55Bc4b zmf-8RQGA$&ZT&p|S?9IcT(RCfc5Mv6enWiBa+CaJ_HBNIBBYsK~#6TtmYF0_hs;{a!-EDtZI&{eo1#sa8c{s{06Vl`jDETHg zKmQye+1CJfK#0GeJe_m+4PUN}Yulpay)IiA*yOgVfI*Hwa0>3V%PQa7&G;Nz-|&D0 z*=N5@P1`POWI#T;@5>Htl7Wr})lD2uhyhgrf`x-d-Ape=eP31Mb2KwkOIN3@9RTYv z%;C2OeQ!(LdeU(;#==*?=n)ZGn2!F3r$$pKDbvfD!TxopqF7&8QIv&WR5FEj(Z+;P+nNi)1)E(K#XhIj5lO z_in=d)`r)ceBwJh%%I9KN`N_tvAbCh@S%u+L>g9pI}k(x=gesCzCwO}PAOv?CfZ!9&d6} zFFfQkypF00GZb`&tlMHT@B90E-!DGtFEDVvZ>2Ra%;;$TIbkJNpL9!1SE9T53t({e z^F`D$ZY+_A&ojvE?+akS=jTiX1E;-KMJ)hw8$-ee3`z&Cdy!9Q#%CUN z`0=|NuvvqZ&~W#2RxsrHYV_GR4^LAf7CDfD3B2=DwJF&M4oi^S3v%!bq-^>(IC<}# zXgUcSz+3xG#dwl11E6M7xD3Q!8)U25c+E;j*P4JzT>1c2ni*h+imgQYV?2lD5zI(~ zLe1_jMv^Fi?(#Q4HRr>L-CQG3icV;ub~pUJGikGOo$C+0 zs4igjJX55=+xCYwlAf(>>~63kAMxRQYuQb(8gDP$8H)6P4l$S{Gm`=t!0pR+y;;_7 zob5bx_wM#+*~H=$Kaya5u`Q8Xs*htO*;^qjfo`KnVCK&u^x znS*5J8<~5th9EH4I2C@4oZT#%t7(8$f^{R^p2}^w_cy+rsa%fq2i}yt$h9~>JbxMx{LDGX^E?K#Z=FcQOwVkwe(ma& zKpzyx{76T@-J4jB!TbAGS=gEstmbXA()^{ZN}U!gAWg6}O-QP01v8L#_W+!@ekOMi z|K$-NaE+IZ=P-o_1|G&MJIGz^?&ij~aZDmGgVMKz^GE92RKoxO@4Nl|t9B2ywFe-H zDcYQ%LV%;0!>YVNmQA(mb@;hppg*(egznPyBVLx;C{pvxqkp2|dV z*nhw2JUpFkg_h>Ri~Q)3PRrMtP&89bYQ2+3-2{+Hl>ffJ_56$~z;3?EJcSz)WZKk~ ze~mW{viM5zY+zCYbFlZaxl8{X%`vgpV&>F&fNy$KNz|uZ%$OhX>;IjhTJ;c*M(isi-=>_Qg@WZe-a1_5c0<*x*MGChu+ss1o;f`7rC33d2*F%bPpMDHeA=PKFK#ysm-~Fs8zFbO0vNS2`0_`+UkEhdY!k7ww9FEbc=$@6;O|IaUm z1yAv?>I1U6M4UMZ-uKq0gY41#2Ha4|ksOlQ?c_eM`RJSBDFLvSv>PJxbo>nX&p%-X zm&Dxwqm$hoKI-NB$!&-7klQJyK6XLVe0KLdC+i!}hf15}N<`oro)A6zq6ro==Y9VN zBNC;729;W+6QusrXsR7?Qc%EN&ojuU>Lg6g?ptvOksHrw*kJXqF6SZEBi^3whvm8% z`^?cf`~Jp%YylvP`2iMeXpd@Fnsxl%DE%)wd7BxslQ(;F^i(v>z@LC< zPut)`x67UHJYs_Rp1+E`E0$r6H|OW+i34%Ba9Qo9*u_elNu|l(HdzucvDpuhi!)o|x>O|SKtIjpKKnJ2pilLO^h%sNx%+FCwm zs3jin=viMOCg}nP{N>g?^O@~IMmH8V7{aylPF2}9`ior>9pees1lzk@B@y0S3?NC5KKM4@B8x{9wcbJSLIV zw!Xl6{lWR?{e*wfnyo2f3Rh`IQ zBIYzOJ1=tX;vXqfH(Wldcn$e7mgvepV4#zwbP-CYLL~-1Et|MRqbc8W-0-MdZ2TM4ZAp1CVA-s?R|haUW0nUsyS{wxV6QM%uqryfz^| zdW;RY>pAQl1mn#s;LJ}&-np3b1w9mC%!E3BdjXMn-<{KtmA|JRk2yn#DqOFn@;9Cj7m`j9fkBY{62EXJz&$7 zp(uWcVj~if!?Q_PLTl#-s?vuDNSP+>i*v@`5L`pwiVC+YBNT2t<;u5foo93h{vzY3LV;&4yY^EXJkdJFY`=D<=Vf zC8v9P^w{`NIz8=lvpoPm5&6HBYnD85EhvOEL^TB?A-Tw-abY0xzeXVq{TDa(yFSzH zfEdg(Ng6Qs{<;o?q9geb6;pBn?e5{A8d`l$F*n=WaXxeV!};AEa?Ys>J4*A5XJ*&9 zIiojMI!3tsAZB1SL%qtkbMWWKHHm0Q`-UQpR4k*IH6;eOvu3E-JWz7YGtxu<_P)Ay z5`D(TPAkdvt%0OoG|tVd%+gJAK(ZNDp|Ftxo_`&Szx&P{MJXc9Hu>mm@}Zr(J!$(I z3qQ*jIkgI;qS@tD2z6sIQziVf_m;Bu?N%pnSNW_Qve_-WruQq%rE4EeY=W*24OOJH zZxwt&k+}(%^E59EI`qBL*!XU8>NMu=dgGz~&LC^#8vqG1#ND5tpUMK~5$tO}=Lr0t zdryN<&8RJfQ35<|i@~;Z1TWnL=$kH|L>~Kag!oK$wtX>#NeV z<{*|$A+5DE+`DrIXr{x0(;S026Vxm_o1BODx+in7)485QHxV6OGoM~o`2GXx)j;gc z)YbMg^|14(9ItMb5{LJl&yR2o8iVt}O0&85!r`MIP7K~I;w0pmLkaXGm6Z{r>TpRW z?=I+Yh%W-Xm()B*xS~?_d1bmpHkE}cATb|7zEhmU5YKfI~h1YeuI}ri<+ICZu)E_xj!?*_f+}&PJSPz#LPO z@`0`9WNby}&}9H?=FyimeqSUUlEX8o zVFh0Ag8T1pD%-bgdY}_Hcj4ckvO1MuL)0ix`D$eas)oTv9kO^`^RlY`4>mvNKV{^c zdH6xmqBD0L!i#W{fNm5AfV|sOKXC-@7LSrgQgt7x-Zq;RX^|Kh4?_Pr2$Rak^HXF{_FUW1hiv9^=?RVdb4E&kj1x_~=ngrMeiy)-B zk^C|Ps)+<(d0n?rfRhM=$$mT1)&=O~?>huO8y+ep=@KkW`AO>UtS+SDUI#9)vsf<5 z_rArAx>3JlQin)I2dzj6QvB&{RCOW{q$mmwk^+^@D%>n|#BmM*_yWPC55@T+Bn=9q zu%=^0p9Tgnr+%BG7@NCBrNGzSirnnNL>92-fj+six1!Vh>6?Ju0X8>w7q(`8--Ne9 zGt>eHTRY-rzakS#2V1)pN%dde3jfSZAqDCZlWP-AzE%S9Q%de$xX}-WXI6gSd++TS zFSy>#RTBh3e5y5w{ZLuajHrdK6IE~T-QT^JqP>isIVYeo2_s~Co<(NeQXs(nmUf_| zgqV?(InOhr`I+v-!CM`1S5$5A|Gewm-5Zkfy_@yk7T*;Nt@rx%y%h9}_{e7ta~=)< z^S^!|xorkG`r+uDD)i2&a^-KB`PZQ?^gs%A&LsE0?^STl!LXycC=1_viDxJhBi@+a zXO1+s-+f;Gz~6jq7`)(+%^Me!(R|F7^olp_ksEFLGzoAt9OnIk6yk~}E3ejRK0y*(!#Qb&kglcf|iEP^!Gb8A3Ie#k*SdjX+oBHT~?GNky zw)>0P#(vv!RJD1AMK^_`!vwA(K(LOWCKXJ|t$k*U$-VFIecxXm*;*!NcK!a|G&o~% zZ;Jle-T9!x7s(NkTOw|Ur)ZWQp`V`Ck2G_h@-aH0Bz1#uCFn0dy8GI~;16Q1NR3KM z2G9o;77UCo)>+@KJV%-|MLEWYqc2*K-uBP zRx@3IAUo817iIGClzrj+2JpM@{uhu658>3a`bSBcVYkM0+c3a+#F76b7!;L7e8PVv zHlcU#4bSsWFWI{bI4qe0$^QP&o9@d-B#wSGRcn?1 z1Ck>QW_iEm%_TSiN3*@|XP}8=avni^@4I)g_bgNIg%d+xT3sCn)bTehi#aQO9_yKb za^GLu(kW2%6qmEu?YM-(WU;$InunNdBhc{(40s*93ma$797zL;abT}E5nNDf1%QG! zI6hCDU(fUCkkBKk@p-5{^zga&wciqh_;9A=08iL*II9HP?>6avO|E@|EIDt{ zOm2-}QFDK9zpBrPmna7ednm0(#UL==`FZ|1b$;s{BKx^?>!V}1!4tAmdGb@+!9+*A zq(wc?6J*Xu!A+d(zGcqBoy?Ohug)p9oKI%z%lAvv*jJn0z24JO3JYWPkrQB`{L>gE zu=d4vN*UzG-5ZMMIbxaiDb`vu^K&}Rvt#Txi^N+WVW`ocKLTka2$PusHUDUEn1gK3 ziOOlV z>n~cKBgWZ28EzHz*K=Yk`f#LlAJ(B2{bzi`Vf2}mzWq8tz25b@d8jdv=NUk(loSy> zM?;!;*Gpeu(M>(J?3R1>QW&J;AxoD)oZ0SOj;u83SHsV;SlP|)#+T>m z9rbfcybKc6SgT<(a|abyc3mG-T+eJ6jbL9vRv|LAJfKt4wS!d*X--w0+pPs9A}m(7 zGxvss93)Hf`OkkuGr0)cduiSc#Y2tgjguaghp8&DGKuDuVKg)Qf!e%{0Z_d)_vfF} z9b@1rr7I|!W^G_lYI#f5f0yp`9GcP8OxNWWY}K%Q>qHYzLDm{{hlPBe0w^Dx9Pe(F zL^1WNfP+EP$DJCEoKBm2c0ef*@O&qu`> zj=lT(?k@Qy8}v+HtT%Vp>;~d9AD)RZ8$#Wnk*^oyaIoALh~N9>E~?#&Th-QV@cr0LzJoVG>t7>qgk2+> zO(q?>8Rm(mRIfv#ZnCwRJ{#4Y5CoH=?Y7|a)7V*m!u2Y@%>9ySy``{r5x_tP6uj8g znP$v5K#ec8?D|6*!6^&){r#PfF|aOvpY=gDJG(1;tj@#CLGw4CH zUWObU$S(L`C=x$AbaYVVL<^7%!J)l-S2|r2mGg`*jbI9~5*2d94J*Uhg3;Chhu=UD z$X5LKX#g8-Mf|ldp>H;Ud0*U`>v0q0y&J5v7sO{%?hNt6lBYCB3fVFj@>%phwOVow z_ISK3j__SCE_`uPj^h2aaCe6qJ#D$AiY~%MZjMq<%ZEv<)1lnKFKV=P@UAgX2Onq1 z?;tJoqWaCsDEPkKYo)RqQpeVQ!61^cH@CUwiNK#99i+kO5GhiL{uCP=W8S^S&Q$jf zVLyYwS4Fx$|1WG@K*ot*1DC8WRoQDU=SN>>QOKHS%@EKQl1rR9=bvdr@EkwFqvx|@ z*MePPR&N+w``-6WQ?$P!g!b#=rEQvy5Dx5je}Dhmz>H`9>B=97RM^_|F6xV$%_KEd z9+AoYRQ>qOH>B4{ce;#l7kAB@2s)#REJ!E9#Q@F5W9(p>dfO`M*6wu+$!^~(eeoFC z1i5VBZD)YcHuSRdfN-|XO#K*q{R(={^X1L}jfsDrN27c9?yh%les9*l_+qFCzsOS# zTzzY>=aZ1W`p)`yKpg>{#b(Le|D3mRC8^VEr2 z1yk}hw%&XF6-(s;M>=Q*641TTpKl>fyjy2Fp`Us5_m{?tyY!r4Fa*&4C%dSu!*Gkz z_`NfL^_%rtBB7(%p?CihI4Pb+CiP%@<|sh9bpgJD4byRZ=k*i-W4~)Jb;scwg?0O$ z1(qF@v~l2okw$BQxvvl=8)bvdLy=_qulfK|&elmPJSc&?^S0}2>^7r`RJI-S&HKB+ zCf;{3cqC^}K`vAUd)64lSdh-?r2A94it}iSxx<2t*IOf42;dw~yV8szm0=j^bi`ZQ zGQ!c+Lssw;iQ#bq#_$DfZaQBtq||o(dkJu)!}87h3WJV9-(BdO=0YsZAO>?zYx5ol z1{QdY&An;PDl~XBpPmh22KRq6>I+F3@tJ>Ub#U>y&NdP+zEB$|R3$Y{TYLs0EI-5dw+qJ<(PMx1 zXaw&4IEeStPWIYu-zk<8((K5t*imKFUpzrID-z`-xls`;;@%`WN5UY7 zq$;)GGzm9Bmxyd+w6IvDPN^ygtThs8V(#@E@yzyQ@eU80tsQ3HefRoqMb#*^JMXOy z;FMt~=$u1NG&91Z`#R|!s2Woq%@8xf-$-T7=;)04JlNRx4pdtp5&qx*kN;Pr0a6v{ z;edhm_jk^ibn|!BumHH>rnjPN45spxAk3F1o#@YAfVMmHsYFdMM||xgA`^sj@0~|u zhO%B6fVLc;4;Ddm{=pO2*`YM@^?4@te|G~MkeG8Q@YgGT@)4lbq9S+y;b4Ti<9n#{ zZ(BkuFx8Y41s-U#9T9k)>)-$Lmb%E2P)8y+H_^yh%zVrdX?z!)Gu34YptGn%uuVDn z-SubsEma4P@cEhjz3YqST;#I_LKR%nC{7U?-CM5|&*6F@Ad_$0PA+oTZ_&t*dv~Oa zs&aZ}c2|QN!&TqV*g3PC>ITjk7aD!QHXFt{K)9|%S?l-Af4uMQm{U`&i_Z8$3R||0 z`fZAJ`E>09b$FpM!G*a81a-5e$guxUUxrI9BV{yAqc*o6XWy^SATtSI|a|8@)a=`($$ z%7~t%Ueda~GBHP7uE4CM?$_dI(5-KfGskdZ0S0q3BQT`A=xH#(&c}%91#V)*&nA?_ zjT4(BYEpV-D`gb{H_hb(yL$Co$;)PECf+&Y&qr2q_wa~9woU#T^mSwCOiUQ!-a9&+ z$-aOf>9BY<4)dgFSjW=johc5#);^{XW~`3rs@ppf^!f z@XF!5_kM~7;@*3Xd@VrFiDm33{0Ta{XgBqlE8D_)jRQKHfFmV)=J_`#z#C3iBj0~i z3+}qDmowumf&Q=4TMEH8Y9$p0+Lk^CHaD4%>(_{l>fmCk2C^WkrWLq|snKyf zt!F>8UC&7%mZtLH54!>G{RPixn7H>|o1ZR&>f8UqT)!x;&m{1bNBmT4lKmxO`Cj7e zF<)fx4Ro^l5<@KYk!SaH?AqG#sKc;1qmDv=IcGPHft>l1b%cx6=ecO9C~65Uf)yXy zVKN`SeRtD*5eC2i{qOH@=0|Xv=2P_$~eGWHc&U+Zu{xB>H_ z+D55Kip;lS=pYb_oX!DRoKxlxbp1J#S*+e1GL)T0LY#hJm$-x;Vs$!T>Mle{1g z^lJ#;J}KN>WbpBd{=zA0c4+|GP(6MaX#(y#x1wM30gKyxBkPFD$mvuUPr^b8viJ&p_y+66IBFej(5%?VvP(2znTiv&@>i~MmS>FY)-oOg46rynl6E}N8Pwrr~A9}s8w7vi>eL1kY_3&2g>9pPhE5A?flC0#Y(fv$nv$c)ms zH_UZo=C5W5?tM9@d~oFQ8_6-mu0II=`kdJ?_ma(cdZi!a2BYE4m1a_dTvUbmMvuC< z9!+H zZSUaj>&VYF+cQmike93hGlDSi?MCWz2i&{%&Uw~Dw6=%?3eGj)2$2nI53 zXMqBQo%@||0EOL-iv8eQc#|0k(0zZ+Z|T&{xS1P1<*eB{s?oiB%x(&*RaY2XW^x95 zoe*UqWf^rwIOvfHfa+DgiiO#)#ak?KYNz0kFR!}Z#rZ_NpX;}%fe>r(QJb8_U6Z46@Bj-t zoZ*na_Y(NvsC6d+EjvQaY1(I1{zNu)4e$Z8@3xv8VSS(TkDcy@VM|XlY8II#pD+1L zBY)y|Xyo_edlHCv28v>@KIwov`pm}N>S2tC_gV~d0FTb~TMGBRX;vzsyDt%PhWriS zJ(?~CzCgh+iJqsaiUukEZCcqY|GU4M1p1l7SOHKe6t)$qJOm_54F~ivAvxY(^3MZK z;tza@QZ)pD2fDa&mBY%@O?HAaw*=Q>qQ83~$|U>Dp%Cy*@V+E<#_`v0vi^+~Md-@| zG5)$We=JbxQ_POy4&p2f+DRUGnd~7xw}GpT=P8V1&3+%M(yMETeJ?d~^UJEe>6+K{ zMyJ|r;A4wd;kk)8obpx?8`9S_83u>hLQ;6n{UeC129cDL>q(1cRiw)IsXzsDgo_h%~1>* znaH9lv0-460OKo5hu4?M-O7m2wZh(Rz*1|&PaNuOLGgynl*Y%s0eplbZ59oX0y1>5qg8%(Mh{ojX{Xr_|HAI3 z|3pZ7eS5VBoMc>s9=u@UT+o`TPR_1@8o+Q$mETXrEcRgE;&pH*gvhP&fn@8$d|rdk z-UfJav4Te0O|^?ezFD2BrOUm0M&isUS&TprbhVYh^{v*|U4J;QxVa>tCJaX>9bF~w z)xg7vx z)d=@wGWMFIz`l#gHpz!aoG6Vm?=pvy-xr#v6dsA0C?DUYT+Z7&sKmiTT%hS0MkjyY z#H*9=ZjqWxr*lr6_yThLbEYtoI=A~T`N;IdzmSiaSzm*5=J)>3GspHoL4MBTM%u=F zjxo$j@ALe0i+ek$ukS;adrJD8YF4v}KaqeMxOx`^H3rV7miL>#W`ov6Xc3eQlq8>SR;J9No|Sinbr>gl)YCP z#a`}NCWns+ozt+Qv<5i^KOr>dX^Zjf{%$T@tm&r-mzgQmj{!c~0g_mnKN$)HzV@#x&6VlJR^dt;t_cz@;-!BPd>y7j)(P4Ad0f1+iOdWgcjD(Kl zx_=>wd2-F+`~E@{wQc}q?`#g{-JPekqTRVhJrLi)0%-Q;t0`D^m;iWWV@8@;FP!Tf zq8sq?ME3q}Mk*661UNr5F`m8N5-}w3X2-}#3^FB3&FKB_t!Q#vIRan4)aRcP;=8|C z={Y3;`)@YLL5HfclK7yBHj7NQS8hTM3GID#PDLRJvf3<4-`I|!A5$kXcYV=y|J{v+^CcRYfi?3LAkl`bfkdAg2@)&$G;8>Ec83)w1@yl*gQ`h;G+IzSixe~)bK>VF1|E;qK)b-`5MBd`>6feK!sH z>3m_1cs4uTH5i(`hFhUcVOO&YAW%Pw8N@tb?lvLad-8l3yTcIPp_Rcm_kmx{P{V(3JGvb;|F5_z(||DzVktsu>~1)`9~cp@o@Oe zdU3rii({g}Ey5Sy#J~?eGs5}~#F$CIdC1Lr!#S#jsuI5Gj>V=tJ~*1}?!GwBbjBG1 zxpy(;dN)XsQ<1fJftlml8HL&42sT1j-rLOi@EjR+-H5t2vm`Ava#mf}z|L3I6Ji}WOmIpQMP--}MYf%WRkr8|aGaUVXc z!qKy98ePS(iXMUDv3T(Mc7IZc?(1bZl~(dIY-lEO@j$^B9Wqiuv7g%DzSkJ(3~Vl! zM(*WfrHKvhCk@$dTX}d-5!)Nag=luEWzFb0dE#B z#429m+lIeo@amv}B)D~Ns#-B9ffqkBCO8?+dgWz4ohDhH2|mA9eYW)0#U zPN?|8V({~vlj*wwR6K&l$#P{ENc`_gFFg)MfJR5RYQI7Is~$SUoadwcw~23jM#pSC zLqz~88tHbfds8Iq>0JiYH`xk?wKs6i(L84~-*BX}-_kUqP8A5)WcUnoj(F6HA7S@d zzfdad5wY#?pijaX{{Y{v~j@Wsm_IuA7udFH3#XWlOglFoez;pnI%7aQO@|9#&e z*9&#N-~WT{;%~w%Bl6Fz@SQwt*3mpr=J}z-M=+RNzs5(Y!eVzD&lWGTB%scKXllJmDO@_o-`SYbwLX#gR}FE0 zUm__brr@9+t7*|470}nY2OvzCb?3k?3kUnbBwue`#2pHKA=1Tz@3+4os{)w4UjQ^` zLbC;(F%@d!D{nYL2NCi0uHSG8{2ewmvKD_}@?Nig^hl!4KM$M)M>DnO!kmQJ-zL$1 zVI{z+x^xcCJmQnLzv8~{{_X|--KjS8#{0R{K%1P0r=1f8-1tLK1DUBhn>ur-nIq>K z_E&n{f_u>Oe1-ZF? zH@mk%jV-7)H6c>B?t08Lbm-mloS)}EkIpy00qcgcYK3dz)X36LXaef_Inu-*sUvYt zsZ#&+TBNjO&n^wIxDM{NQNuvgyPdxpp5XI-t3}HQOd2zbiZE?q3?TvM7PJe zPM;!gL0DgEZ3D3v(xTzpxNVDNf^*Aan6&i;}49}VKe5NV#_1^dX_ilZT{Z@1e zV1@coOOK{W-7Yf_b^9=zyKinPM8Eenpd*UAhPCgXMJ^IC!UY=zZrgY54g7PS&li7z z=7gO(+3`RcY!&(_p~}0v@CJQFsvfK)^kIi-$QAjJQ>2;31y_Xi6^pb_)bP4$Dx3ENB|RrqCTo$>>l;j5?vDpBd?J{wfzo03$Yo z!CkMYGKyP#l09=!TMc2Q;-;je1mhzRT`Iap%9wwNQL1ePvy;txHW zCRgs}LNY{TIFyE2XGZf#;L&sbIpkR%mz90&zWnT#qY&H0kQHeTPG0=f=jzKE1* z?3ZwOrbul-(|1=DAAkuq&IhjSeB;vzmZc*gI#cyw6Tt=zD$*HA2NT99#4%2G7?3x{ zn*1qoY2ni-patx^DYG9$wrrVZ#^*yE1S&-oV)W%YWH@Jd2#)eddl%sF%z1v!0lIGF z|MrPQ_r4K-&NCWDXO2GX>H;Zfb?=tU!;jub2%JcoqjR2-yaDv^OdHR@MC=y8{5qBb zm2xmh-$b(6x={gUBXumuD1d!O_&M|R#~l)OR{COsw|akoH<9*j-HW5q8B7VpRr@Uw zg;{iL+omD$;ysu+1^TRJ#aht2>fIm74=Vv-5|5L(;3UvgD29{k`urmN~;2^M+w)S9W-FF@slAtzw;c;OPHlo^CJ!mx*h z=`PaC9V-;KbEO$_KkSH`qnZtEl94IT;fxBlx|Ix6Ezqx@YoKuK4jJ`PV7YJhy(PV1 zFgj77g*tku-m|4Q;`~6*PcK#k?^ho%>->9cmV{ExW%a;GC7S3%T-ml5_y%IYYKcQk zu-6ADGvpx(Usa8RhPoPqqOeINk8h7kXE0;3F1UxgN ze-08H=#jy7jij-;zfEwDjwH-9@>%nYeYaS9h%vaxiexGJkae#2?wvVikW2>QyRFD* z?57N^hfKL8G9LT@q2A-0v%$XAF0t+$!df=v120q=^SJ!~Ik!zMre*=tBdjudPa3iGg2JhV}P&zrH)CH{cZP6pv-`{>yIg0#S{k8n@O8*# zY44xq9@)_ev3I}x_P)d_ec&S&%{;XmKl1?GZ@bH_tPCG>e%O(l09h!z;Cd1LVFtuW zvsTcA$wqFG=jWtLH1PdahdE4m`JnGKg&7t0R#U2E#x1JFTNP9FxBK3Flziqdosztg z<|%w_nIw9D*WXnA{mQlAIg?z}p-!^9FA^L!O{C>BoOtG>iR(zPn2tnCBHzJownE+P z#(P7X@4gSDz}aix>(BlqQGA=q1eV*mSpw)>gtT{mFP(LB#O9M1Cry8|BY7q|=UWAJ zQf*!E^{?m;;+(KghVS}iZcnMobe+G>Mhf%pHVSCw!LWF)4gfVBX^#toZ;X;6J&=sT zn#r%9hu>wyOk#Z>a1OM0y&f{@iRA9}dB1s7k@cIuWVbEq0ro{uv@gm8Dp!*F!`!u( zR&FK+PPg@DyoEwB(mH(~cn$>3Qw6ZVAD)UlS%uZVooWZ*O-O0|O#|=l-n&hl53%+Z z57*Vvhok-r@=-$jddYRX#@@XOc<(Qw8O@oNzzDnP&77OhK4hmE^nKPD)^;%fcxuon zmvQFj2(6kM>YPscykGT9Tg%7ywlYrqtW~vo<}$j=gf2lF5w)yOB^R~4oRrUtW6@F9~>Htdv9%v zVX7B&?HOCOAG@{)Nep%GdrKQbOeNDLA3p~^0OfjuIrBlq7D3h>&Ncg}V6Ex<+kJgz z3LyrobY`kSmUbQOsFq)}>5rIm?%KPAM+)QHzLfwEe*opCMP|%7qX7=`p+E{}UHUUJ z43&S6TH*Ju9w@EmbM4>U)*7GWwolvns&ZsGKl2=n2rt3mqh}sLvOeVXSJVCe`hM%1 zH9IQ&Vl3Hxaq9B5`jBN7xxr>6uR{~Y;$W&;O4fJF^9OK0OMzI>3aSap_nMj|yL^z9 z;v7{H_9=eyU)$*juy;ZNGi2!Qvq9(E>$j(^XC(L6zeB>CdKW8(h7C)pBJ~qPBsfEf z(+DgblJdU2eb9#{@n3)%3TA8I1p;!iyS@eree4!7G#rZ8)YJh&QqNby5tOfQ-`;KE zoCP}2+@o4t5dx;JiVqaHRd z=}T-+dS9Bbwsx&^hV#SV-Pe1A+i0+_J4R#a`x^5(qUJpFJnW3$`}(dwLyv+ic4q39 z`tHaL+2WjgQzbA}8%iBz5m048Xgwp=1H*(^*?fQf-k|6v)QHWyse0#`v&8-l_17sb zCjgP!*8t!9X^DY+!9v0AFU!m;lMzYoz7B~aoIZjhAqNz`v{#jm>yAWo*T4H~?)S?o z+ndgB%_)9?Wrr_8)`t>jWJ#L2rg0Zy#3(ne4ynex;`3nUG;_gH-*Py=_QqX}zKN1^ zWaMsQPp>@;3^R6aI7+_600K~xCjHU@#>@PRODH1RwCzs;Vo!Om3&3f?h5;K4Ap?i! z`EeG)bhJt{GnzWUZ;OcF+K|JZ5zjO;m(=K#Lx+Yj<6mOjZb;d2F3Wcn5Qx@h<|jNh zcp*gM37~dZe;(jPifBJ`I`8q`nMbK6y@DmM>uKcP8&gw!eKUI7Uhv)D=9vYvzC7H^ z1}#y7eV$Wyy^&y*k!D|yOrve-^VEFT)?1jAEY6YZSTTp&Y?{U^E?%_7NA1FybVd1k zcg~M95T2oT-;04TRveyIeqY(JwlAI^iq6iT&vB#YpR@1v?JcvIDJ}Gcf6gOh@8V1w zHf+orB9~{5=L0S*R*20HA}Ag;d^%;3Za&w7j=X_z3gEb=m>GN#AY^DS*g1As$`8Oc zMY(!Ua6fBjh0bTY<@4RI>JqcJXW`~T18t%Z;>R+Cy~rcB+PT3b2z#(Kp2^v3ka)y2 zbHz0xUFqnNfL(0zJP_#3>oNl&RAeduiVbaoGqWqnA9r%YQ`_r|RHg(TN!O(RoiKU{mR1jT|4*=6Yju1_3wf-vZ7sJQY3I z??~kR`i^mLIn)rC?A@99;e;vQDYy9V8teg92+_)NYmG)Ybd_T)cN*RDpVVyn#f;|p z&ri@Onh>--PeKXY?7RDehan{xi;;Ik)xZo?D^isrKfyXL{G16slQReL?y~& zH(2qYWPrAVINmk);e58;;EU3N@bjJPKt_ON?tb4=!#G%u9?V-ef_-Z0U=j?p!2qc0 z{ratoxU%PPFbxp`Z=E*i1eh(k7vgBB_)4e2mXUE2wXz%avkRz-Q@|!LAB9vym12D6>36ecC8%$F%Dx?PJ3n&YdBn~D@V)67`D|`(& zpSI~Eie^aP&w#xSfcjemMRNLU@I1$_fA^Nfx%|d!5Kdi$94ov9U#Tl%iGANcK@-m; z#1q|Ap2Mu>AtD%}t56NmdSgQQz7%1;{h?W{Steb(Rl=5Ju+~)5G<)+GLNK5!(J;7opPyrYxhLx_ zey)4f<$eb{KxEg5&v^pxebL73b|sY|dE3q+yAWD21@$NGCvjv8u=GzzUaR>+$=$IIsH6Tfg26+ zn9CauLU{AgFNh@3i2inZ60wWVWZ}!JqYsxx6@u8!E;oXgWbQBZ=$sVp+BqE>{KdU) zb%0M`eEIFDRv@MI`zN3?B~p8T>%?d}Ll&7%Dq@f_a4LQQ9>-?{Y^tb7j|FU(f|PON zDY&xpM(=e8r5YfIzF274{Mm*0BDkP(&YWOz`Kg7v_WA0ZDw4{hyvAW2h|IpvIqO!P z=1i)SaX^;OfmjmCJI;6cCS=ijS#&r>UpvJ-q`tYrYqRRENVtDQWae+C@$7Z;SfpbG zl(Q2>cA99@WKD88(BjJnqk%_mO!rcn@9lNwFb)oeeD4demgofz^w#=~WDf7%yZ=1X zm7*ZbDQw5@=6%mI(*!GnjX%XC8R_1Y_%i~rTmG_N`AF1Y_k5|ux(F~)oQ#xu1eN4n zBfv8!Sifb%v@N7T*_;Ynvez8+DH}k*7L4MhcyK-8oOQUzfnS}UaxX(|!clJO$7X!*6)63i z?#*A{!NZ|yD+he{qKVb4Y`1h@R6@D7jfeF2{?7+*@X*y(8#u&&-+P#u2l?9hZ*-gW zu)_AO=7m0o9OdPmq_=8u_+ISbiICLK{*jwxT#-Bn?;RAUbs-T0Y_W^>E_46{qv`&x zF7)oZJopdijb&uA*T9}UMNS8&)z1szULAe--3xF^Nq%PbMe;j*z$aM%&x{Fkyzfvq z=2o{>BCec0=+EOIhq4Ioh_E z|Mq|UKRXWI0yEm!-9$Jf$$K{{og@wyFEcIEJ3t>jLF`{jaEs$m%Z)T!p{6}7X{e5k zW;8C9!R+3xq^NaR3`sn@SG#$rIedeHy@S!|mZm0wLw%f@KkW&@&lW-_*ll{{7f=;( zfCkc6zPuZ#f~QV9KS*3b5d<}-ypr5-Mo+km^?&})|H#2ihwJ6iB-oW)rl)FA(_+TV?KSS2w+fg>(^&Bmt+r@u43dzLwk#72XW!J;d!p~HDC4=N4HhwbGc3fjNM`7q zq@T>_%>HgrRTLXgw%1%%>-4uB1WH2>(9t8w|V|9geauKF(1v$OR8~J;LGnxIz=ZAUzc&@S z^fu48bNO;9=)}xaOXXdCRwIX&aj5$VC8N4WoRDWm;{Cl96Wj|4&*;4u31%MY##u5+ z(~G~jz{SkNbG-sV-_1F*>)kv*cQn(7X{2*WwzN}yarME_y)cb*! zBnhyUS5zww^7SoxnltGm_8UB6Ud_p>pDLog%hT%bj?}x5L_SkxU89c_$H*l{W17f$OBs%!UuAiT? zy9a}V-Bq;PTn_N)=rrB-P*!Mc+$ps!;7V9?vkwo3d$$bx0wa585|h$pdye3bd?M}M z?-(9ofzP0J5PzTJhDTKH2DU`;F}>?*2UxjbdD^wBbVL1RM~&l3g5rJVKX-3cX&=T_ z)v;Ro2-+htHnZM+pc=6Xu*V;umNzaRWZ^i1lA@K9? zh9DOC)|JtEj|LwRk8A6PEcyqom^&rr;D#lA((D!b0%&?W=Es_upt(&3t@Ke zmw8}*Tz&upzo}oRJi?+Y<$zqLv1bcx-jh!av1ryRgt=Za!?|>vGX&)83=(PG!Ex0< zA8hfWf7O}!)=HN)1%UwzuU+xsgzdg;l#GAH~B^k z%)QRN^FdK{y}}pqi4oqHAkR}MkJ$DIA3aT=W^WxaJWri}%$g6@nUugzuTw=B%#;Au z(reFX3!Blyq`>t#Vy(?!u1m-BCHC zYo`Fr_O>k*As+H3Gt6C{2WvOsgakHUl;&423XV?K)H+%_ciR>zHZyZl1a$(gI0YsX zyt$9&?zca8q-1qJ2OLs;&3BT{$X>|1QSBh}Jo5rrw;l0^a6*7iLbU_lrW8{mxpv2< z#p~?1gA;ON%*@9=`4IMeuUi#?GN9}_XP%oEj`RR@SpllBO;UWrr?;gV$+~&@v3R#_ zt10zE+qW&=VE$m2`Kqwsz3(|khu@ZD8}*xfyn2Gf;M>GF{;&|9p6!G>+;@>eWIBn!eLYhFQvr$k zz+nhy?CXtm;{C#6O%kDq8}sYrQfAp0OMeTnn87-U{qy_-u!1y^_vYdJ`aOEUml$wT zXWTM#MV+V-Gr+#@0-`df;3tFp@QAf>QI3bO75VTXaFotxNT`6sO0hq#AuFBE8ru54 z8w>VMB)D-1{)oh}oZA)t(POW35hG`BK9^k`O`7v) zuXpd6$*400id8EGrKQ|@8=MgC_gDWXANX22#`Z-one~%}SD%q~l@s5_WGmn}Ml*_{ zj(AN|2eJNUY#QnA#UzV$mxAal4dg$3e3H$*_meDfZOnjrs+n=D(Qe;sf_S2io#NG> z5xTfl1gQLy-;zXhzv#CGey{=V9WG!LKe(1h!41!znYy%mRRKj#F{K~w9puG{l8 z#xzq-SAx;>71}>YcwA3;5Y;I(GwU$7ePs%t{#uQIY(V>b`bnvpk59px_b#EXnVbus z=GfdOa8sOlv%9bKfaV%sHtb>JGG;zc2nq@Kh!Y&Le+?*h z-BB1hk&v$$;xtzyRX!}A%qr`VcCR#+Xp>FXa@Oa}@7wMy3yZqHJ7wl8;E35lb30OO zHYb9BUCyCz<_LjvcQNx^mqC6EpiNj$pEC=Oi77bLqsQyuf?d(_9PCzC$cUgH=w6_x znQr5armk!86{ z8-1KrrQ>@bKhIN+O`B9_bBEFwM`lc6P0-rmfh!qdG4=NbsZc+NF2cJUQnT;nC}0(i z0EF}67yLww?2DRgGIKVoc5~Rn$?$Ql;g#CvHyN(l4H8Y@VMR8rF^~>2X?;}R00&P^ zPz;s^HNAC_WC*uH>WHWQrO%a6Z9i@XNjEzEN?aMu_oIgpm z+%@i*wvBzJ>PFMhOLm)FIdCxyqG`PSAvI_2z6^a=dN#I04Qmbrk-NEPo;=K3Iy&YY zzYaaXnp69O1GuR>AH;&7`Fv6-EYQR^S3$=XKy;epREt8cT{`lP4CG5WY<>&M;UqZ{pt+%b1{pneYh4&JS+A7RwcJCz~Wxt-%%z!$KWU6@9kpSLzfI0iE!LX{h}OgZ?v;XV z89GmLhx{~dY#q+tS7rZha?ns9<-yt~1PzcIxT zt#T3gZSUsiQPPp0BRriR2cIE^=y;Ai?7T7NOgsGD@7=8W13EQKI#wN=q~>0GN^0;z zhaY2po3RFMEe(1e-&au@e}g2&JvSvSBlNJ{H%GJNGiS32NgdI(ell5bG_*i7!}K~# zZKTwRP3BsCX09ook zqvmUbG|E`54|*pI7@5FsG8zD3E;!LA7&MNYQnR0{j|6}T3lWa+n98C}ai<)OGXErb^p6zvaxv4NPKcME-L77BB5gzxN zouewk58%UHDBIOVy(+z$K0F$Uk>hdx=V-$$kkW~@8)Z4j@6~gJdAFKiW^s3k%>0Ag zzIa1kh0t)q1zc@#se2P*w&N@Dhm!(%0>a7kHe1{RT6s4I9RsGF$_r zTkeiK&w!9|y>;74`C@I`4Jv}z!n?KvuJO>Ql^~??@mP=hCVcM&6 z%Ewf8!gCNq2cMg+?5h2uW*9;Og@qE1?F9zxeCLiPNdc9$iJj9})!ioZiEz$58!Yx? z8eg~(f`)j8{>9P0^E}2f&@k5+brpWd>mB|>H*8|>){Pi)MBTgia!=-y#zU0FCZLt@ z(b5lI{vrEgM?>E`Gc&VmE0bA7l<#Kh0zSRkph{dXzAllwKIa7Iu9KI{oChK0Kf)bF zLg$lQrfDQ6-%#n}zLyqIh;VhRsxdW8tfLkY9QqA3Mp|(JIK=X--;+b3?COy|uoI5` z=95a0(1YV~Hqd_f%iWoS&qVLxxk>VV>}X~%d;MbBbb5cWbT4k=@(%=byT+Svys!RD zR1cr`zAzMij0+csr|Na7L^PbUK3|LSZK%zDPWzyQjN*9zKt*?;BShzORMG2vt{%CUe=DDEXY_6H5G3Ov-#RE~54-=SqHbue=mfqFrd3jTsb%${i z&5_3B&Go)tFqDN21Q@=%)!I$>T){?&I0thYAN~!jZTeGXN?tF%d`B(HoDV{6F%8Bi za{kgD@^+`aH~ao3dEX7O@%!&$8)M9W=6nM=jU=(?N*?yiHV;5TY?rt=~jAbNVo&8IVQ8)3q-cc@|Q3f&3=*?Y+? zZ-*ql2%fr=0HX@mBzL`w-*wgk&YUXgHqoQ(%0Zj@x>yhtX->id<>VS%zU$pRU`Iq1 zE(ETPL@ac>)o?i!ou9Stzaq~d`V(B{7kteNRGpT@NGZH^g#-PALo##t&5iphj`nXQ zRiR)<7`ru!6k{iEbcV!`Z2Gu_*9qn@1m`&L>yTSfIKc&g%L$RZF#M%|WbY=mo|%Ut zbEqjZQK@J)`kQ-<6B`>i*G?9{dyiCo!MCyO#Nbp)MPywWY9~O%^zf_pCd&*kNv>~C zUV;U{h>wxZgLlh9{b-Fu5iXYajLsZrC@u-i-m-aN=Wxim{+(_(B>MAr#7%f8_cX~W zyt@nnH8?EsA8|{aQDV!s?9yST7QPZA(r6G>CJ;b~=DzOqrk@OmKr?)fMw*f42&pFv z`Ch4NHvaxCMeGZg>SKzZC~w^vC9s$Nk6sm((w!>HnDL?&C{jaU1kG*C$L?O&DVliH z-R~9{QO3udW2!1#GLoBkIzid%NMP0Mr%?(fwizg-Kb@na0|s>tN=iY}l{2;ox6OU+@A3{Ei5K;7k)CVc$7;Mg#|S zkXCk_Utc?0B(Z*|56*T(>fn1%Dsi*|J>o7ZRC|HYHWSrJr%8YqseYY@pWlpq0Q|St z%k{n>v)l^#JE#}-%Yzp&%`TFJyti&9Jv3E7Hkm0i$6N1dbH-^Cn`CV4b?&=g7j9$` z-}-{ry!-CjzJ&u9(YZx8hqblVO{FEibO^;R34P&n)C}nEFhl)|B{OqSmohS(7}>rm zGc(ow{QQK&pGO=-5Gw{=ep=&vB)wfQ`yuL-zpTP7t9!Q*7`-}D%8diuY}juRi9^b} z?C+*Y;KjOvFh(#;9UNUKUGv2}^->`Co?A_`a~(2jPERIyc)nyb@0^~gZ)vkLTwfb= zl-#?q7T;2OdXHR*$SC5>U%+PuQL6O=@vh^j6Qp=J#h@0`O!7mLZ=F*XdBperTE3er zU>R@j{T|Zw=Wal=sqo%kvX-}cgmi=by=f2zoBZCKHa_7ZAlBLB-q=P~bDn2#2+wnL zevYI@2HWv%nq-GayuZKem&`5D76{&ml?mVF?V)L0c=u-S8IC5Df#-;fbckwFx!)iB zSEh&(a<4S=4B)7`xdNQK6IJ$w@?QI5*-!_Nn-8y@y~|>@PLMP649?zv+2MgRlBvrs z9KQ^%IL@0}yyJ97p%JJ)o*TQp5=;OYGlN6?`7KP{d`L2UxYZ;vbX09Tr_t(P1rS3>l{Hxj%RxC<9awj}$NjyV?ez5Y&N?7gjIHST6{&Eax+Vg?U2I~@Ipz7=qsZqh&N)^BNF0{8tFdGDKd^WOi5p@gmQ$OyQ< ze~QASz8KKSCHUTdQ#UfPaqOz!!3c5oBi?;DOBz5tnkF68{vaL#ElY|aLStPdaqBSH zeLt%$^}qh-pP38`xT|9~ANrAp6=ih{)6Wp{hnPy~P&qRi%_C@iY3#iuz*U2Oa}PgA zJ#0yxS zlW)xX`j@1=qv1v~7z{b8v1)?Em+XYr*~>!cY!20&6kqg3fK`wU@+ORIc97=mVlQql z)7ZxRfnKWG7tHM2$1247`t4Q^Oa{gA@;PUMEy^RE0nSKLPPSrUPLoPO>9hIkin&EDE~iPq$QS`WZjN9t~H@=--zkfkWPGk zX*ic8XAGQkiXsW6+KdYXSiiq}o%kl6%&-9Rv2*6>G#kiNeR^h7I7_y@!-&xco7}x# z2y^D=lOq)NT-BFdvzx)at{7#M^X&i>SZEUfVVJ{j_{-0wnaVIvLu6(i;&kFL)HCC6 z(3pBFDaH7I^PxWl`mm9XhvksOZ;)G2UP==n?le ze~LXE=A8N;vQ1&T`&!R{*nK~w85QL@r>h9`BqFEcFHi@nUWoz`8NO|z+TLWqZ=~pN zr7=wt{Jep{PL9qqqjX1B#n_e$BDILT!4>37*Vhcdy}onbe@k$Uj-KLfKira#+&rIKTKAc9)^wqK%r zyDBk0#5zS7S4Sk5IS7)WbQD78uwR9P;LI5C-7r91JfxwJtehD3B@uDq85!RGHl$mN zfe_;jN;_TTsM(nuTuz!m;PKhoO1+jK;(zRWTrx|{X-@<*xe4->oyiZ zG?}i)z&Ws+uZ5=EHHjXSo@Wk0J@bJq&?S>hiiKJI%m_F)1V6DYkV*Ti-7jA=L~q#< zsJT7gzM==>##w)p&T-~5OGnNvY=+^ST8L2Fy^E;+uv)_?)t)ot{5(I;^FyX3-^RQ7 zDkDxr+dMqaxArLKi;!zC0)Ea(;AUPv2R!$8i=|QeS1hSG5hLv zbwJU{5Q=s8&ZqGL`-p!Bb~6IB$zFUC^K+!>^5ZY-ueS1wvP=ii08q5H->bgK3~Qm! z2PmaWH!11h6orJ29A{i{cW+f3YCzNng&5|y4;h)u5ip_6WIOC|h~F(5ad;8VkwS(S z^G!>WG|h{|<_jnJTQwz)OLy+PKI=;)Kj)`v7ye~;g6mxg0@S=X=s9O*Zb}yP^?m_U zGYH8usH2mke(ISK3}W@+REHd2_eFy4-N@N@nNK^xGu8DV*=`Xuzk3;^SW0M!nK{on zL+tFw7zp!ehJmaA=9ANIft}j93@)v-`hMGei zpl5Oo#~C$1rC%U?-~DDg3`yUeqREj%r*Y+?&IG=`1zADCU!YDiU{yE+Gve+};w;ok z=JFeMBJlR|HfGLwI%GxyUt8ab&dsWxk!GGJPM=h#+IZ`LBWFkHl%^!Y^trx0r9C>p z#E2Kqi6SbX`3bj=W}Y9G6%^7CCfNg@bN=Vdw_?Gc&by8-q85tHuHP<(|H^i5Q7Rp% zuscBpf5ef|d*6GF;E_5&aK8WFYiiK^y_moZ!EaaTZ*`TX0R%XQB+VjL0dqT%(Z}w^ ze(^9wEs5ItQr1l}ryn>hSzQl&qMHX=lS`0e*XD6s=`vOEfGfQCWv`D;l2A79u!bG0HlNe8jz1Bwn1pVci~U_>d!pQ zpYy!$uXo#4eyc@JhXOHDItX=+@JR#Il*VEV5e&qSIzw@S(h>S>6_z5;nYBFv^{8c- zB=LY>XtZY@pchtlZ$_c+uVw0K^--}c^4?@W5c`J=UClf?VExNzAF9D8BoOKZ`!S1BSrB_uO4Lh|*?QZ9or3cb4)VheDkV`m+e10TA-gRyy{;kCS z%NjjwmG1rY`TXV{i?_&=^E@B}#NHmn0jwJ`8tHhNq=o;qpOhdTTl(+))y9a(> z-&NlNU?nnpukYP=$zT}I-xiAMHr${85q~M^N-ziQD1aH(K^Rm$Tqs`W4RW+q(H+Ui zx=WuXmfF23==j~d%I>@O-uoh>FDTfY13KBJNId5!z?`$jdv8}#!QIwgr)asI=jllK zRE2l#UB>L=_8qaRWk_Hgmg9idyUS;04hx~>sSajpT^$5?vGI;L;;`PG`WGX~fb1i- z=~@4kMg{AHPDCNfy&Hrh>hNGX(8})pSbt128vW@J=x>u}&PVm?qDm(AQ*=OMNmde| zA))No#;mlom5;K$A0Z45aRlN_B{g&#~qL`$u5H5>$V!Z;qafQRLa{0Mn@7&Nt}n3eDhu^ zpUw~o;e$-sLcB%|)_=J(@$19qNRIC&c@URI=)VF$%uC!rr z*W{59y4PT0M)%%#FE>-k8mCjR&I~`zPU#YGV80i`QDqHNC`h)BH=(E?D@-MO7rjp- z@QXo|V(2-DpVaojqDa?E!gt^I>N(De(EuSol^C;ss$JB|W^|Y#9#fi)*LWSQINW%1 zgL0F4aq;^efTpcCeVGsvb}lai*)$K!fS)rW_f}&I92H>ryYGHjp`9RG7=wtU3%Kt4 z2-TC%!srl8=l)&rOEdFyNgxdmHAOsC1Y9ML>}~PoEjYP#2UzV!{HEq}%n&;G@;9hY zL)Lg{#L2qxnH*%_>&5zgL+4O;P2#@S+3gvdgwZ@ynYWO%oUR85e8$4+xm96kpkopWYLpgD%y1W^jqAy2Ipz=xc|7l=|=MRu=%a2r>( zDA}fBjIqCey3{Q5TXdECn7>6<*o)|Z7#`RQxN1~eI^FTyf7d`rj<>R00NxKwL?%W2 z!|(2Xz*;-pX0WLx3zaXaq819{zptB=zU}@_W9f^hLU&OqUj#wCVohBPqBF@JJr76H zGeaJP=Nt`Bqr|*FoEY204mIeDUDiTm{N6jjKR-YJ%s?vbNc+dUq?qp0=vWPkvk!Tu zMl%KbZD4P9Ahn!}z&Qh9z5eyRuPT*m-4z%V`ExYG8^c1Oy~2Dzpfo6knwe9YNRTkQ zsZn=#Q411TIgieqGyI;16w!?@M!*p3XC+#ifjqvy{JP@$j%0FwulK(1{k_*0_bve* zQ8>@@@qvIqOM`(ozH+kb?9DfYrjc9Xlxofin1*}j6Wim$owGQ^{oIV);-d;xJpSF? zC675256`2?z~J87daeQUPPJ_Iy*xuA$H5YK-K*zfSZV(`hec0yogxZDsYa=uiZGg` z*%hRa=lMDO=~Th+b5484K6fpE`c|h1@*u8ezT)OAKB)qznqsgfca!ta&-~Bv?%h}? z_Fl|T^OG44rD1Zvj8%XZb0C`AN@%@zgT?n=3>4fQRrtwm%9j&!*EOQO@9z7pEghWb z9BGc4JBH81+Yc$o5I^UDy=2WZfS4(r2H-RQgff=I(L9*wO!$n%QB9gnifX?vFnOLi zBPsTJzpi;GQrWe0ipxV%w+%d1j#9z-TQ03X{LWxY*(BnMHESEBAbQc=1&6r6#z5s5 zojpwT%hdU!sQd04tnKckD0VRRAyeohX8C(R8@3Z?MNc=~2kJX%=uG3I@vWy@$ZtV=S+9tgKEY35%qfQ(zsseAY8Jt zyrA=APy9Db5l;7-*Y|EsoZox&DTl#CM*QwC+YlsP!`oH*`|c@lwFX#)f=o+3fqf>8OPmb+5w=)~_w{nKI+Iz&9N^H-Ojtrt%A6@4LTS z45uilE;%qYkOy5z+q-Yu90tG*oaQpoWhGXR)1eFjv|1#VG;#qWx7mSdp+dd~U!QK7;wsiquKPw}TpGD7?|nmG?C?0YNm=PuZ4G$p>)rLTDywB&(g+?lFCu*rQJ zS2FtN!2?`XL=oN^KzHx{z87A?XzW)jJjC|{|9#)@%^9uNmm#^iJ2)!9>AryG3lYb8 z9-XO$U^IHZ{PI6p7Q_2{-@ZeYV%02A!|!!O{`?H93YX%V;6Fvqk{@D5lQD9kh{6Nt?;v@tTci+TNw#`li&4Li^uBYuxpE& z@mnMkfXpaNrl_N+leF{YvKyR7M*$r20=choyJi<=@XU!@*6PIl0s6#~)XZRxGIs2j z!H6@|cQJs6_FD=P{>#`BhNrWS>!A8HfJGJJ+iWf`oWSwMmX3{WN1duzAr8n5e658! zA$RD;S5VIKra0YJ$4+1gT$_NTLxNxYIYE4J)}3|E-j|CnRTe{Z`oN=;Ir&4P{QUF7 zNKZKs61jVWErt%I`gE-lG?4Ufy<@-?Jp$bO3b8)pp1{(pV)(9j<_J|Dr8-IO{m)Jo z(BjOTBtPdo=TPI_&%aYR9`FTe_i(N*@&hn8n7jWsU*=bmY&k50By*Uojl6rSLm(-g zug@j)^;tq1zb*hgqlbtQi8-tQRR$}`sn|fQnN8GKa%XJZsulHCWmka<$usQYGDCvTbM%}949nqeKrFWQ zfiG1}U{eHL#nYU8%TD@w8zRKa43WM2dfip}vIf;Jc{}$xdXCNrg0~aIe%0D|V1ZWe z<{JE!j@?KRBMru)|Mk?p&|JDhLajUjr~s=(S{B&E0dWqQ0luE*6Bx|2TB!!NJYe8Y zeUgp?08zu!)TKTkk>SN1@|<(#Q9c%vy>+q_0u_7e4hE7%X;D$3Cl3L(84cTlUU zd1KrL6P33!hZ<2D;mp=LwLZf<;&5gF8rfYuy=B}Qi=i?_G;$o{p#k z%WG9WnGIpF-gyQHf7H%D5F?lF4rN45id-)go5X0&^D~+det!iRbhg{`sr?95?K&|L za{&vd9xyZXHPc0XGel67lRXdsH^c*hSt8fo7E$S*)xhujc^8KthyM5OyPYTfex8~k zKPt63ty_(BKV61RQH&g6h_uy&ldQi?`gUd|Ellg?PdPDrGn$sOw+_5%=yDj`Z3i>y zu!NLOjQd$vbT?~2E_b|(^ptM!1y29W|2#kK$GzWY2IN0x z$w08|iqu1C@0K24@hkYYae5%YH949Kf4Nhs|Hy z5RC(p*B3%WU%&Ua2q~NP{=VCyz@+Wn3S0gARXugw=e+c}=s(%~bXY9hl4N8rX+Pg$f5mK__QDtN96!nit@R5q=93(eu8%>YD=3Y82_Ph%RFGB3QI%2&(D3xn| zq^WZJlTDNsQQsX|N4%vBC@vcr6XxDu&Yb5sP4_b-aGs~-Hpp!3#o#~P1))ECUzc?i zwPe5Tjq|Y?0dsw?fYB^`sB_eOcM3Bk=|tzu`JUJVibYM6BKm6I6;8{@V1dr)zY}RP z)DS%&*tO{Be2zf0*&sXi3GLic@v1FZ`0n4Xa7g*SS*IVn%C;bP31hwz>|X3m76+R7 zDN`Q0L6X-*H7DF%D3)E?HTVG-u-r4^H}~MT04#saNKCeSTTY7yYW_fTGq+M;6^-gG zaG4wm%tK;8D8}i0zpZ*}Etujwn17C|*M!e1Tg}D03mn|n?|T8$)&EpIMhV_~qc&;7 zQBlI(0@}$PDzF|_T$RWS^E=fHB)ePv?I!QPzjnO{7=8Q0&mdE^yo2guIt2iXoTnKf z)C^af#qM>mNj69pAZJ9S(gJ<1{uVh#l#Gs0TR!ysoc`}?_x8tb%=`y(Slri5g7N+e zr1}54Z&80xZre^^;6EcGXKdX2jm%~~;aDZ7WXt-U&48P9XjRF>jH)k0FdT<;C9hCi z*LjgYqYo}diVODWSw~1Mn!FPZ0J!Z}qWIh}1?%r5Y!n=(MHCy~rf0IQa`!~GkW~sBa;NJK8cOG?y-wOI0 zhmP8H6Rz$>$TLc?_u4n!m~gI_6m=ZjyU{ly?vGJMFII7`w_#xHKo0&&KiHPD_VvA_ z5-tT~TLwtye3I>CLGE&Unw|4J2Zm;Jl<@qV;S*LK$~s~4kqqJ8-Pc>`D`R9_y`nky zz17IDuLL+crGl_9tc|zL8}5b_lXSlvtZ&&VbwDh>b-{htdAaF+Tp0Yht7}d~kV0Lb zMj%x5hP6LN-kHS}p_#*^Cyou_oWW|hnaH_o=L6;h9%)YJ?D4*d+bNS^M9u&|)#(Sh zeN2$Obk8dZ>`=G!c`y9Ft>pdZ^ex4MW%MpC$pOko^!sK zE(hSXY4FY6i{)Mux}8{YG!tU<3_jua1^=0Oejae@n|p>l2S_0^dbGPF-j}-%K#fS;l$No