Obs/bin/ObsDep/content/Powershell/Roles/Common/JustEnoughAdministrationDSC.psm1

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


Import-Module -Name "$PSScriptRoot\..\..\Common\Helpers.psm1"
Import-Module -Name "$PSScriptRoot\..\..\Common\StorageHelpers.psm1" -Force
Import-Module -Name "$PSScriptRoot\DscHelper.psm1"
Import-Module -Name "$PSScriptRoot\JeaHelper.psm1"

<#
.Synopsis
    Generates DSC configuration document(s) for the target node(s), as specified
    by the Role configuration. Returns the list of the JEA endpoints captured in the
    configuration.
#>

function New-JustEnoughAdministrationConfiguration
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$true)]
        [CloudEngine.Configurations.EceInterfaceParameters]
        $Parameters,

        [Parameter(Mandatory=$true)]
        [IO.DirectoryInfo] $ModulesRootPath,

        [Parameter(Mandatory=$false)]
        [IO.DirectoryInfo] $MofOutputPath=$null,

        [Parameter(Mandatory=$false)]
        [string] $TargetComputerName = 'localhost',

        [string[]] $TargetImageRole = $Parameters.Configuration.Role.Id,

        [string[]] $SourceImageRole
    )

    $ErrorActionPreference = 'Stop'
    if ($MofOutputPath -eq $null)
    {
        $MofOutputPath = Join-Path $ModulesRootPath "DSCConfigs\ConfigureJustEnoughAdministration"
    }
    Trace-Execution "$($MyInvocation.InvocationName) : BEGIN on $($env:COMPUTERNAME) as $($env:USERDOMAIN)\$($env:USERNAME)"
    $cloudRole = $Parameters.Roles["Cloud"].PublicConfiguration
    $securityInfo = $cloudRole.PublicInfo.SecurityInfo
    $domainRole = $Parameters.Roles["Domain"].PublicConfiguration
    $domainName = $domainRole.PublicInfo.DomainConfiguration.DomainName

    # Get all the roles that have JEA information
    $RolesToConfigure = $Parameters.Roles.GetEnumerator() |
        Where-Object { $Parameters.Roles[$_.Name].PublicConfiguration.PublicInfo.JEA } |
        Foreach-Object { $_.Name }

    if ($SourceImageRole)
    {
        Trace-Execution "Getting list of JEA endpoints defined under the following roles: $($SourceImageRole -join ', ')."
        $RolesToConfigure = $RolesToConfigure | where { $_ -in $SourceImageRole }
    }

    $endpoints = @()
    foreach($role in $RolesToConfigure)
    {
        $configuration = $Parameters.Roles[$role].PublicConfiguration.PublicInfo.JEA.Endpoints.Endpoint
        # Loop through all the endpoints defined
        foreach($endpoint in $configuration)
        {
            if (!$endpoint.TargetRoles)
            {
                if (-not ($TargetImageRole -contains $role))
                {
                    continue
                }
            }
            else
            {
                $applicable = $endpoint.TargetRoles.TargetRole | Where-Object { $TargetImageRole -contains $_.Id }
                if (!$applicable)
                {
                    continue
                }
            }

            $runAsGmsa = $endpoint.RunAsGmsa -and ($endpoint.RunAsGmsa -eq "True")
            $runAsVirtualAccount = $endpoint.RunAsVirtualAccount -and ($endpoint.RunAsVirtualAccount -eq "True")

            if ( -not ($runAsGmsa -or $runAsVirtualAccount) )
            {
                Trace-Execution "Create JEA endpoint '$($endpoint.Name)' as non-GMSA and non-virtual account (will use pass-through credential)."
            }

            Trace-Execution "Creating JEA Endpoint $($endpoint.Name) for Role $($TargetImageRole -join ', ')"

            # Define transportation options
            $transportOption = $null
            if ($endpoint.TransportOptions)
            {
                $transportOption = @{}
                $endpoint.TransportOptions.GetEnumerator() | foreach {
                    if ([Microsoft.PowerShell.Commands.WSManConfigurationOption].GetProperties().Name.Contains($_.Name))
                    {
                        $transportOption[$_.Name] = $_.Value
                    }
                    else
                    {
                        throw "Transport Option '$($_.Name)' for JEA endpoint not valid for WSManConfigurationOption"
                    }
                }

                $endpoint | Add-Member -MemberType NoteProperty -Name "TransportOption" -Value $transportOption -Force
            }

            # Path to the Powershell Modules folder
            $modulePath = Join-Path $ModulesRootPath "Program Files\WindowsPowerShell\Modules\"

            # Path where the psrc file will be stored
            $rcPath = Join-Path $modulePath "JEA\RoleCapabilities"

            # Create the folder where the RC files will be stored
            New-Item -Path $rcPath -ItemType Directory -Force | Out-Null

            $deployLatestVersion = -not($endpoint.AllVersions -and $endpoint.AllVersions -eq "True")

            # This flag checks if the endpoint gathers its rolecapability configuration from a nuget.
            # If there is no rc nuget dependency, then conduct the custom configuration
            $psrcFromNuget = $false
            $endpointVersion = ""
            $sourceVersionExtensionList = @()

            # If the endpoint has nuget defined, copy the contents inside the nuget to the right location.
            if($endpoint.Nugets)
            {
                $clusterName = Get-ManagementClusterName $Parameters
                $nugets = $endpoint.Nugets.Nuget
                foreach($nuget in $nugets)
                {
                    $nugetName = $nuget.Name
                    Trace-Execution "EndpointName: $($endpoint.Name) , NugetName: $nugetName"

                    # Get nuget store location on the library share
                    $virtualMachinesRole = $Parameters.Roles["VirtualMachines"].PublicConfiguration
                    $libraryShareNugetStorePath = Get-SharePath $Parameters $virtualMachinesRole.PublicInfo.LibraryShareNugetStoreFolder.Path $clusterName
                    $buildLocally = $Parameters.Context.ExecutionContext.BuildVhdLocally -and [bool]::Parse($Parameters.Context.ExecutionContext.BuildVhdLocally)

                    # Use the NuGet store on the file share, unless explicitly told not to (BuildVhdLocally) or the file share is not reachable.
                    $useLibrarySharePath = -not $buildLocally -and (Test-Path $libraryShareNugetStorePath)
                    Trace-Execution "useLibrarySharePath: $useLibrarySharePath"

                    # Collect all versions of the JEA endpoint nugets to support upgrading from an unknown stamp version
                    $getNugetVersionsParams = @{
                        NugetName = $NugetName
                        MostRecent = $deployLatestVersion
                    }

                    if($useLibrarySharePath)
                    {
                        $getNugetVersionsParams.NugetStorePath = $libraryShareNugetStorePath
                    }

                    $versionList = Get-NugetVersions @getNugetVersionsParams

                    # If version is required, but none are found, throw
                    if ($endpoint.RequiresVersion -and ($versionList.Count -eq 0)) {
                        Trace-Error "Requires version was specified, but no versions were found for endpoint '$($endpoint.Name)'"
                    }

                    # Loop through the list of versions and copy the content and PSRC(if applicable) to the right location
                    foreach($nugetVersion in $versionList)
                    {
                        if ($nuget.PackagedModules -and $nuget.PackagedModules.Path)
                        {
                            # Temporary location where the JEA module source code will be extracted
                            $tempPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
                            New-Item -Path $tempPath -ItemType Directory -Force | Out-Null

                            try
                            {
                                # Unpack the scripts for the JEA endpoint at a temporary location
                                Trace-Execution "Expand nuget: $nugetName with content from: $($nuget.PackagedModules.Path) to : $tempPath "

                                $expandNugetContentParams = @{
                                    NugetName = $NugetName
                                    SourcePath = $nuget.PackagedModules.Path
                                    DestinationPath = $tempPath
                                    Version = $nugetVersion
                                }

                                if($useLibrarySharePath)
                                {
                                    $expandNugetContentParams.NugetStorePath = $libraryShareNugetStorePath
                                }

                                Expand-NugetContent @expandNugetContentParams

                                # Define what the module path will look like and if the path does not exist, create it
                                $targetModulePath = $modulePath
                                if($nuget.PackagedModules.Destination)
                                {
                                    $targetModulePath = Join-Path $modulePath $nuget.PackagedModules.Destination
                                    if ((Test-Path -Path $targetModulePath) -eq $false)
                                    {
                                        $null = New-Item -Path $targetModulePath -ItemType Directory -Force
                                    }
                                }

                                # Copy content from the temporary path to the target path
                                $copy = @{ Path = "$tempPath\*"; Destination = "$targetModulePath\"; Recurse = $true; Force = $true}
                                if ($nuget.PackagedModules.Filter)
                                {
                                    $copy["Filter"] = $nuget.PackagedModules.Filter
                                }

                                Trace-Execution "Copying content from $tempPath to $targetModulePath"

                                try
                                {
                                    Copy-Item @copy
                                }
                                catch [System.IO.IOException]
                                {
                                    Trace-Execution "I/O exception ignored during copying of existing JEA modules, potentially due to module already being loaded"
                                }
                            }
                            catch
                            {
                                # Printing error message here as Remove-Item occasionally throws errors that mask the original issue.
                                Trace-Execution ($_ | Format-List *)
                                throw
                            }
                            finally
                            {
                                Remove-Item -Recurse $tempPath -Force -ErrorAction SilentlyContinue
                                if (Test-Path $tempPath)
                                {
                                    Remove-Item -Recurse $tempPath -Force -ErrorAction Stop
                                }
                            }
                        }

                        # If the RoleCapability is present and has a path value, psrc files will be picked up from the nuget
                        if ($nuget.RoleCapability -and $nuget.RoleCapability.Path)
                        {
                            Trace-Execution "Role Capability for the endpoint is defined in the nuget with path: $($nuget.RoleCapability.Path)"

                            # Recurse over all available versions of the target package
                            # There may be multiple RC files within the nuget, each representing a versioned endpoint.
                            # The customer config will only define one broad endpoint, so need to expand the endpoints
                            # to register by the versioned names.
                            $tempPath = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath ([System.IO.Path]::GetRandomFileName())
                            New-Item -Path $tempPath -ItemType Directory -Force | Out-Null
                            $psrcFromNuget = $true
                            try
                            {
                                $expandNugetContentParams = @{
                                    NugetName = $NugetName
                                    SourcePath = $nuget.RoleCapability.Path
                                    DestinationPath = $tempPath
                                    Version = $nugetVersion
                                }

                                if($useLibrarySharePath)
                                {
                                    $expandNugetContentParams.NugetStorePath = $libraryShareNugetStorePath
                                }

                                Expand-NugetContent @expandNugetContentParams

                                # Copy each RC file for each whitelist
                                foreach($whiteList in $endpoint.WhiteList)
                                {
                                    $copy = @{ Path = "$tempPath\*"; Filter = "$($whiteList.Name)*"; Destination = $rcPath; Recurse = $true; Force = $true }
                                    Trace-Execution "Copying content from: $tempPath to: $rcPath with whitelist name: $($whiteList.Name)"
                                    Copy-Item @copy

                                    Trace-Execution "Get version for the endpoint:$($endpoint.Name)"
                                    # If the version is not set yet, pick up the RC file with the name as (endpointName + Version)
                                    if ($whiteList.Name -like "$($endpoint.Name)*")
                                    {
                                        $rcFile = Get-ChildItem -Path $rcPath -Filter "$($whiteList.Name)*"
                                        foreach ($whitelistFile in $rcFile)
                                        {
                                            $roleCapabilityName = [System.IO.Path]::GetFileNameWithoutExtension($whitelistFile.FullName)
                                            $endpointVersion = $roleCapabilityName.Substring($whitelist.Name.Length, $roleCapabilityName.Length - $whitelist.Name.Length)
                                            if (-not($sourceVersionExtensionList -contains $endpointVersion))
                                            {
                                                $sourceVersionExtensionList += $endpointVersion
                                            }
                                        }
                                    }
                                }
                            }
                            catch
                            {
                                # Printing error message here as Remove-Item occasionally throws errors that mask the original issue.
                                Trace-Execution ($_ | Format-List *)
                                throw
                            }
                            finally
                            {
                                Remove-Item -Recurse $tempPath -Force -ErrorAction SilentlyContinue
                                if (Test-Path $tempPath)
                                {
                                    Remove-Item -Recurse $tempPath -Force -ErrorAction Stop
                                }
                            }
                        }
                    }
                 }
            } # Nuget expansion completed

            # No versions were found, so ensure that at least the non-versioned endpoint is created
            if([string]::IsNullOrEmpty($endpointVersion))
            {
                $sourceVersionExtensionList = @("")
            }

            # As we are done with Nuget expansion, if the PSRC file was not picked up from the nuget, create it.
            if(-not $psrcFromNuget)
            {
                # Simple endpoint from configuration definition, with no versions
                # Loop through all the whitelists and generate the PSRC files at the desired location.
                foreach($whiteList in $endpoint.Whitelist)
                {
                    $RCParams = Get-RoleCapabilityParams($whitelist)
                    Trace-Execution "Role Capabilities for endpoint '$($endpoint.Name)': "
                    Trace-Execution ($RCParams | ConvertTo-Json -depth 3)

                    New-Item -Path $rcPath -ItemType Directory -Force | Out-Null
                    New-PSRoleCapabilityFile -Path "$rcPath\$($whitelist.Name).psrc" @RCParams
                }
            }

            foreach ($endpointVersion in $sourceVersionExtensionList)
            {
                # Gather information needed to create the PSSC file and also for registration of JEA endpoint.
                # Clone the endpoint
                $e = $endpoint.Clone()

                # Session configuration
                $sessionConfigurationArgs = @{
                    SessionConfig = $endpoint.SessionConfiguration;
                    Endpointname = $endpoint.Name;
                }

                # If version was found add it to the name of the endpoint as it will be a versioned endpoint
                if([string]::IsNullOrEmpty($endpointVersion) -eq $false)
                {
                    $e.Name = $endpoint.Name + $endpointVersion
                    $sessionConfigurationArgs["Endpointname"] = $e.Name
                    $sessionConfigurationArgs["VersionExtension"] = $endpointVersion
                }

                # RunAs accounts
                if ($runAsGmsa)
                {
                    $RunAsAccountUser = "$domainName\$($endpoint.RunAsAccountID)"
                    $sessionConfigurationArgs["RunAsAccountUser"] = $RunAsAccountUser
                    $sessionConfigurationArgs["RunAsGmsa"] = $true
                    $e | Add-Member -MemberType NoteProperty -Name "RunAsAccountUser" -Value $RunAsAccountUser -Force
                }
                elseif($runAsVirtualAccount)
                {
                    Trace-Execution "[$($endpoint.Name)] will run under virtual admin account"
                    $e | Add-Member -MemberType NoteProperty -Name "RunAsVirtualAccount" -Value $true -Force
                    $sessionConfigurationArgs["RunAsVirtualAccount"] = $true
                }
                else
                {
                    Trace-Execution "Endpoint $($endpoint.Name) will use user pass-through credential"
                    $sessionConfigurationArgs["RunAsPassThroughCredential"] = $true
                }

                $scParams = Get-SessionConfigurationParams @sessionConfigurationArgs
                $e | Add-Member -MemberType NoteProperty -Name "RoleDefinitions" -Value $scParams.RoleDefinitions -Force
                if($scParams.TranscriptDirectory)
                {
                    $e | Add-Member -MemberType NoteProperty -Name "TranscriptDirectory" -Value $scParams.TranscriptDirectory -Force
                }

                if($scParams.SessionType)
                {
                    $e | Add-Member -MemberType NoteProperty -Name "SessionType" -Value $scParams.SessionType -Force
                }

                if($scParams.LanguageMode)
                {
                    $e | Add-Member -MemberType NoteProperty -Name "LanguageMode" -Value $scParams.LanguageMode -Force
                }

                $endpoints += $e
            }
        }
    }

    # If no endpoints are defined, move on.
    if ($endpoints.Count -eq 0)
    {
        Trace-Execution "No endpoints to deploy for role [$TargetImageRole]"
        return;
    }

    # DSC is slow to import at module parse time. Defer import of all DSC configurations until runtime.
    Import-Module "$PSScriptRoot\JustEnoughAdministrationDSCconfig.psm1" -DisableNameChecking

    $dscEncryptionCert = GetDscEncryptionCert
    $ConfigData= @{
        AllNodes = @(
                @{
                    NodeName = $TargetComputerName
                    CertificateFile = "$env:temp\DscEncryptionPublicKey.cer"
                    ThumbPrint = $dscEncryptionCert.ThumbPrint
                };
            );
    }

    Remove-Item  "$MofOutputPath\$TargetComputerName.mof" -Force -ErrorAction SilentlyContinue

    Trace-Execution "Generating JustEnoughAdministration endpoint MOFs"
    ConfigureJustEnoughAdministration -ConfigurationData $ConfigData -Endpoints $endpoints -OutputPath $MofOutputPath | Out-Null

    Trace-Execution "$($MyInvocation.InvocationName) : END on $($env:COMPUTERNAME) as $($env:USERDOMAIN)\$($env:USERNAME)"

    Trace-Execution "Created configuration for the following endpoints:$([System.Environment]::NewLine)$($endpoints.Name -join [System.Environment]::NewLine)"

    return $endpoints.Name
}

function Get-NugetVersions
{
    <#
    .SYNOPSIS
    Gets all versions of Nuget packages that exist in a specified source location.
 
    .EXAMPLE
    Get-NugetVersions -NugetName "MyNuget" -SourcePath "content"
 
    .PARAMETER NugetName
    The name of the nuget to filter by.
 
    .PARAMETER MostRecent
    Whether to report the most recent version only
 
    .PARAMETER NugetStorePath
    The path from which the nuget packages should be derived.
 
    #>

    [CmdletBinding()]
    PARAM (
        [Parameter(Mandatory=$true, Position=0)]
        [ValidateNotNullOrEmpty()]
        [string[]]
        $NugetName,

        [Parameter(Mandatory=$false)]
        [switch]
        $MostRecent,

        [Parameter()]
        [ValidateNotNullOrEmpty()]
        [string]
        $NugetStorePath = "$env:SystemDrive\CloudDeployment\NuGetStore"
    )
    PROCESS
    {
        $ErrorActionPreference = "stop"

        Trace-Execution "Finding nuget package $NugetName from store $NugetStorePath"

        $nugetPackageList = Find-Package -Source $NugetStorePath -Name $NugetName -ProviderName "nuget" -AllVersions:$(-not $MostRecent) -Verbose -Force

        if ($nugetPackageList)
        {
            $versionArray = $nugetPackageList.Version
        }
        else
        {
            $versionArray = @()
        }

        return $versionArray
    }
}

Export-ModuleMember New-JustEnoughAdministrationConfiguration
# SIG # Begin signature block
# MIInzgYJKoZIhvcNAQcCoIInvzCCJ7sCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCqAiA/u5EXKJ25
# cdRpgvdnQk4G9Wp9nEHgRODHkpP+D6CCDYUwggYDMIID66ADAgECAhMzAAADri01
# 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/Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAOuLTVRyFOPVR0AAAAA
# A64wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIPdQ
# 11oAHrmktdAw/ha3CecLykCnX9UV4e7bw19fGD/rMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEAl4K4EB7DoJGTWeEeTgg42npRwu1SjrLvfgE6
# v5xsX2JDOUjedGvZhAfZY+vW2+hGc9DURn2D0BT0hyGj/Fr8z7Igf2ME6fwJwVI2
# eFfXg/dqxY6nKSC7wf01cxkMPQWjnP5CNSCRBGArjEt6GSlmWeFL85g9O4YYBGOw
# D67KRAEMHS9DDcxP017zmh3smJeWUOl8GDkgGJVnhs8RG2O/+FYTKzgsQZFsUxF/
# wUG+uah7pAYhx0wdns7/VR3x7Z+m7VI3uxfryQXW1143sI6qOUzFXtLgWZLrBHae
# 3jIit49GaHSq3Ps7JZLP3lyXJZ6Mzy2SG3FuzXVIMqPo3Di+36GCFykwghclBgor
# BgEEAYI3AwMBMYIXFTCCFxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCDMGGQjUlUunrjXaJfA0HZIk02oQQ39Q+Fk
# aZsV9ZgUBwIGZdXm1gI/GBMyMDI0MDMxMTE4MTY1NC45MjZaMASAAgH0oIHYpIHV
# MIHSMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsT
# HVRoYWxlcyBUU1MgRVNOOjA4NDItNEJFNi1DMjlBMSUwIwYDVQQDExxNaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAHajtXJ
# WgDREbEAAQAAAdowDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTAwHhcNMjMxMDEyMTkwNjU5WhcNMjUwMTEwMTkwNjU5WjCB0jELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z
# b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMg
# VFNTIEVTTjowODQyLTRCRTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJOQ
# Bgh2tVFR1j8jQA4NDf8bcVrXSN080CNKPSQo7S57sCnPU0FKF47w2L6qHtwm4EnC
# lF2cruXFp/l7PpMQg25E7X8xDmvxr8BBE6iASAPCfrTebuvAsZWcJYhy7prgCuBf
# 7OidXpgsW1y8p6Vs7sD2aup/0uveYxeXlKtsPjMCplHkk0ba+HgLho0J68Kdji3D
# M2K59wHy9xrtsYK+X9erbDGZ2mmX3765aS5Q7/ugDxMVgzyj80yJn6ULnknD9i4k
# UQxVhqV1dc/DF6UBeuzfukkMed7trzUEZMRyla7qhvwUeQlgzCQhpZjz+zsQgpXl
# PczvGd0iqr7lACwfVGog5plIzdExvt1TA8Jmef819aTKwH1IVEIwYLA6uvS8kRdA
# 6RxvMcb//ulNjIuGceyykMAXEynVrLG9VvK4rfrCsGL3j30Lmidug+owrcCjQagY
# mrGk1hBykXilo9YB8Qyy5Q1KhGuH65V3zFy8a0kwbKBRs8VR4HtoPYw9z1DdcJfZ
# BO2dhzX3yAMipCGm6SmvmvavRsXhy805jiApDyN+s0/b7os2z8iRWGJk6M9uuT24
# 93gFV/9JLGg5YJJCJXI+yxkO/OXnZJsuGt0+zWLdHS4XIXBG17oPu5KsFfRTHREl
# oR2dI6GwaaxIyDySHYOtvIydla7u4lfnfCjY/qKTAgMBAAGjggFJMIIBRTAdBgNV
# HQ4EFgQUoXyNyVE9ZhOVizEUVwhNgL8PX0UwHwYDVR0jBBgwFoAUn6cVXQBeYl2D
# 9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3Nv
# ZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy
# MDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1l
# LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUB
# Af8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQAD
# ggIBALmDVdTtuI0jAEt41O2OM8CU237TGMyhrGr7FzKCEFaXxtoqk/IObQriq1ca
# HVh2vyuQ24nz3TdOBv7rcs/qnPjOxnXFLyZPeaWLsNuARVmUViyVYXjXYB5DwzaW
# ZgScY8GKL7yGjyWrh78WJUgh7rE1+5VD5h0/6rs9dBRqAzI9fhZz7spsjt8vnx50
# WExbBSSH7rfabHendpeqbTmW/RfcaT+GFIsT+g2ej7wRKIq/QhnsoF8mpFNPHV1q
# /WK/rF/ChovkhJMDvlqtETWi97GolOSKamZC9bYgcPKfz28ed25WJy10VtQ9P5+C
# /2dOfDaz1RmeOb27Kbegha0SfPcriTfORVvqPDSa3n9N7dhTY7+49I8evoad9hdZ
# 8CfIOPftwt3xTX2RhMZJCVoFlabHcvfb84raFM6cz5EYk+x1aVEiXtgK6R0xn1wj
# MXHf0AWlSjqRkzvSnRKzFsZwEl74VahlKVhI+Ci9RT9+6Gc0xWzJ7zQIUFE3Jiix
# 5+7KL8ArHfBY9UFLz4snboJ7Qip3IADbkU4ZL0iQ8j8Ixra7aSYfToUefmct3dM6
# 9ff4Eeh2Kh9NsKiiph589Ap/xS1jESlrfjL/g/ZboaS5d9a2fA598mubDvLD5x5P
# P37700vm/Y+PIhmp2fTvuS2sndeZBmyTqcUNHRNmCk+njV3nMIIHcTCCBVmgAwIB
# AgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1
# WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O
# 1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZn
# hUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t
# 1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxq
# D89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmP
# frVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSW
# rAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv
# 231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zb
# r17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYcten
# IPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQc
# xWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17a
# j54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQAB
# MCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQU
# n6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEw
# QTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9E
# b2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQB
# gjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/
# MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJ
# oEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01p
# Y1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYB
# BQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9v
# Q2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3h
# LB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x
# 5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74p
# y27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1A
# oL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbC
# HcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB
# 9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNt
# yo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3
# rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcV
# v7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A24
# 5oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lw
# Y1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB
# 0jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMk
# TWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1U
# aGFsZXMgVFNTIEVTTjowODQyLTRCRTYtQzI5QTElMCMGA1UEAxMcTWljcm9zb2Z0
# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAQqIfIYljHUbNoY0/
# wjhXRn/sSA2ggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN
# BgkqhkiG9w0BAQUFAAIFAOmZbs4wIhgPMjAyNDAzMTExOTUxNDJaGA8yMDI0MDMx
# MjE5NTE0MlowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA6ZluzgIBADAHAgEAAgId
# CzAHAgEAAgISMjAKAgUA6ZrATgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEE
# AYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GB
# AIi6AJjK3X06yU7I1N7cNeDL7Y4KHnoV+edLLpe1LVX2wHKwkW/cS/ZYNJv5jRVs
# r94Ocx00hXLSnxs6bOI1JHYttMOwPCrwbadN6ka0G6EdPH84Qpxjbnk01kGKEBx+
# JWKnOoKnrRDLR/wrNxGgXO1fvMTP1jrdbADoa/PistERMYIEDTCCBAkCAQEwgZMw
# fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
# TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAHajtXJWgDREbEAAQAA
# AdowDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB
# BDAvBgkqhkiG9w0BCQQxIgQgR4PPuQgCEWo3h48VoseY6xp9t0fOqP9qWrEdRJYN
# NsUwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCAipaNpYsDvnqTe95Dj1C09
# 020I5ljibrW/ndICOxg9xjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
# QSAyMDEwAhMzAAAB2o7VyVoA0RGxAAEAAAHaMCIEIOVlnbiuMr9qn8Ud96DRKf8K
# fVfppLN1O1DuKcs5MV7cMA0GCSqGSIb3DQEBCwUABIICACsJkkVZWf2yAC+u66n7
# iCiI49t5d7rCikqkYZ1HZYQ6+fXDSWffHCSEGZRN2MVcRdlHlCCt3uyAALjuvvTt
# S6IV8uhyEnFBztgJ6qq26zuN745o9L9wSgznXgLLrdGB92ddDTV5uOw7dIP7Ei8j
# niOjObaaMgaUwVx6sj3sV+5nL1IhNEOVNBcP6UEwdicQt7YSJhRRCD2fMHNbM1a4
# lyNapL1wq2DOsI2gVAtp0TqNiQjr+OhPvO8FX9DRSERuvCoPBN7cgdL/aZTemvDD
# c7d0hoQu5E9jTcMgs61iG/6hatSCb+8pNhA0v2fkOOsbF7M67I2n7rjYnS+agmpz
# ioZgOziH45qSSK+my9O5gDMFjk4yXyO6v0SINroMd8xspZqjm+vy5DtyWOBCVZio
# 68b/LiGYNcN9VR88K4SRKXgCuZSnMcz3Shst54IL3QLblNv2g45A27/kmAsShio+
# ZxRt0qQyXzMMfe0MXpzm0epPzAg12E5mevrsNGiS8ZT1XeRdJtmzJxJPkRUvpJqg
# +BMagE2/4ocHi59vHPJGu5xnu12jbEfks0SI7O1xerJnOrNiTlkyPvM87qGXtBSZ
# 0b4Y4dGIeu8YJuHks259Pmtwyum92v21GoW+iK4Im/gwPbCrDN6knZQNaT9kDl9+
# GfFEfiPs9qIAz1hNm+4a0hZ1
# SIG # End signature block