AzStackHciSoftware/AzStackHci.Software.Helpers.psm1

Import-LocalizedData -BindingVariable lswTxt -FileName AzStackHci.Software.Strings.psd1

function Test-OSVersion
{
    <#
    .SYNOPSIS
        Test OS Version is correct
    .DESCRIPTION
        Get OS Version from local machine to use as minimum OS version.
        Expecting data from PsSessions to include local machine indicating ECE.
    #>

    [CmdletBinding()]
    param (
        [Parameter()]
        [System.Management.Automation.Runspaces.PSSession[]]
        $PsSession,

        [Parameter()]
        [string]
        $MinimumVersion
    )
    try
    {
        # Get All OS versions
        $OsVersion = @()
        $OsVersion = GetOSVersion -PsSession $PsSession

        # Get OS Version from local machine to use as desired OS version
        # Expecting data from PsSessions to include local machine indicating ECE.
        $localOs = $OsVersion | Where-Object ComputerName -EQ $ENV:COMPUTERNAME
        if ($localOs)
        {
            # Check local machine for minimum OS
            $instanceResults = @()
            $params = @{
                Version = $localOs
            }
            if ($MinimumVersion)
            {
                $params += @{MinVersion = $MinimumVersion}
            }
            $instanceResults += TestOsMinimumVersion @params
            # Check other nodes for consistency against local node
            $localOsVersion = $localOs | Select-Object -ExpandProperty OSVersion

            foreach ($version in ($OsVersion | Where-Object ComputerName -NE $ENV:COMPUTERNAME))
            {
                $detail = $lswTxt.OSVersion -f $version.OSVersion, $localOsVersion
                if ($version.OSVersion -eq $localOsVersion)
                {
                    $status = 'SUCCESS'
                    Log-Info ("Checking {0}. {1}" -f $version.ComputerName, $detail)
                }
                else
                {
                    $status = 'FAILURE'
                    Log-Info ("Checking {0}. {1}" -f $version.ComputerName, $detail) -type Warning
                }

                $params = @{
                    Name               = 'AzStackHci_Software_OperatingSystem_Version'
                    Title              = 'Test Operating System Version'
                    DisplayName        = 'Test Operating System Version'
                    Severity           = 'CRITICAL'
                    Description        = 'Checking Operating System Version matches existing cluster'
                    Tags               = @{}
                    Remediation        = 'https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-install-os'
                    TargetResourceID   = $version.ComputerName
                    TargetResourceName = $version.ComputerName
                    TargetResourceType = 'OperatingSystem'
                    Timestamp          = [datetime]::UtcNow
                    Status             = $status
                    AdditionalData     = @{
                        Source    = $version.ComputerName
                        Resource  = 'OS Version'
                        Detail    = $detail
                        Status    = $status
                        TimeStamp = [datetime]::UtcNow
                    }
                    HealthCheckSource  = $ENV:EnvChkrId
                }
                $instanceResults += New-AzStackHciResultObject @params

                # Check for matching build
                if (([system.version]$localOsVersion).Build -eq ([system.version]$version.OSVersion).Build)
                {
                    $status = 'SUCCESS'
                    $detail = $lswTxt.OSBuild -f $version.ComputerName, ([system.version]$version.OSVersion).Build, ([system.version]$localOsVersion).Build
                    Log-Info $detail
                }
                else
                {
                    $status = 'FAILURE'
                    $detail = $lswTxt.OSBuild -f $version.ComputerName, ([system.version]$version.OSVersion).Build, ([system.version]$localOsVersion).Build
                    Log-Info $detail -Type CRITICAL
                }

                $params = @{
                    Name               = 'AzStackHci_Software_OperatingSystem_Build'
                    Title              = 'Test Operating System Build'
                    DisplayName        = 'Test Operating System Build'
                    Severity           = 'CRITICAL'
                    Description        = 'Checking Operating System Build matches existing cluster'
                    Tags               = @{}
                    Remediation        = 'https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-install-os'
                    TargetResourceID   = $version.ComputerName
                    TargetResourceName = $version.ComputerName
                    TargetResourceType = 'OperatingSystem'
                    Timestamp          = [datetime]::UtcNow
                    Status             = $status
                    AdditionalData     = @{
                        Source    = $version.ComputerName
                        Resource  = 'OS Build'
                        Detail    = $detail
                        Status    = $status
                        TimeStamp = [datetime]::UtcNow
                    }
                    HealthCheckSource  = $ENV:EnvChkrId
                }
                $instanceResults += New-AzStackHciResultObject @params
            }
            return $instanceResults
        }
        else
        {
            Log-Info $lswTxt.OSVersionSkip
        }
    }
    catch
    {
        throw $_
    }
}

function GetOSVersion
{
    <#
    .SYNOPSIS
        Get OS Version from local or remote
    #>


    [CmdletBinding()]
    param (
        [System.Management.Automation.Runspaces.PSSession[]]
        $PsSession
    )
    $sb = {
        $osVersion = (Get-CimInstance -ClassName Win32_OperatingSystem -Property Version).Version
        $ntoskrnl = (Get-Item -Path (Join-Path -Path ([System.Environment]::SystemDirectory) -ChildPath 'ntoskrnl.exe')).VersionInfo.ProductVersion
        return New-Object PSObject -Property @{
            ComputerName = $ENV:COMPUTERNAME
            OSVersion    = [System.Version]("{0}.{1}" -f $osVersion,($ntoskrnl -Split '\.')[-1])
        }
    }
    $osVersion = if ($PsSession)
    {
        Invoke-Command -Session $PsSession -ScriptBlock $sb
    }
    else
    {
        Invoke-Command -ScriptBlock $sb
    }
    return $osVersion
}

function TestOsMinimumVersion
{
    <#
    .SYNOPSIS
        A short one-line action-based description, e.g. 'Tests if a function is valid'
    #>


    [CmdletBinding()]
    param (
        [Parameter()]
        [psobject]
        $Version,

        [Parameter()]
        [system.version]
        $MinVersion = '10.0.19045'

    )
    try {
        if ($version.OSVersion -ge $MinVersion)
        {
            $Status = 'SUCCESS'
            $detail = $lswTxt.MinOSCheck -f $Version.ComputerName, $Version.OsVersion, $MinVersion
            Log-Info $detail -Type Info
        }
        else
        {
            $Status = 'FAILURE'
            $detail = $lswTxt.MinOSCheck -f $Version.ComputerName, $Version.OsVersion, $MinVersion
            Log-Info $detail -Type Warning
        }
        $params = @{
            Name               = 'AzStackHci_Software_OperatingSystem_Version'
            Title              = 'Test Operating System Minimum Version'
            DisplayName        = 'Test Operating System Minimum Version'
            Severity           = 'CRITICAL'
            Description        = 'Checking Operating System Version meets minimum version'
            Tags               = @{}
            Remediation        = 'https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-install-os'
            TargetResourceID   = $version.ComputerName
            TargetResourceName = $version.ComputerName
            TargetResourceType = 'OperatingSystem'
            Timestamp          = [datetime]::UtcNow
            Status             = $status
            AdditionalData     = @{
                Source    = $version.ComputerName
                Resource  = 'OS Version'
                Detail    = $detail
                Status    = $status
                TimeStamp = [datetime]::UtcNow
            }
            HealthCheckSource  = $ENV:EnvChkrId
        }
        $instanceResult = New-AzStackHciResultObject @params
        return $instanceResult
    }
    catch {
        throw $_
    }
}

function GetNTPServer
{
    <#
    .SYNOPSIS
        Get NTP server from local or remote
    #>


    [CmdletBinding()]
    param (
        [System.Management.Automation.Runspaces.PSSession[]]
        $PsSession
    )
    $sb = {
        $ntpSource = & w32tm.exe /query /source
        $ntpServer = ($ntpSource -split ',' | Select-Object -first 1).Trim()
        $retry = 0
        $maxRetry = 3
        do {
            $retry++
            if ($retry -gt 1) { Start-Sleep -Seconds 5 }
            $stripchart = & w32tm.exe /stripchart /computer:$ntpServer /dataonly /samples:1
        } while ($stripchart -match 'error' -and $retry -le $maxRetry)
        return New-Object PSObject -Property @{
            ComputerName = $ENV:COMPUTERNAME
            NtpServer    = $ntpServer
            Stripchart   = $stripchart
            Retries      = "$retry/$maxRetry"
        }
    }
    $ntpServer = if ($PsSession)
    {
        Invoke-Command -Session $PsSession -ScriptBlock $sb
    }
    else
    {
        Invoke-Command -ScriptBlock $sb
    }
    return $ntpServer
}

function Test-NtpServer
{
    <#
    .SYNOPSIS
        Test NTP Server is consistent across nodes and all nodes are in sync.
    #>

    [CmdletBinding()]
    param (
        [System.Management.Automation.Runspaces.PSSession[]]
        $PsSession
    )
    try {
        $ntpServerConfig = GetNTPServer -PsSession $PsSession
        $ntpStr = $ntpServerConfig | ForEach-Object { '{0}:{1}' -f $_.ComputerName, $_.ntpServer }
        $instanceResults = @()
        $AdditionalData = @()

        # localNtp should be read from local machine when running in ECE
        $localNtp = $ntpServerConfig | Where-Object ComputerName -EQ $ENV:COMPUTERNAME | Select-Object -ExpandProperty ntpServer

        # if it's not set to an external source return immediately with failure
        if ($localNtp -eq 'Local CMOS Clock')
        {
            $detail = $lswTxt.NTPServerNotSet -f $ENV:COMPUTERNAME, $localNtp
            Log-Info $detail -Type CRITICAL

            $params = @{
                Name               = 'AzStackHci_Software_NTP_Server'
                Title              = 'Test NTP server'
                DisplayName        = 'Test NTP server'
                Severity           = 'CRITICAL'
                Description        = 'Checking NTP server is configured with valid time source and synchronizing.'
                Tags               = @{}
                Remediation        = 'https://learn.microsoft.com/en-us/azure-stack/hci/deploy/deployment-install-os#configure-the-operating-system-using-sconfig'
                TargetResourceID   = $ENV:COMPUTERNAME
                TargetResourceName = $ENV:COMPUTERNAME
                TargetResourceType = 'OperatingSystem'
                Timestamp          = [datetime]::UtcNow
                Status             = 'FAILURE'
                AdditionalData     = @{
                    Source    = $ENV:COMPUTERNAME
                    Resource  = 'NTP Server'
                    Detail    = $detail
                    Status    = 'FAILURE'
                    TimeStamp = [datetime]::UtcNow
                }
                HealthCheckSource  = $ENV:EnvChkrId
            }
            $instanceResult = New-AzStackHciResultObject @params
            return $instanceResult
        }

        # if we found more than one node check for consistency
        if ($PsSession.Count -gt 1)
        {
            # if we found local ntp cfg, expect all nodes to be set to that.
            # if not, expect all nodes to be consistent with each other anyway.
            if ($localNtp)
            {
                Log-Info ("Checking all nodes are configured with NTP Server: {0}" -f $localNtp)
                foreach ($nodeNtp in $ntpServerConfig)
                {
                    $detail = $lswTxt.NTPServerCheck -f $nodeNtp.ComputerName, $nodeNtp.ntpServer, $localNtp
                    if ($nodeNtp.ntpServer -eq $localNtp)
                    {
                        $Status = 'SUCCESS'
                        Log-Info $detail -Type Info
                    }
                    else
                    {
                        $Status = 'FAILURE'
                        Log-Info $detail -Type Warning
                    }

                    $params = @{
                        Name               = 'AzStackHci_Software_NTP_Server_Consistency'
                        Title              = 'Test NTP server'
                        DisplayName        = "Test NTP server $($nodeNtp.ComputerName)"
                        Severity           = 'WARNING'
                        Description        = 'Checking NTP server is configured consistently.'
                        Tags               = @{}
                        Remediation        = 'https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings'
                        TargetResourceID   = $nodeNtp.ComputerName
                        TargetResourceName = $nodeNtp.ComputerName
                        TargetResourceType = 'OperatingSystem'
                        Timestamp          = [datetime]::UtcNow
                        Status             = $status
                        AdditionalData     = @{
                            Source    = $nodeNtp.ComputerName
                            Resource  = 'NTP Server'
                            Detail    = $detail
                            Status    = $status
                            TimeStamp = [datetime]::UtcNow
                        }
                        HealthCheckSource  = $ENV:EnvChkrId
                    }
                    $instanceResults += New-AzStackHciResultObject @params
                }
            }
            else
            {
                if (($ntpServerConfig.ntpServer | Sort-Object | Get-Unique).Count -eq 1)
                {
                    $Status = 'SUCCESS'
                    $detail = $lswTxt.NTPServerCheckPass -f ($ntpStr -join ', ')
                    Log-Info $detail -Type Info
                }
                else
                {
                    $Status = 'FAILURE'
                    $detail = $lswTxt.NTPServerCheckFail -f $ntpServerConfig.ntpServer
                    Log-Info $detail -Type Warning
                }

                $AdditionalData += New-Object -TypeName PSObject -Property @{
                    Source    = 'All Nodes'
                    Resource  = 'NTP Server'
                    Detail    = $detail
                    Status    = $status
                    TimeStamp = [datetime]::UtcNow
                }
            }

            $params = @{
                Name               = 'AzStackHci_Software_NTP_Server_Consistent'
                Title              = 'Test NTP server'
                DisplayName        = "Test NTP server $($nodeNtp.ComputerName)"
                Severity           = 'WARNING'
                Description        = 'Checking NTP server is configured consistently.'
                Tags               = @{}
                Remediation        = 'https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings'
                TargetResourceID   = $nodeNtp.ComputerName
                TargetResourceName = $nodeNtp.ComputerName
                TargetResourceType = 'OperatingSystem'
                Timestamp          = [datetime]::UtcNow
                Status             = $status
                AdditionalData     = @{
                    Source    = 'All Nodes'
                    Resource  = 'NTP Server'
                    Detail    = $detail
                    Status    = $status
                    TimeStamp = [datetime]::UtcNow
                }
                HealthCheckSource  = $ENV:EnvChkrId
            }
            $instanceResults += New-AzStackHciResultObject @params
            Clear-Variable -Name AdditionalData, instanceResult -ErrorAction SilentlyContinue
        }

        foreach ($ntpCfg in $ntpServerConfig)
        {
            $stripChart = $ntpCfg.Stripchart
            if ($stripchart.Count -ge 4 -and (($stripchart[3] -like '*, +*') -or ($stripchart[3] -like '*, -*'))) {
                $status = 'SUCCESS'
                $detail = $lswTxt.NtpStripChartPass -f $ntpCfg.ComputerName, $ntpCfg.NtpServer, $stripchart[3]
                Log-Info $detail
            }
            else {
                $status = 'FAILURE'
                $failureDetail = $stripchart | Select-String -Pattern 'error'
                $detail = $lswTxt.NtpStripChartFail -f $ntpCfg.ComputerName, $ntpCfg.NtpServer, $failureDetail
                Log-Info $detail -Type CRITICAL
                $stripchart | ForEach-Object { Log-Info $_ -Type Warning }
            }

            $params = @{
                Name               = 'AzStackHci_Software_NTP_Server_Sync'
                Title              = 'Test NTP server'
                DisplayName        = "Test NTP server $($ntpCfg.ComputerName)"
                Severity           = 'CRITICAL'
                Description        = 'Checking NTP server is synchronisation'
                Tags               = @{}
                Remediation        = 'https://learn.microsoft.com/en-us/windows-server/networking/windows-time-service/windows-time-service-tools-and-settings'
                TargetResourceID   = "$($nodeNtp.ComputerName)/$($NodeNtp.NtpServer)"
                TargetResourceName = "$($nodeNtp.ComputerName)/$($NodeNtp.NtpServer)"
                TargetResourceType = 'OperatingSystem'
                Timestamp          = [datetime]::UtcNow
                Status             = $status
                AdditionalData     = @{
                    Source    = $ntpCfg.ComputerName
                    Resource  = 'NTP Server Sync'
                    Detail    = $detail
                    Status    = $status
                    TimeStamp = [datetime]::UtcNow
                }
                HealthCheckSource  = $ENV:EnvChkrId
            }
            $instanceResults += New-AzStackHciResultObject @params
        }
        return $instanceResults
    }
    catch {
        throw $_
    }
}

function Test-LocalGroupEnumeration
{
    <#
    .SYNOPSIS
        Test Local Group Enumeration
    .DESCRIPTION
        Test Local Group Enumeration because it is required during Azure Stack HCI deployment.
    #>


    [CmdletBinding()]
    param (
        [Parameter()]
        [System.Management.Automation.Runspaces.PSSession[]]
        $PsSession
    )
    try
    {
        $instanceResults = @()
        $sb = {
            try {
                # Get-LocalGroupMember doesn't play nice with error stream, assigning to variable to get around this.
                $errorDetail = $null
                $localAdminGroup = Get-LocalGroupMember -SID S-1-5-32-544 -ErrorVariable errorDetail
            }
            catch {
                $localAdminGroup = $null
                if ([string]::IsNullOrEmpty($errorDetail))
                {
                    $errorDetail = $_.Exception.Message
                }
            }
            return New-Object PSObject -Property @{
                ComputerName = $ENV:COMPUTERNAME
                LocalAdminGroupTest  = [bool]$localAdminGroup
                errorDetail = $errorDetail
            }
        }
        $localGroupTests = if ($PsSession)
        {
            Invoke-Command -Session $PsSession -ScriptBlock $sb -ErrorAction SilentlyContinue
        }
        else
        {
            Invoke-Command -ScriptBlock $sb -ErrorAction SilentlyContinue
        }

        $localGroupTests | ForEach-Object {
            $localGroup = $_
            if ($localGroup.LocalAdminGroupTest)
            {
                $status = 'SUCCESS'
                $detail = $lswTxt.LocalGroupEnumerationSuccess -f $localGroup.ComputerName
                Log-Info $detail
            }
            else
            {
                $status = 'FAILURE'
                $detail = $lswTxt.LocalGroupEnumerationFailure -f $localGroup.ComputerName, $localGroup.errorDetail
                Log-Info $detail -Type CRITICAL
            }

            $params = @{
                Name               = 'AzStackHci_Software_LocalGroupEnumeration'
                Title              = 'Test Local Group Enumeration'
                DisplayName        = "Test Local Group Enumeration on $($localGroup.ComputerName)"
                Severity           = 'CRITICAL'
                Description        = 'Checking Local Group Enumeration'
                Tags               = @{}
                Remediation        = 'https://docs.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-install-os'
                TargetResourceID   = "$($localGroup.ComputerName)/Administrators"
                TargetResourceName = "$($localGroup.ComputerName)/Administrators"
                TargetResourceType = 'OperatingSystem'
                Timestamp          = [datetime]::UtcNow
                Status             = $status
                AdditionalData     = @{
                    Source    = $localGroup.ComputerName
                    Resource  = 'Local Group'
                    Detail    = $detail
                    Status    = $status
                    TimeStamp = [datetime]::UtcNow
                }
                HealthCheckSource  = $ENV:EnvChkrId
            }
            $instanceResults += New-AzStackHciResultObject @params
        }
        return $instanceResults
    }
    catch {
        throw $_
    }
}

function Test-IsNotPartofDomain
{
    <#
    .SYNOPSIS
        Test if the node is part of a domain
    .DESCRIPTION
        Test if the node is part of a domain
    #>


    [CmdletBinding()]
    param (
        [Parameter()]
        [System.Management.Automation.Runspaces.PSSession[]]
        $PsSession
    )
    try
    {
        $instanceResults = @()
        $sb = {
            $PartOfDomain = [bool](Get-WmiObject -Class Win32_ComputerSystem).PartOfDomain
            return New-Object PSObject -Property @{
                ComputerName = $ENV:COMPUTERNAME
                PartOfDomain = $PartOfDomain
            }
        }
        $domainTests = if ($PsSession)
        {
            Invoke-Command -Session $PsSession -ScriptBlock $sb
        }
        else
        {
            Invoke-Command -ScriptBlock $sb
        }

        foreach ($domainTest in $domainTests)
        {
            if ($domainTest.PartOfDomain)
            {
                $status = 'FAILURE'
                $detail = $lswTxt.IsNotPartofDomainFailure -f $domainTest.ComputerName
                Log-Info $detail -Type CRITICAL
            }
            else
            {
                $status = 'SUCCESS'
                $detail = $lswTxt.IsNotPartofDomainSuccess -f $domainTest.ComputerName
                Log-Info $detail
            }

            $params = @{
                Name               = 'AzStackHci_Software_IsNotPartofDomain'
                Title              = 'Test node is not part of a domain'
                DisplayName        = "Test node is not part of a domain on $($domainTest.ComputerName)"
                Severity           = 'CRITICAL'
                Description        = 'Checking if the node is not part of a domain'
                Tags               = @{}
                Remediation        = 'https://docs.microsoft.com/en-us/azure-stack/hci/deploy/deployment-tool-install-os'
                TargetResourceID   = $domainTest.ComputerName
                TargetResourceName = $domainTest.ComputerName
                TargetResourceType = 'OperatingSystem'
                Timestamp          = [datetime]::UtcNow
                Status             = $status
                AdditionalData     = @{
                    Source    = $domainTest.ComputerName
                    Resource  = 'Domain'
                    Detail    = $detail
                    Status    = $status
                    TimeStamp = [datetime]::UtcNow
                }
                HealthCheckSource  = $ENV:EnvChkrId
            }

            $instanceResults += New-AzStackHciResultObject @params
        }
        return $instanceResults
    }
    catch {
        throw $_
    }
}

Export-ModuleMember -Function Test-*
Export-ModuleMember -Function GetOSVersion
# SIG # Begin signature block
# MIIoPAYJKoZIhvcNAQcCoIIoLTCCKCkCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBSxqLES7VoXofW
# HuXuwQwc178/9i5NvA3Iky/AxB3VaaCCDYUwggYDMIID66ADAgECAhMzAAAEhJji
# EuB4ozFdAAAAAASEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjUwNjE5MTgyMTM1WhcNMjYwNjE3MTgyMTM1WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDtekqMKDnzfsyc1T1QpHfFtr+rkir8ldzLPKmMXbRDouVXAsvBfd6E82tPj4Yz
# aSluGDQoX3NpMKooKeVFjjNRq37yyT/h1QTLMB8dpmsZ/70UM+U/sYxvt1PWWxLj
# MNIXqzB8PjG6i7H2YFgk4YOhfGSekvnzW13dLAtfjD0wiwREPvCNlilRz7XoFde5
# KO01eFiWeteh48qUOqUaAkIznC4XB3sFd1LWUmupXHK05QfJSmnei9qZJBYTt8Zh
# ArGDh7nQn+Y1jOA3oBiCUJ4n1CMaWdDhrgdMuu026oWAbfC3prqkUn8LWp28H+2S
# LetNG5KQZZwvy3Zcn7+PQGl5AgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUBN/0b6Fh6nMdE4FAxYG9kWCpbYUw
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwNTM2MjAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# AGLQps1XU4RTcoDIDLP6QG3NnRE3p/WSMp61Cs8Z+JUv3xJWGtBzYmCINmHVFv6i
# 8pYF/e79FNK6P1oKjduxqHSicBdg8Mj0k8kDFA/0eU26bPBRQUIaiWrhsDOrXWdL
# m7Zmu516oQoUWcINs4jBfjDEVV4bmgQYfe+4/MUJwQJ9h6mfE+kcCP4HlP4ChIQB
# UHoSymakcTBvZw+Qst7sbdt5KnQKkSEN01CzPG1awClCI6zLKf/vKIwnqHw/+Wvc
# Ar7gwKlWNmLwTNi807r9rWsXQep1Q8YMkIuGmZ0a1qCd3GuOkSRznz2/0ojeZVYh
# ZyohCQi1Bs+xfRkv/fy0HfV3mNyO22dFUvHzBZgqE5FbGjmUnrSr1x8lCrK+s4A+
# bOGp2IejOphWoZEPGOco/HEznZ5Lk6w6W+E2Jy3PHoFE0Y8TtkSE4/80Y2lBJhLj
# 27d8ueJ8IdQhSpL/WzTjjnuYH7Dx5o9pWdIGSaFNYuSqOYxrVW7N4AEQVRDZeqDc
# fqPG3O6r5SNsxXbd71DCIQURtUKss53ON+vrlV0rjiKBIdwvMNLQ9zK0jy77owDy
# XXoYkQxakN2uFIBO1UNAvCYXjs4rw3SRmBX9qiZ5ENxcn/pLMkiyb68QdwHUXz+1
# fI6ea3/jjpNPz6Dlc/RMcXIWeMMkhup/XEbwu73U+uz/MIIHejCCBWKgAwIBAgIK
# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGg0wghoJAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAASEmOIS4HijMV0AAAAA
# BIQwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIBE5
# oH7zxFE2k3Ju1zL5GAvDnnYMG7WevkWfqBy/GBYsMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEAunszhn4pDGi0fshQnTlOR+b00jqnBLGdQVwl
# nk5kwOY9LNft5oxhM+lYWBynSZttRJ6tt9KUwoH59MNrVkEziICs3Tyus4x+Ct3u
# IDQgFqnvMBYHlH4FnqwPoLaLE2cF2z+fizuaoHiyjMuhKVnUukaeF9PdCVu22lyF
# SlIivKLM1WW6PQXrCNA52dUOQ3fk8a0reY1/289pgczDUoDycVnztu7ElqKrNCdg
# +CeZMJltUIi+9h6SOhqIcuk33YXgbR2thY+YzsxEwtAtqsmLadU0cbRBbaI6dNGs
# ons6gbWDDSKhqrQOcjDcBScUfZq6D/boBkBnJXcSe+DJsrvRVaGCF5cwgheTBgor
# BgEEAYI3AwMBMYIXgzCCF38GCSqGSIb3DQEHAqCCF3AwghdsAgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFSBgsqhkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCBGu48Seb0KUu98U+om9UOUYIuMCgGuQELK
# 0mDS/+fkbwIGaKOe9xb1GBMyMDI1MDkwOTE5MjIxMC4xNjRaMASAAgH0oIHRpIHO
# MIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL
# ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxk
# IFRTUyBFU046REMwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1l
# LVN0YW1wIFNlcnZpY2WgghHtMIIHIDCCBQigAwIBAgITMwAAAgO7HlwAOGx0ygAB
# AAACAzANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx
# MDAeFw0yNTAxMzAxOTQyNDZaFw0yNjA0MjIxOTQyNDZaMIHLMQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l
# cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0w
# NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Uw
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQChl0MH5wAnOx8Uh8RtidF0
# J0yaFDHJYHTpPvRR16X1KxGDYfT8PrcGjCLCiaOu3K1DmUIU4Rc5olndjappNuOg
# zwUoj43VbbJx5PFTY/a1Z80tpqVP0OoKJlUkfDPSBLFgXWj6VgayRCINtLsUasy0
# w5gysD7ILPZuiQjace5KxASjKf2MVX1qfEzYBbTGNEijSQCKwwyc0eavr4Fo3X/+
# sCuuAtkTWissU64k8rK60jsGRApiESdfuHr0yWAmc7jTOPNeGAx6KCL2ktpnGegL
# Dd1IlE6Bu6BSwAIFHr7zOwIlFqyQuCe0SQALCbJhsT9y9iy61RJAXsU0u0TC5YYm
# TSbEI7g10dYx8Uj+vh9InLoKYC5DpKb311bYVd0bytbzlfTRslRTJgotnfCAIGML
# qEqk9/2VRGu9klJi1j9nVfqyYHYrMPOBXcrQYW0jmKNjOL47CaEArNzhDBia1wXd
# JANKqMvJ8pQe2m8/cibyDM+1BVZquNAov9N4tJF4ACtjX0jjXNDUMtSZoVFQH+Fk
# WdfPWx1uBIkc97R+xRLuPjUypHZ5A3AALSke4TaRBvbvTBYyW2HenOT7nYLKTO4j
# w5Qq6cw3Z9zTKSPQ6D5lyiYpes5RR2MdMvJS4fCcPJFeaVOvuWFSQ/EGtVBShhmL
# B+5ewzFzdpf1UuJmuOQTTwIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFLIpWUB+EeeQ
# 29sWe0VdzxWQGJJ9MB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8G
# A1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv
# Y3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBs
# BggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy
# MDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH
# AwgwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4ICAQCQEMbesD6TC08R
# 0oYCdSC452AQrGf/O89GQ54CtgEsbxzwGDVUcmjXFcnaJSTNedBKVXkBgawRonP1
# LgxH4bzzVj2eWNmzGIwO1FlhldAPOHAzLBEHRoSZ4pddFtaQxoabU/N1vWyICiN6
# 0It85gnF5JD4MMXyd6pS8eADIi6TtjfgKPoumWa0BFQ/aEzjUrfPN1r7crK+qkmL
# ztw/ENS7zemfyx4kGRgwY1WBfFqm/nFlJDPQBicqeU3dOp9hj7WqD0Rc+/4VZ6wQ
# jesIyCkv5uhUNy2LhNDi2leYtAiIFpmjfNk4GngLvC2Tj9IrOMv20Srym5J/Fh7y
# WAiPeGs3yA3QapjZTtfr7NfzpBIJQ4xT/ic4WGWqhGlRlVBI5u6Ojw3ZxSZCLg3v
# RC4KYypkh8FdIWoKirjidEGlXsNOo+UP/YG5KhebiudTBxGecfJCuuUspIdRhStH
# AQsjv/dAqWBLlhorq2OCaP+wFhE3WPgnnx5pflvlujocPgsN24++ddHrl3O1FFab
# W8m0UkDHSKCh8QTwTkYOwu99iExBVWlbYZRz2qOIBjL/ozEhtCB0auKhfTLLeuNG
# BUaBz+oZZ+X9UAECoMhkETjb6YfNaI1T7vVAaiuhBoV/JCOQT+RYZrgykyPpzpmw
# MNFBD1vdW/29q9nkTWoEhcEOO0L9NzCCB3EwggVZoAMCAQICEzMAAAAVxedrngKb
# SZkAAAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmlj
# YXRlIEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIy
# NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXI
# yjVX9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjo
# YH1qUoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1y
# aa8dq6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v
# 3byNpOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pG
# ve2krnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viS
# kR4dPf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYr
# bqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlM
# jgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSL
# W6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AF
# emzFER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIu
# rQIDAQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIE
# FgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWn
# G1M1GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEW
# M2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5
# Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBi
# AEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV
# 9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js
# Lm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAx
# MC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2
# LTIzLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv
# 6lwUtj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZn
# OlNN3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1
# bSNU5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4
# rPf5KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU
# 6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDF
# NLB62FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/
# HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdU
# CbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKi
# excdFYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTm
# dHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZq
# ELQdVTNYs6FwZvKhggNQMIICOAIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJp
# Y2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOkRDMDAtMDVF
# MC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMK
# AQEwBwYFKw4DAhoDFQDNrxRX/iz6ss1lBCXG8P1LFxD0e6CBgzCBgKR+MHwxCzAJ
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv
# c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA7GpzkzAi
# GA8yMDI1MDkwOTA5MzYxOVoYDzIwMjUwOTEwMDkzNjE5WjB3MD0GCisGAQQBhFkK
# BAExLzAtMAoCBQDsanOTAgEAMAoCAQACAghwAgH/MAcCAQACAhMuMAoCBQDsa8UT
# AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSCh
# CjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEBAAgbPJ/jW1EfLym916w4t046
# yfryh1iT2gbCJwsGTWuikKq28o0SaNxTI2oAx6TVk3AIh8LVv28f/FLK59s3XcaD
# TQ4noUuCw14IyMKphESmqTPnDmvdE9hKp5sSfg1MVqjszKSOk7yXlSPFAmGk+3II
# 8Nr240FYHciFd6mmfBEHEaCc+Iuwbt9cmu5shXxGMMCcVx4obp3j2sGKIFeZTv9j
# fA78JM3yi64adcy6J6Ipon3vl43K4QhR0X22/lUQ0DLJPm/fr7l+tdkIKy40tddE
# DyUK7F1Woy4NDrsUVMb3c0TyTevw/HSCOtgkbQUzZs9Zb/mNB2NGssZdpeXUja8x
# ggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAA
# AgO7HlwAOGx0ygABAAACAzANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkD
# MQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCCx3/JZ2LlS6QbqrbZB+BhC
# wiXPP4Kme/yEIAK1/VHQcTCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIEsD
# 3RtxlvaTxFOZZnpQw0DksPmVduo5SyK9h9w++hMtMIGYMIGApH4wfDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0
# IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAIDux5cADhsdMoAAQAAAgMwIgQg8GY8
# zU2h36E3hxvNxOlwWtNGiyAuSczWaq514LSLruIwDQYJKoZIhvcNAQELBQAEggIA
# CuI6e4SPuM9+3wqzIyE6V924dYEJebL7FJ+nmDCLFluQGcr6Od8Nfiy/k92SLaOB
# i0uTrnilUIv09hm9VSvKUNt43VlR/aeZNSSmdHQiCZrg3NJA2h3Sb0P8KlKUDgIe
# pvtp8r2TqIT5FpnX58vdmNSblbQYcivGKppkZOjHKAfYy/pihbpLfktIWOfgMNsi
# pjQCnquBl61TGtz/YFgJVRG2h53Ghabo3AGMOExudSnu80jGpvZyZVKQegXpxbMU
# fsNIyRI77prPi2gSDAptpak+sdZI/oI7vLhnyBZma0z8Gil9BtCUPXf+mldz+uuh
# 1x7qoxUfAsUEdWiPK1kiVL8ZaGVmZrzC9BBkisB8Kcs+wtf05j9wXol6hOVvqIQd
# dtWGoPhPdETJsRzXmUsfaLkW+X8MXot+UKQ+Uia3bc1rPK/mMZo9DcdQ3L2YERp3
# sthKRFCnOzSnDhpg6QbzhL7f/ZKcoKwDJjYddagDMMMH+6HVC6rdahmirYdGbJn3
# baly31jTdCxTof90QLoxeVeH9zOAA3nt4vyf2u6YZ/gK3+916oId9YFm1VBLH59t
# Ayh8LIMeXDrvGw2NULy0+92YFZIJuAh0HYLdM63h7CWhBJph3hOBMxu7Zi6CcRnC
# tWI6v5HxsGFKk8Grjw5uwHiPHMOFPVTp5YTlj6r3tXo=
# SIG # End signature block