Private/_DeploymentFunctions.ps1
|
function _deployProject { param ( [Parameter(Mandatory = $true)] [string]$FunctionName, [Parameter(Mandatory = $false)] [string]$FunctionHandler, [Parameter(Mandatory = $false)] [string]$PowerShellFunctionHandler, [Parameter(Mandatory = $false)] [string]$ProfileName, [Parameter(Mandatory = $false)] [string]$AWSAccessKeyId, [Parameter(Mandatory = $false)] [string]$AWSSecretKey, [Parameter(Mandatory = $false)] [string]$AWSSessionToken, [Parameter(Mandatory = $false)] [string]$Region, [Parameter(Mandatory = $false)] [string]$FunctionRole, [Parameter(Mandatory = $false)] [int]$FunctionMemory, [Parameter(Mandatory = $false)] [string]$FunctionArchitecture, [Parameter(Mandatory = $false)] [int]$FunctionTimeout, [Parameter(Mandatory = $false)] [string[]]$FunctionLayer, [Parameter(Mandatory = $false)] [Boolean]$PublishNewVersion, [Parameter(Mandatory = $false)] [Hashtable]$EnvironmentVariables, [Parameter(Mandatory = $false)] [string]$KmsKeyArn, [Parameter(Mandatory = $false)] [string[]]$FunctionSubnets, [Parameter(Mandatory = $false)] [string[]]$FunctionSecurityGroups, [Parameter(Mandatory = $false)] [string]$DeadLetterQueueArn, [Parameter(Mandatory = $false)] [string]$TracingMode, [Parameter(Mandatory = $false)] [string]$S3Bucket, [Parameter(Mandatory = $false)] [string]$S3KeyPrefix, [Parameter(Mandatory = $false)] [Hashtable]$Tags, [Parameter(Mandatory = $false)] [Boolean]$DisableInteractive, [Parameter(Mandatory = $false)] [string]$BuildDirectory ) _validateDotnetInstall if ($BuildDirectory) { Push-Location $BuildDirectory } try { $arguments = '"{0}"' -f $FunctionName $arguments += " --configuration Release --framework $AwsPowerShellTargetFramework --function-runtime $AwsPowerShellLambdaRuntime" $arguments += ' ' $arguments += _setupAWSCredentialsCliArguments -ProfileName $ProfileName -AWSAccessKeyId $AWSAccessKeyId -AWSSecretKey $AWSSecretKey -AWSSessionToken $AWSSessionToken $arguments += ' ' $arguments += _setupAWSRegionCliArguments -Region $Region if (($FunctionHandler)) { $arguments += " --function-handler $FunctionHandler" } if (($FunctionRole)) { $arguments += " --function-role $FunctionRole" } if (($FunctionMemory)) { $arguments += " --function-memory-size $FunctionMemory" } if (($FunctionArchitecture)) { $arguments += " --function-architecture $FunctionArchitecture" } if (($FunctionTimeout)) { $arguments += " --function-timeout $FunctionTimeout" } $formattedLayers = _formatArray($FunctionLayer) if(($formattedLayers)) { $arguments += " --function-layers $formattedLayers" } if (($PublishNewVersion)) { $arguments += ' --function-publish true' } if ($PowerShellFunctionHandler) { $arguments += ' --append-environment-variables "{0}={1}"' -f $AwsPowerShellFunctionEnvName, $PowerShellFunctionHandler Write-Host "Setting the $AwsPowerShellFunctionEnvName environment variable to $PowerShellFunctionHandler to identify the PowerShell function to call" } $formattedEnvironmentVariables = _formatHashTable($EnvironmentVariables) if (($formattedEnvironmentVariables)) { $arguments += ' --environment-variables "{0}"' -f $formattedEnvironmentVariables } if (($KmsKeyArn)) { $arguments += " --kms-key $KmsKeyArn" } $formattedSubnets = _formatArray($FunctionSubnets) if (($formattedSubnets)) { $arguments += " --function-subnets $formattedSubnets" } $formattedSecurityGroups = _formatArray($FunctionSecurityGroups) if (($formattedSecurityGroups)) { $arguments += " --function-security-groups $formattedSecurityGroups" } if (($DeadLetterQueueArn)) { $arguments += " --dead-letter-target-arn $DeadLetterQueueArn" } if (($TracingMode)) { $arguments += " --tracing-mode $TracingMode" } if (($S3Bucket)) { $arguments += " --s3-bucket $S3Bucket" } if (($S3KeyPrefix)) { $arguments += " --s3-prefix $S3KeyPrefix" } $formattedTags = _formatHashTable($Tags) if (($formattedTags)) { $arguments += ' --tags "{0}"' -f $formattedTags } if (($DisableInteractive)) { $arguments += ' --disable-interactive true' } $amazonLambdaToolsPath = _configureAmazonLambdaTools $moduleVersion = "Unknown" $module = $MyInvocation.MyCommand.Module if ($module) { $moduleVersion = $module.Version.ToString() } $userAgent = "lib/AWSLambdaPSCore#$moduleVersion" if ($env:AWS_EXECUTION_ENV) { $env:AWS_EXECUTION_ENV += " $userAgent" } else { $env:AWS_EXECUTION_ENV = "AWSLambdaPSCore $userAgent" } try { if ($DisableInteractive) { Invoke-Expression "$amazonLambdaToolsPath deploy-function $arguments" | Foreach-Object {Write-Verbose -Message "$_`r"} } else { Write-Host 'Initiate deployment' Invoke-Expression "$amazonLambdaToolsPath deploy-function $arguments" } } finally { Remove-Item Env:\AWS_EXECUTION_ENV } if ($LASTEXITCODE -ne 0) { $msg = @" Error publishing PowerShell Lambda Function: $LastExitCode CALLSTACK:$(Get-PSCallStack | Out-String) "@ throw $msg } } finally { Pop-Location } } function _packageProject { param ( [Parameter(Mandatory = $true)] [string]$OutputPackage, [Parameter(Mandatory = $false)] [string]$BuildDirectory, [Parameter(Mandatory = $false)] [string]$FunctionArchitecture ) _validateDotnetInstall if (($BuildDirectory)) { Push-Location $BuildDirectory } try { $arguments = " --configuration Release --framework $AwsPowerShellTargetFramework --function-runtime $AwsPowerShellLambdaRuntime" if (($OutputPackage)) { $arguments += " --output-package `"$OutputPackage`"" } if($FunctionArchitecture) { $arguments += " --function-architecture $FunctionArchitecture" } $amazonLambdaToolsPath = _configureAmazonLambdaTools Write-Host 'Initiate packaging' # All output from the function deployment is sent to the verbose stream to allow user controlled access # to this level of detail Write-Verbose -Message "$amazonLambdaToolsPath package $arguments" Invoke-Expression "$amazonLambdaToolsPath package $arguments" | Foreach-Object {Write-Verbose -Message "$_`r"} if ($LASTEXITCODE -ne 0) { $msg = @" Error publishing PowerShell Lambda Function: $LastExitCode CALLSTACK:$(Get-PSCallStack | Out-String) "@ throw $msg } } finally { Pop-Location } } function _setupAWSCredentialsCliArguments { param ( [string]$ProfileName, [string]$AWSAccessKeyId, [string]$AWSSecretKey, [string]$AWSSessionToken ) if ($ProfileName) { return "--profile $ProfileName" } if ($AWSAccessKeyId -or $AWSSecretKey -or $AWSSessionToken) { if(!($AWSAccessKeyId)) { throw "The AWSAccessKeyId parameter is required when AWSSecretKey or AWSSessionToken are set." } if(!($AWSSecretKey)) { throw "The AWSSecretKey parameter is required when AWSAccessKeyId is set." } $arguments = "--aws-access-key-id $AWSAccessKeyId --aws-secret-key $AWSSecretKey" if($AWSSessionToken) { $arguments += " --aws-session-token $AWSSessionToken" } return $arguments } # Look to see if the AWS module is loaded and that it was used to configure credentials for the shell. # If it has then pass those credentials into the Lambda dotnet CLI tool. if (Get-Command 'Get-AWSCredentials' -ErrorAction SilentlyContinue) { $shellCredentials = Get-AWSCredentials if ($shellCredentials) { $realCreds = $shellCredentials.GetCredentials() Write-Verbose -Message 'Using aws credentials configured for the hosting shell' $arguments = '--aws-access-key-id {0} --aws-secret-key {1}' -f $realCreds.AccessKey, $realCreds.SecretKey if ($realCreds.UseToken) { Write-Verbose -Message 'Using session token' $arguments += ' --aws-session-token {0}' -f $realCreds.Token } return $arguments } } return [String]::Empty } function _setupAWSRegionCliArguments { param ( [string]$Region ) if ($Region) { return "--region $Region" } if (Get-Command 'Get-DefaultAWSRegion' -ErrorAction SilentlyContinue) { $shellRegion = Get-DefaultAWSRegion if ($shellRegion) { Write-Verbose -Message ('Using region {0} configured for the hosting shell' -f $shellRegion.Region) return '--region {0}' -f $shellRegion.Region } } return [String]::Empty } function _configureAmazonLambdaTools { Write-Host 'Restoring .NET Lambda deployment tool' # see if tool is already installed $amazonLambdaToolsInstalled = & dotnet tool list -g | Select-String -Pattern Amazon.Lambda.Tools -SimpleMatch -Quiet # When "-Verbose" switch was used this output was not hidden. # Using stream redirection to force hide all output from the dotnet cli call if (-not $amazonLambdaToolsInstalled) { Write-Verbose -Message 'Installing .NET Global Tool Amazon.Lambda.Tools' & dotnet tool install -g Amazon.Lambda.Tools *>&1 | Out-Null } else { Write-Verbose -Message 'Updating .NET Global Tool Amazon.Lambda.Tools' # When "-Verbose" switch was used this output was not hidden. # Using stream redirection to force hide all output from the dotnet cli call & dotnet tool update -g Amazon.Lambda.Tools *>&1 | Out-Null } if ($LASTEXITCODE -ne 0) { $msg = @" Error configuring .NET CLI AWS Lambda deployment tools: $LastExitCode CALLSTACK:$(Get-PSCallStack | Out-String) "@ throw $msg } $toolsFolder = Join-Path -Path '~' -ChildPath '.dotnet' -AdditionalChildPath 'tools' $amazonLambdaToolsPath = Join-Path -Path $toolsFolder -ChildPath 'dotnet-lambda.exe' Write-Verbose -Message 'Looking for windows excutable for dotnet-lambda.exe' if (!(Test-Path -Path $amazonLambdaToolsPath)) { Write-Verbose -Message 'Did not find windows executable, assuming on non windows platform and using dotnet-lambda' $amazonLambdaToolsPath = Join-Path -Path $toolsFolder -ChildPath 'dotnet-lambda' } return $amazonLambdaToolsPath } function _formatHashTable { param ( [Parameter(Mandatory = $false)] [Hashtable]$Table ) if (!($Table) -or $Table.Count -eq 0) { return $null } $sb = [System.Text.StringBuilder]::new() $Table.Keys | ForEach-Object { if ($sb.Length -ne 0) { $sb.Append(";") | Out-Null } $sb.AppendFormat('{0}={1}', $_, $Table[$_]) | Out-Null } return $sb.ToString() } function _formatArray { param ( [Parameter(Mandatory = $false)] [string[]]$Items ) if (!($Items) -or $Items.Count -eq 0) { return $null } $sb = [System.Text.StringBuilder]::new() $items | ForEach-Object { if ($sb.Length -ne 0) { $sb.Append(",") | Out-Null } $sb.Append($_) | Out-Null } return $sb.ToString() } function _prepareDependentPowerShellModules { param ( [Parameter(Mandatory = $true)] [string]$Script, [Parameter(Mandatory = $true)] [string]$ProjectDirectory, [Parameter(Mandatory = $true)] [bool]$ClearExisting, [Parameter()] [string[]]$ModuleRepository ) $SavedModulesDirectory = Join-Path -Path $ProjectDirectory -ChildPath $ProjectModuleDirectory if ($ClearExisting -and (Test-Path -Path $SavedModulesDirectory)) { Remove-Item -Path $SavedModulesDirectory -Recurse -Force } if (!(Test-Path -Path $SavedModulesDirectory)) { New-Item -ItemType directory -Path $SavedModulesDirectory | Out-Null } ## Use the FullName property of the $Script fileinfo object, as [System.Management.Automation.Language.Parser]::ParseFile() does not succeed with PSPath values like `Microsoft.PowerShell.Core\FileSystem::\\someserver\somepath\Get-Something.ps1`. ## $Script will have a PSPath value like this when the given file is at a UNC path. $strScriptFullname = (Get-Item -Path $Script).FullName ## variable in which to place any ParseFile() errors, so as to be able to check for them $arrErrorFromParseFile = @() $ast = [System.Management.Automation.Language.Parser]::ParseFile($strScriptFullname, [ref]$null, [ref]$arrErrorFromParseFile) if (($arrErrorFromParseFile | Measure-Object).Count -gt 0) { ## Write a warning (not terminating for now) Write-Warning "Received error trying to parse given script file '$Script'. Resulting Lambda package might not contain required PowerShell modules needed for success" } ## end if if ($ast.ScriptRequirements.RequiredModules) { $ast.ScriptRequirements.RequiredModules | ForEach-Object -Process { if ($_.Name -ieq 'AWSPowerShell') { Write-Warning 'This script requires the AWSPowerShell module which is not supported. Please change the #Requires statement to use the service specifc modules like AWS.Tools.S3 which is compatible with PowerShell 6.0 and above.' Write-Warning 'To use the AWS CmdLets install the AWS.Tools.* module for the services needed and then update the #Requires statement to the version installed. If you are not going to use the AWS CmdLets then remove the #Requires statement from the script.' throw 'The AWSPowerShell Module is not supported. Change the #Requires statement to reference the service specific modules like AWS.Tools.S3 module instead.' } $localModule = _findLocalModule -Name $_.Name -Version $_.Version if ($localModule) { Write-Host ('Copying local module {0}({1}) from {2}' -f $localModule.Name, $localModule.Version, $localModule.ModuleBase) $copyPath = Join-Path -Path $SavedModulesDirectory -ChildPath $localModule.Name -AdditionalChildPath $localModule.Version.ToString() if (!(Test-Path -Path $copyPath)) { New-Item -ItemType directory -Path $copyPath | Out-Null } Copy-Item -Path (Join-Path -Path $localModule.ModuleBase -ChildPath '*') -Destination $copyPath -Recurse } else { $splat = @{ Name = $_.Name Path = $SavedModulesDirectory ErrorAction = 'Stop' } if ($_.Version) { $splat.Add('RequiredVersion',$_.Version) } if ($ModuleRepository) { $splat.Add('Repository',$ModuleRepository) } # in the Save-Module call, replace -RequiredVersion with @splat Write-Host ('Saving module {0}' -f $_.Name) Save-Module @splat } } } ## Add verbosity that no RequiredModules found else {Write-Verbose "No RequiredModules found for script '$Script'"} } function _findLocalModule { param ( [Parameter(Mandatory = $true)] [string]$Name, [Parameter()] [Version]$Version ) $loadedModule = Get-Module -Name $Name if ($loadedModule -and ($Version -eq $null -or $Version -eq $loadedModule.Version)) { $message = 'Found imported module {0} ({1}) to save with package bundle.' -f $loadedModule.Name, $loadedModule.Version.ToString() Write-Verbose -Message $message return $loadedModule } $availableModules = Get-Module -ListAvailable -Name $Name | Sort-Object -Property Version -Descending # Select-Object added to ensure multiple installed copies of a specified version won't break staging folder # names. Before: ModuleName\System.Obejct[]\. After: Module\Version\ $availableModules | ForEach-Object -Process { if ($null -eq $Version -or $_.Version -eq $Version) { $message = 'Found installed module {0} ({1}) to save with package bundle.' -f $_.Name, $_.Version.ToString() Write-Verbose -Message $message return $_ } } | Select-Object -First 1 return $null } function _validateDotnetInstall { $application = Get-Command -Name dotnet if (!($application)) { throw '.NET 6 SDK was not found which is required to build the PowerShell Lambda package bundle. Download the .NET 6 SDK from https://www.microsoft.com/net/download' } $minVersion = [System.Version]::Parse('6.0.100') $foundMin = $false $installedSDKs = & dotnet --list-sdks foreach ($sdk in $installedSDKs) { $foundVersion = $sdk.split(' ')[0] $version = [System.Version]::new() if ([System.Version]::TryParse($foundVersion, [ref]$version)) { if ($minVersion -le $foundVersion) { $foundMin = $true } } } if (!($foundMin)) { throw 'The installed .NET SDK does not meet the minimum requirement to build the PowerShell Lambda package bundle. Download the .NET 6 SDK from https://www.microsoft.com/net/download' } } function _createStagingDirectory { param ( [Parameter(Mandatory = $true)] [String]$Name, [Parameter(Mandatory = $false)] [String]$StagingDirectory ) if ($StagingDirectory) { $NewStagingDirectory = Join-Path -Path $StagingDirectory -ChildPath $Name } else { $NewStagingDirectory = Join-Path -Path ([System.IO.Path]::GetTempPath()) -ChildPath $Name } if (Test-Path -Path $NewStagingDirectory) { Write-Verbose -Message 'Removing previous staging directory' Remove-Item -Path $NewStagingDirectory -Recurse -Force } Write-Host "Staging deployment at $NewStagingDirectory" New-Item -ItemType Directory -Path $NewStagingDirectory -Force | Out-Null return $NewStagingDirectory } # SIG # Begin signature block # MIIutQYJKoZIhvcNAQcCoIIupjCCLqICAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCApAWm4DNJ9qxoY # ygEcvmyxDXKbZFQ6KSs9YpDJRtD0lqCCE+owggXAMIIEqKADAgECAhAP0bvKeWvX # +N1MguEKmpYxMA0GCSqGSIb3DQEBCwUAMGwxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xKzApBgNV # BAMTIkRpZ2lDZXJ0IEhpZ2ggQXNzdXJhbmNlIEVWIFJvb3QgQ0EwHhcNMjIwMTEz # MDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMM # RGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQD # ExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz7MKnJS7JIT3yithZwuEppz1Yq3aa # za57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS5F/WBTxSD1Ifxp4VpX6+n6lXFllV # cq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7bXHiLQwb7iDVySAdYyktzuxeTsiT # +CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfISKhmV1efVFiODCu3T6cw2Vbuyntd # 463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jHtrHEtWoYOAMQjdjUN6QuBX2I9YI+ # EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14Ztk6MUSaM0C/CNdaSaTC5qmgZ92k # J7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2h4mXaXpI8OCiEhtmmnTK3kse5w5j # rubU75KSOp493ADkRSWJtppEGSt+wJS00mFt6zPZxd9LBADMfRyVw4/3IbKyEbe7 # f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPRiQfhvbfmQ6QYuKZ3AeEPlAwhHbJU # KSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ERElvlEFDrMcXKchYiCd98THU/Y+wh # X8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4KJpn15GkvmB0t9dmpsh3lGwIDAQAB # o4IBZjCCAWIwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU7NfjgtJxXWRM3y5n # P+e6mK4cD08wHwYDVR0jBBgwFoAUsT7DaQP4v0cB1JgmGggC72NkK8MwDgYDVR0P # AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMH8GCCsGAQUFBwEBBHMwcTAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEkGCCsGAQUFBzAC # hj1odHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRIaWdoQXNzdXJh # bmNlRVZSb290Q0EuY3J0MEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydEhpZ2hBc3N1cmFuY2VFVlJvb3RDQS5jcmwwHAYD # VR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQELBQADggEBAEHx # qRH0DxNHecllao3A7pgEpMbjDPKisedfYk/ak1k2zfIe4R7sD+EbP5HU5A/C5pg0 # /xkPZigfT2IxpCrhKhO61z7H0ZL+q93fqpgzRh9Onr3g7QdG64AupP2uU7SkwaT1 # IY1rzAGt9Rnu15ClMlIr28xzDxj4+87eg3Gn77tRWwR2L62t0+od/P1Tk+WMieNg # GbngLyOOLFxJy34riDkruQZhiPOuAnZ2dMFkkbiJUZflhX0901emWG4f7vtpYeJa # 3Cgh6GO6Ps9W7Zrk9wXqyvPsEt84zdp7PiuTUy9cUQBY3pBIowrHC/Q7bVUx8ALM # R3eWUaNetbxcyEMRoacwggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggduMIIFVqADAgECAhADmooc3J4LAjb9FLn2g0iAMA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjUwNjAzMDAwMDAwWhcNMjYwNjAyMjM1OTU5WjCB9jET # MBEGCysGAQQBgjc8AgEDEwJVUzEZMBcGCysGAQQBgjc8AgECEwhEZWxhd2FyZTEd # MBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xEDAOBgNVBAUTBzQxNTI5NTQx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdTZWF0 # dGxlMSIwIAYDVQQKExlBbWF6b24gV2ViIFNlcnZpY2VzLCBJbmMuMRcwFQYDVQQL # Ew5TREtzIGFuZCBUb29sczEiMCAGA1UEAxMZQW1hem9uIFdlYiBTZXJ2aWNlcywg # SW5jLjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAKc7ffRFlFB89cU3 # j76EOoK8sFXFunuUhvU6LMeAzgO2fjlMn2l3WJBPZmrHXIicBHmejbJDRgMc+FPd # oSUR6ZsuVX08txcdv8yHqC+u2BHrj+GRakq7WF148X1PR8kOhkon+qNSh+cxoIHm # m+Lxg9kZuddkr1m+Fuv79VGj3E9xp4YjbhvVEVbxLs86p812WgVz3eoqvpNXBC0m # H4eM3FUmNHcDA6ubRR/qh3OGYQHyQs4PeMOGACqcySO+XNRKxMNxIzf+fkQU8cuR # A8eYl6s0pQ+KlJudGt2psY+5nkTU9TOC99wvRmfuuG+jpG7vEMsuGy26wCOp7hry # k5kinq/EFImAxdx1WQ3pJuk+rcuSnuOcSieW+zSKEczJOCsbemDbF+9P5Iv0f0nx # kHPYrrjdgValyxosQENsHeq1HztsE46IbBq2S4I9kGzZcaal5hKT/Yxcom9tBfXq # oNs1KaL54mC4ddBGx07kAGE0kiHpY5pr4al2lGpOmBH4B5xKmwIDAQABo4ICAjCC # Af4wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFALy # CdwoelU9i0FZLXOC5NXeXmVqMD0GA1UdIAQ2MDQwMgYFZ4EMAQMwKTAnBggrBgEF # BQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIH # gDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRw # Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu # Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hB # Mzg0MjAyMUNBMS5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNB # NDA5NlNIQTM4NDIwMjFDQTEuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQAD # ggIBACHYo9QgnoH4+yG1TQT8lxxsYPuy3+FiWd2sZxn/4dwBautbZSLaP5yAKlE0 # o7SFQq5IYV2FVA4c5LwJf3eoF0/8+Bh+SMmAHTteqHcAJ3VK8+VETL/qr9kFQx8j # cMA3kF2OOaLVWuB5ffEsGCRqCnS2r8r2lCstb/oEqJLyUXkqEDbyJxgkJ0vQp1XD # agCi68ujhDBwVQPoHmBux2V8TWaOuAT/5kZUJsqwUhBTxYSCKVdIYYkRppaUemJ0 # oULhtxeg1M5zumgLf432qyk6xchohECA1QSXsPflhLZ+eWk3RneSt0fAV/caEBma # mfVj4OysofDA4bCgZSWFk/16O4PEMsLZhR8FCnFr5lxFYKUgAcnVczo75KSBKp2r # aoUVAWIw9w1Z1NQljqfZbFUxWCIWLjmXmEbfy3IXeEpvlXidjPVwdqwbleyl0WR/ # ENGBEiy+I4a/ezu+HoA5zK+1b7INjLgxk8m5MnD75k6Pq+XctyTkzEh6F4Whhq7s # ck16llf7N+i28flIkqzcXuSHxeOZUZb2VNDIcCXiapaxS7cslbP4wafWGEYs2SN3 # +Q398T0fI7uJ4ATp58qdIp6w7Z9PomrVKE0LQMC1P1j9VDiCv7VqnU1cM/2uPpzA # Lop57Q8mTPr7Mh7nl0/QusIr8V/o6XWwRynumecNqn1oeMlaMYIaITCCGh0CAQEw # fTBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNV # BAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hB # Mzg0IDIwMjEgQ0ExAhADmooc3J4LAjb9FLn2g0iAMA0GCWCGSAFlAwQCAQUAoHww # EAYKKwYBBAGCNwIBDDECMAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEICRKaZql # npN8S12gR60Bc2E+Iuw8jfQM/Tm23wEH9TXJMA0GCSqGSIb3DQEBAQUABIIBgIca # NDIlbm6uXAM6mU7LYK+Ss3/z1j3M56ktAc9ZebZbs9oFwRKNIIpbiE8+oyh1Q5VN # 2w102RNuGR2beifd21YQugbBJjkCQjlzzB1tzVzKG1XI+vPx3HSkDeMmiAhZviS5 # QsS7UHRfTpN4+npY0L8+fOmeejea4e3n4RDYyylgPu1OMi2B3mfQmA5kiLIZJwd8 # TvfIG4OFy95T9CeFZjXxsoUoXoyCrTplgg7D9TrEK46ZhTcVjmSig+7INWUFO27u # UvmU1gy284KQtz2JIcDzr8bOvePxkdTAvY3k7xJ6dppbX1myVGtvnvxAnDkAjdME # 7v4SATjTPssQp2ixlmAngxbFQci2beFLST+uhsg4ubqqGTwBC92uvzXsPMdFGXR7 # pOaRN7eRZQncjkymFHRhp1O0H3Q7m+rSAKeJBlAIMIgS4zesPnygsXCZpAVHnh59 # v1dojyO/XFDX3Q+g6ec7EWh/v2goTkaz/fbl9f4oM+xvCTVDv997FFhL8ZeWOaGC # F3cwghdzBgorBgEEAYI3AwMBMYIXYzCCF18GCSqGSIb3DQEHAqCCF1AwghdMAgED # MQ8wDQYJYIZIAWUDBAIBBQAweAYLKoZIhvcNAQkQAQSgaQRnMGUCAQEGCWCGSAGG # /WwHATAxMA0GCWCGSAFlAwQCAQUABCD7jLOmEgqPaYKqfqEY4vhBx/QOxFK6Q2XE # m0k27s7bFwIRAP4I9EKO5PS2Q4/KHbqBKv4YDzIwMjYwMjE5MDAxODU2WqCCEzow # ggbtMIIE1aADAgECAhAKgO8YS43xBYLRxHanlXRoMA0GCSqGSIb3DQEBCwUAMGkx # CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UEAxM4 # RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEyNTYg # MjAyNSBDQTEwHhcNMjUwNjA0MDAwMDAwWhcNMzYwOTAzMjM1OTU5WjBjMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lD # ZXJ0IFNIQTI1NiBSU0E0MDk2IFRpbWVzdGFtcCBSZXNwb25kZXIgMjAyNSAxMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0EasLRLGntDqrmBWsytXum9R # /4ZwCgHfyjfMGUIwYzKomd8U1nH7C8Dr0cVMF3BsfAFI54um8+dnxk36+jx0Tb+k # +87H9WPxNyFPJIDZHhAqlUPt281mHrBbZHqRK71Em3/hCGC5KyyneqiZ7syvFXJ9 # A72wzHpkBaMUNg7MOLxI6E9RaUueHTQKWXymOtRwJXcrcTTPPT2V1D/+cFllESvi # H8YjoPFvZSjKs3SKO1QNUdFd2adw44wDcKgH+JRJE5Qg0NP3yiSyi5MxgU6cehGH # r7zou1znOM8odbkqoK+lJ25LCHBSai25CFyD23DZgPfDrJJJK77epTwMP6eKA0kW # a3osAe8fcpK40uhktzUd/Yk0xUvhDU6lvJukx7jphx40DQt82yepyekl4i0r8OEp # s/FNO4ahfvAk12hE5FVs9HVVWcO5J4dVmVzix4A77p3awLbr89A90/nWGjXMGn7F # QhmSlIUDy9Z2hSgctaepZTd0ILIUbWuhKuAeNIeWrzHKYueMJtItnj2Q+aTyLLKL # M0MheP/9w6CtjuuVHJOVoIJ/DtpJRE7Ce7vMRHoRon4CWIvuiNN1Lk9Y+xZ66laz # s2kKFSTnnkrT3pXWETTJkhd76CIDBbTRofOsNyEhzZtCGmnQigpFHti58CSmvEyJ # cAlDVcKacJ+A9/z7eacCAwEAAaOCAZUwggGRMAwGA1UdEwEB/wQCMAAwHQYDVR0O # BBYEFOQ7/PIx7f391/ORcWMZUEPPYYzoMB8GA1UdIwQYMBaAFO9vU0rp5AZ8esri # kFb2L9RJ7MtOMA4GA1UdDwEB/wQEAwIHgDAWBgNVHSUBAf8EDDAKBggrBgEFBQcD # CDCBlQYIKwYBBQUHAQEEgYgwgYUwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp # Z2ljZXJ0LmNvbTBdBggrBgEFBQcwAoZRaHR0cDovL2NhY2VydHMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZEc0VGltZVN0YW1waW5nUlNBNDA5NlNIQTI1NjIw # MjVDQTEuY3J0MF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYy # MDI1Q0ExLmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJ # KoZIhvcNAQELBQADggIBAGUqrfEcJwS5rmBB7NEIRJ5jQHIh+OT2Ik/bNYulCrVv # hREafBYF0RkP2AGr181o2YWPoSHz9iZEN/FPsLSTwVQWo2H62yGBvg7ouCODwrx6 # ULj6hYKqdT8wv2UV+Kbz/3ImZlJ7YXwBD9R0oU62PtgxOao872bOySCILdBghQ/Z # LcdC8cbUUO75ZSpbh1oipOhcUT8lD8QAGB9lctZTTOJM3pHfKBAEcxQFoHlt2s9s # XoxFizTeHihsQyfFg5fxUFEp7W42fNBVN4ueLaceRf9Cq9ec1v5iQMWTFQa0xNqI # tH3CPFTG7aEQJmmrJTV3Qhtfparz+BW60OiMEgV5GWoBy4RVPRwqxv7Mk0Sy4QHs # 7v9y69NBqycz0BZwhB9WOfOu/CIJnzkQTwtSSpGGhLdjnQ4eBpjtP+XB3pQCtv4E # 5UCSDag6+iX8MmB10nfldPF9SVD7weCC3yXZi/uuhqdwkgVxuiMFzGVFwYbQsiGn # oa9F5AaAyBjFBtXVLcKtapnMG3VH3EmAp/jsJ3FVF3+d1SVDTmjFjLbNFZUWMXuZ # yvgLfgyPehwJVxwC+UpX2MSey2ueIu9THFVkT+um1vshETaWyQo8gmBto/m3acaP # 9QsuLj3FNwFlTxq25+T4QwX9xa6ILs84ZPvmpovq90K8eWyG2N01c4IhSOxqt81n # MIIGtDCCBJygAwIBAgIQDcesVwX/IZkuQEMiDDpJhjANBgkqhkiG9w0BAQsFADBi # MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 # d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3Qg # RzQwHhcNMjUwNTA3MDAwMDAwWhcNMzgwMTE0MjM1OTU5WjBpMQswCQYDVQQGEwJV # UzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRy # dXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtHgx0wqYQXK+PEbAHKx126NG # aHS0URedTa2NDZS1mZaDLFTtQ2oRjzUXMmxCqvkbsDpz4aH+qbxeLho8I6jY3xL1 # IusLopuW2qftJYJaDNs1+JH7Z+QdSKWM06qchUP+AbdJgMQB3h2DZ0Mal5kYp77j # YMVQXSZH++0trj6Ao+xh/AS7sQRuQL37QXbDhAktVJMQbzIBHYJBYgzWIjk8eDrY # hXDEpKk7RdoX0M980EpLtlrNyHw0Xm+nt5pnYJU3Gmq6bNMI1I7Gb5IBZK4ivbVC # iZv7PNBYqHEpNVWC2ZQ8BbfnFRQVESYOszFI2Wv82wnJRfN20VRS3hpLgIR4hjzL # 0hpoYGk81coWJ+KdPvMvaB0WkE/2qHxJ0ucS638ZxqU14lDnki7CcoKCz6eum5A1 # 9WZQHkqUJfdkDjHkccpL6uoG8pbF0LJAQQZxst7VvwDDjAmSFTUms+wV/FbWBqi7 # fTJnjq3hj0XbQcd8hjj/q8d6ylgxCZSKi17yVp2NL+cnT6Toy+rN+nM8M7LnLqCr # O2JP3oW//1sfuZDKiDEb1AQ8es9Xr/u6bDTnYCTKIsDq1BtmXUqEG1NqzJKS4kOm # xkYp2WyODi7vQTCBZtVFJfVZ3j7OgWmnhFr4yUozZtqgPrHRVHhGNKlYzyjlroPx # ul+bgIspzOwbtmsgY1MCAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAw # HQYDVR0OBBYEFO9vU0rp5AZ8esrikFb2L9RJ7MtOMB8GA1UdIwQYMBaAFOzX44LS # cV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEF # BQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp # Z2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYy # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5j # cmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEB # CwUAA4ICAQAXzvsWgBz+Bz0RdnEwvb4LyLU0pn/N0IfFiBowf0/Dm1wGc/Do7oVM # Y2mhXZXjDNJQa8j00DNqhCT3t+s8G0iP5kvN2n7Jd2E4/iEIUBO41P5F448rSYJ5 # 9Ib61eoalhnd6ywFLerycvZTAz40y8S4F3/a+Z1jEMK/DMm/axFSgoR8n6c3nuZB # 9BfBwAQYK9FHaoq2e26MHvVY9gCDA/JYsq7pGdogP8HRtrYfctSLANEBfHU16r3J # 05qX3kId+ZOczgj5kjatVB+NdADVZKON/gnZruMvNYY2o1f4MXRJDMdTSlOLh0HC # n2cQLwQCqjFbqrXuvTPSegOOzr4EWj7PtspIHBldNE2K9i697cvaiIo2p61Ed2p8 # xMJb82Yosn0z4y25xUbI7GIN/TpVfHIqQ6Ku/qjTY6hc3hsXMrS+U0yy+GWqAXam # 4ToWd2UQ1KYT70kZjE4YtL8Pbzg0c1ugMZyZZd/BdHLiRu7hAWE6bTEm4XYRkA6T # l4KSFLFk43esaUeqGkH/wyW4N7OigizwJWeukcyIPbAvjSabnf7+Pu0VrFgoiovR # Diyx3zEdmcif/sYQsfch28bZeUz2rtY/9TCA6TD8dC3JE3rYkrhLULy7Dc90G6e8 # BlqmyIjlgp2+VqsS9/wQD7yFylIz0scmbKvFoW2jNrbM1pD2T7m3XDCCBY0wggR1 # oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X # DTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEh # MB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0B # AQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLh # Kac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+ # vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMp # Lc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+n # MNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1Dek # LgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmk # wuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0 # yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP # 9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHh # D5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnf # fEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId # 5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LS # cV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgP # MA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0 # dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2Vy # dHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNV # HR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRB # c3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0B # AQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlU # Iu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqa # i7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eH # qNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01 # YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ # 8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3wwggN4AgEBMH0waTELMAkGA1UE # BhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2Vy # dCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAyMDI1IENB # MQIQCoDvGEuN8QWC0cR2p5V0aDANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0B # CQMxDQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTI2MDIxOTAwMTg1Nlow # KwYLKoZIhvcNAQkQAgwxHDAaMBgwFgQU3WIwrIYKLTBr2jixaHlSMAf7QX4wLwYJ # KoZIhvcNAQkEMSIEICNDE/2KlcRAjYlSYmDekBWFK+K6SQMlfupDt1jpHrsTMDcG # CyqGSIb3DQEJEAIvMSgwJjAkMCIEIEqgP6Is11yExVyTj4KOZ2ucrsqzP+NtJpqj # NPFGEQozMA0GCSqGSIb3DQEBAQUABIICAH8scj6dfRuUnGfBrZCg20tqYWzt+Kwv # Y8nqo9YqVRkpKa8jT+cUauarusxuyltJmmQI98LEZRvCsYt2rTV8J8DG+uHNM445 # u7NkkE2dNF3kO8CWXsiUetLjaDMJ+Em/9KDF7yN6Z7RllfF4SZkLtk6JJx3oyiou # NWRJCPvN69wYTjbhlcQGxteLafSpGzXFbM11TX9tx9IyQh1+bJVOqlFmYe2LpiQd # EBrjNSOkZY1VzHMmRA84H+O7CXGKm62yFafc9IGgeWnDew/fGluW7jTPNBLAybu+ # G7Y7MQoeKB982I6wc15Lan5AO5FHWZAct2Up2wuf01MshGE0NaNVUVvpRtIxDHdo # BEjMpdYZrEhbJTy81jk6fxsMSnrFl28wCxwlNG/zu8P2UEDsOu31l5FrINT740jX # XkkWAPh7vEPYozgI1w/gExpwtZVx/7k/cx8WxLTcMzUjQ5JsBTiuBKYQ+ndtrTG1 # OGZMftU8B0WfMjmVjL0CVqrP2lHW41hK4gCe3AMcW7yHpfOIe3JGAZURycTqXZ5d # 9T2aWu33YpHHjjbwECJGmbTzTZ+s/u691rYQn2fvuZTIER8mudlaSoIzkt+BJIYw # FTWMCBeOAxYc9CjO9K8rr8dV2UGix6R9PxlBa/ChNqolJasfFqme9HYWgVhrdRCb # X1t6h7TVAbWn # SIG # End signature block |