Framework/Core/AzureMonitoring/OMSMonitoring.ps1

Set-StrictMode -Version Latest 

class OMSMonitoring: CommandBase
{
    [string] $OMSSampleViewTemplateFilepath;
    [string] $OMSSearchesTemplateFilepath;
    [string] $OMSAlertsTemplateFilepath;
    [string] $OMSGenericTemplateFilepath;
    
    [string] $OMSLocation;
    [string] $OMSResourceGroup;
    [string] $OMSWorkspaceName;
    [string] $OMSWorkspaceId;
    [string] $ApplicationSubscriptionName

    OMSMonitoring([string] $_omsSubscriptionId,[string] $_omsResourceGroup,[string] $_omsWorkspaceId, [InvocationInfo] $invocationContext): 
        Base([string] $_omsSubscriptionId, $invocationContext) 
    {                     
        $this.OMSResourceGroup = $_omsResourceGroup
        $this.OMSWorkspaceId = $_omsWorkspaceId
        $omsWorkSpaceInstance = Get-AzureRmOperationalInsightsWorkspace | Where-Object {$_.CustomerId -eq "$_omsWorkspaceId" -and $_.ResourceGroupName -eq  "$($this.OMSResourceGroup)"}
        if($null -eq $omsWorkSpaceInstance)
        {
            throw "Invalid OMS Workspace."
        }
        $this.OMSWorkspaceName = $omsWorkSpaceInstance.Name;
        $locationInstance = Get-AzureRmLocation | Where-Object { $_.DisplayName -eq $omsWorkSpaceInstance.Location -or  $_.Location -eq $omsWorkSpaceInstance.Location } 
        $this.OMSLocation = $locationInstance.Location                
    }

    [void] ConfigureOMS([string] $_applicationSubscriptionId,[string] $_applicationResourceGroups,[string] $_uniqueName,[string] $_securityContactEmails,[OMSInstallationOption] $_omsInstallationOption, [bool] $_validateOnly, [bool] $_useOMSModel)    
    {        
        
        $this.PublishCustomMessage([Constants]::DoubleDashLine + "`r`nStarted setting up AzSDK OMS solution pack`r`n"+[Constants]::DoubleDashLine);
        
        $OptionalParameters = New-Object -TypeName Hashtable

        #the default installation option is All
        if($null -eq $_omsInstallationOption)
        {
            $OMSInstallationOption = [OMSInstallationOption]::All
        }

        $OMSLogPath = [Constants]::AzSdkTempFolderPath + "\OMS";
        if(-not (Test-Path -Path $OMSLogPath))
        {
            mkdir -Path $OMSLogPath -Force | Out-Null
        }
        
        if($_useOMSModel)
        {
            [MessageData] $data = [MessageData]@{                            
                            Message = "`nSetting up OMS view using old query language.";
                            MessageType = [MessageType]::Warning;
                    };                    
            $this.PublishCustomMessage($data)
            $appSub = Get-AzureRmSubscription -SubscriptionId $_applicationSubscriptionId
            $this.ApplicationSubscriptionName = $appSub.Name
            if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::Queries -eq $_omsInstallationOption)
            {
                $searchesTemplateFilepath = [ConfigurationManager]::LoadServerConfigFile("AzSDK.AM.OMS.Searches.omsview");
                $this.OMSSearchesTemplateFilepath = $OMSLogPath+"\AzSDK.AM.OMS.Searches.omsview";
                $searchesTemplateFilepath | ConvertTo-Json -Depth 100 | Out-File $this.OMSSearchesTemplateFilepath
                
                $this.PublishCustomMessage("`r`nSetting up OMS search queries.");
                $this.ConfigureSearches($_validateOnly);
            }
            if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::Alerts -eq $_omsInstallationOption)
            {
                $alertsTemplateFilepath = [ConfigurationManager]::LoadServerConfigFile("AzSDK.AM.OMS.Alerts.omsview"); 
                $this.OMSAlertsTemplateFilepath = $OMSLogPath+"\AzSDK.AM.OMS.Alerts.omsview";
                $alertsTemplateFilepath | ConvertTo-Json -Depth 100 | Out-File $this.OMSAlertsTemplateFilepath
                $this.PublishCustomMessage("`r`nSetting up OMS alerts.");
                $this.ConfigureAlerts($_uniqueName, $_securityContactEmails, $_validateOnly);
            }
            if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::SampleView -eq $_omsInstallationOption)
            {
                $sampleViewTemplateFilepath = [ConfigurationManager]::LoadServerConfigFile("AzSDK.AM.OMS.SampleView.omsview"); 
                $this.OMSSampleViewTemplateFilepath = $OMSLogPath+"\AzSDK.AM.OMS.SampleView.omsview";    
                $sampleViewTemplateFilepath | ConvertTo-Json -Depth 100 | Out-File $this.OMSSampleViewTemplateFilepath

                $this.PublishCustomMessage("`r`nSetting up OMS sample view.");
                $this.ConfigureSampleView($_uniqueName, $_applicationResourceGroups, $_validateOnly);
            }
            if([OMSInstallationOption]::All -eq $_omsInstallationOption -or [OMSInstallationOption]::GenericView -eq $_omsInstallationOption)
            {
                $sampleViewTemplateFilepath = [ConfigurationManager]::LoadServerConfigFile("AZSDK.AM.OMS.GenericView.V1.omsview"); 
                $this.OMSGenericTemplateFilepath = $OMSLogPath+"\AZSDK.AM.OMS.GenericView.V1.omsview";    
                $sampleViewTemplateFilepath | ConvertTo-Json -Depth 100 | Out-File $this.OMSGenericTemplateFilepath

                $this.PublishCustomMessage("`r`nSetting up OMS AzSDK Generic view.");
                $this.ConfigureGenericView($_uniqueName, $_validateOnly);
            }
        }
        else
        {
            $genericViewTemplateFilepath = [ConfigurationManager]::LoadServerConfigFile("AZSDK.AM.OMS.GenericView.V2.omsview");                 
            $this.OMSGenericTemplateFilepath = $OMSLogPath+"\AZSDK.AM.OMS.GenericView.V2.omsview";
            $genericViewTemplateFilepath | ConvertTo-Json -Depth 100 | Out-File $this.OMSGenericTemplateFilepath
            $this.PublishCustomMessage("`r`nSetting up OMS AzSDK generic view.");
            $this.ConfigureGenericView($_uniqueName, $_validateOnly);            
        }
        $this.PublishCustomMessage([Constants]::SingleDashLine + "`r`nCompleted setting up AzSDK OMS solution pack.`r`n"+[Constants]::DoubleDashLine);           
    }

    [void] ConfigureGenericView([string] $_uniqueName, [bool] $_validateOnly)
    {
        $OptionalParameters = New-Object -TypeName Hashtable

        $OptionalParameters = $this.GetOMSGenericViewParameters($_uniqueName);

        $ErrorMessages = @()
        if ($_validateOnly) {
            $ErrorMessages =@()
                Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup `
                                                    -TemplateFile $this.OMSGenericTemplateFilepath `
                                                    -TemplateParameterObject $OptionalParameters -Verbose
        }
        else {

            $ErrorMessages =@()
            $SubErrorMessages = @()
            New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSGenericTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
                                        -ResourceGroupName $this.OMSResourceGroup `
                                        -TemplateFile $this.OMSGenericTemplateFilepath  `
                                        -TemplateParameterObject $OptionalParameters `
                                        -Verbose -Force -ErrorVariable SubErrorMessages
            $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") }
            $ErrorMessages += $SubErrorMessages
           
        }
        if ($ErrorMessages)
        {
            "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool]$_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));}
        }
    }

    [void] ConfigureSampleView([string] $_applicationName, [string] $_applicationResourceGroups, [bool] $_validateOnly)
    {
        $OptionalParameters = New-Object -TypeName Hashtable
        $_query = $this.GetOMSAppQuery($_applicationResourceGroups);

        $OptionalParameters = $this.GetOMSSampleViewParameters($_applicationName, $_query);

        $ErrorMessages = @()
        if ($_validateOnly) {
            $ErrorMessages =@()
                Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup `
                                                    -TemplateFile $this.OMSSampleViewTemplateFilepath `
                                                    -TemplateParameterObject $OptionalParameters -Verbose
        }
        else {

            $ErrorMessages =@()
            $SubErrorMessages = @()
            New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSSampleViewTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
                                        -ResourceGroupName $this.OMSResourceGroup `
                                        -TemplateFile $this.OMSSampleViewTemplateFilepath  `
                                        -TemplateParameterObject $OptionalParameters `
                                        -Verbose -Force -ErrorVariable SubErrorMessages
            $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") }
            $ErrorMessages += $SubErrorMessages
           
        }
        if ($ErrorMessages)
        {
            "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool]$_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));}
        }
    }

    [void] ConfigureSearches([bool] $_validateOnly)
    {

        $OptionalParameters = New-Object -TypeName Hashtable

        $savedSearches = Get-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $this.OMSResourceGroup -WorkspaceName $this.OMSWorkspaceName
        $azSdkSearches = @()
        if($savedSearches -ne $null -and $savedSearches.Value -ne $null)
        {
            $savedSearches.Value | %{
                Set-Variable -Name savedSearch -Value $_
                if($savedSearch.Properties -ne $null -and $savedSearch.Properties.Category -like "AzSDK_Searches*")
                {
                    $azSdkSearches += $savedSearch
                }
            }
        }        
        if($azSdkSearches.Length -gt 0)
        {
            return;
        }
        $OptionalParameters = $this.GetOMSBaseParameters();

        $ErrorMessages = @()
        if ($_validateOnly) {
            $ErrorMessages =@()
                Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup `
                                                    -TemplateFile $this.OMSSearchesTemplateFilepath `
                                                    -TemplateParameterObject $OptionalParameters -Verbose
        }
        else {

            $ErrorMessages =@()
            $SubErrorMessages = @()
            New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSSearchesTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
                                        -ResourceGroupName $this.OMSResourceGroup `
                                        -TemplateFile $this.OMSSearchesTemplateFilepath  `
                                        -TemplateParameterObject $OptionalParameters `
                                        -Verbose -Force -ErrorVariable SubErrorMessages
            $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") }
            $ErrorMessages += $SubErrorMessages
           
        }
        if ($ErrorMessages)
        {
            "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool] $_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));}
        }
    }

    [void] ConfigureAlerts([string] $_applicationName, [string] $_alertemails, [bool] $_validateOnly)
    {

        $OptionalParameters = New-Object -TypeName Hashtable
        $OptionalParameters = $this.GetOMSAlertParameters($_applicationName, $_alertemails);

        $ErrorMessages = @()
        if ($_validateOnly) {
            $ErrorMessages =@()
                Test-AzureRmResourceGroupDeployment -ResourceGroupName $this.OMSResourceGroup `
                                                    -TemplateFile $this.OMSAlertsTemplateFilepath `
                                                    -TemplateParameterObject $OptionalParameters -Verbose
        }
        else {

            $ErrorMessages =@()
            $SubErrorMessages = @()
            New-AzureRmResourceGroupDeployment -Name ((Get-ChildItem $this.OMSAlertsTemplateFilepath).BaseName + '-' + ((Get-Date).ToUniversalTime()).ToString('MMdd-HHmm')) `
                                        -ResourceGroupName $this.OMSResourceGroup `
                                        -TemplateFile $this.OMSAlertsTemplateFilepath  `
                                        -TemplateParameterObject $OptionalParameters `
                                        -Verbose -Force -ErrorVariable SubErrorMessages
            $SubErrorMessages = $SubErrorMessages | ForEach-Object { $_.Exception.Message.TrimEnd("`r`n") }
            $ErrorMessages += $SubErrorMessages
           
        }
        if ($ErrorMessages)
        {
            "", ("{0} returned the following errors:" -f ("Template deployment", "Validation")[[bool]$_validateOnly]), @($ErrorMessages) | ForEach-Object { $this.PublishCustomMessage([MessageData]::new($_));}
        }
    }

    [void] UninstallOMSPack()
    {
        $this.PublishCustomMessage("Started Clean up of OMS Security Solution pack");
    
        #Get all the searches with the name of AzSDK
        $savedSearches = Get-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $this.OMSResourceGroup -WorkspaceName $this.OMSWorkspaceName
        $azSdkSearches = @()
        if($savedSearches -ne $null -and $savedSearches.Value -ne $null)
        {
            $savedSearches.Value | %{
                Set-Variable -Name savedSearch -Value $_
                if($savedSearch.Properties -ne $null -and $savedSearch.Properties.Category -like "*AzSDK*")
                {
                    $azSdkSearches += $savedSearch
                }
            }
        }        
        $RequestURI= [Constants]::OMSRequestURI
        $accessToken =  [Helpers]::GetAccessToken([Constants]::ARMManagementUri);
        $header = "Bearer " + $accessToken
        $headers = @{"Authorization"=$header;"Content-Type"="application/json"}
        $schedules = $null
        $azSdkSearches | %{
            Set-Variable -Name azSdkSearch -Value $_
            $azSdkSearchId = $azSdkSearch.Id.Replace($azSdkSearch.Properties.DisplayName.ToLower(),$azSdkSearch.Properties.DisplayName)
            Set-Variable -Name scheduleURI 
            $scheduleURI = ($RequestURI -f ($azSdkSearchId +"/schedules"))
            #Get all the Schedules configured using this search
            $result = ""
            $err = $null;
            try { 
                $result = Invoke-WebRequest -Method GET -Uri $scheduleURI -Headers $headers 
            } 
            catch{ 
                $err = $_ 
            }
            if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){
                if($result.Content -ne $null){
                    $json = (ConvertFrom-Json $result.Content)
                    if($json -ne $null){
                        $schedules = $json
                        if($json.value -ne $null)
                        {
                            $schedules = $json.value
                        }        
                    }
                }
            }
            if($err -ne $null)
            {
                if($err.ErrorDetails.Message -ne $null){
                    $json = (ConvertFrom-Json $err.ErrorDetails.Message)
                    if($json -ne $null){
                        $return = $json
                        if($json.'odata.error'.code -eq "Request_ResourceNotFound")
                        {
                            $return = $json.'odata.error'.message
                        }
                    }
                }
                return $null           
            }
            $actions = $null;
            #Get AlertActions
            if($schedules -ne $null)
            {
                $schedules | %{
                    Set-Variable -Name schedule -Value $_
                    Set-Variable -Name actionsURI 
                    if(Get-Member -InputObject $schedule -Name id)
                    {
                        $actionsURI = ($RequestURI -f ($schedule.Id +"/Actions"))
                        #Get all the actions configured using this search
                        $result = ""
                        $err = $null;
                        try { 
                            $result = Invoke-WebRequest -Method GET -Uri $actionsURI -Headers $headers 
                        } 
                        catch{ 
                            $err = $_ 
                        }
                        if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){
                            if($result.Content -ne $null){
                                $json = (ConvertFrom-Json $result.Content)
                                if($json -ne $null){
                                    $actions = $json
                                    if($json.value -ne $null)
                                    {
                                        $actions = $json.value
                                    }        
                                }
                            }
                        }
                        if($err -ne $null)
                        {
                            if($err.ErrorDetails.Message -ne $null){
                                $json = (ConvertFrom-Json $err.ErrorDetails.Message)
                                if($json -ne $null){
                                    $return = $json
                                    if($json.'odata.error'.code -eq "Request_ResourceNotFound")
                                    {
                                        $return = $json.'odata.error'.message
                                    }
                                }
                            }
                            return $null           
                        }

                        if($actions -ne $null)
                        {
                            $actions | %{
                                Set-Variable -Name action -Value $_
                                if(Get-Member -InputObject $actions -Name name)
                                {
                                    $subValues = $action.name.Split("|",[StringSplitOptions]::RemoveEmptyEntries)
                                    if($subValues.Length -gt 0)
                                    {
                                        $actionid = $subValues[$subValues.Length-1]
                                        Set-Variable -Name actionURI 
                                        $actionURI = ($RequestURI -f ($schedule.Id+"/Actions/"+$actionid))
                                        #Get all the actions configured using this search
                                        $result = ""
                                        $err = $null;
                                        try { 
                                            $result = Invoke-WebRequest -Method DELETE -Uri $actionURI -Headers $headers 
                                            $this.PublishCustomMessage($action.Id + " : Deleted") 
                                        } 
                                        catch{ 
                                            $err = $_ 
                                        }
                                        if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){
                                            if($result.Content -ne $null){
                                                $json = (ConvertFrom-Json $result.Content)
                                                if($json -ne $null){
                                                    $actions = $json
                                                    if($json.value -ne $null)
                                                    {
                                                        $actions = $json.value
                                                    }        
                                                }
                                            }
                                        }
                                        if($err -ne $null)
                                        {
                                            if($err.ErrorDetails.Message -ne $null){
                                                $json = (ConvertFrom-Json $err.ErrorDetails.Message)
                                                if($json -ne $null){
                                                    $return = $json
                                                    if($json.'odata.error'.code -eq "Request_ResourceNotFound")
                                                    {
                                                        $return = $json.'odata.error'.message
                                                    }
                                                }
                                            }
                                            return $null           
                                        }
                                    }
                                }
                                #TODO Message
                            }
                        }

                        #clean up schedule
                        Set-Variable -Name scheduleURI 
                        $scheduleURI = ($RequestURI -f $schedule.Id)
                        #Get all the actions configured using this search
                        $result = ""
                        try { 
                            $result = Invoke-WebRequest -Method DELETE -Uri $scheduleURI -Headers $headers 
                                $this.PublishCustomMessage($schedule.Id + " : Deleted") 
                        } 
                        catch{ 
                            $err = $_ 
                        }
                        if($result.StatusCode -ge 200 -and $result.StatusCode -le 399){
                            if($result.Content -ne $null){
                                $json = (ConvertFrom-Json $result.Content)
                                if($json -ne $null){
                                    $actions = $json
                                    if($json.value -ne $null)
                                    {
                                        $actions = $json.value
                                    }        
                                }
                            }
                        }
                        if($err -ne $null)
                        {
                            if($err.ErrorDetails.Message -ne $null){
                                $json = (ConvertFrom-Json $err.ErrorDetails.Message)
                                if($json -ne $null){
                                    $return = $json
                                    if($json.'odata.error'.code -eq "Request_ResourceNotFound")
                                    {
                                        $return = $json.'odata.error'.message
                                    }
                                }
                            }
                            return $null           
                        }
                    }
                }
            }
            #Done cleaning up all the schedules and actions
             
            }
            #Finally remove the saved search
            $azSdkSearches | ForEach-Object {
                $tempAzSDKSearch = $_;
                Remove-AzureRmOperationalInsightsSavedSearch -ResourceGroupName $this.OMSResourceGroup -WorkspaceName $this.OMSWorkspaceName -SavedSearchId $tempAzSDKSearch.Properties.DisplayName
                $this.PublishCustomMessage($tempAzSDKSearch.Id + " : Deleted");     
        }
        $this.PublishCustomMessage("Completed clean up of OMS Security Solution pack.");
    }

    [Hashtable] GetOMSBaseParameters()
    {
        [Hashtable] $omsParams = @{};
        $omsParams.Add("omsWorkspaceLocation",$this.OMSLocation);
        $omsParams.Add("omsResourcegroup",$this.OMSResourceGroup);
        $omsParams.Add("omsSubscriptionId",$this.SubscriptionContext.SubscriptionId);
        $omsParams.Add("omsWorkspaceName",$this.OMSWorkspaceName);
        return $omsParams;
    }

    [Hashtable] GetOMSAlertParameters([string] $_applicationName, [string] $_alertemails)
    {
        $uniqueID =  (Get-Date).ToUniversalTime().ToString("yyyyMMddHHmmss");
        $emailList = $_alertemails.Split(",",[StringSplitOptions]::RemoveEmptyEntries)
        [Hashtable] $omsParams = $this.GetOMSBaseParameters();
        $omsParams.Add("alertEmailsPointOfContact",$emailList);
        $omsParams.Add("appName",$_applicationName);
        $omsParams.Add("uniqueId",$uniqueID);
        $omsParams.Add("applicationSubscriptionName",$this.ApplicationSubscriptionName);
        return $omsParams;
    }

    [Hashtable] GetOMSSampleViewParameters([string] $_applicationName,[string] $_query)
    {
        [Hashtable] $omsParams = $this.GetOMSBaseParameters();
        $omsParams.Add("appName",$_applicationName);
        $omsParams.Add("query",$_query);
        $omsParams.Add("applicationSubscriptionName",$this.ApplicationSubscriptionName);
        return $omsParams;
    }

    [Hashtable] GetOMSGenericViewParameters([string] $_applicationName)
    {
        [Hashtable] $omsParams = $this.GetOMSBaseParameters();
        $omsParams.Add("uniqueName",$_applicationName);
        return $omsParams;
    }

    [string] GetOMSAppQuery([string] $_resourceGroups)
    {
        $rgQueryFormat = "ResourceGroup=""{0 }"""

        $queryOutput = ""
        $resourceGroupList = $_resourceGroups.Split(',',[StringSplitOptions]::RemoveEmptyEntries);
        if($resourceGroupList.Length -gt 0)
        {
            $resourceGroupList | ForEach-Object {
                if([string]::IsNullOrWhiteSpace($queryOutput))
                {
                    $queryOutput = $rgQueryFormat -f $_
                }
                else
                {
                    $queryOutput += " OR " + [string]::Format($rgQueryFormat, $_);
                }
            }
        }

        return $queryOutput;
    }
    
}
# SIG # Begin signature block
# MIIkAQYJKoZIhvcNAQcCoIIj8jCCI+4CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBn7Neaqjf/5HQG
# i1/6hDYBwI1tpc0N6LBQ7NzAvg02OqCCDZMwggYRMIID+aADAgECAhMzAAAAjoeR
# pFcaX8o+AAAAAACOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMTYxMTE3MjIwOTIxWhcNMTgwMjE3MjIwOTIxWjCBgzEL
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q
# UjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0B
# AQEFAAOCAQ8AMIIBCgKCAQEA0IfUQit+ndnGetSiw+MVktJTnZUXyVI2+lS/qxCv
# 6cnnzCZTw8Jzv23WAOUA3OlqZzQw9hYXtAGllXyLuaQs5os7efYjDHmP81LfQAEc
# wsYDnetZz3Pp2HE5m/DOJVkt0slbCu9+1jIOXXQSBOyeBFOmawJn+E1Zi3fgKyHg
# 78CkRRLPA3sDxjnD1CLcVVx3Qv+csuVVZ2i6LXZqf2ZTR9VHCsw43o17lxl9gtAm
# +KWO5aHwXmQQ5PnrJ8by4AjQDfJnwNjyL/uJ2hX5rg8+AJcH0Qs+cNR3q3J4QZgH
# uBfMorFf7L3zUGej15Tw0otVj1OmlZPmsmbPyTdo5GPHzwIDAQABo4IBgDCCAXww
# HwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0OBBYEFKvI1u2y
# FdKqjvHM7Ww490VK0Iq7MFIGA1UdEQRLMEmkRzBFMQ0wCwYDVQQLEwRNT1BSMTQw
# MgYDVQQFEysyMzAwMTIrYjA1MGM2ZTctNzY0MS00NDFmLWJjNGEtNDM0ODFlNDE1
# ZDA4MB8GA1UdIwQYMBaAFEhuZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEsw
# SaBHoEWGQ2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0Nv
# ZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsG
# AQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p
# Y0NvZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkq
# hkiG9w0BAQsFAAOCAgEARIkCrGlT88S2u9SMYFPnymyoSWlmvqWaQZk62J3SVwJR
# avq/m5bbpiZ9CVbo3O0ldXqlR1KoHksWU/PuD5rDBJUpwYKEpFYx/KCKkZW1v1rO
# qQEfZEah5srx13R7v5IIUV58MwJeUTub5dguXwJMCZwaQ9px7eTZ56LadCwXreUM
# tRj1VAnUvhxzzSB7pPrI29jbOq76kMWjvZVlrkYtVylY1pLwbNpj8Y8zon44dl7d
# 8zXtrJo7YoHQThl8SHywC484zC281TllqZXBA+KSybmr0lcKqtxSCy5WJ6PimJdX
# jrypWW4kko6C4glzgtk1g8yff9EEjoi44pqDWLDUmuYx+pRHjn2m4k5589jTajMW
# UHDxQruYCen/zJVVWwi/klKoCMTx6PH/QNf5mjad/bqQhdJVPlCtRh/vJQy4njpI
# BGPveJiiXQMNAtjcIKvmVrXe7xZmw9dVgh5PgnjJnlQaEGC3F6tAE5GusBnBmjOd
# 7jJyzWXMT0aYLQ9RYB58+/7b6Ad5B/ehMzj+CZrbj3u2Or2FhrjMvH0BMLd7Hald
# G73MTRf3bkcz1UDfasouUbi1uc/DBNM75ePpEIzrp7repC4zaikvFErqHsEiODUF
# he/CBAANa8HYlhRIFa9+UrC4YMRStUqCt4UqAEkqJoMnWkHevdVmSbwLnHhwCbww
# ggd6MIIFYqADAgECAgphDpDSAAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv
# ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5
# MDlaFw0yNjA3MDgyMTA5MDlaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIw
# MTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQ
# TTS68rZYIZ9CGypr6VpQqrgGOBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULT
# iQ15ZId+lGAkbK+eSZzpaF7S35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYS
# L+erCFDPs0S3XdjELgN1q2jzy23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494H
# DdVceaVJKecNvqATd76UPe/74ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZ
# PrGMXeiJT4Qa8qEvWeSQOy2uM1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5
# bmR/U7qcD60ZI4TL9LoDho33X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGS
# rhwjp6lm7GEfauEoSZ1fiOIlXdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADh
# vKwCgl/bwBWzvRvUVUvnOaEP6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON
# 7E1JMKerjt/sW5+v/N2wZuLBl4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xc
# v3coKPHtbcMojyyPQDdPweGFRInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqw
# iBfenk70lrC8RqBsmNLg1oiMCwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMC
# AQAwHQYDVR0OBBYEFEhuZOVQBdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQM
# HgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud
# IwQYMBaAFHItOgIxkEO5FAVO4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0
# dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0Nl
# ckF1dDIwMTFfMjAxMV8wM18yMi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUF
# BzAChkJodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl
# ckF1dDIwMTFfMjAxMV8wM18yMi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGC
# Ny4DMIGDMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2RvY3MvcHJpbWFyeWNwcy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcA
# YQBsAF8AcABvAGwAaQBjAHkAXwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZI
# hvcNAQELBQADggIBAGfyhqWY4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4s
# PvjDctFtg/6+P+gKyju/R6mj82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKL
# UtCw/WvjPgcuKZvmPRul1LUdd5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7
# pKkFDJvtaPpoLpWgKj8qa1hJYx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft
# 0N3zDq+ZKJeYTQ49C/IIidYfwzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4
# MnEnGn+x9Cf43iw6IGmYslmJaG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxv
# FX1Fp3blQCplo8NdUmKGwx1jNpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG
# 0QaxdR8UvmFhtfDcxhsEvt9Bxw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf
# 0AApxbGbpT9Fdx41xtKiop96eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkY
# S//WsyNodeav+vyL6wuA6mk7r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrv
# QQqxP/uozKRdwaGIm1dxVk5IRcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIV
# xDCCFcACAQEwgZUwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAA
# AI6HkaRXGl/KPgAAAAAAjjANBglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMx
# DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq
# hkiG9w0BCQQxIgQgQa/bcaBHQv7nYAGJ/2RAITJFJvnrnGW15bfqZIfwdQ4wRAYK
# KwYBBAGCNwIBDDE2MDSgEoAQAEEAegBTAEQASwAyADUAMqEegBxodHRwczovL2Fr
# YS5tcy9henNka29zc2RvY3MgMA0GCSqGSIb3DQEBAQUABIIBAEooQKdJpYAyfwQG
# CxP04XrELt3XJ0RgMVmwp+7rw9Yp++0gQzafnWj0U+cP3w4IgAdVKjeD7ZzHpID/
# //NYMsMWYUbWPPmtEZM8ywF7U0EPUL0NiOIKvsVQe5kpdzCOxZh8OoCmiM3N3Lra
# +/EMywN1iXUqsrhGQGJCGjHqwb+PHF5ijz2jx8YhhkT48bpO+ib5d7+xHtNMleM+
# zbcvOM2yuvEZ2lqh3jEhN2VJjBNQFdf7wBFvrU9d6RIvsFJ2O+vlF7i9zoYJrKOa
# ojnpPpOaxac2h9i3zvPUa//KVuYE49liI4M5MYk2loEZJFcD09oEjc+gVzB/Z0mJ
# +XWSQdWhghNMMIITSAYKKwYBBAGCNwMDATGCEzgwghM0BgkqhkiG9w0BBwKgghMl
# MIITIQIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBPAYLKoZIhvcNAQkQAQSgggErBIIB
# JzCCASMCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQgxF9ECmFJKrZu
# XlVw70+9aozyZyg/7Q5EUXe48frX46gCBlmSONxQthgSMjAxNzA5MDUwOTM3MDQu
# OTlaMAcCAQGAAgH0oIG5pIG2MIGzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz
# aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv
# cnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BSMScwJQYDVQQLEx5uQ2lwaGVyIERTRSBF
# U046N0QyRS0zNzgyLUIwRjcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1w
# IFNlcnZpY2Wggg7QMIIGcTCCBFmgAwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0B
# AQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAG
# A1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAw
# HhcNMTAwNzAxMjEzNjU1WhcNMjUwNzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzET
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T
# dGFtcCBQQ0EgMjAxMDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkd
# Dbx3EYo6IOz8E5f1+n9plGt0VBDVpQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMn
# BDEfQRsalR3OCROOfGEwWbEwRA/xYIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq
# 9UeBzb8kYDJYYEbyWEeGMoQedGFnkV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8
# RsEnHSRnEnIaIYqvS2SJUGKxXf13Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v
# 0Ev9buWayrGo8noqCjHw2k4GkbaICDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN
# /LzAyURdXhacAQVPIk0CAwEAAaOCAeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0G
# A1UdDgQWBBTVYzpcijGQ80N7fEYbxTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMA
# dQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAW
# gBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8v
# Y3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRf
# MjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEw
# LTA2LTIzLmNydDCBoAYDVR0gAQH/BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYI
# KwYBBQUHAgEWMWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMv
# ZGVmYXVsdC5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwA
# aQBjAHkAXwBTAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIB
# AAfmiFEN4sbgmD+BcQM9naOhIW+z66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4
# vceoniXj+bzta1RXCCtRgkQS+7lTjMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3Tv
# QhDIr79/xn/yN31aPxzymXlKkVIArzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8
# z+0DpZaPWSm8tv0E4XCfMkon/VWvL/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVK
# C5Em4jnsGUpxY517IW3DnKOiPPp/fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhqu
# BEKDuLWAmyI4ILUl5WTs9/S/fmNZJQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF
# 0M2n0O99g/DhO3EJ3110mCIIYdqwUB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+
# YWtvd6mBy6cJrDm77MbL2IK0cs0d9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt
# 6o3gMy4SKfXAL1QnIffIrE7aKLixqduWsqdCosnPGUFN4Ib5KpqjEWYw07t0Mkvf
# Y3v1mYovG8chr1m1rtxEPJdQcdeh0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgv
# vM9YBS7vDaBQNdrvCScc1bN+NR4Iuto229Nfj950iEkSMIIE2jCCA8KgAwIBAgIT
# MwAAAKJMjh3aqSF8hAAAAAAAojANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJV
# UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt
# ZS1TdGFtcCBQQ0EgMjAxMDAeFw0xNjA5MDcxNzU2NDlaFw0xODA5MDcxNzU2NDla
# MIGzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQL
# EwRNT1BSMScwJQYDVQQLEx5uQ2lwaGVyIERTRSBFU046N0QyRS0zNzgyLUIwRjcx
# JTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0GCSqG
# SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCmAXcFe8N9DnZovcaog8aCewFwqLBqhHJP
# VI5tvmcgar7sLd0vR3Hhkv10Ymu+dNuFNts0yMdpCuY2EklAR7hBNFliPfETp64J
# ASjRFFhjHzmwaDYE2FnaTVvgkXES/EGzDc7BcqEVJvbzmVvo4IquEHWqOdfxDvIJ
# wTF1DCkqKd3sjjcq32uq4zK42E17yHEQkMG+OoYZC+jprR+4NCOtYYyWLvs+TC9C
# ZcYLHrGwWMJrm+fPiwTHk0Gd5nm45feWV9yAxQUFAKZBIjcW+bTrR6wvOa3QxdMM
# RNcJW2nRCfMDK2MnWgeQ9O+MozMljTcsPyWZs/MVPqaS6vlRGOXVAgMBAAGjggEb
# MIIBFzAdBgNVHQ4EFgQUbrvZwcLaFrB8rcJTf+fQFxM9vFcwHwYDVR0jBBgwFoAU
# 1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny
# bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENBXzIw
# MTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAxMC0w
# Ny0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDANBgkq
# hkiG9w0BAQsFAAOCAQEANZlXbTP2SJ2eQdzMqWDuXEdIVBEKhrlXP6dtmI7KfGmm
# apaDzjmyvWQOmTC7vtzgdYJrQinhhUSOMXtzaFl5mJ1XtBYH/KIpvKNwgiEmHWVL
# GeaJKlXNr7qSat7ImgkCWyUWl8eruVra9POgG4JwqkrGRrV6gMRiQoP3cVpkKyb9
# 844jC04W8hvy0DUKQ9o886kakYrENXjZEKhjBqNkf6y/KO6oHBV4j6D3wnHF2LiS
# zqqXcjlMD2hkRE7KhuUty7ICsSg9/Rm/ANZI098NtO0MJJBFFLyVeToD7GOGPDTu
# cbI9Lmp5kIK26xsaWbuvi4t58an9SjHyPGobFV06xqGCA3kwggJhAgEBMIHjoYG5
# pIG2MIGzMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYD
# VQQLEwRNT1BSMScwJQYDVQQLEx5uQ2lwaGVyIERTRSBFU046N0QyRS0zNzgyLUIw
# RjcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiJQoBATAJ
# BgUrDgMCGgUAAxUAXi8X6XGE0jLL7NdeSjv4TreH6fWggcIwgb+kgbwwgbkxCzAJ
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xDTALBgNVBAsTBE1PUFIx
# JzAlBgNVBAsTHm5DaXBoZXIgTlRTIEVTTjo1N0Y2LUMxRTAtNTU0QzErMCkGA1UE
# AxMiTWljcm9zb2Z0IFRpbWUgU291cmNlIE1hc3RlciBDbG9jazANBgkqhkiG9w0B
# AQUFAAIFAN1YrWwwIhgPMjAxNzA5MDUwNDU4MjBaGA8yMDE3MDkwNjA0NTgyMFow
# dzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA3VitbAIBADAKAgEAAgIOeQIB/zAHAgEA
# AgIYtDAKAgUA3Vn+7AIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMB
# oAowCAIBAAIDFuNgoQowCAIBAAIDB6EgMA0GCSqGSIb3DQEBBQUAA4IBAQByYaME
# FOv6bl13h4QN1zZRQWbgCX8IYfNliB04Uq99nX9ieycfowy6hSADAbr4SERbIwOg
# VRuzI0Z1TJdc315A8OaNPgaTVOXtxAeAcQpWaoSWBUDIMhITdXcK+piXKkJqxiWK
# 4639oT4SIG16tWaQ88QH5cXPUz5YwUSOMD+X/3NNCP1diN7LjjXmjHn+ThNPTYEZ
# Sv7Q5xTX/sHMvcKoQdGlqX0RLqLv7yMWybzGCLuJ8xlJNV4WVzDQDM7fz5hRztP6
# i2GNafnQuXQg1hYgTW4cw/oz6EY318PxMrRZ2Foo/n2ltwyl313eSMb6w16CBKFv
# BxU8mI3NxUhoZuPEMYIC9TCCAvECAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTACEzMAAACiTI4d2qkhfIQAAAAAAKIwDQYJYIZIAWUDBAIBBQCgggEy
# MBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgrJCf
# 6A0DgMZHi9MN2MSbzTOtKJHN0W2/TjVAF5cPqBgwgeIGCyqGSIb3DQEJEAIMMYHS
# MIHPMIHMMIGxBBReLxfpcYTSMsvs115KO/hOt4fp9TCBmDCBgKR+MHwxCzAJBgNV
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
# dCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAAokyOHdqpIXyEAAAAAACiMBYEFMwE
# SrWjo1vDkQE04SippZzOshpAMA0GCSqGSIb3DQEBCwUABIIBAIXm4wqpr9Xrsluy
# OO3jdHXFFq9X4RsxJ5WVX+ssoFjbeeEAB2n7lbQjfcd/wJXUr+K+oa/KDYm9tdfR
# M69Gtrm5ObL0H9Yaw7fCvi9oPfxaVT3leaqYp8bdJIVwI5FyUPkeEHNeoYfahT7O
# tRugKOb3HMDB9lcFotGEzm5PxALO9f9ma1C18yXDBFL8ZXEljKoGsa4PLF9nmaB6
# Ebqsg2ktI20vldc1vrrzWFmrq2v47EdXbnmg+hskNexQAqNOIDtn0yix/YM42fLq
# canvV+RgqrpdzqLzbE7OKVz0g0vVweTDaJq3tU7t2lmnZ/F0ZEh2N4F7Hxz+mwLX
# rbFZOU0=
# SIG # End signature block