<#
INTEL CONFIDENTIAL
Copyright (C) 2024 Intel Corporation All Rights Reserved.

The source code contained or described herein and all documents
related to the source code ("Material") are owned by Intel Corporation
or its suppliers or licensors. Title to the Material remains with
Intel Corporation or its suppliers and licensors. The Material
contains trade secrets and proprietary and confidential information of
Intel or its suppliers and licensors. The Material is protected by
worldwide copyright and trade secret laws and treaty provisions. No
part of the Material may be used, copied, reproduced, modified,
published, uploaded, posted, transmitted, distributed, or disclosed in
any way without Intel's prior express written permission.

No license under any patent, copyright, trade secret or other
intellectual property right is granted to or conferred upon you by
disclosure or delivery of the Materials, either expressly, by
implication, inducement, estoppel or otherwise. Any license under such
intellectual property rights must be express and approved by Intel in
writing.

#>

#Requires -RunAsAdministrator

param (
    [switch] $Information,
    [switch] $Install,
    [switch] $Uninstall,
    [switch] $Verbose ,
    [switch] $Silent
)

$scriptVersion = "2549.9.1.0"
$pnpUtil = "C:\Windows\System32\pnputil.exe"

class Component {
    
    [ValidateNotNull()][string]$DisplayName
    [ValidateNotNullOrEmpty()][string]$SearchName
    [ValidateNotNullOrEmpty()][string]$InfName
    [ValidateNotNull()]       [string]$ExtensionGuid
    [string]$OEMInfName
    [string]$Version

    Component($DisplayName, $SearchName, $InfName, $ExtensionGuid) {
        if ($DisplayName -eq "") {
            $this.DisplayName = $SearchName
        }
        else {
            $this.DisplayName = $DisplayName
        }
        $this.SearchName = $SearchName
        $this.InfName = $InfName
        $this.ExtensionGuid = $ExtensionGuid
        $this.OEMInfName = ""
        $this.Version = ""
    }
}

# by design Powershell adds non-discarded output stream values to the return value of the function
# so it's not recommended to use Write-Output in the functions that return values
# caller then should filter out the output stream values from the return value
# when Write-Host is not polluting output stream but it's could not be used for redirection
# So solution is to aggregate the output and print it in the end of the script
# read more here https://devblogs.microsoft.com/scripting/understanding-streams-redirection-and-write-host-in-powershell/
class ActionResult {
    [int]$ReturnCode
    [System.Collections.Generic.List[string]]$InformationBefore
    [System.Collections.Generic.List[string]]$InformationAfter
    [System.Collections.Generic.List[PSCustomObject]]$Table

    ActionResult() {
        $this.ReturnCode = 0
        $this.Table = New-Object System.Collections.Generic.List[PSCustomObject]
        $this.InformationBefore = New-Object System.Collections.Generic.List[string]
        $this.InformationAfter = New-Object System.Collections.Generic.List[string]
    }

    [void] AddInformationBefore($info) {
        $this.InformationBefore.Add($info)
    }

    [void] AddTableRow($row) {
        $this.Table.Add($row)
    }

    [void] AddInformationAfter($info) {
        $this.InformationAfter.Add($info)
    }
}

$SOL_PATTERN = "Intel(R) Active Management Technology - SOL"

$components = @(
    [Component]::new("", "Intel(R) Management Engine Interface #1", "MEI\win10\heci.inf", "")
    , [Component]::new("Intel(R) SOL LMS Extension", "Intel.+SOL LMS Extension", "SOL_LMS_Extension\SOLLMSExtension.inf", "72522ea3-94a8-4184-92c8-88769998a634")
    , [Component]::new("", $SOL_PATTERN, "SOL\mesrl.inf", "")
    , [Component]::new("", "Intel(R) Management and Security Application Local Management", "LMS\LMS.inf", "")
    , [Component]::new("", "Intel(R) Management Engine WMI Provider", "WMIProvider\MEWMIProv.inf", "")
    , [Component]::new("Intel(R) Wireless Manageability Driver extension", "Intel.+Wireless Manageability Driver extension", "wiman_wlan_extension\wiman_wlan_extension.inf", "babe2782-eb1b-46a7-871a-f043d3200542")
    , [Component]::new("", "Intel(R) Wireless Manageability", "WiMan\WiMan.inf", "")
)

$returnCode_SUCCESS = 0
# $returnCode_ADMIN_REQUIRED = 1
$returnCode_GENERAL_FAILURE = 2
$returnCode_INSTALLATION_FAILED = 3
$returnCode_UNINSTALLATION_FAILED = 4
$returnCode_NO_INF_FILES = 5
$returnCode_REBOOT_REQUIRED = 6


function PrintString {
    param(
        [Parameter(Mandatory = $true)] [string]$str
    )
    if (-not $Silent) {
        Write-Output $str
    }
}

function PrintVerbose {
    param(
        [Parameter(Mandatory = $true)] [string]$str
    )
    if ($Verbose) {
        Write-Output $str
    }
}

function Exit-Script {
    param(
        [Parameter(Mandatory = $true)] [int]$exitCode
    )
    PrintString "[!] Exit with Errorlevel $exitCode"
    exit $exitCode
}

# Check params compatibility
if ($Verbose -and $Silent) {
    Write-Output "Error: Verbose and Silent flags cannot be used together."
    $Silent = $false
    Exit-Script $returnCode_GENERAL_FAILURE
}

$action_INFORMATION = 'Information'
$action_INSTALL = 'Install'
$action_UNINSTALL = 'Uninstall'

$action = $action_INFORMATION

$actionCount = 0
if ($Information) { 
    $action = $action_INFORMATION
    $actionCount++ 
}
if ($Install) { 
    $action = $action_INSTALL
    $actionCount++
}
if ($Uninstall) { 
    $action = $action_UNINSTALL
    $actionCount++ 
}

if ($actionCount -gt 1) {
    PrintString "Error: Only one action could be specified."
    Exit-Script $returnCode_GENERAL_FAILURE
}

if ($actionCount -eq 0) {
    PrintString "Error: At least one action should be specified."
    Exit-Script $returnCode_GENERAL_FAILURE
}


$pnpUtilErrorCode_ERROR_NO_MORE_ITEMS = 259
$pnpUtilErrorCode_ERROR_SUCCESS_REBOOT_INITIATED = 1641
$pnpUtilErrorCode_ERROR_SUCCESS_REBOOT_REQUIRED = 3010
$pnpUtilErrorCode_ERROR_FILE_NOT_INSTALLED_INF = -536870340
$pnpUtilErrorCode_ERROR_DRIVER_MATCHING_INF_NOT_FOUND = 1168


function Show-Header {
    PrintString "Intel(R) Management Engine Component Installer v$scriptVersion"
}

# Get-Extensions-Information, GetIntelExtensionInfs, Test-Candidate, InfBelongsToUs, 
#
# Why we need this set of the functions? 
# Our goal is to gather the information about the drivers installed in the system,
# but first we need somehow find them. 
# Most obvious way is to search by the Friendly name.
# And this is good approach since Friendly name tends to be unique identifier 
# given the fact that we prefix our names with Intel (R) string.
# Here comes the problem: Extension INF files doesn't have Friendly name property 
# which makes it impossible to search by it. Moreover another possible candidate -
# Extension GUID is not unique too.
#
# So we need to solve it hard way:
# 1. List extension installed INFs originated by Intel - take last version
# 2. Search original INF file for some specific pattern (Service name, Display name, etc)

function GetIntelExtensionInfs {
    Get-WindowsDriver -Online -All | 
    Where-Object -FilterScript { $_.ProviderName -eq 'Intel' -and $_.ClassName -eq 'Extension' }  |
    Select-Object Driver, OriginalFileName, Version |
    Sort-Object -Descending -Property Version
}

function InfBelongsToUs {
    param (
        [Parameter(Mandatory = $true)] [string]$infName,
        [Parameter(Mandatory = $true)] [string]$extensionGuid,
        [Parameter(Mandatory = $true)] [string]$searchName
    )
    $extensionMatch = Select-String -Quiet -SimpleMatch -Path $infName -Pattern "$extensionGuid"
    $nameMatch = Select-String -Quiet -Path $infName -Pattern "$searchName"
    return $extensionMatch -and $nameMatch
}

function Test-Candidate() {
    param(
        [Parameter(Mandatory = $true)] [System.Object]$candidate 
    )
    foreach ($component in $components) {
        if ($component.ExtensionGuid -eq "") {
            continue
        }
        if ($component.Version -ne "") {
            continue
        }
        if (InfBelongsToUs -infName $candidate.OriginalFileName -extensionGuid $component.ExtensionGuid -searchName $component.SearchName) {
            $component.OEMInfName = $candidate.Driver
            $component.Version = $candidate.Version
            return
        }
    }
}

function Get-ExtensionsInformation {
    $intelExtensions = GetIntelExtensionInfs
    foreach ($candidate in $intelExtensions) {
        Test-Candidate $candidate
    }    
}

function Invoke-Devices-Scan {
    $pnpUtilOutput = & $pnpUtil /scan-devices 
    $errorCode = $LASTEXITCODE
    if ((-Not $?) -or ($errorCode -ne 0)) {
        return 1
    }
    return 0
}

function Get-Latest-Driver {
    param(
        [Parameter(Mandatory = $true)] [System.Object]$friendlyName
    )
    $resultsTable = New-Object System.Collections.Generic.List[System.Object]

    Get-PnpDevice -ErrorAction Stop -FriendlyName $friendlyName | Where-Object { $_.Present -eq $true } | ForEach-Object {
        $deviceStatus = $_.Status
        $errorCode = ""
        $driverVersion = (Get-PnpDeviceProperty -InputObject $_ -KeyName 'DEVPKEY_Device_DriverVersion').Data
        if ($deviceStatus -eq "Error") {
            $errorCode = $_.Problem
        }
        $resultsTable.Add(
            [PSCustomObject]@{ Status = $_.Status; Version = $driverVersion; ErrorCode = $errorCode }
        )
    }
    return $resultsTable |  Sort-Object -Descending -Property Version | Select-Object -First 1
}

function Show-Information {

    $actionResult = [ActionResult]::new()
    $actionResult.AddInformationBefore("[+] Scanning Devices\Drivers")

    if (Invoke-Devices-Scan -ne 0) {
        $actionResult.ReturnCode = $returnCode_GENERAL_FAILURE
        return $actionResult
    }
    $actionResult.AddInformationBefore("[+] Driver Information:")
    
    Update-Components-Information

    foreach ( $component in $components ) {
        $deviceStatus = ""
        $errorCode = ""
        $verboseDetails = ""
        try {
            if ($component.Version -eq "") {
                $latestDriver = Get-Latest-Driver $component.SearchName
                if ($null -eq $latestDriver) {
                    $driverVersion = "Not installed"
                }
                else {
                    $deviceStatus = $latestDriver.Status
                    $driverVersion = $latestDriver.Version
                    if ($deviceStatus -eq "Error") {
                        $errorCode = $latestDriver.ErrorCode
                    }
                }
            }
            else {
                $deviceStatus = "OK"
                $driverVersion = $component.Version
                $verboseDetails = "Extension INF"
            }
            
        }
        catch [Microsoft.PowerShell.Cmdletization.Cim.CimJobException] {
            $driverVersion = "Not installed"
        }
        catch {
            $driverVersion = "Not installed"
            $verboseDetails = $PSItem.Exception
        }
        if (-not $Verbose) {
            $verboseDetails = ""
        }
        $actionResult.AddTableRow(
            [PSCustomObject]@{Component = $component.DisplayName; Version = $driverVersion; Status = $deviceStatus; ErrorCode = $errorCode; Details = $verboseDetails }
        )
    }

    $actionResult.ReturnCode = $returnCode_SUCCESS
    return $actionResult
}

function Install-Software {

    $actionResult = [ActionResult]::new()
    $actionResult.AddInformationBefore("[+] Starting installation of CSE Software...")
    $actionResult.ReturnCode = $returnCode_SUCCESS
    $rebootRequired = $false

    $componentsFound = 0
    $componentsFailed = 0
    foreach ( $component in $components ) {
        if ( ! (Test-Path $component.InfName) ) {
            if ($Verbose) {
                $actionResult.AddTableRow(
                    [PSCustomObject]@{Component = $component.DisplayName; Status = ""; ErrorCode = ""; Details = "INF is absent" }
                )
            }
            continue
        }
        $verboseDetails = ""
        $componentsFound += 1
        $pnpUtilOutput = & $pnpUtil /add-driver $($component.InfName) /install
        $pnpUtilOutput = "Inf:" + $component.InfName + " " + $pnpUtilOutput
        $errorCode = $LASTEXITCODE
        if ((-Not $?) -or ($errorCode -ne 0)) {
            $deviceStatus = 'Failed'
            switch ( $errorCode ) {
                $pnpUtilErrorCode_ERROR_NO_MORE_ITEMS { 
                    $verboseDetails = "No devices match or there is already a better driver"
                    $deviceStatus = 'Successful'  
                }
                $pnpUtilErrorCode_ERROR_SUCCESS_REBOOT_INITIATED {
                    $verboseDetails = "A system reboot is underway"
                    $deviceStatus = 'Successful'
                    $returnCode = $returnCode_REBOOT_REQUIRED
                    $rebootRequired = $true
                }
                $pnpUtilErrorCode_ERROR_SUCCESS_REBOOT_REQUIRED {
                    $verboseDetails = "A system reboot is required"
                    $deviceStatus = 'Successful'  
                    $returnCode = $returnCode_REBOOT_REQUIRED
                    $rebootRequired = $true
                }
            }
        }
        else {
            $deviceStatus = 'Successful'
        }
        if (-not $Verbose) {
            $verboseDetails = ""
        }
        if ($deviceStatus -ne 'Successful') {
            $componentsFailed += 1
        }
        if ($Verbose) {
            $actionResult.AddTableRow(
                [PSCustomObject]@{Component = $component.DisplayName; Status = $deviceStatus; ErrorCode = $errorCode; 
                    Details = $verboseDetails; PnpUtilOutput = $pnpUtilOutput 
                }
            )
        }
        else {
            $actionResult.AddTableRow(
                [PSCustomObject]@{Component = $component.DisplayName; Status = $deviceStatus; ErrorCode = $errorCode;
                    Details = $verboseDetails 
                }
            )
        }
        
    }
    if ($componentsFailed -gt 0) {
        $actionResult.ReturnCode = $returnCode_INSTALLATION_FAILED
        return $actionResult
    }
    if ($componentsFound -eq 0) {
        $actionResult.ReturnCode = $returnCode_NO_INF_FILES
        return $actionResult
    }
    if ($rebootRequired) {
        $actionResult.ReturnCode = $returnCode_REBOOT_REQUIRED
    }
    else {
        $actionResult.ReturnCode = $returnCode_SUCCESS
    }
    return $actionResult
}

function Get-PartialNameMatch {

    $devices = Get-PnpDevice -ErrorAction Stop
    $partialNameMatchList = @($SOL_PATTERN)
    $matchesFound = 0
    
    foreach ($device in $devices) {
        foreach ($pattern in $partialNameMatchList) {
            if ($device.FriendlyName -like "$pattern*") {
                $matchesFound += 1
                foreach ($component in $components) {
                    if ($component.SearchName -eq $pattern) {
                        $component.SearchName = $device.FriendlyName
                        break
                    }
                }
                if ($matchesFound -eq $partialNameMatchList.Count) {
                    return
                }
                break
            }
        }
    }
}

function Update-Components-Information {
    Get-PartialNameMatch
    Get-ExtensionsInformation
}

function Uninstall-Software {
    $actionResult = [ActionResult]::new()
    $actionResult.AddInformationBefore("[+] Starting uninstallation of CSE Software...")
    $actionResult.ReturnCode = $returnCode_SUCCESS
    $rebootRequired = $false

    [Array]::Reverse($components)
	
    Update-Components-Information

    $componentsFailed = 0
    foreach ( $component in $components ) {
        $componentFailed = $true
        $errorCode = ""
        $verboseDetails = ""
        $oemFilename = ""
        try {
            if ($component.OEMInfName -eq "") {
                $pnpDevices = Get-PnpDevice -ErrorAction Stop -FriendlyName $component.SearchName | Where-Object { $_.Present -eq $true }
                if ($pnpDevices -is [Array]) {
                    $actionResult.AddTableRow(
                        [PSCustomObject]@{Component = $component.DisplayName; Status = "Multiple devices"; ErrorCode = "";
                            Details = "Manual uninstall required"; PnpUtilOutput = ""
                        }
                    )
                    $componentsFailed += 1
                    continue
                }
                if ($null -eq $pnpDevices) {
                    $actionResult.AddTableRow(
                        [PSCustomObject]@{Component = $component.DisplayName; Status = 'Not installed'; ErrorCode = ""; 
                            Details = ""; PnpUtilOutput = ""  
                        }
                    )
                    continue
                }
                $pnpDevice = $pnpDevices
                $oemFilename = (Get-PnpDeviceProperty -InputObject $pnpDevice -KeyName 'DEVPKEY_Device_DriverInfPath').Data
            }
            else {
                $oemFilename = $component.OEMInfName
            }

            $pnpUtilOutput = & $pnpUtil /delete-driver $oemFilename /uninstall /force
            $pnpUtilOutput = "Inf:" + $component.InfName + " " + $pnpUtilOutput
            $errorCode = $LASTEXITCODE
            if ((-Not $?) -or ($errorCode -ne 0)) {
                $deviceStatus = 'Failed'
                if ($errorCode -eq $pnpUtilErrorCode_ERROR_DRIVER_MATCHING_INF_NOT_FOUND) {
                    $verboseDetails = "Driver matching to INF not found."
                }
                if ($errorCode -eq $pnpUtilErrorCode_ERROR_FILE_NOT_INSTALLED_INF) {
                    $verboseDetails = "The specified file is not an installed OEM INF."
                }
                if (($errorCode -eq $pnpUtilErrorCode_ERROR_SUCCESS_REBOOT_REQUIRED) -or
                    ($errorCode -eq $pnpUtilErrorCode_ERROR_SUCCESS_REBOOT_INITIATED) ) {
                    $componentFailed = $false
                    $deviceStatus = 'Successful'
                    $verboseDetails = "Reboot required."
                    $rebootRequired = $true
                }
            }
            else {
                $componentFailed = $false
                $deviceStatus = 'Successful'
            }
        } 
        catch [Microsoft.PowerShell.Cmdletization.Cim.CimJobException] {
            $componentFailed = $false
            $verboseDetails = ""
            $deviceStatus = 'Not installed'
        }
        catch {
            $verboseDetails = $PSItem.Exception
            $deviceStatus = 'Error'
        }
        if (-not $Verbose) {
            $verboseDetails = ""
        }
        if ($componentFailed) {
            $componentsFailed += 1
        }
        if ($Verbose) {
            $actionResult.AddTableRow(
                [PSCustomObject]@{Component = $component.DisplayName; Status = $deviceStatus; ErrorCode = $errorCode; 
                    Details = $verboseDetails; PnpUtilOutput = $pnpUtilOutput 
                }
            )
        }
        else {
            $actionResult.AddTableRow(
                [PSCustomObject]@{Component = $component.DisplayName; Status = $deviceStatus; ErrorCode = $errorCode;
                    Details = $verboseDetails 
                }
            )
        }
    }

    if ($componentsFailed -gt 0) {
        $actionResult.ReturnCode = $returnCode_UNINSTALLATION_FAILED
        return $actionResult
    }
    if ($rebootRequired) {
        $actionResult.ReturnCode = $returnCode_REBOOT_REQUIRED
    }
    else {
        $actionResult.ReturnCode = $returnCode_SUCCESS
    }
    return $actionResult
}

# Main script logic
function Main {
    switch ($action) {
        $action_INFORMATION {
            return Show-Information
        }
        $action_INSTALL {
            return Install-Software
        }
        $action_UNINSTALL {
            return Uninstall-Software
        }
    }
}

Show-Header
$res = Main

# We cannot encapsulate print logic in the class ActionResult
# For details: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_classes?view=powershell-6#output-in-class-methods
foreach ($info in $res.InformationBefore) {
    PrintString $info
}
if (-not $Silent) {
    $res.Table | Format-Table -Wrap -AutoSize
}
foreach ($info in $res.InformationAfter) {
    PrintString $info
}
Exit-Script $res.ReturnCode

# SIG # Begin signature block
# MIItogYJKoZIhvcNAQcCoIItkzCCLY8CAQExDzANBglghkgBZQMEAgIFADCBiQYK
# KwYBBAGCNwIBBKB7MHkwNAYKKwYBBAGCNwIBHjAmAgMBAAAEEB/MO2BZSwhOtyTS
# xil+81ECAQACAQACAQACAQACAQAwQTANBglghkgBZQMEAgIFAAQwnfshB4ej5Cnt
# AxM+Lo+qcA72EzH/1ECPn+lzN0Apqrt3I74DhyCGg7BG2+Cba26BoIIRWDCCBW8w
# ggRXoAMCAQICEEj8k7RgVZSNNqfJionWlBYwDQYJKoZIhvcNAQEMBQAwezELMAkG
# A1UEBhMCR0IxGzAZBgNVBAgMEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBwwH
# U2FsZm9yZDEaMBgGA1UECgwRQ29tb2RvIENBIExpbWl0ZWQxITAfBgNVBAMMGEFB
# QSBDZXJ0aWZpY2F0ZSBTZXJ2aWNlczAeFw0yMTA1MjUwMDAwMDBaFw0yODEyMzEy
# MzU5NTlaMFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQx
# LTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBSb290IFI0NjCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAI3nlBIiBCR0Lv8WIwKSirau
# NoWsR9QjkSs+3H3iMaBRb6yEkeNSirXilt7Qh2MkiYr/7xKTO327toq9vQV/J5tr
# ZdOlDGmxvEk5mvFtbqrkoIMn2poNK1DpS1uzuGQ2pH5KPalxq2Gzc7M8Cwzv2zNX
# 5b40N+OXG139HxI9ggN25vs/ZtKUMWn6bbM0rMF6eNySUPJkx6otBKvDaurgL6en
# 3G7X6P/aIatAv7nuDZ7G2Z6Z78beH6kMdrMnIKHWuv2A5wHS7+uCKZVwjf+7Fc/+
# 0Q82oi5PMpB0RmtHNRN3BTNPYy64LeG/ZacEaxjYcfrMCPJtiZkQsa3bPizkqhiw
# xgcBdWfebeljYx42f2mJvqpFPm5aX4+hW8udMIYw6AOzQMYNDzjNZ6hTiPq4MGX6
# b8fnHbGDdGk+rMRoO7HmZzOatgjggAVIQO72gmRGqPVzsAaV8mxln79VWxycVxrH
# eEZ8cKqUG4IXrIfptskOgRxA1hYXKfxcnBgr6kX1773VZ08oXgXukEx658b00Pz6
# zT4yRhMgNooE6reqB0acDZM6CWaZWFwpo7kMpjA4PNBGNjV8nLruw9X5Cnb6fgUb
# QMqSNenVetG1fwCuqZCqxX8BnBCxFvzMbhjcb2L+plCnuHu4nRU//iAMdcgiWhOV
# GZAA6RrVwobx447sX/TlAgMBAAGjggESMIIBDjAfBgNVHSMEGDAWgBSgEQojPpbx
# B+zirynvgqV/0DCktDAdBgNVHQ4EFgQUMuuSmv81lkgvKEBCcCA2kVwXheYwDgYD
# VR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYBBQUH
# AwMwGwYDVR0gBBQwEjAGBgRVHSAAMAgGBmeBDAEEATBDBgNVHR8EPDA6MDigNqA0
# hjJodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9BQUFDZXJ0aWZpY2F0ZVNlcnZpY2Vz
# LmNybDA0BggrBgEFBQcBAQQoMCYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNv
# bW9kb2NhLmNvbTANBgkqhkiG9w0BAQwFAAOCAQEAEr+h74t0mphEuGlGtaskCgyk
# ime4OoG/RYp9UgeojR9OIYU5o2teLSCGvxC4rnk7U820+9hEvgbZXGNn1EAWh0SG
# cirWMhX1EoPC+eFdEUBn9kIncsUj4gI4Gkwg4tsB981GTyaifGbAUTa2iQJUx/xY
# +2wA7v6Ypi6VoQxTKR9v2BmmT573rAnqXYLGi6+Ap72BSFKEMdoy7BXkpkw9bDlz
# 1AuFOSDghRpo4adIOKnRNiV3wY0ZFsWITGZ9L2POmOhp36w8qF2dyRxbrtjzL3TP
# uH7214OdEZZimq5FE9p/3Ef738NSn+YGVemdjPI6YlG87CQPKdRYgITkRXta2DCC
# BcMwggQroAMCAQICEHqVHgg2WvB2BEAdFLTzupEwDQYJKoZIhvcNAQEMBQAwVDEL
# MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMi
# U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNjAeFw0yNTAyMTkwMDAw
# MDBaFw0yNjAyMTkyMzU5NTlaMFoxCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxp
# Zm9ybmlhMRowGAYDVQQKDBFJbnRlbCBDb3Jwb3JhdGlvbjEaMBgGA1UEAwwRSW50
# ZWwgQ29ycG9yYXRpb24wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC7
# ctWHp2WukDL/iZJ5Evpu+wnlTpOj4mnnm446XRUIiE0T5EGA4bwHTl6qGE4fhqmT
# u6ekyRjPk/gOs3fGQ3XjruB9c6zm9RyCFe6YAfkW0ui2PHo+PfStZptuNqeI3Ur8
# qj53KtZ0uGwNtiga7cimlI4EevMKnJ0dUMry+JUPlbbdxnX9Xj+CKhxm2W0CfuI/
# RfW/zH0gMX6tLuogeN0ix5k+lZs/NPxRGIEOUkqC3bgPoQ7hPPJVsYWldc3RQ63C
# CVKLgUkYaGnTXd3MNbIjy+o6oVbih3k3sUqhFg1UfVxMLtHjA2nLzPyOK7fW/l6P
# gKGURJnFaii48HXfwJHwI3FWydn8YSxUYDpvKWAWplcxNnOEuDaIcxBczHVdPQGS
# AIwoJBpvvIAvbTQ3Z8XAtIrd0YL9VYgCUOeAqSXOcgs9CIj9nnrrmUEKxeEid+1W
# 7Z8pKWK8K+8Yke0G3ixfCSXuyVweJWlaJvW/mdys+xvOWMUDSl7EMndMdoDUMPMC
# AwEAAaOCAYkwggGFMB8GA1UdIwQYMBaAFA8qyyCHKLjsb0iuK1SmKaoXpM0MMB0G
# A1UdDgQWBBSO3zfJ+ielYF2FeRwEGUjzxX2aCDAOBgNVHQ8BAf8EBAMCB4AwDAYD
# VR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDAzBKBgNVHSAEQzBBMDUGDCsG
# AQQBsjEBAgEDAjAlMCMGCCsGAQUFBwIBFhdodHRwczovL3NlY3RpZ28uY29tL0NQ
# UzAIBgZngQwBBAEwSQYDVR0fBEIwQDA+oDygOoY4aHR0cDovL2NybC5zZWN0aWdv
# LmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcmwweQYIKwYBBQUH
# AQEEbTBrMEQGCCsGAQUFBzAChjhodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3Rp
# Z29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNydDAjBggrBgEFBQcwAYYXaHR0cDov
# L29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggGBAFy6xht7KeNCUeMs
# SSkyj0/x7XR9XdEGJnHKF645UBAP/grRzwp2stFv9JjY/ikQ5vqu1k16JWqXFOk9
# oUX9Ik/Csm2KxtetybzT2XiLMhq3HUL26fm1RPKDcK6ryBdSButZPeSIK4xFWZQW
# aruPokORS9AuXy6RndCoacy1uNI5ZzONt4GEqng2LMQohdjEDauCUluK+sQ3t09Y
# f9Mzuux6D/ldXAzsW8XoR6mqQmZ4mX2rNPAKBNyQIZ/cAsmkH+AaElhMdQE0bYtR
# dKKIBUuC1UNZrDjGbpHuymvkFd7zszZy0flFkyUj2bBsgwMkIO5Gh84QT+HRd/qM
# pU6+EwVjphG7XLkry6EnQJxw3ACxPsK1CQUoN0h81ncJyH8KM5TKQxR4DPBVwKKh
# edXn6+FMdMjrJBljlwTfLDHbHE/cuq5zSTuaixxK1Z+lvX33kF4gr2G5cBOxGoCt
# jkoElOqXec9ptBLRPCKOBs7nEMMNeO3u+8+eTdnThBWrYw+BKTCCBhowggQCoAMC
# AQICEGIdbQxSAZ47kHkVIIkhHAowDQYJKoZIhvcNAQEMBQAwVjELMAkGA1UEBhMC
# R0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEtMCsGA1UEAxMkU2VjdGlnbyBQ
# dWJsaWMgQ29kZSBTaWduaW5nIFJvb3QgUjQ2MB4XDTIxMDMyMjAwMDAwMFoXDTM2
# MDMyMTIzNTk1OVowVDELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGlt
# aXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIz
# NjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAJsrnVP6NT+OYAZDasDP
# 9X/2yFNTGMjO02x+/FgHlRd5ZTMLER4ARkZsQ3hAyAKwktlQqFZOGP/I+rLSJJmF
# eRno+DYDY1UOAWKA4xjMHY4qF2p9YZWhhbeFpPb09JNqFiTCYy/Rv/zedt4QJuIx
# eFI61tqb7/foXT1/LW2wHyN79FXSYiTxcv+18Irpw+5gcTbXnDOsrSHVJYdPE9s+
# 5iRF2Q/TlnCZGZOcA7n9qudjzeN43OE/TpKF2dGq1mVXn37zK/4oiETkgsyqA5lg
# AQ0c1f1IkOb6rGnhWqkHcxX+HnfKXjVodTmmV52L2UIFsf0l4iQ0UgKJUc2RGarh
# OnG3B++OxR53LPys3J9AnL9o6zlviz5pzsgfrQH4lrtNUz4Qq/Va5MbBwuahTcWk
# 4UxuY+PynPjgw9nV/35gRAhC3L81B3/bIaBb659+Vxn9kT2jUztrkmep/aLb+4xJ
# bKZHyvahAEx2XKHafkeKtjiMqcUf/2BG935A591GsllvWwIDAQABo4IBZDCCAWAw
# HwYDVR0jBBgwFoAUMuuSmv81lkgvKEBCcCA2kVwXheYwHQYDVR0OBBYEFA8qyyCH
# KLjsb0iuK1SmKaoXpM0MMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/
# AgEAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYEVR0gADAIBgZn
# gQwBBAEwSwYDVR0fBEQwQjBAoD6gPIY6aHR0cDovL2NybC5zZWN0aWdvLmNvbS9T
# ZWN0aWdvUHVibGljQ29kZVNpZ25pbmdSb290UjQ2LmNybDB7BggrBgEFBQcBAQRv
# MG0wRgYIKwYBBQUHMAKGOmh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5wN2MwIwYIKwYBBQUHMAGGF2h0dHA6Ly9v
# Y3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4ICAQAG/4Lhd2M2bnuhFSCb
# E/8E/ph1RGHDVpVx0ZE/haHrQECxyNbgcv2FymQ5PPmNS6Dah66dtgCjBsULYAor
# 5wxxcgEPRl05pZOzI3IEGwwsepp+8iGsLKaVpL3z5CmgELIqmk/Q5zFgR1TSGmxq
# oEEhk60FqONzDn7D8p4W89h8sX+V1imaUb693TGqWp3T32IKGfIgy9jkd7GM7YCa
# 2xulWfQ6E1xZtYNEX/ewGnp9ZeHPsNwwviJMBZL4xVd40uPWUnOJUoSiugaz0yWL
# ODRtQxs5qU6E58KKmfHwJotl5WZ7nIQuDT0mWjwEx7zSM7fs9Tx6N+Q/3+49qTtU
# vAQsrEAxwmzOTJ6Jp6uWmHCgrHW4dHM3ITpvG5Ipy62KyqYovk5O6cC+040Si15K
# JpuQ9VJnbPvqYqfMB9nEKX/d2rd1Q3DiuDexMKCCQdJGpOqUsxLuCOuFOoGbO7Uv
# 3RjUpY39jkkp0a+yls6tN85fJe+Y8voTnbPU1knpy24wUFBkfenBa+pRFHwCBB1Q
# tS+vGNRhsceP3kSPNrrfN2sRzFYsNfrFaWz8YOdU254qNZQfd9O/VjxZ2Gjr3xgA
# NHtM3HxfzPYF6/pKK8EE4dj66qKKtm2DTL1KFCg/OYJyfrdLJq1q2/HXntgr2GVw
# +ZWhrWgMTn8v1SjZsLlrgIfZHDGCG48wghuLAgEBMGgwVDELMAkGA1UEBhMCR0Ix
# GDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMiU2VjdGlnbyBQdWJs
# aWMgQ29kZSBTaWduaW5nIENBIFIzNgIQepUeCDZa8HYEQB0UtPO6kTANBglghkgB
# ZQMEAgIFAKCBjDAQBgorBgEEAYI3AgEMMQIwADAZBgkqhkiG9w0BCQMxDAYKKwYB
# BAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTA/BgkqhkiG9w0B
# CQQxMgQwQ0s5hY7jMQEEnP2qUVHwkxReWbzT0CLscBOzBiRT8i8M8KvDQFsC7ySz
# 6lUZ7Ow+MA0GCSqGSIb3DQEBAQUABIIBgBc6E4UXu4sUt8Qw8Bp+9Iow6iVPWIM+
# YdPbH6mEhngRT93dnqRrqlbqvIe4chezCS5yivAe9FWHeoH4OGOxsq+9ha790Mx6
# wMWgyOtktuRytSekyG4j/iy2X3PbRe8RNTPNBIHk+QjDT/TGVL8KsnqYKEEANiO0
# d67yuXm2nb9JrPpKOXm9bu6ORYyAhKoI64XH/uGe2RlqubvWO1SHJjXrABv6z9+Q
# L2Lauy05iMEhAIA0EDpqd9MduWedZYOcSyy4/GBCQMQ9MIOvReNkNYrnLRg09HH9
# D03ddQM6qg68hb1AfpuP9CafxwG9Dj9ib02J7wFfm2I55EFWHr+EJbaq2x608j+d
# Aj/Q2PJGvo59f1/VE+5Hgu6NcQtwJKTOH6dvWrAH+AEwBad6mXAFGKnZ41CtfEF/
# HA9ZHuF3b94YI26uVLqsVSiavcY48XRFWxjYHJ/+2xO1+nb3ra7RYU/cY/DFo1Jn
# Y8hGwy9blTplo0hbxvJqclFXsc/5b8Ze/qGCGOkwghjlBgorBgEEAYI3AwMBMYIY
# 1TCCGNEGCSqGSIb3DQEHAqCCGMIwghi+AgEDMQ8wDQYJYIZIAWUDBAICBQAwggEI
# BgsqhkiG9w0BCRABBKCB+ASB9TCB8gIBAQYKKwYBBAGyMQIBATBBMA0GCWCGSAFl
# AwQCAgUABDCLrKHRRMBIdWQ0HeCsev/RqAplR2vgsXZkjGnQyYnUKLviz4RebDr8
# 3vmCBsDmDJoCFQDS+TJOnEUVFLbgV5p3aeIkYyjMqRgPMjAyNTEyMDQxMDA4MTha
# oHakdDByMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOV2VzdCBZb3Jrc2hpcmUxGDAW
# BgNVBAoTD1NlY3RpZ28gTGltaXRlZDEwMC4GA1UEAxMnU2VjdGlnbyBQdWJsaWMg
# VGltZSBTdGFtcGluZyBTaWduZXIgUjM2oIITBDCCBmIwggTKoAMCAQICEQCkKTtu
# Ht3XpzQIh616TrckMA0GCSqGSIb3DQEBDAUAMFUxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMTI1NlY3RpZ28gUHVibGljIFRp
# bWUgU3RhbXBpbmcgQ0EgUjM2MB4XDTI1MDMyNzAwMDAwMFoXDTM2MDMyMTIzNTk1
# OVowcjELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDldlc3QgWW9ya3NoaXJlMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxMDAuBgNVBAMTJ1NlY3RpZ28gUHVibGljIFRp
# bWUgU3RhbXBpbmcgU2lnbmVyIFIzNjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
# AgoCggIBANOElfRupFN48j0QS3gSBzzclIFTZ2Gsn7BjsmBF659/kpA2Ey7NXK3M
# P6JdrMBNU8wdmkf+SSIyjX++UAYWtg3Y/uDRDyg8RxHeHRJ+0U1jHEyH5uPdk1tt
# iPC3x/gOxIc9P7Gn3OgW7DQc4x07exZ4DX4XyaGDq5LoEmk/BdCM1IelVMKB3WA6
# YpZ/XYdJ9JueOXeQObSQ/dohQCGyh0FhmwkDWKZaqQBWrBwZ++zqlt+z/QYTgEnZ
# o6dyIo2IhXXANFkCHutL8765NBxvolXMFWY8/reTnFxk3MajgM5NX6wzWdWsPJxY
# RhLxtJLSUJJ5yWRNw+NBqH1ezvFs4GgJ2ZqFJ+Dwqbx9+rw+F2gBdgo4j7CVomP4
# 9sS7CbqsdybbiOGpB9DJhs5QVMpYV73TVV3IwLiBHBECrTgUfZVOMF0KSEq2zk/L
# sfvehswavE3W4aBXJmGjgWSpcDz+6TqeTM8f1DIcgQPdz0IYgnT3yFTgiDbFGOFN
# t6eCidxdR6j9x+kpcN5RwApy4pRhE10YOV/xafBvKpRuWPjOPWRBlKdm53kS2aMh
# 08spx7xSEqXn4QQldCnUWRz3Lki+TgBlpwYwJUbR77DAayNwAANE7taBrz2v+Mnn
# ogMrvvct0iwvfIA1W8kp155Lo44SIfqGmrbJP6Mn+Udr3MR2oWozAgMBAAGjggGO
# MIIBijAfBgNVHSMEGDAWgBRfWO1MMXqiYUKNUoC6s2GXGaIymzAdBgNVHQ4EFgQU
# iGGMoSo3ZIEoYKGbMdCM/SwCzk8wDgYDVR0PAQH/BAQDAgbAMAwGA1UdEwEB/wQC
# MAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwSgYDVR0gBEMwQTA1BgwrBgEEAbIx
# AQIBAwgwJTAjBggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYG
# Z4EMAQQCMEoGA1UdHwRDMEEwP6A9oDuGOWh0dHA6Ly9jcmwuc2VjdGlnby5jb20v
# U2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjM2LmNybDB6BggrBgEFBQcBAQRu
# MGwwRQYIKwYBBQUHMAKGOWh0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY1RpbWVTdGFtcGluZ0NBUjM2LmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29j
# c3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggGBAAKBPqSGclEh+WWpLj1S
# iuHlm8xLE0SThI2yLuq+75s11y6SceBchpnKpxWaGtXc8dya1Aq3RuW//y3wMThs
# vT4fSba2AoSWlR67rA4fTYGMIhgzocsids0ct/pHaocLVJSwnTYxY2pE0hPoZAvR
# ebctbsTqENmZHyOVjOFlwN2R3DRweFeNs4uyZN5LRJ5EnVYlcTOq3bl1tI5poru9
# WaQRWQ4eynXp7Pj0Fz4DKr86HYECRJMWiDjeV0QqAcQMFsIjJtrYTw7mU81qf4FB
# c4u4swphLeKRNyn9DDrd3HIMJ+CpdhSHEGleeZ5I79YDg3B3A/fmVY2GaMik1Vm+
# FajEMv4/EN2mmHf4zkOuhYZNzVm4NrWJeY4UAriLBOeVYODdA1GxFr1ycbcUEGlU
# ecc4RCPgYySs4d00NNuicR4a9n7idJlevAJbha/arIYMEuUqTeRRbWkhJwMKmb9y
# EvppRudKyu1t6l21sIuIZqcpVH8oLWCxHS0LpDRF9Y4jijCCBhQwggP8oAMCAQIC
# EHojrtpTaZYPkcg+XPTH4z8wDQYJKoZIhvcNAQEMBQAwVzELMAkGA1UEBhMCR0Ix
# GDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMlU2VjdGlnbyBQdWJs
# aWMgVGltZSBTdGFtcGluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAz
# MjEyMzU5NTlaMFUxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxLDAqBgNVBAMTI1NlY3RpZ28gUHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjM2
# MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAzZjYQ0GrboIr7PYzfiY0
# 5ImM0+8iEoBUPu8mr4wOgYPjoiIz5vzf7d5wu8GFK1JWN5hciN9rdqOhbdxLcSVw
# nOTJmUGfAMQm4eXOls3iQwfapEFWuOsYmBKXPNSpwZAFoLGl5y1EaGGc5LByM8wj
# cbSF52/Z42YaJRsPXY545E3QAPN2mxDh0OLozhiGgYT1xtjXVfEzYBVmfQaI5QL3
# 5cTTAjsJAp85R+KAsOfuL9Z7LFnjdcuPkZWjssMETFIueH69rxbFOUD64G+rUo7x
# FIdRAuDNvWBsv0iGDPGaR2nZlY24tz5fISYk1sPY4gir99aXAGnoo0vX3Okew4Ms
# iyBn5ZnUDMKzUcQrpVavGacrIkmDYu/bcOUR1mVBIZ0X7P4bKf38JF7Mp7tY3LFF
# /h7hvBS2tgTYXlD7TnIMPrxyXCfB5yQq3FFoXRXM3/DvqQ4shoVWF/mwwz9xoRku
# 05iphp22fTfjKRIVpm4gFT24JKspEpM8mFa9eTgKWWCvAgMBAAGjggFcMIIBWDAf
# BgNVHSMEGDAWgBT2d2rdP/0BE/8WoWyCAi/QCj0UJTAdBgNVHQ4EFgQUX1jtTDF6
# omFCjVKAurNhlxmiMpswDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8C
# AQAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAAMEwGA1Ud
# HwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1Ymxp
# Y1RpbWVTdGFtcGluZ1Jvb3RSNDYuY3JsMHwGCCsGAQUFBwEBBHAwbjBHBggrBgEF
# BQcwAoY7aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljVGltZVN0
# YW1waW5nUm9vdFI0Ni5wN2MwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3Rp
# Z28uY29tMA0GCSqGSIb3DQEBDAUAA4ICAQAS13sgrQ41WAyegR0lWP1MLWd0r8di
# JiH2VVRpxqFGhnZbaF+IQ7JATGceTWOS+kgnMAzGYRzpm8jIcjlSQ8JtcqymKhgx
# 1s6cFZBSfvfeoyigF8iCGlH+SVSo3HHr98NepjSFJTU5KSRKK+3nVSWYkSVQgJlg
# Gh3MPcz9IWN4I/n1qfDGzqHCPWZ+/Mb5vVyhgaeqxLPbBIqv6cM74Nvyo1xNsllE
# CJJrOvsrJQkajVz4xJwZ8blAdX5umzwFfk7K/0K3fpjgiXpqNOpXaJ+KSRW0HdE0
# FSDC7+ZKJJSJx78mn+rwEyT+A3z7Ss0gT5CpTrcmhUwIw9jbvnYuYRKxFVWjKklW
# 3z83epDVzoWJttxFpujdrNmRwh1YZVIB2guAAjEQoF42H0BA7WBCueHVMDyV1e4n
# M9K4As7PVSNvQ8LI1WRaTuGSFUd9y8F8jw22BZC6mJoB40d7SlZIYfaildlgpgbg
# tu6SDsek2L8qomG57Yp5qTqof0DwJ4Q4HsShvRl/59T4IJBovRwmqWafH0cIPEX7
# cEttS5+tXrgRtMjjTOp6A9l0D6xcKZtxnLqiTH9KPCy6xZEi0UDcMTww5Fl4VvoG
# bMG2oonuX3f1tsoHLaO/Fwkj3xVr3lDkmeUqivebQTvGkx5hGuJaSVQ+x60xJ/Y2
# 9RBr8Tm9XJ59AjCCBoIwggRqoAMCAQICEDbCsL18Gzrno7PdNsvJdWgwDQYJKoZI
# hvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQw
# EgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3
# b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9y
# aXR5MB4XDTIxMDMyMjAwMDAwMFoXDTM4MDExODIzNTk1OVowVzELMAkGA1UEBhMC
# R0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMlU2VjdGlnbyBQ
# dWJsaWMgVGltZSBTdGFtcGluZyBSb290IFI0NjCCAiIwDQYJKoZIhvcNAQEBBQAD
# ggIPADCCAgoCggIBAIid2LlFZ50d3ei5JoGaVFTAfEkFm8xaFQ/ZlBBEtEFAgXcU
# manU5HYsyAhTXiDQkiUvpVdYqZ1uYoZEMgtHES1l1Cc6HaqZzEbOOp6YiTx63ywT
# on434aXVydmhx7Dx4IBrAou7hNGsKioIBPy5GMN7KmgYmuu4f92sKKjbxqohUSfj
# k1mJlAjthgF7Hjx4vvyVDQGsd5KarLW5d73E3ThobSkob2SL48LpUR/O627pDchx
# ll+bTSv1gASn/hp6IuHJorEu6EopoB1CNFp/+HpTXeNARXUmdRMKbnXWflq+/g36
# NJXB35ZvxQw6zid61qmrlD/IbKJA6COw/8lFSPQwBP1ityZdwuCysCKZ9ZjczMqb
# UcLFyq6KdOpuzVDR3ZUwxDKL1wCAxgL2Mpz7eZbrb/JWXiOcNzDpQsmwGQ6Stw8t
# TCqPumhLRPb7YkzM8/6NnWH3T9ClmcGSF22LEyJYNWCHrQqYubNeKolzqUbCqhSq
# mr/UdUeb49zYHr7ALL8bAJyPDmubNqMtuaobKASBqP84uhqcRY/pjnYd+V5/dcu9
# ieERjiRKKsxCG1t6tG9oj7liwPddXEcYGOUiWLm742st50jGwTzxbMpepmOP1mLn
# JskvZaN5e45NuzAHteORlsSuDt5t4BBRCJL+5EZnnw0ezntk9R8QJyAkL6/bAgMB
# AAGjggEWMIIBEjAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNV
# HQ4EFgQU9ndq3T/9ARP/FqFsggIv0Ao9FCUwDgYDVR0PAQH/BAQDAgGGMA8GA1Ud
# EwEB/wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRV
# HSAAMFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9V
# U0VSVHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDA1BggrBgEFBQcB
# AQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJ
# KoZIhvcNAQEMBQADggIBAA6+ZUHtaES45aHF1BGH5Lc7JYzrftrIF5Ht2PFDxKKF
# Oct/awAEWgHQMVHol9ZLSyd/pYMbaC0IZ+XBW9xhdkkmUV/KbUOiL7g98M/yzRyq
# UOZ1/IY7Ay0YbMniIibJrPcgFp73WDnRDKtVutShPSZQZAdtFwXnuiWl8eFARK3P
# mLqEm9UsVX+55DbVIz33Mbhba0HUTEYv3yJ1fwKGxPBsP/MgTECimh7eXomvMm0/
# GPxX2uhwCcs/YLxDnBdVVlxvDjHjO1cuwbOpkiJGHmLXXVNbsdXUC2xBrq9fLrfe
# 8IBsA4hopwsCj8hTuwKXJlSTrZcPRVSccP5i9U28gZ7OMzoJGlxZ5384OKm0r568
# Mo9TYrqzKeKZgFo0fj2/0iHbj55hc20jfxvK3mQi+H7xpbzxZOFGm/yVQkpo+ffv
# 5gdhp+hv1GDsvJOtJinJmgGbBFZIThbqI+MHvAmMmkfb3fTxmSkop2mSJL1Y2x/9
# 55S29Gu0gSJIkc3z30vU/iXrMpWx2tS7UVfVP+5tKuzGtgkP7d/doqDrLF1u6Ci3
# TpjAZdeLLlRQZm867eVeXED58LXd1Dk6UvaAhvmWYXoiLz4JA5gPBcz7J311uahx
# CweNxE+xxxR3kT0WKzASo5G/PyDez6NHdIUKBeE3jDPs2ACc6CkJ1Sji4PKWVT0/
# MYIEkjCCBI4CAQEwajBVMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBM
# aW1pdGVkMSwwKgYDVQQDEyNTZWN0aWdvIFB1YmxpYyBUaW1lIFN0YW1waW5nIENB
# IFIzNgIRAKQpO24e3denNAiHrXpOtyQwDQYJYIZIAWUDBAICBQCgggH5MBoGCSqG
# SIb3DQEJAzENBgsqhkiG9w0BCRABBDAcBgkqhkiG9w0BCQUxDxcNMjUxMjA0MTAw
# ODE4WjA/BgkqhkiG9w0BCQQxMgQw9pIujqadIyLZaaMwDemcI18giDD1AwCnmAdE
# iUjgHGZgJeCI9EYQRdwK1UJJmv7cMIIBegYLKoZIhvcNAQkQAgwxggFpMIIBZTCC
# AWEwFgQUOMkUgRBEtNxmPpPUdEuBQYaptbEwgYcEFMauVOR4hvF8PVUSSIxpw0p6
# +cLdMG8wW6RZMFcxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxLjAsBgNVBAMTJVNlY3RpZ28gUHVibGljIFRpbWUgU3RhbXBpbmcgUm9vdCBS
# NDYCEHojrtpTaZYPkcg+XPTH4z8wgbwEFIU9Yy2TgoJhfNCQNcSR3pLBQtrHMIGj
# MIGOpIGLMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEplcnNleTEUMBIG
# A1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29y
# azEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0
# eQIQNsKwvXwbOuejs902y8l1aDANBgkqhkiG9w0BAQEFAASCAgC5hV26hLT0F2MY
# xRrPy12A7A+L6XrhX8jO9wnkPUhT0WJn5dRb2cwPhAsbhSZnS/B0uyFZcX9CBAGL
# huZnoqxC19lqXug/lvJjZbOqSRCV5D8lLJr98Sf4SsFlp6g6+yZGuAIyXE73rygf
# lgVzfQQPGK4KUgb+ujZ08YHkUy0QpFHxDffsERSiQ0+jgNQ3QRn5TMLeqv7H68YC
# k2FUbgGAWKfnDoFT5KEUYdxy6WXkUDLu1FA676EOmys7VJRhJOj51UJHjMw2iIKI
# wNQa9JveWiS0vIdE8bx2kDFcocevZbNouZFonwXk/JTle5PW89TkWb/Wyub9yw2e
# 8xOyK/lmHOX5Z6ZpqWuWceK5lzOnFw0u/k9gTb7MAebdr+nE32PyKRRS4EH4r7gL
# s+9A4sdhR+vqGiRRMhGxTZNJ66vN1MAs2HO8PdLQeKXhqgXNYYXWT5zoRer7UvRY
# xmoi9Zz1pPqeosWWLqcN085zxAtMLDHz2VbcWVAFvkZWP/jYMrOgBd52sTD3BylB
# EXZy4v/wpial22rLYVWwMlAEz0BBLiIIz/rg8JqX69d2v9yb0pZ/D9YV5RKoIhtp
# swaAWIxhxbXg7jhkwgN1/8kkzu2ZqqS8Q5wZh1ibBOo6VKCyV5yMu1eRtCKRpMCb
# XEDoTSONs4PLDznYsJUSDYB2nz8eRw==
# SIG # End signature block
