function Initialize-Log($log)
{	
    if ($log -ne $null)
    {        
        $Global:GlobalLogFile = $log
        if(!(Test-Path $Global:GlobalLogFile))
        {
            New-Item -Path $Global:GlobalLogFile -ItemType File -Force | Out-Null
        }
    }    	
}


function Write-Log($message)
{    
    $log = $Global:GlobalLogFile
    if (![System.String]::IsNullOrWhiteSpace($log)) { Add-content "$log" ("`n[{0}]: {1}`n" -f (Get-Date), $message) }
}

function Write-Exception($Exception)
{
    Write-Log "$($Exception.Exception) : $($Exception.InvocationInfo.PositionMessage)"
}

function ExecuteWith-Retry($codeBlock, $blockMessage, $maxRetry, $sleepTime)
{    
    Write-Log "$blockMessage`: Starting execution with retry"
    if ($maxRetry -eq $null -or $maxRetry -le 0)
    {
        $maxRetry = 5
    }

    if ($sleepTime -eq $null -or $sleepTime -lt 0)
    {
        $sleepTime = 30
    }

    $retry = 0
    for($retry = 0; $retry -lt $maxRetry; $retry++)
    {
        try
        {
            &$codeBlock
            break;
        }
        catch
        {
            $exception = $_
            $message = "Exception during $blockMessage`: "
            if($retry -lt $maxRetry-1)
            {
                Write-Log $message
                Write-Exception $exception                
                Write-Log "Sleeping 30s before retrying"
                Sleep $sleepTime
            }
            else
            {
                $message = "Max retry count reached during $blockMessage`: "
                Write-Log $message
                Write-Exception $exception
                throw $exception
            }
        }
    }
    $retry++
    Write-Log "$blockMessage`: Completed execution in $retry iterations"
}

function Decode-Settings($config)
{
    $settings = @{}
    if ($config -ne $null)
    {
        $decodedConfig = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($config))
        $settings = ConvertFrom-Json $decodedConfig
    }

    return $settings
}

function Construct-PrivateAosInstanceUrl($PublicUrl)
{
    $publicUrlSegments = $PublicUrl.Split('.')
    $publicUrlSegments[0] += "private"
    $privateUrl = $publicUrlSegments -join "."
    return $privateUrl
}

function Restart-IIS
{
    Write-Log "Restarting IIS"

    $restartScriptBlock = {
        # To get the equivalent behavior of IISRESET, 
        # the WAS service will be restarted with the -Force switch.
        Restart-Service -Name WAS -Force
    
        # Handle edge-case where W3SVC was not
        # in a running state when WAS was restarted.
        $iisService = Get-Service W3SVC
        if ($iisService.Status -eq 'Stopped')
        {
            Start-Service W3SVC
        }
    }

    Write-Log "Starting job that will restart IIS"
    $job = Start-Job -ScriptBlock $restartScriptBlock -Name "Restart IIS service job"

    Write-Log "Waiting for the job to finish (15 min timeout)"
    $startTime = [DateTime]::UtcNow
    while (([DateTime]::UtcNow - $startTime).TotalMinutes -lt 15)
    {
        Receive-Job -job $job
        if (Wait-Job -Job $job -Timeout 1)
        {
            # Job is done; 
            # break out of the while loop.
            break
        }
    }

    # Log any errors that have accumulated.
    Receive-Job -Job $job
    if ($job.JobStateInfo.State -eq 'Failed')
    {
        $job.ChildJobs | %{$_.Error} | %{Write-Log $_}
    }

    # If the job is still running, 
    # the "force" switch will stop it.
    Remove-Job $job -Force

    # Validate that the job completed without any errors.
    Write-Log "$($job.Name): $($job.JobStateInfo.State)"
    if ($job.JobStateInfo.State -ne 'Completed')
    {
        Write-Log "$($job.Name) is not in a 'Completed' state."
        throw "Job to restart IIS services did not complete."
    }

    # Validate the status of W3SVC service.
    $iisService = Get-Service W3SVC
    Write-Log "- service W3SVC status: $($iisService.Status)";
    if ($iisService.Status -ne "Running")
    {
        throw "Failed to restart IIS service."
    }

    # Validate the status of first-level services that W3SVC depends on.
    # Note: this includes the WAS service.
    $dependsOnServiceNotRunning = $false
    foreach($dependsOnService in $iisService.ServicesDependedOn)
    {
        Write-Log "- service $($dependsOnService.Name) status: $($dependsOnService.Status)";
        if ($dependsOnService.Status -ne "Running")
        {
            $dependsOnServiceNotRunning = $true
        }
    }
    if ($dependsOnServiceNotRunning)
    {
        throw "Failed to restart one or more services that IIS depends on."
    }
}

function SqlTableExists($TableName, $Server, $Database, $Login, $Password)
{
    $TableExistsQuery = "if exists(select * from INFORMATION_SCHEMA.TABLES where table_name = '$TableName' and table_schema = 'dbo') select 1 as result else select 0 as result"
    $connectionString = "Server='{0}';Database='{1}';Trusted_Connection=false;UID='{2}';Pwd='{3}';" -f $Server,$Database,$Login,$Password
    $connection = new-object system.data.SqlClient.SQLConnection($connectionString)
    $command = new-object system.data.sqlclient.sqlcommand($TableExistsQuery,$connection)
    $command.CommandTimeout = 15    
    $connection.Open()
    $queryResult = $command.ExecuteScalar()

    $result = $false   
    if ($queryResult -eq 0)
    {      
        $result = $false        
    }
    else
    {
        $result = $true
    }

    $connection.Close()

    return $result
}

function StopAndDisableService($ServiceName)
{
    if (Get-Service $ServiceName -ErrorAction "SilentlyContinue")
    {
        $timeout = new-timespan -Minutes 5
        $serviceProcessStarting = $true;
        $sw = [diagnostics.stopwatch]::StartNew()
        while ($sw.elapsed -lt $timeout -and $serviceProcessStarting)
        {
            if ((Get-Service $ServiceName | where status -ne 'Running' ) -and (Get-Service $ServiceName | where status -ne 'Stopped' ))
            {
                start-sleep -seconds 60 
            }
            else
            {
                $serviceProcessStarting = $false;
            }
        }
        if($serviceProcessStarting)
        {
            throw "Unable to execute the $ServiceName shutdown script because the  process is not in a state where operation can be performed."
        }

        Set-Service $ServiceName -startupType Disabled
        Stop-Service $ServiceName
        Write-Output "$ServiceName stopped."
    }
}

function Get-FileVersion([string] $filePath)
{
    [string] $value = "";

    if ($filePath -ne $null -and [System.IO.File]::Exists($filePath))
    {
        $fileInfo = Get-ChildItem -File $filePath

        if ($fileInfo -ne $null)
        { 
            $value = [string]::Format("{0}.{1}.{2}.{3}", $fileInfo.VersionInfo.FileMajorPart, $fileInfo.VersionInfo.FileMinorPart, $fileInfo.VersionInfo.FileBuildPart, $fileInfo.VersionInfo.FilePrivatePart);
        }
    }

    return $value;
}

# SIG # Begin signature block
# MIIr9gYJKoZIhvcNAQcCoIIr5zCCK+MCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBEBjwgo7UC28MR
# g8E78RGYJzEMtQSslaPPob5FEynw2qCCEX0wggiNMIIHdaADAgECAhM2AAACAR26
# 8SCNUOBoAAIAAAIBMA0GCSqGSIb3DQEBCwUAMEExEzARBgoJkiaJk/IsZAEZFgNH
# QkwxEzARBgoJkiaJk/IsZAEZFgNBTUUxFTATBgNVBAMTDEFNRSBDUyBDQSAwMTAe
# Fw0yNDExMDgxMjQ0MTRaFw0yNTExMDgxMjQ0MTRaMCQxIjAgBgNVBAMTGU1pY3Jv
# c29mdCBBenVyZSBDb2RlIFNpZ24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK
# AoIBAQC5EbpMULKgL3ArJn1rQqUye5Mzq2Eqlu0Ov9Vv2X+MvePQtXj4Cr7dLpJO
# VjPrUvirL6Jn8gYuDRxhVZbj3s81AfC8wq0sC/928aXCleSUDwX4scwK7vbpur2+
# TJm0WZ0E1gk8VY1bAjG9G3sQ2A+bpcMaBu7soLLH0ofyYzf6cl9irH3iHAw1ZucU
# mpROzEZcn3cmcxNwS0P2MX1nPE3qJEPoa3odBFZd5RXfDo7ro62MeNVjR/4bPjic
# IcnT/G0wWEXwKwTOkxFHibmmbhgfWAxDh75LZMYeLSeGkXhhBgQ/7Y11swZdaK3l
# okxcrV7d6jus7is+p6o8nep1OGGrAgMBAAGjggWZMIIFlTApBgkrBgEEAYI3FQoE
# HDAaMAwGCisGAQQBgjdbAQEwCgYIKwYBBQUHAwMwPQYJKwYBBAGCNxUHBDAwLgYm
# KwYBBAGCNxUIhpDjDYTVtHiE8Ys+hZvdFs6dEoFgg93NZoaUjDICAWQCAQ4wggJ2
# BggrBgEFBQcBAQSCAmgwggJkMGIGCCsGAQUFBzAChlZodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpaW5mcmEvQ2VydHMvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDEu
# YW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUy
# MDAxKDIpLmNydDBSBggrBgEFBQcwAoZGaHR0cDovL2NybDIuYW1lLmdibC9haWEv
# QlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBS
# BggrBgEFBQcwAoZGaHR0cDovL2NybDMuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAx
# LkFNRS5HQkxfQU1FJTIwQ1MlMjBDQSUyMDAxKDIpLmNydDBSBggrBgEFBQcwAoZG
# aHR0cDovL2NybDQuYW1lLmdibC9haWEvQlkyUEtJQ1NDQTAxLkFNRS5HQkxfQU1F
# JTIwQ1MlMjBDQSUyMDAxKDIpLmNydDCBrQYIKwYBBQUHMAKGgaBsZGFwOi8vL0NO
# PUFNRSUyMENTJTIwQ0ElMjAwMSxDTj1BSUEsQ049UHVibGljJTIwS2V5JTIwU2Vy
# dmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1BTUUsREM9R0JM
# P2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0aWZpY2F0aW9uQXV0
# aG9yaXR5MB0GA1UdDgQWBBSOzWIbg/0woPHoJiGbNef2gihnJDAOBgNVHQ8BAf8E
# BAMCB4AwVAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5k
# IE9wZXJhdGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjM2MTY3KzUwMzE2NTCCAeYG
# A1UdHwSCAd0wggHZMIIB1aCCAdGgggHNhj9odHRwOi8vY3JsLm1pY3Jvc29mdC5j
# b20vcGtpaW5mcmEvQ1JML0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0dHA6
# Ly9jcmwxLmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyGMWh0
# dHA6Ly9jcmwyLmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5jcmyG
# MWh0dHA6Ly9jcmwzLmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgyKS5j
# cmyGMWh0dHA6Ly9jcmw0LmFtZS5nYmwvY3JsL0FNRSUyMENTJTIwQ0ElMjAwMSgy
# KS5jcmyGgb1sZGFwOi8vL0NOPUFNRSUyMENTJTIwQ0ElMjAwMSgyKSxDTj1CWTJQ
# S0lDU0NBMDEsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNlcnZpY2VzLENOPVNl
# cnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9QU1FLERDPUdCTD9jZXJ0aWZpY2F0
# ZVJldm9jYXRpb25MaXN0P2Jhc2U/b2JqZWN0Q2xhc3M9Y1JMRGlzdHJpYnV0aW9u
# UG9pbnQwHwYDVR0jBBgwFoAUllGE4Gtve/7YBqvD8oXmKa5q+dQwHwYDVR0lBBgw
# FgYKKwYBBAGCN1sBAQYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggEBABAaRi/Y
# mQnOw4MrZVaGuauVsykbusUmfa8tbfFNYfqqGhlJhBp8cWnpJnc39N3MDq22orPd
# dbidV8+YPxQ8FyhqFIkGKlV2WoD9kQV5LH+1RapE1nrHrGWH+vFdCcIy/X81ARIZ
# 2q3VHjNXQzMg+6vAJNMQRZIjk5pE/3YQvCNUOABt9gYFd8GEnTMeBaJaQibKB0o+
# 8tPKWRpse5J4/O4/Yj3dwI5YYmNPUFerhszwU6IXH/k3EwvgbFVCYCgtl6vckET8
# 36Ph/bJEA1uKmsFhtTAj8xE2USF9OHKFietrYEmA3aP0eIkyjRmZGRcla5P9fS62
# o2/gYAp0+NCn7C0wggjoMIIG0KADAgECAhMfAAAAUeqP9pxzDKg7AAAAAABRMA0G
# CSqGSIb3DQEBCwUAMDwxEzARBgoJkiaJk/IsZAEZFgNHQkwxEzARBgoJkiaJk/Is
# ZAEZFgNBTUUxEDAOBgNVBAMTB2FtZXJvb3QwHhcNMjEwNTIxMTg0NDE0WhcNMjYw
# NTIxMTg1NDE0WjBBMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQB
# GRYDQU1FMRUwEwYDVQQDEwxBTUUgQ1MgQ0EgMDEwggEiMA0GCSqGSIb3DQEBAQUA
# A4IBDwAwggEKAoIBAQDJmlIJfQGejVbXKpcyFPoFSUllalrinfEV6JMc7i+bZDoL
# 9rNHnHDGfJgeuRIYO1LY/1f4oMTrhXbSaYRCS5vGc8145WcTZG908bGDCWr4GFLc
# 411WxA+Pv2rteAcz0eHMH36qTQ8L0o3XOb2n+x7KJFLokXV1s6pF/WlSXsUBXGaC
# IIWBXyEchv+sM9eKDsUOLdLTITHYJQNWkiryMSEbxqdQUTVZjEz6eLRLkofDAo8p
# XirIYOgM770CYOiZrcKHK7lYOVblx22pdNawY8Te6a2dfoCaWV1QUuazg5VHiC4p
# /6fksgEILptOKhx9c+iapiNhMrHsAYx9pUtppeaFAgMBAAGjggTcMIIE2DASBgkr
# BgEEAYI3FQEEBQIDAgACMCMGCSsGAQQBgjcVAgQWBBQSaCRCIUfL1Gu+Mc8gpMAL
# I38/RzAdBgNVHQ4EFgQUllGE4Gtve/7YBqvD8oXmKa5q+dQwggEEBgNVHSUEgfww
# gfkGBysGAQUCAwUGCCsGAQUFBwMBBggrBgEFBQcDAgYKKwYBBAGCNxQCAQYJKwYB
# BAGCNxUGBgorBgEEAYI3CgMMBgkrBgEEAYI3FQYGCCsGAQUFBwMJBggrBgEFBQgC
# AgYKKwYBBAGCN0ABAQYLKwYBBAGCNwoDBAEGCisGAQQBgjcKAwQGCSsGAQQBgjcV
# BQYKKwYBBAGCNxQCAgYKKwYBBAGCNxQCAwYIKwYBBQUHAwMGCisGAQQBgjdbAQEG
# CisGAQQBgjdbAgEGCisGAQQBgjdbAwEGCisGAQQBgjdbBQEGCisGAQQBgjdbBAEG
# CisGAQQBgjdbBAIwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQD
# AgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHwYDVR0jBBgwFoAUKV5RXmSuNLnrrJwN
# p4x1AdEJCygwggFoBgNVHR8EggFfMIIBWzCCAVegggFToIIBT4YxaHR0cDovL2Ny
# bC5taWNyb3NvZnQuY29tL3BraWluZnJhL2NybC9hbWVyb290LmNybIYjaHR0cDov
# L2NybDIuYW1lLmdibC9jcmwvYW1lcm9vdC5jcmyGI2h0dHA6Ly9jcmwzLmFtZS5n
# YmwvY3JsL2FtZXJvb3QuY3JshiNodHRwOi8vY3JsMS5hbWUuZ2JsL2NybC9hbWVy
# b290LmNybIaBqmxkYXA6Ly8vQ049YW1lcm9vdCxDTj1BTUVSb290LENOPUNEUCxD
# Tj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1
# cmF0aW9uLERDPUFNRSxEQz1HQkw/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9i
# YXNlP29iamVjdENsYXNzPWNSTERpc3RyaWJ1dGlvblBvaW50MIIBqwYIKwYBBQUH
# AQEEggGdMIIBmTBHBggrBgEFBQcwAoY7aHR0cDovL2NybC5taWNyb3NvZnQuY29t
# L3BraWluZnJhL2NlcnRzL0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYIKwYBBQUHMAKG
# K2h0dHA6Ly9jcmwyLmFtZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9vdC5jcnQwNwYI
# KwYBBQUHMAKGK2h0dHA6Ly9jcmwzLmFtZS5nYmwvYWlhL0FNRVJvb3RfYW1lcm9v
# dC5jcnQwNwYIKwYBBQUHMAKGK2h0dHA6Ly9jcmwxLmFtZS5nYmwvYWlhL0FNRVJv
# b3RfYW1lcm9vdC5jcnQwgaIGCCsGAQUFBzAChoGVbGRhcDovLy9DTj1hbWVyb290
# LENOPUFJQSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxD
# Tj1Db25maWd1cmF0aW9uLERDPUFNRSxEQz1HQkw/Y0FDZXJ0aWZpY2F0ZT9iYXNl
# P29iamVjdENsYXNzPWNlcnRpZmljYXRpb25BdXRob3JpdHkwDQYJKoZIhvcNAQEL
# BQADggIBAFAQI7dPD+jfXtGt3vJp2pyzA/HUu8hjKaRpM3opya5G3ocprRd7vdTH
# b8BDfRN+AD0YEmeDB5HKQoG6xHPI5TXuIi5sm/LeADbV3C2q0HQOygS/VT+m1W7a
# /752hMIn+L4ZuyxVeSBpfwf7oQ4YSZPh6+ngZvBHgfBaVz4O9/wcfw91QDZnTgK9
# zAh9yRKKls2bziPEnxeOZMVNaxyV0v152PY2xjqIafIkUjK6vY9LtVFjJXenVUAm
# n3WCPWNFC1YTIIHw/mD2cTfPy7QA1pT+GPARAKt0bKtq9aCd/Ym0b5tPbpgCiRtz
# yb7fbNS1dE740re0COE67YV2wbeo2sXixzvLftH8L7s9xv9wV+G22qyKt6lmKLjF
# K1yMw4Ni5fMabcgmzRvSjAcbqgp3tk4a8emaaH0rz8MuuIP+yrxtREPXSqL/C5bz
# MzsikuDW9xH10graZzSmPjilzpRfRdu20/9UQmC7eVPZ4j1WNa1oqPHfzET3ChIz
# J6Q9G3NPCB+7KwX0OQmKyv7IDimj8U/GlsHD1z+EF/fYMf8YXG15LamaOAohsw/y
# wO6SYSreVW+5Y0mzJutnBC9Cm9ozj1+/4kqksrlhZgR/CSxhFH3BTweH8gP2FEIS
# RtShDZbuYymynY1un+RyfiK9+iVTLdD1h/SxyxDpZMtimb4CgJQlMYIZzzCCGcsC
# AQEwWDBBMRMwEQYKCZImiZPyLGQBGRYDR0JMMRMwEQYKCZImiZPyLGQBGRYDQU1F
# MRUwEwYDVQQDEwxBTUUgQ1MgQ0EgMDECEzYAAAIBHbrxII1Q4GgAAgAAAgEwDQYJ
# YIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYB
# BAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIKL4mqjAXkKo
# pAjK6aCyHs8altRQBoNiMDNp+acJA0xBMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBN
# AGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJ
# KoZIhvcNAQEBBQAEggEAJ3R3rZM8ax7tezuaUJafpLtAZu0IXGgVmNgeONEtuMBj
# ruKISYJU2pJnx5cchSg01yLIRxkNrbZMYVKCQDkAcFe0tCLPx5RC7NlA6u/p45G2
# mYfMytqZ/aRQRh/tLGQVveWH4ukzFJ8hn8DqM6yuNDz/JvbyZL8VoLCre2Xhbav9
# JA/uPiQaj5hiSJ2BrFoEn3oH1aXsUBi2Hrn/uEmn8xxBPN345EMsO+L+cOSmbt5j
# TZ8DzmEsZLRFbgG74cG/o36Ibe49DZR0oD6EkvzOQLVn9zc+0V4zpD72wmdYKx8I
# wb7aWX381jI0bRyTC81WuEkcz/GJgcpnk98IguY8mKGCF5cwgheTBgorBgEEAYI3
# AwMBMYIXgzCCF38GCSqGSIb3DQEHAqCCF3AwghdsAgEDMQ8wDQYJYIZIAWUDBAIB
# BQAwggFSBgsqhkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAx
# MA0GCWCGSAFlAwQCAQUABCB9p4TCq+sNMpFYAUSzB9BK04GsjKYSMyUvFr00ExP5
# wgIGaBpnHQQZGBMyMDI1MDUwOTExMjE0NC4xMzNaMASAAgH0oIHRpIHOMIHLMQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNy
# b3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBF
# U046MzcwMy0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1w
# IFNlcnZpY2WgghHtMIIHIDCCBQigAwIBAgITMwAAAgpHshTZ7rKzDwABAAACCjAN
# BgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0y
# NTAxMzAxOTQyNTdaFw0yNjA0MjIxOTQyNTdaMIHLMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP
# cGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046MzcwMy0wNUUwLUQ5
# NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G
# CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCy7NzwEpb7BpwAk9LJ00Xq30TcTjcw
# NZ80TxAtAbhSaJ2kwnJA1Au/Do9/fEBjAHv6Mmtt3fmPDeIJnQ7VBeIq8Rcfjcjr
# bPIg3wA5v5MQflPNSBNOvcXRP+fZnAy0ELDzfnJHnCkZNsQUZ7GF7LxULTKOYY2Y
# Jw4TrmcHohkY6DjCZyxhqmGQwwdbjoPWRbYu/ozFem/yfJPyjVBql1068bcVh58A
# 8c5CD6TWN/L3u+Ny+7O8+Dver6qBT44Ey7pfPZMZ1Hi7yvCLv5LGzSB6o2OD5GIZ
# y7z4kh8UYHdzjn9Wx+QZ2233SJQKtZhpI7uHf3oMTg0zanQfz7mgudefmGBrQEg1
# ox3n+3Tizh0D9zVmNQP9sFjsPQtNGZ9ID9H8A+kFInx4mrSxA2SyGMOQcxlGM30k
# tIKM3iqCuFEU9CHVMpN94/1fl4T6PonJ+/oWJqFlatYuMKv2Z8uiprnFcAxCpOsD
# IVBO9K1vHeAMiQQUlcE9CD536I1YLnmO2qHagPPmXhdOGrHUnCUtop21elukHh75
# q/5zH+OnNekp5udpjQNZCviYAZdHsLnkU0NfUAr6r1UqDcSq1yf5RiwimB8Sjsdm
# Hll4gPjmqVi0/rmnM1oAEQm3PyWcTQQibYLiuKN7Y4io5bJTVwm+vRRbpJ5UL/D3
# 3C//7qnHbeoWBQIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFAKvF0EEj4AyPfY8W/qr
# sAvftZwkMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY
# MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p
# Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF
# BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo
# MSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYD
# VR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4ICAQCwk3PW0CyjOaqXCMOusTde
# 7ep2CwP/xV1J3o9KAiKSdq8a2UR5RCHYhnJseemweMUH2kNefpnAh2Bn8H2opDzt
# DJkj8OYRd/KQysE12NwaY3KOwAW8Rg8OdXv5fUZIsOWgprkCQM0VoFHdXYExkJN3
# EzBbUCUw3yb4gAFPK56T+6cPpI8MJLJCQXHNMgti2QZhX9KkfRAffFYMFcpsbI+o
# ziC5Brrk3361cJFHhgEJR0J42nqZTGSgUpDGHSZARGqNcAV5h+OQDLeF2p3URx/P
# 6McUg1nJ2gMPYBsD+bwd9B0c/XIZ9Mt3ujlELPpkijjCdSZxhzu2M3SZWJr57uY+
# FC+LspvIOH1Opofanh3JGDosNcAEu9yUMWKsEBMngD6VWQSQYZ6X9F80zCoeZwTq
# 0i9AujnYzzx5W2fEgZejRu6K1GCASmztNlYJlACjqafWRofTqkJhV/J2v97X3ruD
# vfpuOuQoUtVAwXrDsG2NOBuvVso5KdW54hBSsz/4+ORB4qLnq4/GNtajUHorKRKH
# GOgFo8DKaXG+UNANwhGNxHbILSa59PxExMgCjBRP3828yGKsquSEzzLNWnz5af9Z
# meH4809fwIttI41JkuiY9X6hmMmLYv8OY34vvOK+zyxkS+9BULVAP6gt+yaHaBlr
# ln8Gi4/dBr2y6Srr/56g0DCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAA
# ABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1
# dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDEL
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWlj
# cm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/
# bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNE
# t6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2
# Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOOR
# j7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnop
# N6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0g
# z3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/
# BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8Qmgu
# EOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFd
# XzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y
# 7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQAB
# o4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS
# /mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1Gely
# MFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAT
# BgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+ii
# XGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0y
# My5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1p
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNy
# dDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5O
# R2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6
# th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhT
# dSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnD
# vBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvf
# SaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+
# CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5a
# GZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+
# fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmN
# cP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGe
# Pu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNY
# s6FwZvKhggNQMIICOAIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3Bl
# cmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjM3MDMtMDVFMC1EOTQ3
# MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYF
# Kw4DAhoDFQDRAMVJlA6bKq93Vnu3UkJgm5HlYaCBgzCBgKR+MHwxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBU
# aW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA68gxIzAiGA8yMDI1
# MDUwOTA3NDUzOVoYDzIwMjUwNTEwMDc0NTM5WjB3MD0GCisGAQQBhFkKBAExLzAt
# MAoCBQDryDEjAgEAMAoCAQACAgkMAgH/MAcCAQACAhK6MAoCBQDryYKjAgEAMDYG
# CisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEA
# AgMBhqAwDQYJKoZIhvcNAQELBQADggEBAGzUcDm0CYJys9uxk5FStYK/84yV6/PV
# A26ndvmwbtO1WWGeOO19/Fh0G7NbeYRK/0evNNqPlWeqaKGZI3hCNV39ojyx75aw
# IDjYxLHdhSv6YCQM+UH5wqLz4gjAtJ+0BO5foU6bx9NNB0+/Qco1WDAZWD1kVICv
# g5EMoNCNL9BC9EXSPR0iwJ2D6AjA45g/27qSBP16Gt831PRmRTUlN3GejK5U6KL5
# bnXGpnfLBxtG8KEIk7+LcNKOw5ilXKaRoYRlaB6VwCA5r68G0nPapR3I9KjyMTUb
# MgluApmwsKN8XJjAStn6pSflAWgRRWPyM/Pdagv5EYH0vdnBlveNkpUxggQNMIIE
# CQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw
# JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAgpHshTZ
# 7rKzDwABAAACCjANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqG
# SIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCBd0+65YtES+YIVGjk9rjspWL9f7sOb
# F/S/wYik3PWiHTCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIE2ay/y0epK/
# X3Z03KTcloqE8u9IXRtdO7Mex0hw9+SaMIGYMIGApH4wfDELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgUENBIDIwMTACEzMAAAIKR7IU2e6ysw8AAQAAAgowIgQgyVJ0hE47Fc+C
# 7fe4hR/om+BIvpq+vooimaqWB3qiheQwDQYJKoZIhvcNAQELBQAEggIAgTpk2CBw
# bSLbEj4QS026SVHln/HQfpucuy/Sj0zGfhWYLOk8gW8Xc6srXN67hIxRrrDFSQxd
# En/M7HU5J2wAPRtOnFOjKnx7G6DtISMvpxe0hboAiYEydxiUAxTSRoXW59gJhhpt
# t06u9VvSg+PO3d3w2Lky65sbtd3vBG6va89FBwj6Oe37jbL/+p5w0sUcplgKQNH4
# UcIfj1AISMMAch7T9yOPZFqhkoavMg2rrVId5BqY8v4xCaBwLLgUcFddCX0NLe4z
# aOSYixo4hxzmzINIFETySEsLtuY0Gw+Fm9HVTeR5xJPnbQ6Qa7hKVd870CTr1q9b
# sM3fkTzkrldL6nSk4DBy+GH8z3n3AcJWfJBzo/HzO0Ki+yi/Ou64ZRY4pL5TNlEz
# 26PJyZ1GjPfbMlGEBqLLuwkBfnMPTOXMyx7BAdAfiesiHh3p6daMor1CKKLeOBor
# IV9vekhCytRhWliwYs0a1PP4EpRw+iFWVITH6FRSCGdO+szNCy+KuFQewPiXMOOq
# o8mWicIsA8bsH9QcSmzZNxzhxuTJ1k2fAyE+7aJkf85pBCNv4O/knai9Tgb/IbxC
# SzrR76T1G+CLKHPmlOxhkCMauHQrTjpU1GbCZb9REdR6UDHtg1Yi+/nTTS54Xlwh
# VoEBgnRmA7WSCa87rW2/aIkRJ0VZn0x02dA=
# SIG # End signature block
