packages/AzStackHci.DiagnosticSettings.0.6.9/Private/AzStackHci.Network.Helpers.ps1

# ////////////////////////////////////////////////////////////////////////////
# Strict Mode v1 (PS 5.1 safe) - surfaces reads of uninitialised variables at runtime.
Set-StrictMode -Version 1.0

# Test if proxy is enabled and return boolean
function Get-Proxy
{
    <#
    .SYNOPSIS
        Check if proxy is enabled and return boolean and proxy server uri
    #>


    begin {
        # Write-Debug "Get-Proxy: Beginning proxy detection process"
    }

    process {
        $line1, $line2, $line3, $JsonLines = netsh winhttp show advproxy
        $ProxyInformation = $JsonLines | ConvertFrom-Json -ErrorAction SilentlyContinue
        # Return True/False and the Proxy server uri as a PSObject
        $ProxyReturnVariable = New-Object PsObject -Property @{
            # True/False
            Enabled = [bool]$ProxyInformation.Proxy
            # Proxy server URI
            Server = $ProxyInformation.Proxy
            # Arc Gateway scenario can carry distinct HTTP and HTTPS proxies in a single
            # 'http=customerproxy:8080;https=localhost:40343' string. These are parsed out
            # below (null when a single, un-prefixed proxy is configured — Server holds it).
            HttpProxy = $null
            HttpsProxy = $null
            # Proxy bypass configuration (v0.6.8). Two independent sources are captured so the
            # RFC1918 / Private-Link classification can VERIFY whether a private-endpoint FQDN is
            # correctly excluded from the forward proxy (rather than merely advising it):
            # ProxyBypass - the WinHTTP 'Bypass List' (comma-separated, '*' wildcard). Read from
            # the TEXT `netsh winhttp show proxy` output below; the advproxy JSON
            # parsed above does not expose the bypass entries.
            # NoProxyEnv - the machine NO_PROXY environment variable (comma-separated; entries
            # may be CIDR ranges, '.'-prefixed domain suffixes, hostnames or IPs).
            # Since Azure Local 2506 this is configured automatically at Arc
            # registration, so it is the authoritative bypass fallback.
            ProxyBypass = @()
            NoProxyEnv  = @()
        }
        # Initialised here so the later `if($ProxyStrings)` read is safe under Set-StrictMode v1.0
        # even when the proxy server string contains no ';' (no semicolon -> never assigned below).
        $ProxyStrings = $null

        # ------------------------------------------------------------------------
        # Capture the WinHTTP 'Bypass List' (v0.6.8) from the human-readable
        # `netsh winhttp show proxy` output. It prints a 'Bypass List : a,b,c' line
        # when a static WinHTTP proxy is configured. Best-effort: never throws.
        try {
            $winHttpProxyText = netsh winhttp show proxy 2>$null
            if ($winHttpProxyText) {
                $bypassLine = $winHttpProxyText | Where-Object { $_ -match '(?i)Bypass\s*List' } | Select-Object -First 1
                if ($bypassLine) {
                    $bypassRaw = ($bypassLine -split ':', 2)[1]
                    if (-not [string]::IsNullOrWhiteSpace($bypassRaw)) {
                        $ProxyReturnVariable.ProxyBypass = @(
                            $bypassRaw -split ',' |
                                ForEach-Object { $_.Trim() } |
                                Where-Object { $_ -and $_ -ne '(none)' }
                        )
                    }
                }
            }
        } catch {
            Write-Debug "Get-Proxy: failed to read WinHTTP bypass list: $($_.Exception.Message)"
        }

        # Capture the NO_PROXY environment variable (machine scope first, then the
        # current process scope as a fallback). Best-effort: never throws.
        try {
            $noProxyRaw = [Environment]::GetEnvironmentVariable('NO_PROXY', 'Machine')
            if ([string]::IsNullOrWhiteSpace($noProxyRaw)) {
                $noProxyRaw = $env:NO_PROXY
            }
            if (-not [string]::IsNullOrWhiteSpace($noProxyRaw)) {
                $ProxyReturnVariable.NoProxyEnv = @(
                    $noProxyRaw -split ',' |
                        ForEach-Object { $_.Trim() } |
                        Where-Object { $_ }
                )
            }
        } catch {
            Write-Debug "Get-Proxy: failed to read NO_PROXY environment variable: $($_.Exception.Message)"
        }

        # Check if the Proxy is enabled and if the proxy server is set
        if($ProxyReturnVariable.Enabled) {
            if(-not($ProxyReturnVariable.Server)){
                # In case the proxy server is not set from netsh winhttp show advproxy output
                $proxyUri = [Uri]$null
                $ProxyTest = [System.Net.WebRequest]::GetSystemWebProxy()
                $ProxyTest.Credentials = [System.Net.CredentialCache]::DefaultCredentials
                # use a known URL to test the proxy server, but http, in case of Arc Gateway, to prevent "localhost" from being returned
                # This is a known URL that should be accessible from any network
                $TestUrl = [System.Uri]::new("http://oneocsp.microsoft.com")
                # Test the proxy server using a known URL
                $proxyUri = $ProxyTest.GetProxy($TestUrl)
                if($proxyUri -eq $TestUrl) {
                    # Proxy is not required, so do not use it
                    $ProxyReturnVariable.Enabled = $false
                    Write-HostAzS "`t`nNo proxy server detected, using direct connection...`n" -ForegroundColor Green
                } else {
                    # Proxy is required, so use it
                    $ProxyReturnVariable.Server = $proxyUri
                }
            }
            # Check if the proxy server string has a semi-colon which can be used for Arc Gateway
            if(-not [string]::IsNullOrWhiteSpace($ProxyReturnVariable.Server) -and $ProxyReturnVariable.Server -match ";"){
                # In case the proxy server is set from netsh winhttp show advproxy output
                [array]$ProxyStrings = $ProxyReturnVariable.Server.ToString().Split(";")
            }
            if($ProxyStrings){
                # Check if the proxy server string has a semi-colon which can be used for Arc Gateway
                # Multiple proxy servers detected
                Write-HostAzS "`n`tArc Gateway scenario detected (possible), as multiple proxy servers detected ('netsh winhttp show advproxy')..."
                ForEach($ProxyServer in $ProxyStrings){
                    # Trim the proxy server string
                    $ProxyServer = $ProxyServer.Trim()
                    if($ProxyServer -like "http=*"){
                        # HTTP proxy server (should be customer proxy server)
                        # Check if the proxy server is set from netsh winhttp show advproxy output
                        $ProxyReturnVariable.HttpProxy = $ProxyServer.Substring(5)
                        Write-HostAzS "`tHTTP Proxy server detected, using proxy: $($ProxyServer)" -ForegroundColor Green    
                    } elseif($ProxyServer -like "https=*"){
                        # HTTPS proxy server (might be Arc Gateway Agent, "localhost")
                        # Check if the proxy server is set from netsh winhttp show advproxy output
                        $ProxyReturnVariable.HttpsProxy = $ProxyServer.Substring(6)
                        Write-HostAzS "`tHTTPS Proxy server detected, using proxy: $($ProxyServer)" -ForegroundColor Green    
                    } else {
                        # Other proxy server detected
                        # Check if the proxy server is set from netsh winhttp show advproxy output
                        Write-HostAzS "`tProxy server detected, using proxy: $($ProxyServer)" -ForegroundColor Green    
                    }
                } # End ForEach
                Write-HostAzS ""
            } else {
                # Single proxy detected
                # A single proxy can still carry an 'http=' / 'https=' prefix (no semicolon);
                # parse it so HttpProxy / HttpsProxy are populated for consumers in that case too.
                $singleProxy = $ProxyReturnVariable.Server.ToString().Trim()
                if($singleProxy -like "http=*"){
                    $ProxyReturnVariable.HttpProxy = $singleProxy.Substring(5)
                } elseif($singleProxy -like "https=*"){
                    $ProxyReturnVariable.HttpsProxy = $singleProxy.Substring(6)
                }
                Write-HostAzS "`t`nProxy server detected, using proxy: $($ProxyReturnVariable.Server)`n" -ForegroundColor Green
            }

        } else {
            # Proxy is NOT enabled
            # No proxy server detected, so use direct connection
            Write-HostAzS "`t`nNo proxy server detected, using direct connection...`n" -ForegroundColor Green
        }

    } # End of process block

    end {
        # Write-Debug "Get-Proxy: Proxy detection process completed"

        # Return the ProxyReturnVariable object
        Return $ProxyReturnVariable
    }
} # End Function Get-Proxy


# ////////////////////////////////////////////////////////////////////////////
# Determine whether an IPv4 address falls inside a CIDR range (v0.6.8).
# IPv4-only — the Azure Local NO_PROXY bypass CIDRs (10.0.0.0/8, 172.16.0.0/12,
# 192.168.0.0/16, infra subnets) are all IPv4. Best-effort: never throws.
function Test-IpInCidr
{
    <#
    .SYNOPSIS
        Return $true if the given IPv4 address is contained within the given CIDR range.
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)][string]$IpAddress,
        [Parameter(Mandatory = $true)][string]$Cidr
    )
    try {
        $parts = $Cidr -split '/'
        if ($parts.Count -ne 2) { return $false }
        $network = [System.Net.IPAddress]::Parse($parts[0].Trim())
        $prefix  = [int]$parts[1].Trim()
        if ($prefix -lt 0 -or $prefix -gt 32) { return $false }
        $ip = [System.Net.IPAddress]::Parse($IpAddress.Trim())
        $ipBytes  = $ip.GetAddressBytes()
        $netBytes = $network.GetAddressBytes()
        # IPv4 only (4 bytes). Reverse for little-endian BitConverter on both.
        if ($ipBytes.Length -ne 4 -or $netBytes.Length -ne 4) { return $false }
        [array]::Reverse($ipBytes)
        [array]::Reverse($netBytes)
        $ipInt  = [uint64][System.BitConverter]::ToUInt32($ipBytes, 0)
        $netInt = [uint64][System.BitConverter]::ToUInt32($netBytes, 0)
        # /0 matches everything. Otherwise compare only the top $prefix (network) bits by
        # right-shifting away the (32 - prefix) host bits on both operands. Using -shr avoids
        # the unreliable uint64 -shl mask construction in Windows PowerShell.
        if ($prefix -eq 0) { return $true }
        $hostBits = 32 - $prefix
        return (($ipInt -shr $hostBits) -eq ($netInt -shr $hostBits))
    } catch {
        return $false
    }
} # End Function Test-IpInCidr


# ////////////////////////////////////////////////////////////////////////////
# Verify whether an endpoint (FQDN + its resolved IP) is excluded from the forward
# proxy via either the WinHTTP bypass list or the NO_PROXY environment variable (v0.6.8).
#
# Private-endpoint traffic (RFC1918 addresses) MUST bypass the proxy and route over
# ExpressRoute / Site-to-Site VPN. This helper turns the module's previous *advisory*
# ("ensure this FQDN is on the bypass list") into a *verified* check, honouring the two
# different bypass syntaxes documented for Azure Local:
# * WinHTTP / WinInet : '*' wildcard (e.g. '*.blob.core.windows.net', '192.168.1.*')
# * NO_PROXY env var : '.'-prefix / bare-suffix domains and CIDR ranges
# (e.g. '.contoso.com', '10.0.0.0/8')
# Matching is case-insensitive. Returns a result object; never throws.
function Test-EndpointBypassed
{
    <#
    .SYNOPSIS
        Return a result object indicating whether an FQDN/IP is on a proxy bypass source.
    .OUTPUTS
        [pscustomobject] @{ Bypassed = [bool]; Source = 'WinHTTP'|'NO_PROXY'|''; MatchedRule = [string] }
    #>

    [CmdletBinding()]
    param(
        [Parameter(Mandatory = $true)][string]$Fqdn,
        [Parameter()][string]$IpAddress,
        [Parameter()][string[]]$WinHttpBypass = @(),
        [Parameter()][string[]]$NoProxyEnv = @()
    )

    $result = [pscustomobject]@{ Bypassed = $false; Source = ''; MatchedRule = '' }
    if ([string]::IsNullOrWhiteSpace($Fqdn)) { return $result }
    $normalizedFqdn = $Fqdn.Trim().ToLower().TrimEnd('.')

    # --- WinHTTP / WinInet bypass entries ('*' wildcard) ---
    foreach ($entry in $WinHttpBypass) {
        if ([string]::IsNullOrWhiteSpace($entry)) { continue }
        $e = $entry.Trim().ToLower()
        # Escape everything, then turn the escaped '*' back into '.*' for a full-string match.
        $pattern = '^' + ([regex]::Escape($e) -replace '\\\*', '.*') + '$'
        if ($normalizedFqdn -match $pattern) {
            $result.Bypassed = $true; $result.Source = 'WinHTTP'; $result.MatchedRule = $entry
            return $result
        }
        if ($IpAddress -and ($IpAddress -match $pattern)) {
            $result.Bypassed = $true; $result.Source = 'WinHTTP'; $result.MatchedRule = $entry
            return $result
        }
    }

    # --- NO_PROXY env entries ('.'-prefix / bare suffix + CIDR) ---
    foreach ($entry in $NoProxyEnv) {
        if ([string]::IsNullOrWhiteSpace($entry)) { continue }
        $e = $entry.Trim().ToLower()
        if ($e -match '^\d{1,3}(\.\d{1,3}){3}/\d{1,2}$') {
            # CIDR range — match against the resolved IP (NO_PROXY uses CIDR, not wildcards).
            if ($IpAddress -and (Test-IpInCidr -IpAddress $IpAddress -Cidr $e)) {
                $result.Bypassed = $true; $result.Source = 'NO_PROXY'; $result.MatchedRule = $entry
                return $result
            }
            continue
        }
        # A leading '.' means "this domain and any subdomain"; a bare domain is treated the
        # same way (suffix match) plus an exact-host match.
        $suffix = $e.TrimStart('.')
        if ($normalizedFqdn -eq $suffix -or $normalizedFqdn.EndsWith('.' + $suffix)) {
            $result.Bypassed = $true; $result.Source = 'NO_PROXY'; $result.MatchedRule = $entry
            return $result
        }
        if ($IpAddress -and ($IpAddress -eq $e)) {
            $result.Bypassed = $true; $result.Source = 'NO_PROXY'; $result.MatchedRule = $entry
            return $result
        }
    }

    return $result
} # End Function Test-EndpointBypassed


# ////////////////////////////////////////////////////////////////////////////
# This function retrieves the SSL certificate chain from a remote HTTPS endpoint
# It uses the System.Net.Http.HttpClient class to make the request and capture the certificate chain.
#
# Renamed from Get-SslCertificateChain in v0.6.6 to avoid a name collision with the
# AzStackHci.EnvironmentChecker module (10.2509+), which exports a function with the
# same name but a different parameter set. Because Get-AzStackHciEnvironmentCheckerModule
# Import-Module's that module from inside our module's session state, EnvironmentChecker's
# exported Get-SslCertificateChain shadowed our private helper, breaking certificate-detail
# capture for every HTTPS endpoint with: "A parameter cannot be found that matches
# parameter name 'AllowAutoRedirect'". Renaming the private helper resolves the conflict
# permanently.
function Get-AzSHciSslCertificateChain
{
    <#
    .SYNOPSIS
        Retrieve remote ssl certificate & chain from https endpoint for Desktop and Core
    .NOTES
        Credit: https://github.com/markekraus
    #>

    [CmdletBinding()]
    param (
        [system.uri]
        $url,

        [Parameter()]
        [bool]
        $AllowAutoRedirect,

        [Parameter()]
        [string]
        $Proxy
    )

    begin {
        # Write-Debug "Get-AzSHciSslCertificateChain: Beginning SSL certificate chain retrieval for '$url'"
    }

    process {
    try
    {
        $cs = @'
    using System;
    using System.Collections.Generic;
    using System.Net.Http;
    using System.Net.Security;
    using System.Security.Cryptography.X509Certificates;
 
    namespace CertificateCapture
    {
        public class Utility
        {
            public static Func<HttpRequestMessage,X509Certificate2,X509Chain,SslPolicyErrors,Boolean> ValidationCallback =
                (message, cert, chain, errors) => {
                    CapturedCertificates.Clear();
                    var newCert = new X509Certificate2(cert);
                    var newChain = new X509Chain();
                    newChain.Build(newCert);
                    CapturedCertificates.Add(new CapturedCertificate(){
                        Certificate = newCert,
                        CertificateChain = newChain,
                        PolicyErrors = errors,
                        URI = message.RequestUri
                    });
                    return true;
                };
            public static List<CapturedCertificate> CapturedCertificates = new List<CapturedCertificate>();
        }
 
        public class CapturedCertificate
        {
            public X509Certificate2 Certificate { get; set; }
            public X509Chain CertificateChain { get; set; }
            public SslPolicyErrors PolicyErrors { get; set; }
            public Uri URI { get; set; }
        }
    }
'@


        try
        {
            if (-not ('CertificateCapture.Utility' -as [type]))
            {
                if ($PSEdition -ne 'Core')
                {
                    Add-Type -AssemblyName System.Net.Http
                    Add-Type $cs -ReferencedAssemblies System.Net.Http
                }
                else
                {
                    Add-Type $cs
                }
            }
        }
        catch
        {
            if ($_.Exception.Message -notmatch 'Definition of new types is not supported in this language mode')
            {
                throw "Language mode does not allow this test Error: $_"
            }
        }

        # Reset resources so exceptional setup paths remain safe in the finally block.
        $Certs = $null
        $Handler = $null
        $Client = $null
        $Request = $null

        # Create a new list to hold captured certificates.
        $Certs = [CertificateCapture.Utility]::CapturedCertificates
        # Clear any previously captured certificates.
        $Certs.Clear()
        # Create the HttpClientHandler.
        $Handler = [System.Net.Http.HttpClientHandler]::new()
        # This is important to capture the certificate chain of the first endpoint, not redirected endpoints.
        if($AllowAutoRedirect -eq $false)
        {
            # Set the handler to not allow auto redirects
            # https://learn.microsoft.com/en-us/dotnet/api/system.net.http.httpclienthandler.allowautoredirect
            $Handler.AllowAutoRedirect = $false
        }
        if ($Proxy)
        {
            $Handler.Proxy = New-Object System.Net.WebProxy($proxy)
        }
        # Set the ServerCertificateCustomValidationCallback to our custom callback.
        $Handler.ServerCertificateCustomValidationCallback = [CertificateCapture.Utility]::ValidationCallback
        # Create the HttpClient with the handler
        $Client = [System.Net.Http.HttpClient]::new($Handler)
        # Set a timeout to 15 seconds (reduced from 60s to limit impact of unresponsive backend pool servers):
        $Client.Timeout = [timespan]::FromTicks($script:CERT_CAPTURE_TIMEOUT_TICKS)
        try {
            # Setup the request to the URL.
            $Request = $Client.GetAsync($url)
            # Wait for the request to complete calling the Result method.
            $Null = $Request.Result
            # Check if the request is completed and that certificates were captured.
            if(($Request.IsCompleted) -and $Certs){
                # Return the captured certificate chain
                Write-Debug "Successfully obtained SSL certificate chain from endpoint: '$url'"
                return $Certs.CertificateChain
            } else {
                # Return null if no certificates were captured.
                Write-Debug "Failed to obtain SSL certificate chain from endpoint: '$url'"
                return $null
            }
        }
        finally {
            # Dispose IDisposable resources to prevent socket/handle leaks
            if ($Request) { $Request.Dispose() }
            if ($Client)  { $Client.Dispose() }
            if ($Handler) { $Handler.Dispose() }
        }

    }
    catch
    {
        throw $_
    }
    } # End of process block

    end {
        # Write-Debug "Get-AzSHciSslCertificateChain: SSL certificate chain retrieval completed"
    }
} # End Function Get-AzSHciSslCertificateChain

# SIG # Begin signature block
# MIInNwYJKoZIhvcNAQcCoIInKDCCJyQCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBwKL0TS5XcAu2N
# e6qmTuppom+MNTCj18VVThMtujL2XqCCDMkwggYEMIID7KADAgECAhMzAAACHPrN
# xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD
# b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1
# OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD
# VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB
# DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP
# oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC
# /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf
# rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j
# qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT
# xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B
# Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O
# BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT
# DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw
# YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy
# bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z
# b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl
# MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC
# AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN
# rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK
# 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK
# Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY
# BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu
# uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE
# msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz
# 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6
# U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO
# 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD
# 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC
# EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS
# b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX
# DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ
# Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq
# lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo
# 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv
# QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a
# 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1
# FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO
# GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7
# ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ
# uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS
# CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm
# VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3
# SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E
# BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX
# LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB
# Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP
# oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv
# TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw
# TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv
# TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC
# AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D
# 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY
# nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI
# vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6
# aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w
# PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7
# RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK
# /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK
# YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw
# YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT
# Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghnEMIIZwAIBATBu
# MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc
# +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCggZAwGQYJKoZIhvcNAQkDMQwG
# CisGAQQBgjcCAQQwLwYJKoZIhvcNAQkEMSIEIMN0xT1ITxjMpJqj05BmXrvQxDFP
# gP13EMzF6lEpxn8LMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBv
# AGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAE
# ggEAKSOsz+IC8MJHBJLdIK6VdnjsnmAXoVIseYFcewflPbuE+0WpCo1bxlHVTYvp
# IRU01dDkYa/2I82e2iyk9Hk4ej6CdFbWmpal5adng9qyPaoIi3502dV8rZT48la8
# t4elyO9HdUYRNk/GuviyT2DgDrYovUPr4prXxupmt8Sz02+bh77QIAd8GdEvadEs
# 7lSQbJN+sVm/wJ45veqNbIMYbMCK+Y6O1o7GqNeocOmT9C+Re8/Y2zHkgS4HJleL
# PEMoAEbBy/3qJU3+KtGFTMiOVoJuqkdmzFLAYcxGWB+CVV77X/9CsRo8LnSGS3gB
# QOkNKHvupz0kPDklC55fDQ0niqGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCCF3wG
# CSqGSIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsqhkiG
# 9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQC
# AQUABCBhhxLDE/ZHmYLYo5VsCuaBE7g7Sr2yucahen3dVSaluAIGaoV1PXoMGBMy
# MDI2MDkwMjE1MjcyMi4yODNaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJVUzET
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmlj
# YSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046RjAwMi0wNUUw
# LUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghHq
# MIIHIDCCBQigAwIBAgITMwAAAiAk4ebgF7m0jgABAAACIDANBgkqhkiG9w0BAQsF
# ADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yNjAyMTkxOTM5NTJa
# Fw0yNzA1MTcxOTM5NTJaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScw
# JQYDVQQLEx5uU2hpZWxkIFRTUyBFU046RjAwMi0wNUUwLUQ5NDcxJTAjBgNVBAMT
# HE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQDRYY7yr7ijW6CR178uKveIMufutWOicxgJwKOce/2GOQce
# us6ZWfX14i3jNg3JOP7MGJMkOAucwWBwiA8URp+ZYkGjpVoVkGZsV27WjqLwpf2A
# wqBsJ/TzqwE7JFFaxup3Ldxj8GjdJymDFRrdVN/pYHoBFrjD1IkIDu8b1CWn8tgo
# miKRSY+STvJq99mVkdphMBIUGOegQny8qRd24VME0xi8Oomks9Zq9EjDeKHGpvAb
# XUEQ6m3cROoEPhTE/miweQH9TqJt3IOsqPv3L8urojB747XBC2y0CDIHlKLcLl3Z
# G8D7JXKnWTFen3msMPJpcvrQ3zUBVJrH/mI3RxHmCh9ppDP0uG1+PJwk6H/x+sfo
# G9hW64xoXkpx6DEfNZNfcXdKbXF28XEXdLNnzo3SLNVymeQJhNqOSKhnU84QnKmr
# jEk541JiurlDCkCWO9lUBUMb9x0nyfXUbNRPVLgP+PTMRdXOowJdYCzCQfN2ZqL0
# s4YI28F1Dbn7Bgw2E4P1E9unsvMzJHtzhS2Th3TpCfBbOGalIlF9x/DJZ/ssm/yy
# zT9YtIFeqmfNxBPTE3aOuh6HxmTICzfYAATvWNhBbo19QwsjPeA9JvhqTLC2KUNg
# rXroGy4eDZo0n7jFYjZkUih1Ty+8E6qEvV2Na6Z5gUyD5a+tHGDmq69CmUiHfwID
# AQABo4IBSTCCAUUwHQYDVR0OBBYEFNvInOCIhxGA8mY7l1g07UHvyNgzMB8GA1Ud
# IwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0
# dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRp
# bWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYI
# KwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMv
# TWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1Ud
# EwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeA
# MA0GCSqGSIb3DQEBCwUAA4ICAQCtKGBto1BSvm4WFI+J0NSyVhU1LHL7F3fbjZ2d
# 7F5Kn/FCTBZXpzrDVl63FLRNcIFpnJy4/nlg43r7T5sJPdo4Ms8ADSHQEJnHSu3x
# 9UpjCzREBPi9+nHhvDgRx/1WmBD6gQUZJLOhcN2TxW4KJyhinMtiBFtkNRZ2vmZ1
# MAdNXTm5d0Lwk3wzj+/f7VCCTWCXJSoqNa3VU/6sACHI97Evbnzg8bd3hxrfz6Cc
# CVuf77egvRHinthJuwSRePP7aVmcevb1nWUIAICdBebHQOrzNIeWBIQwvcFaS3SF
# c+49rqrwQOMFDR4FYBzS7b0QeBVxFuLL2iVu4KAHMNUhLLSD4iKLDFBNTOtTzTlh
# GvMgG77A1cjeQrDMHa6oReMDeUDqHUrxv8g7IRdIh+h0gDLkzN0xIuzli0Bv7Jty
# bGJbV6JxaDF4CzSCIMRpK59nI6iKo4LgnbQBZJW7+6akYsKG/pXPlfxNv2InpD10
# tSCkCvw9kr6W1+NRN+EuZczRgAwWlcK9XJZ3uu/v/oxHtO7/kmVIs51F9qV6Y2QN
# Xd6tU46YPrK98m2QDys+lvLNimK0e1xZ7Z1GawKohKGvlLALWDlZQqgHfJ31CB0L
# lIDI7iLyYTpd2iyKjqskbQiyMtICH+RmH/oCg7JOK0ZA3XIMba9aSWgBF3QZ6pG3
# EGeQqjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcN
# AQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
# VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAw
# BgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEw
# MB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk
# 4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9c
# T8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWG
# UNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6Gnsz
# rYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2
# LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLV
# wIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTd
# EonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0
# gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFph
# AXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJ
# YfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXb
# GjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJ
# KwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnP
# EP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMw
# UQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9z
# b2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggr
# BgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYw
# DwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoY
# xDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtp
# L2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYB
# BQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0B
# AQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U5
# 18JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgAD
# sAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo
# 32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZ
# iefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZK
# PmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RI
# LLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgk
# ujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9
# af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzba
# ukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/
# OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNNMIIC
# NQIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUG
# A1UECxMeblNoaWVsZCBUU1MgRVNOOkYwMDItMDVFMC1EOTQ3MSUwIwYDVQQDExxN
# aWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQCTGA9v
# psJ6glqCLmI0rggGx4YEEqCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
# QSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA7kJmZzAiGA8yMDI2MDkwMjA5MDk1OVoY
# DzIwMjYwOTAzMDkwOTU5WjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDuQmZnAgEA
# MAcCAQACAgQxMAcCAQACAhPGMAoCBQDuQ7fnAgEAMDYGCisGAQQBhFkKBAIxKDAm
# MAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcN
# AQELBQADggEBABQPcDoiqkVyB9wuznd+cmT4l2AKBm+eHYPXOfv4r3oFtV/5vn+E
# eZlwbPnotQNWVbYRSdHzJ3RzQSNFHFPIwhcUWNwpVYw8F8/gTJJmQU1DNhXK8GlX
# hx/nBOs+bGYnvNYlERS6VsNvsWnyagU0A6j5a9B66aVA4w6LrX94WU9JgO93dEDE
# lkpVgqVRwDVu017/7LAwRs2GdhpFcpkIVdxq74cuHYyBOxWTRtqKvfcGNJyAVG60
# KOLLL5t1PHqFWjiYrR90Q2PxoysT+7LgeeegSipThiIApu4rroOPIgwTycV5z3M3
# Dh8wyySf60KdfbdheM2k6JoSvFk0na5vms4xggQNMIIECQIBATCBkzB8MQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAiAk4ebgF7m0jgABAAACIDANBglg
# hkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqG
# SIb3DQEJBDEiBCBK1rxt5avm+YNHuBiVY6IxKUl21TDdPIKZxlEe4LTk7TCB+gYL
# KoZIhvcNAQkQAi8xgeowgecwgeQwgb0EION7vyOlPA1VqlEp0QIVGlNd8S5YWBnK
# j97LuTWHSO2vMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAC
# EzMAAAIgJOHm4Be5tI4AAQAAAiAwIgQgrQhkh2lFJv1eoHRIkoQl2tB11lRXWwkK
# XKytg4eXg0YwDQYJKoZIhvcNAQELBQAEggIAe+iRkJ9f9FqhIOLD7+T+AoZ1CfX2
# xi/Ru8HE3lgRm2F7WqLH/JeR9Ex3KecADLE75Q2TBG4E3kjrqedPf/vg9Vv6Nub5
# Lu9FrlUiPZY/AZWmQABtMzNdQYaNmBg/1lBqnzmSZ/Vhxc8PSj+W+9hKFYkgXpDw
# THaVhl4s/WESesgnqRoX1NNja0TcOMIDxUsGr4WlgwbhpWPcH74JWEjIuuAAo8y0
# adCdmc/0UX8RihAfeHLutJX2NY2XL/RFS0o5mi09qChATDcfRKkw+0J4CHKUJWUJ
# x3igSfvh0Vunudm2cbEQI5eVEZyxjAk6hDuMdqtJWi0j1EDCc4xmkXsCfFUQJAfy
# TEYGfwhHg8e1WP4QE7mx5wAt158floATFkV0YmWfTLW8br9/XfsIE6uyScwF4EnY
# LkUBroti8iQQrQBWszLSXNNZcpVmqEXn4yORES+OKSDBQn6nGIpqRddRtdXTjMBn
# baOeRYwyl0gk+9Vp+TCT9b4mu5621Q1Kdm2q11mkMkanyL0hMJgTC2dBEfXBpZT3
# eXD+pppe5k6owgohDlj3tPMzQkiqevP0DuD6U641NuYtnDIQyIqWLo812wGQ+5/Z
# UKnDx0UP71KMzF2SBR5/pqFzi043vgozfQWhznOpEV0kIRYBWVi2JpaYRWz8nqQk
# lXpNMP/VzX56L0s=
# SIG # End signature block