Obs/bin/ObsDep/content/Powershell/ObservabilityCensusHelpers.psm1

<###################################################
 # #
 # Copyright (c) Microsoft. All rights reserved. #
 # #
 ##################################################>


# Import Observability EventSource
$observabilityNugetPath = "$PSScriptRoot\..\.."
Add-Type -Path "$observabilityNugetPath\lib\net472\Microsoft.AzureStack.Observability.ObservabilityDeployment.dll"

$nodeName = $env:ComputerName

# Census event scheduled task with retries.
function Set-CensusTaskWithRetry
{
    $retryAttempt = 0
    $retrySleepTimeInSeconds = 10
    $Retries = 5
    $success = $false
    while(-not($success) -and ($retryAttempt -lt $Retries))
    {
        $retryAttempt = $retryAttempt + 1
        try
        {
            Write-InfoLog "Trying to setup census events scheduled task. Attempt $retryAttempt of $Retries"
            Set-CensusEventTask
            $success = $true
        }
        catch
        {
            if ($retryAttempt -lt $Retries)
            {
                $exceptionMessage = $_.Exception.Message
                Write-ErrorLog "Failure during census events scheduled task setup: '$exceptionMessage'. Retrying."
            }
            else
            {
                # All retries failed.
                return $_
            }
            Start-Sleep -Seconds $retrySleepTimeInSeconds
        }
    }
    return $true
}

# Registration events one-time task with retries.
function Set-RegistrationEventsTaskWithRetry
{
    $retryAttempt = 0
    $retrySleepTimeInSeconds = 10
    $Retries = 5
    $success = $false
    while(-not($success) -and ($retryAttempt -lt $Retries))
    {
        $retryAttempt = $retryAttempt + 1
        try
        {
            Write-InfoLog "Trying to setup registration events one-time task. Attempt $retryAttempt of $Retries"
            Set-RegistrationEventTask
            $success = $true
        }
        catch
        {
            if ($retryAttempt -lt $Retries)
            {
                $exceptionMessage = $_.Exception.Message
                Write-ErrorLog "Failure during registration events one-time task setup: '$exceptionMessage'. Retrying."
            }
            else
            {
                # All retries failed.
                return $_
            }
            Start-Sleep -Seconds $retrySleepTimeInSeconds
        }
    }
    return $true
}

# Create the census events scheduled task.
function Set-CensusEventTask
{
    $observabilityNugetPath = "$PSScriptRoot\..\.."
    $censusObservabilityPath = "$observabilityNugetPath\content\Powershell\ObservabilityCensus.ps1"

    # Create the scheduled task to generate census events using HCI CensusDiagnosticProvider.
    $taskName = "ObservabilityCensus"
    if(Test-ScheduledTaskExists -TaskName $taskName)
    {
        Write-InfoLog "Existing task found. Cleaning up task $taskName."    
        Unregister-ScheduledTask -TaskName $taskName -Confirm:$false | Out-Null
    }

    Write-InfoLog "Creating new scheduled task $taskName."
    $frequency = New-TimeSpan -Hours 24
    $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount
    $trigger = New-ScheduledTaskTrigger -Once -RepetitionInterval $frequency -At (Get-Date).AddMinutes(60) -RepetitionDuration (([DateTime]::Now).AddYears(10) - [DateTime]::Now)
    $action = New-ScheduledTaskAction `
        -Execute "powershell.exe"  `
        -Argument "-Command $censusObservabilityPath"
    $settings = New-ScheduledTaskSettingsSet 
    $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings -Principal $principal
    Register-ScheduledTask -TaskName $taskName -TaskPath "Microsoft\AzureStack\Observability" -InputObject $task
    Write-InfoLog "Creating new scheduled task $taskName succeeded."
}

# Create the registration events one-time task.
function Set-RegistrationEventTask
{
    $observabilityNugetPath = "$PSScriptRoot\..\.."
    $registrationObservabilityPath = "$observabilityNugetPath\content\Powershell\ObservabilityCensusRegistration.ps1"

    # Create the one-time task to gather registration events using HCI CensusDiagnosticProvider.
    $taskName = "ObservabilityRegistrationCensus"
    if(Test-ScheduledTaskExists -TaskName $taskName)
    {
        Unregister-ScheduledTask -TaskName $taskName -Confirm:$false | Out-Null
    }

    Write-InfoLog "Creating new scheduled task $taskName."
    $principal = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount
    $trigger = New-ScheduledTaskTrigger -Once -At (Get-Date).AddMinutes(60)
    $action = New-ScheduledTaskAction `
        -Execute "powershell.exe"  `
        -Argument "-Command $registrationObservabilityPath"
    $settings = New-ScheduledTaskSettingsSet 
    $task = New-ScheduledTask -Action $action -Trigger $trigger -Settings $settings -Principal $principal
    Register-ScheduledTask -TaskName $taskName -TaskPath "Microsoft\AzureStack\Observability" -InputObject $task
    Write-InfoLog "Creating new scheduled task $taskName succeeded."
}

# Returns true if a given task exists and false otherwise.
function Test-ScheduledTaskExists
{
    param(
        [string]
        [Parameter(Mandatory=$true)] 
        $TaskName
    )
    try
    {
        if(Get-ScheduledTask -TaskName $TaskName -ErrorAction Stop)
        {
            return $true
        }
    }
    catch {}
    return $false
}

# Write census event.
function Write-CensusEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing census event for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteCensusEvent($eventString)
}

# Write registration event.
function Write-RegistrationEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $EventName,
        [string]
        [Parameter(Mandatory=$true)]
        $Message
    )

    Write-InfoLog "Writing $EventName event for node: $NodeName"
    switch($EventName)
    {
            "ClusterRegistrationStart" {[Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteClusterRegistrationStart($Message); break}
            "ArcRegistrationStart" {[Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteArcRegistrationStart($Message); break}
            "ArcRegistrationEnd" {[Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteArcRegistrationEnd($Message); break}
            "ClusterRegistrationEnd" {[Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteClusterRegistrationEnd($Message); break}
            "ClusterRegistrationParameters" {[Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteClusterRegistrationParameters($Message); break}
            "ClusterRegistrationFailure" {[Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteClusterRegistrationFailure($Message); break}
    }
}

function Write-ClusterPropertiesEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing census event for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteClusterPropertiesEvent($eventString)
}

function Write-InstalledWin32ProgramListEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing InstalledWin32ProgramList event for node $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteInstalledWin32ProgramListEvent($eventString)
}

function Write-PhysicalDiskListEvent {
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing physical disk list for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WritePhysicalDiskListEvent($eventString)
}

function Write-VirtualDiskListEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing VirtualDiskList event for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteVirtualDiskListEvent($eventString)
}

function Write-StoragePoolListEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing StoragePoolList event for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteStoragePoolListEvent($eventString)
}

function Write-StorageTierListEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing StorageTierList event for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteStorageTierListEvent($eventString)
}

function Write-StorageSubSystemListEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing StorageSubSystemList event for node: $NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteStorageSubSystemListEvent($eventString)
}

function Write-DisasterRecoveryEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing DisasterRecovery event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteDisasterRecoveryEvent($eventString)
}

function Write-SddcVolumeSummaryEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing SddcVolumeSummary event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteSddcVolumeSummaryEvent($eventString)
}

function Write-VMCensusEvent
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $eventString
    )
    Write-InfoLog "Writing VMCensus event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteVMCensusEvent($eventString)
}

function Write-StorageAdapterListEvent 
{
    param([string]
          [Parameter(Mandatory=$true)]
          $eventString
    )
    Write-InfoLog "Writing StorageAdapterList event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteStorageAdapterListEvent($eventString);
}

function Write-DiskDriveListEvent
{
    param([string]
          [Parameter(Mandatory=$true)]
          $eventString
    )
    Write-InfoLog "Writing DiskDriveList event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteDiskDriveListEvent($eventString);
}

function Write-GPUPnPDeviceListEvent
{
    param([string]
          [Parameter(Mandatory=$true)]
          $eventString
    )
    Write-InfoLog "Writing GPUPnPDeviceList event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteGPUPnPDeviceListEvent($eventString);
}

function Write-ProductFeaturesEvent
{
    param([string]
          [Parameter(Mandatory=$true)]
          $eventString
    )
    Write-InfoLog "Writing ProductFeatures event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteProductFeaturesEvent($eventString);
}

function Write-TPMCensusEvent
{
    param([string]
          [Parameter(Mandatory=$true)]
          $eventString
    )
    Write-InfoLog "Writing TPMCensus event for node :$NodeName"
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteTPMCensusEvent($eventString);
}

function Write-InfoLog
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $Message
    )
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteInformational($Message)
}

function Write-ErrorLog
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $Message
    )
    [Microsoft.AzureStack.Observability.CensusEventSource]::Instance.WriteError($Message)
}

function Get-PnPDeviceListPayload
{
    param(
        [string]
        [Parameter(Mandatory=$true)]
        $Class
    )
    $result = @()
    $devices = Get-PnpDevice -Class $Class

    ForEach ($device in $devices) {
        $driver = Get-CimInstance -ClassName Win32_SystemDriver -Filter "Name like '$($device.Service)'"
         
        $result += [pscustomobject] @{
            Name = $device.Name
            ClassGuid = $device.ClassGuid
            DeviceID = $device.DeviceID
            PNPClass = $device.PNPClass
            Present = $device.Present
            Service = $device.Service
            Manufacturer = $device.Manufacturer
            Problem = $device.Problem
            ProblemDescription = $device.ProblemDescription
            DriverName = (Get-Item -LiteralPath $driver.PathName).Name
            DriverDate = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverDate).Data
            DriverVersion = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverVersion).Data
            DriverDesc = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverDesc).Data
            MatchingDeviceId = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_MatchingDeviceId).Data
            DriverRank = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverRank).Data
            DriverProvider = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverProvider).Data
        }
    }
    return $result | ConvertTo-Json
}

function Get-DiskDrivePnPDeviceListPayload
{
    $diskDrives = @()
    $devices = Get-PnpDevice -Class "DiskDrive"

    ForEach ($device in $devices)
    {
        $diskDrives += [pscustomobject] @{
            Name = $device.Name
            DeviceID = $device.DeviceID
            PNPClass = $device.PNPClass
            Present = $device.Present
            Service = $device.Service
            Manufacturer = $device.Manufacturer
            MatchingDeviceId = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_MatchingDeviceId).Data
            DeviceParent = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_Parent).Data
        }
    }
    return $diskDrives | ConvertTo-Json
}

function Get-GPUPnPDeviceListPayload
{
    $result = @()
    $devices = Get-PnpDevice -Class "Display"

    $gpupPartitionCount = @{}
    $gpuWithDDA = New-Object System.Collections.Generic.HashSet[string]
    $vms = Get-VM
    
    ForEach ($vm in $vms) 
    { 
        # GPUP
        $vmGpuPartitionAdapters = $vm | Get-VMGpuPartitionAdapter
        ForEach ($vmGpuPartitionAdapter in $vmGpuPartitionAdapters) {
            # If the VM does not have an instance path, the VM is not GPUP enabled
            if ([string]::IsNullOrEmpty($vmGpuPartitionAdapter.InstancePath)) {
                continue
            }

            $gpuInstanceIdModified = [regex]::Replace($vmGpuPartitionAdapter.InstancePath, "[^a-zA-Z0-9]", "")
            if ($gpupPartitionCount.Contains($gpuInstanceIdModified)) {
                $gpupPartitionCount[$gpuInstanceIdModified] += 1
            } else {
                $gpupPartitionCount[$gpuInstanceIdModified] = 0
            }
        }

        # GPU-DDA
        $vmAssignableDevices = $vm | Get-VMAssignableDevice
        ForEach ($device in $vmAssignableDevices) {
            $gpuInstanceIdModified = $device.InstanceId -split "\\" | Select-Object -Last 1
            $gpuWithDDA.Add($gpuInstanceIdModified)
        }
    }

    # Create the payload
    ForEach ($device in $devices) {
        $driver = Get-CimInstance -ClassName Win32_SystemDriver -Filter "Name like '$($device.Service)'"
        $videoController = Get-CimInstance -ClassName Win32_VideoController -Filter "PNPDeviceID like '$($device.DeviceID.Replace('\', '\\'))'"
        $deviceId = [regex]::Replace($device.DeviceID, "[^a-zA-Z0-9]", "")
        
        $partitionCount = 0
        ForEach ($gpupEntry in $gpupPartitionCount.Keys) {
            if ($gpupEntry -like ($deviceId + '*')) {
                $partitionCount = $gpupPartitionCount[$gpupEntry]
                break
            }
        }

        $gpuDDAEnabled = $false
        ForEach ($entry in $gpuWithDDA) {
            $gpuDDAEnabled = $device.DeviceID.Contains($entry)
        }
         
        $result += [pscustomobject] @{
            Name = $device.Name
            TotalMemory = $videoController.AdapterRAM
            GPUPEnabled = $partitionCount -gt 0
            GPUPPartitions = $partitionCount
            GPUDDAEnabled = $gpuDDAEnabled
            ClassGuid = $device.ClassGuid
            DeviceID = $device.DeviceID
            PNPClass = $device.PNPClass
            Present = $device.Present
            Service = $device.Service
            Manufacturer = $device.Manufacturer
            Problem = $device.Problem
            ProblemDescription = $device.ProblemDescription
            DriverName = (Get-Item -LiteralPath $driver.PathName).Name
            DriverDate = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverDate).Data
            DriverVersion = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverVersion).Data
            DriverDesc = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverDesc).Data
            MatchingDeviceId = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_MatchingDeviceId).Data
            DriverRank = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverRank).Data
            DriverProvider = ($device | Get-PnpDeviceProperty -KeyName DEVPKEY_Device_DriverProvider).Data
        }
    }
    return $result | ConvertTo-Json
}

function Get-ProductFeaturesPayload
{
    $result = @{ InstalledFeatures = @() }
    $enabledEnum = 1
    $productFeatures = Get-WmiObject -Class Win32_OptionalFeature | Where-Object { $_.InstallState -eq $enabledEnum}
    foreach ($feature in $productFeatures) 
    {
        $result.InstalledFeatures += $feature.Name
    }
    return $result | ConvertTo-Json
}

function Get-TPMCensusPayload
{
    $tpm = Get-Tpm 
    $result = [pscustomobject] @{
        TpmPresent = $tpm.TpmPresent
        TpmReady = $tpm.TpmReady
        TpmEnabled = $tpm.TpmEnabled
        TpmActivated = $tpm.Activated
        TpmOwned = $tpm.TpmOwned
        RestartPending = $tpm.RestartPending
        ManufacturerId = $tpm.ManufacturerId
        ManufacturerIdTxt = $tpm.ManufacturerIdTxt
        ManufacturerVersion = $tpm.ManufacturerVersion
        ManufacturerVersionFull20 = $tpm.ManufacturerVersionFull20
        OwnerClearDisabled = $tpm.OwnerClearDisabled
        AutoProvisioning = $tpm.AutoProvisioning
        LockedOut = $tpm.LockedOut
        LockoutHealTime = $tpm.LockoutHealTime
        LockoutCount = $tpm.LockoutCount
        LockoutMax = $tpm.LockoutMax
    }
    return $result | ConvertTo-Json
}

Export-ModuleMember -Function Set-CensusTaskWithRetry
Export-ModuleMember -Function Set-RegistrationEventsTaskWithRetry
Export-ModuleMember -Function Write-CensusEvent
Export-ModuleMember -Function Write-RegistrationEvent
Export-ModuleMember -Function Write-ClusterPropertiesEvent
Export-ModuleMember -Function Write-InstalledWin32ProgramListEvent
Export-ModuleMember -Function Write-PhysicalDiskListEvent
Export-ModuleMember -Function Write-VirtualDiskListEvent
Export-ModuleMember -Function Write-StoragePoolListEvent
Export-ModuleMember -Function Write-StorageTierListEvent
Export-ModuleMember -Function Write-StorageSubSystemListEvent
Export-ModuleMember -Function Write-DisasterRecoveryEvent
Export-ModuleMember -Function Write-SddcVolumeSummaryEvent
Export-ModuleMember -Function Write-VMCensusEvent
Export-ModuleMember -Function Get-PnPDeviceListPayload
Export-ModuleMember -Function Write-StorageAdapterListEvent
Export-ModuleMember -Function Get-DiskDrivePnPDeviceListPayload
Export-ModuleMember -Function Write-DiskDriveListEvent
Export-ModuleMember -Function Get-GPUPnPDeviceListPayload
Export-ModuleMember -Function Write-GPUPnPDeviceListEvent
Export-ModuleMember -Function Get-ProductFeaturesPayload
Export-ModuleMember -Function Write-ProductFeaturesEvent
Export-ModuleMember -Function Get-TPMCensusPayload
Export-ModuleMember -Function Write-TPMCensusEvent
Export-ModuleMember -Function Write-ErrorLog
Export-ModuleMember -Function Write-InfoLog
# SIG # Begin signature block
# MIIoOwYJKoZIhvcNAQcCoIIoLDCCKCgCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAtS5NqemlYwQB9
# UBLJ9jLu3MJy/r63NRZa2NEQGYMwD6CCDYUwggYDMIID66ADAgECAhMzAAADri01
# UchTj1UdAAAAAAOuMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjMxMTE2MTkwODU5WhcNMjQxMTE0MTkwODU5WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQD0IPymNjfDEKg+YyE6SjDvJwKW1+pieqTjAY0CnOHZ1Nj5irGjNZPMlQ4HfxXG
# yAVCZcEWE4x2sZgam872R1s0+TAelOtbqFmoW4suJHAYoTHhkznNVKpscm5fZ899
# QnReZv5WtWwbD8HAFXbPPStW2JKCqPcZ54Y6wbuWV9bKtKPImqbkMcTejTgEAj82
# 6GQc6/Th66Koka8cUIvz59e/IP04DGrh9wkq2jIFvQ8EDegw1B4KyJTIs76+hmpV
# M5SwBZjRs3liOQrierkNVo11WuujB3kBf2CbPoP9MlOyyezqkMIbTRj4OHeKlamd
# WaSFhwHLJRIQpfc8sLwOSIBBAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUhx/vdKmXhwc4WiWXbsf0I53h8T8w
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMTgzNjAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# AGrJYDUS7s8o0yNprGXRXuAnRcHKxSjFmW4wclcUTYsQZkhnbMwthWM6cAYb/h2W
# 5GNKtlmj/y/CThe3y/o0EH2h+jwfU/9eJ0fK1ZO/2WD0xi777qU+a7l8KjMPdwjY
# 0tk9bYEGEZfYPRHy1AGPQVuZlG4i5ymJDsMrcIcqV8pxzsw/yk/O4y/nlOjHz4oV
# APU0br5t9tgD8E08GSDi3I6H57Ftod9w26h0MlQiOr10Xqhr5iPLS7SlQwj8HW37
# ybqsmjQpKhmWul6xiXSNGGm36GarHy4Q1egYlxhlUnk3ZKSr3QtWIo1GGL03hT57
# xzjL25fKiZQX/q+II8nuG5M0Qmjvl6Egltr4hZ3e3FQRzRHfLoNPq3ELpxbWdH8t
# Nuj0j/x9Crnfwbki8n57mJKI5JVWRWTSLmbTcDDLkTZlJLg9V1BIJwXGY3i2kR9i
# 5HsADL8YlW0gMWVSlKB1eiSlK6LmFi0rVH16dde+j5T/EaQtFz6qngN7d1lvO7uk
# 6rtX+MLKG4LDRsQgBTi6sIYiKntMjoYFHMPvI/OMUip5ljtLitVbkFGfagSqmbxK
# 7rJMhC8wiTzHanBg1Rrbff1niBbnFbbV4UDmYumjs1FIpFCazk6AADXxoKCo5TsO
# zSHqr9gHgGYQC2hMyX9MGLIpowYCURx3L7kUiGbOiMwaMIIHejCCBWKgAwIBAgIK
# 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/Xmfwb1tbWrJUnMTDXpQzTGCGgwwghoIAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAOuLTVRyFOPVR0AAAAA
# A64wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIP+S
# W3266yf3MwrEcFuizHa/178eJZ9LMMlWX9pQ8tGKMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEAjdxm141IScpXrdbYg3GQoG2Cu3KWN6krBMEa
# x+ZqrSHln3AT5gHsTGYW84vapvhXlt/iZR7ixde51VNj4aP4Z1JrfyZiqCmYGi28
# zcJzlbb79+585yi3S4vDi1vogVBqm7LKDtCupKaLG2h/yKuDG16ouJJs8ZyZXplb
# ZzBuobKBeX6ujBw4bk/9J5yDTm9Trl8aJg9O2b9vvy3XxNg+wzAAzUOqUliV0dWA
# 7aovEPtAXuSup7mnDJp/jCgm2QChShGeQo2niqXuGL+/JzGorQIWNWRdFw1VUhYD
# A8iY/7f+KgquGFZN6mHTL5eQfq58jcPVGL8OILRFIdhXkBHJ46GCF5YwgheSBgor
# BgEEAYI3AwMBMYIXgjCCF34GCSqGSIb3DQEHAqCCF28wghdrAgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCAeW7djCJNTvMkJrMF1KrAJLCeFn1lr3uNh
# ijB/Qm9TXgIGZeeoE9uVGBIyMDI0MDMxMTE4MTgyMC4wOFowBIACAfSggdGkgc4w
# gcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsT
# HE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQg
# VFNTIEVTTjozNzAzLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgU2VydmljZaCCEe0wggcgMIIFCKADAgECAhMzAAAB6pokctVZP2FjAAEA
# AAHqMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
# MB4XDTIzMTIwNjE4NDUzMFoXDTI1MDMwNTE4NDUzMFowgcsxCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy
# aWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjozNzAzLTA1
# RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALULX/FIPyAH1fsu52ijatZv
# aSypoXrlC0mRtCmaxzobhuDkw6/pY/+4nhc4m8pf9zW3R6PihYGp0YPpVuNdfhPQ
# p/KVO6WvMq2DGfFmHurW4PQPL/DkbQMkM9vqjFCvPq8xXZnfL1nGN9moGcN+oaif
# /hUMedmF1qzbay9ILkYfLCxDYn3Qwzsvh5xjxOcsjzmRddNURJvT23Eva0cxisH4
# ocLLTx2zfpqfshw4Z9GaEdsWg9rmib1galUpLzF5PsQDBbtZtcv+Wjmn0pFEiMCW
# wEEcPVN0YG5ysYLdNBdJOn2zsOOS+80W5RrQEqzPpSIIvEkZBJmF3aI4lMR8nV/F
# iTadjpIIqxX5Wa1XlqI/Nj+xagVjnjb7POsA+vh6Wu+v24HpyL8pyL/8Q4RFkRRM
# E9cwT+Jr63yOtPbLe6DXkxIJW6E6w2ua5kXBpEKtEQPTLPhX3CUxMYcglbnmI0zc
# c9UknX285K+sI/2WwRwTBZkhDUULI86eQzV+zvzzR1qEBrlSY+oyTlYQrHMM9WnT
# zVflFDocZVTPpl2BDSNxPn0Qb4IoM9EPqbHyi/MilL+v/AQc8q3mQ6FiuPJAddz0
# ocpNZ9ekBWPVLKq3lfiev4yl65u/438+NAQ+vSJgkONLMmuoguEGzmnK1vq/JHwd
# RUyn6YADiteM7Dja+Qd9AgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUK4FFJaJR5ukX
# QFTUxMhyiwVuWV4wHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXwYD
# VR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9j
# cmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3JsMGwG
# CCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIw
# MjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
# CDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBACiDrVZeP37+fFVt
# fcbfsqC/Kg0Ce67bDcehZmPcfRgJ5Ddv0pJlOFVOFbiIVwesqeEUwFtclfi5Ajne
# Q5ZJpYJpXfELOelG3dzj+BKfd287/UY/cwmSkl+CjnoKBL3Ms6I/fWR+alR0+p6R
# lviK8xHoug9vkc2WrRZsGnMVu2xOM2tPJ+qpyoDBzqv30N/ZRBOoNrS/PCkDwLGI
# CDYqVs/IzAE49yv2ElPywalf9mEsOHXV1lxtQDNcejVEmitJJ+1Vr2EtafPEbMQZ
# p89TAuagROKE4YuohCUKm+v3geJqTQarTBjqV25RCOT+XFngTMDD9wYx6TwndB2I
# 1Ly726NiHUHs0uvq3ciCV9JwNXdt1VZ63WK1NSgpVEsiK9EPABPt1EfXcKrfaPYk
# bkFi79eK1ETxx3NomYNUHNiGU+X1Be8L7qpHwjo0g3/33XhtOr9LiDoUXh/V2LFT
# ETiqV9Q8yLEavQW3j9LQ/h/CaGz5YdGfrY8HiPfMIeLEokKxGf0hHcTEFApB0yLl
# q6KoHrFAEANR/4XuFIpl9sDywVIWt4tKqG+P6pRAXzg1zG5rGlslZWmw7XwgvhBu
# 3jkLP9AxrsSYwY2ftrwwze5NA6VDLS7pz+OrXXWLUmoyNrJNx5Bk0wEwzkQxzkOv
# mbdPhsOP1ZM0uA/xIV7cSpNpZUw5MIIHcTCCBVmgAwIBAgITMwAAABXF52ueAptJ
# mQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNh
# dGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1
# WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQD
# Ex1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEB
# BQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfSqWxOdcjK
# NVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893MsAQGOhg
# fWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWECesSq/XJp
# rx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W7IVWTe/d
# vI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWYbWg7mka9
# 7aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdbZ2De+JKR
# Hh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn427DZM9itu
# qBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1DTsEzOUyO
# ArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12NvDMk2ZItb
# oKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6
# bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3tz5q4i6t
# AgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQW
# BBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacb
# UzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYz
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnku
# aHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIA
# QwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2
# VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwu
# bWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEw
# LTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93
# d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYt
# MjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Geckv8qW/q
# XBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6
# U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY3m2CDPVt
# I1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09J+BAljis
# 9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTp
# kbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0
# sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lUZNlz138e
# W0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJ
# sWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7
# Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0
# dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUFEMFxBmoQ
# tB1VM1izoXBm8qGCA1AwggI4AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQGEwJVUzET
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmlj
# YSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046MzcwMy0wNUUw
# LUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoB
# ATAHBgUrDgMCGgMVAInbHtxB+OlGyQnxQYhy04KSYSSPoIGDMIGApH4wfDELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z
# b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDpmWZ+MCIY
# DzIwMjQwMzExMTExNjE0WhgPMjAyNDAzMTIxMTE2MTRaMHcwPQYKKwYBBAGEWQoE
# ATEvMC0wCgIFAOmZZn4CAQAwCgIBAAICDx4CAf8wBwIBAAICEvQwCgIFAOmat/4C
# AQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEK
# MAgCAQACAwGGoDANBgkqhkiG9w0BAQsFAAOCAQEAABxsBfHxfS0GP3CeaKTCNVN3
# 3y5EeSuoyTzGyAqj1BEKsrLNe8R+3LyN36AqP9fk1njspzhWRv71lky6KMwvdt4x
# 4WZ2uYk0G1CbYmcKY4dHRmMalM5UakHPf6GzRSSXgilA1uBU3jm7UnS3LnJ6QmkT
# F0r8r32d4eNwOHjeSZHtb0i3BlZLJJBTQwYerlxX+uo+Oxydq6x9O0pbMbdkV6lp
# IepLeQpJZdK8BbjeS6UqPJaCTMJQNOetAxCt+Sy4FZ7sVdwqA7TgkAIvI/n3ls7F
# m6YQdiSOQxyj66pdXNcq36/CGVZEW9S4E378hqfewt/fGz3yx8UX7Mbe1MZ8GTGC
# BA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB
# 6pokctVZP2FjAAEAAAHqMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMx
# DQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIAnA2v9o791mTY2eHuWSQz/8
# eMHCxw7jPlHnMpq26iUEMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgKY+h
# 1eNkNHiLCDSW0sA1cGHkbW4qooi+ryyMp6S4ZngwgZgwgYCkfjB8MQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
# VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAeqaJHLVWT9hYwABAAAB6jAiBCDiIZ6X
# LVKa+tVKDESTZ/W3egFuwvy+cWFBikTMOoOWZTANBgkqhkiG9w0BAQsFAASCAgBm
# 2Sp5cM2ME/0dsR7q70XXeUhzMpYbQFnXNwxSc96KVpuBq6xGBlUyQujm17Wz9N7A
# H5oVdP2+IssEp/e8PXaDBHA0hJpq5/mfmIIalYcIdMrAcrkAKs7TSZlRwFDYdFWC
# Cvc0PLg2UZPxMEoH07SVoYL5Sx21HTyAcuI1c1D975SbGAkNFG2aN7J8yOjjdAdC
# aDeAXlAe2lMXarbv6w28XKD+vKogcdy+wza8pe6zYYlAxlXEvsNrcIJ2fdLhkh1x
# PH595unFM+MsLvYuDt8eJF6EvUbCPhmIAHpY+S+9nCtLeS2Wx+RPdiM5tqL8zjPw
# meOG3qAFCMbuoAtrvvDVr8Y/LiV30+27eNw2/2cxQeKmEh3KOuD1lSy15drXQ8wq
# ayygWlsbwX6v1Jnj8TqIE3T5tHJPcCA9Gvwq8+hlNlj4FNCw+lHn6IGsaaRwSZpe
# XuaTJfslYY/SCJkKXHRoAF5S5bD/RHT6Hiks5CQhPnypRQAvF5AVkBLXZ45Cg+db
# j/9U9HF0VEZvKYCtRIGtIB3peuVcAz0ko7CB5EpxtzUFWxTq3jG7io9VOccozNOC
# zThXhnXxdZXq8niTAbvx0xhXEyVOG609Wuwp6iVCk0u7XRrD4JbrWBEyyhCIBjcs
# zoVDWhpElVXxeL1QkHy+upILLPbH2vHgbc0vW4qPlw==
# SIG # End signature block