Private/az-commands.ps1
|
$MAX_RETRY_COUNT = 4 # for some operations, retry a couple of times $SNAILMODE_MAX_RETRY_COUNT = 10 # For very slow tenants, retry more often $script:Snail_Mode = $false $Sleep_Factor = 1 $Snail_Maximum_Sleep_Factor = 90 # times ten is 15 minutes function Convert-LinesToObject { param ( [Parameter(ValueFromPipeline = $true)] [string[]] $Lines ) BEGIN { $linesJsonBuilder = new-object System.Text.StringBuilder } PROCESS { if ($null -eq $Lines) { return } $null = $linesJsonBuilder.Append([string]::Concat($Lines)) } END { if ($null -eq $Lines) { return } return ConvertFrom-Json $linesJsonBuilder.ToString() } } $PERMISSION_ALREADY_ASSIGNED = "Permission already assigned" $PERMISSION_DOES_NOT_EXIST = "Permission does not exist" function CheckAzOutput($azOutput, $fThrowOnError, $noSecretLeakageWarning = $false) { [String[]]$errorMessages = @() foreach ($outputElement in $azOutput) { if ($null -ne $outputElement) { if ($outputElement.GetType() -eq [System.Management.Automation.ErrorRecord]) { if ($outputElement.ToString().Contains("Permission being assigned already exists on the object") -or $outputElement.ToString().Contains("RoleAssignmentExists") -or $outputElement.ToString().Contains("Permission already assigned") -or $outputElement.ToString() -match 'A role assignment with ID.*already exists') { Write-Information "Permission is already assigned when executing $azCommand" Write-Output $PERMISSION_ALREADY_ASSIGNED } elseif ($outputElement.ToString().Contains("Permission being assigned was not found on")) { Write-Information "Could not assign permission, as it does not exist for this application, when executing $azCommand" Write-Output $PERMISSION_DOES_NOT_EXIST } elseif ($outputElement.ToString().EndsWith("does not exist or one of its queried reference-property objects are not present.")) { # This indicates we are in a tenant with especially long delays between creation of an object and when it becomes available via Graph (this happens and it seems to be tenant-specific). # Let's go into snail mode and thereby grant Graph more time Write-Warning "Created object is not yet available via MS Graph. Reducing executing speed to give Graph more time." $script:Snail_Mode = $true $Sleep_Factor = 0.8 * $Sleep_Factor + 0.2 * $Snail_Maximum_Sleep_Factor # approximate longer sleep times Write-Verbose "Retrying operations now $SNAILMODE_MAX_RETRY_COUNT times, and waiting for (n * $Sleep_Factor) seconds on n-th retry" } elseif ($outputElement.ToString().Contains("Blowfish") -or $outputElement.ToString().Contains('cryptography on a 32-bit Python')) { # Ignore, this is an issue of az 2.45.0 and az 2.45.0-preview Write-Debug "Ignoring expected warning about Blowfish: $outputElement" } elseif ($outputElement.ToString().EndsWith('MGMT_DEPLOYMENTMANAGER') -and $outputElement.ToString().StartsWith('ERROR')) { Write-Warning "Ignoring error message from az account show: $outputElement" } elseif ($outputElement.ToString().Contains("CryptographyDeprecationWarning")) { # Ignore, this is an issue of az 2.64.0-preview Write-Debug "Ignoring expected warning about algorithm deprecation: $outputElement" $expectAlgorithmToBeIgnored = $true } elseif ($expectAlgorithmToBeIgnored -and ($outputElement.ToString().Trim(' ').StartsWith('"class": algorithms') -or $outputElement.ToString().Trim(' ').StartsWith('"cipher": algorithms'))) { # Ignore, this is the next line of the previous issue Write-Debug "Ignoring algorithm line for crypto warning: $outputElement" $expectAlgorithmToBeIgnored = $false } elseif ($expectPackageWarning -and $outputElement.ToString().Contains('pkg_resources')) { # Ignore, this is the next line of the previous issue Write-Debug "Ignoring package warning line: $outputElement" $expectPackageWarning = $false } elseif($outputElement.ToString().Contains("The specified table: 'SCEPman_CL' does not exist.")) { # Ignore, the table does not exist yet Write-Debug "Ignoring expected warning about missing table" $expectResourceNotFound = $true } elseif($outputElement.ToString().Contains("The Resource 'Microsoft.Insights/dataCollectionRules/dcr-scepmanlogs'") -and $outputElement.ToString().Contains("was not found.")) { # Ignore, the table does not exist yet Write-Debug "Ignoring expected warning about missing DCR" $expectResourceNotFound = $true } elseif ($expectResourceNotFound -and ($outputElement.ToString().Contains('Code: ResourceNotFound'))) { Write-Debug "Ignoring expected error: ResourceNotFound" } elseif ($outputElement.ToString().Trim(' ') -in @("ERROR: (ResourceNotFound) None", "Code: ResourceNotFound", "Message: None")) { Write-Debug "Ignoring expected generic error: $outputElement" } elseif ($outputElement.ToString().Contains("SyntaxWarning: invalid escape sequence '\ '")) { # Ignore, this is a harmless issue of az graph extension 2.10 with more recent python versions (?) # See https://github.com/Azure/azure-cli-extensions/issues/8369 Write-Debug "Ignoring expected warning about wrong escape seqences: $outputElement" $expectIntervalWarning = $true } elseif ($expectIntervalWarning -and ($outputElement.ToString().Trim(' ').StartsWith('"""'))) { # Ignore, this is the next line of the previous issue Write-Debug "Ignoring line for syntax warning: $outputElement" $expectIntervalWarning = $false } elseif ($outputElement.ToString().Contains("SyntaxWarning: invalid escape sequence '\s'")) { # See https://github.com/HandBrake/HandBrake/issues/5454 Write-Debug "Ignoring expected warning about wrong escape seqences: $outputElement" $expectAzSuggestionWarning = $true } elseif ($expectAzSuggestionWarning -and ($outputElement.ToString().Trim(' ').StartsWith('az monitor'))) { Write-Debug "Ignoring expected AI suggestion about some other az module: $outputElement" } elseif ($outputElement.ToString().StartsWith("WARNING") -or $outputElement.ToString().Contains("UserWarning: ")) { if ($outputElement.ToString().StartsWith("WARNING: The underlying Active Directory Graph API will be replaced by Microsoft Graph API") ` -or $outputElement.ToString().StartsWith("WARNING: This command or command group has been migrated to Microsoft Graph API.")) { # Ignore, we know that Write-Debug "Ignoring expected warning about Graph API migration: $outputElement" } elseif ($outputElement.ToString().StartsWith("WARNING: App settings have been redacted.")) { # Ignore, this is a new behavior of az 2.53.1 and affects the output of az webapp settings set, which we do not use anyway. Write-Debug "Ignoring expected warning about redacted app settings: $outputElement" } elseif ($noSecretLeakageWarning -and $outputElement.ToString().StartsWith("WARNING: [Warning] This output may compromise security by showing")) { Write-Debug "Ignoring expected warning about secret leakage: $outputElement" } elseif ($outputElement.ToString().Contains("pkg_resources is deprecated as an API.")) { # Ignore, see https://developercommunity.visualstudio.com/t/Azure-DevOps-Extension-reports-pkg_resou/10919558 Write-Debug "Ignoring expected warning about a deprecated package because of some extension: $outputElement" $expectPackageWarning = $true } else { Write-Debug "Warning about unexpected az output" Write-Warning $outputElement.ToString() } } else { if ($outputElement.ToString().contains("does not have authorization to perform action 'Microsoft.Authorization/roleAssignments/write'")) { $errorMessages += "You have insufficient privileges to assign roles to Managed Identities. Make sure you have the Global Admin or Privileged Role Administrator role." } elseif ($outputElement.ToString().Contains("Forbidden")) { $errorMessages += "You have insufficient privileges to complete the operation. Please ensure that you run this CMDlet with required privileges e.g. Global Administrator" } Write-Debug "Error about unexpected az output: $outputElement" $errorMessages += $outputElement } } else { Write-Output $outputElement # add to return value of this function } } } if ($errorMessages.Count -gt 0) { $ErrorMessageOneLiner = [String]::Join("`r`n", $errorMessages) if ($fThrowOnError) { throw $ErrorMessageOneLiner } else { Write-Error $ErrorMessageOneLiner } } } function AzLogin { # Check whether az is available $azCommand = Get-Command az 2>&1 if ($azCommand.GetType() -eq [System.Management.Automation.ErrorRecord]) { if ($azCommand.CategoryInfo.Reason -eq "CommandNotFoundException") { $errorMessage = "Azure CLI (az) is not installed, but required. Please use the Azure Cloud Shell or install Azure CLI as described here: https://docs.microsoft.com/en-us/cli/azure/install-azure-cli" Write-Error $errorMessage throw $errorMessage } else { Write-Error "Unknown error checking for az" throw $azCommand } } # check whether already logged in $env:AZURE_HTTP_USER_AGENT = "pid-a262352f-52a9-4ed9-a9ba-6a2b2478d19b" try { $account = Invoke-Az -azCommand @("account", "show") -MaxRetries 0 } catch { $errorMessage = $_.Exception.Message if (($errorMessage.Contains("az login")) -or ($errorMessage.Contains("az account set"))) { Write-Warning "Not logged in with az yet. Trying to log in ... if this doesn't work, please log in manually." $null = az login # TODO: Check whether the login worked return AzLogin } else { Write-Error "Error $errorMessage while trying to use az" # possibly az not installed? throw new-object System.Exception("Error when checking whether az is logged in", $_.Exception) } } try { $accountInfo = Convert-LinesToObject($account) } catch { $errormessage = "Error parsing output from az account show. Error message: $_" $errorMessage += "`r`Output from az account show: $account" Write-Error $errormessage throw $errorMessage } Write-Information "Logged in to az as $($accountInfo.user.name)" return $accountInfo } $azVersionInfo = $null function GetAzVersion { if ($null -eq $azVersionInfo) { $azVersionInfo = Convert-LinesToObject -lines $(az version) } return $azVersionInfo } function AzUsesAADGraph { $cliVersion = [Version]::Parse((GetAzVersion).'azure-cli') return $cliVersion -lt '2.37' } # Check heuristically whether we are in Azure Cloud Shell function IsAzureCloudShell { $cloudShellProves = 0 # The more proves, the more likely we are in Azure Cloud Shell. We use a 2 out of 3 vote. $azuredrive = get-psdrive -Name Azure -ErrorAction Ignore if ($null -ne $azuredrive) { ++$cloudShellProves } if (Test-Path -Path ~/clouddrive) { ++$cloudShellProves } if ($PSVersionTable.Platform -eq "Unix") { ++$cloudShellProves } return $cloudShellProves -ge 2 } function Invoke-Az ($azCommand, $maxRetries = $MAX_RETRY_COUNT) { return ExecuteAzCommandRobustly -azCommand $azCommand -callAzNatively -maxRetries $maxRetries } # It is intended to use for az cli add permissions and az cli add permissions admin # $azCommand - The command to execute. # $noSecretLeakageWarning - Pass true if you are sure that the output contains no secrets. This will supress az warnings about leaking secrets in the output. function ExecuteAzCommandRobustly($azCommand, $principalId = $null, $appRoleId = $null, $GraphBaseUri = $null, $maxRetries = $MAX_RETRY_COUNT, [switch]$callAzNatively, [switch]$noSecretLeakageWarning) { $azErrorCode = 1234 # A number not null $retryCount = 0 $script:Snail_Mode = $false try { $definedPreference = $PSNativeCommandUseErrorActionPreference $PSNativeCommandUseErrorActionPreference = $false # See https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7.3#psnativecommanduseerroractionpreference while ($azErrorCode -gt 0 -and ($retryCount -le $maxRetries -or $script:Snail_Mode -and $retryCount -le $SNAILMODE_MAX_RETRY_COUNT)) { $PreviousErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = "Continue" # In Windows PowerShell, if this is set to "Stop", az will not return the error code, but instead throw an exception $LASTEXITCODE = 0 # Required for unit tests when mocking az if ($callAzNatively) { Write-Debug "Calling az natively: az $azCommand" $lastAzOutput = az $azCommand 2>&1 } else { $lastAzOutput = Invoke-Expression "$azCommand 2>&1" # the output is often empty in case of error :-(. az just writes to the console then } $azErrorCode = $LASTEXITCODE $ErrorActionPreference = $PreviousErrorActionPreference Write-Debug "az command $azCommand returned with error code $azErrorCode" try { $lastAzOutput = CheckAzOutput -azOutput $lastAzOutput -fThrowOnError $true -noSecretLeakageWarning $noSecretLeakageWarning # If we were requested to check that the permission is there and there was no error, do the check now. # However, if the permission has been there previously already, we can skip the check if ($null -ne $appRoleId -and $azErrorCode -eq 0 -and $PERMISSION_ALREADY_ASSIGNED -ne $lastAzOutput) { $appRoleAssignments = Convert-LinesToObject -lines $(az rest --method get --url "$GraphBaseUri/v1.0/servicePrincipals/$principalId/appRoleAssignments") $grantedPermission = $appRoleAssignments.value | Where-Object { $_.appRoleId -eq $appRoleId } if ($null -eq $grantedPermission) { $azErrorCode = 999 # A number not 0 } } elseif ($null -ne $appRoleId -and $PERMISSION_ALREADY_ASSIGNED -eq $lastAzOutput) { $azErrorCode = 0 # The permission was already there, so we are done. Ignore the error message that the permission was already there. } elseif ($null -ne $appRoleId -and $PERMISSION_DOES_NOT_EXIST -eq $lastAzOutput) { $azErrorCode = -24 # This kind of permission doesn't even exist. We are probably not in the global cloud or something else is unusual. No need to retry. } } catch { Write-Warning $_ $azErrorCode = 654 # a number not 0 $message = $_.ToString() if ($message.Contains("Failed to connect to MSI. Please make sure MSI is configured correctly") -and $message.Contains("400")) { if (IsAzureCloudShell) { Write-Warning "Trying to log in again to Azure CLI, as this usually fixes the token issue in Azure Cloud Shell" az login } } } if ($azErrorCode -gt 0) { ++$retryCount Write-Verbose "Retry $retryCount for $azCommand after $($retryCount * $SLEEP_FACTOR) seconds of sleep because Error Code is $azErrorCode" Start-Sleep ($retryCount * $SLEEP_FACTOR) # Sleep for some seconds, as the grant sometimes only works after some time } } } finally { $PSNativeCommandUseErrorActionPreference = $definedPreference } if ($azErrorCode -ne 0 ) { if ($null -eq $lastAzOutput) { $errorMessage = "no error message" $readableAzOutput = "no az output" } else { # might be an object[] $readableAzOutput = CheckAzOutput -azOutput $lastAzOutput -fThrowOnError $false try { $null = CheckAzOutput -azOutput $lastAzOutput -fThrowOnError $true throw "During second evaluation of az output, the output was not an error, but it should have been. This is unexpected." } catch { $errorMessage = $_.ToString() } } throw "Error $azErrorCode when executing $azCommand : $readableAzOutput; Error message: $errorMessage" } else { return $lastAzOutput } } function HashTable2AzJson($psHashTable) { $output = ConvertTo-Json -Compress -InputObject $psHashTable -Depth 10 if ($PSVersionTable.PSVersion.Major -lt 7 -or ($PSVersionTable.PSVersion.Major -eq 7 -and $PSVersionTable.PSVersion.Minor -lt 3) ` -or $PSVersionTable.OS.StartsWith("Microsoft Windows")) { # The double quoting is now also required on PS 7.3.0 on Windows ... does it depend on the az version? $output = $output -replace '"', '\"' # The double quoting is required by PowerShell <7.2 (see https://github.com/PowerShell/PowerShell/issues/1995 and https://docs.microsoft.com/en-us/cli/azure/use-cli-effectively?tabs=bash%2Cbash2#use-quotation-marks-in-parameters) return $output.Insert(1, ' ') # Seemingly, there needs to be a space in the JSON somewhere in the beginning for PS 5 to pass consecutive spaces to az instead of having space-separated parameters } return $output } function AppSettingsHashTable2AzJson($psHashTable, $convertForLinux) { if ($convertForLinux) { $escapedpsHashTable = @{} foreach ($key in $psHashTable.Keys) { $escapedpsHashTable.Add($key.Replace(":", "__"), $psHashTable[$key]) } } else { $escapedpsHashTable = $psHashTable } return HashTable2AzJson -psHashTable $escapedpsHashTable } # SIG # Begin signature block # MIIsjAYJKoZIhvcNAQcCoIIsfTCCLHkCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC3P/ktfUdA5CVn # a3lOCMVCMScqCVp345O1SYhWaeZ546CCFA4wggVyMIIDWqADAgECAhB2U/6sdUZI # k/Xl10pIOk74MA0GCSqGSIb3DQEBDAUAMFMxCzAJBgNVBAYTAkJFMRkwFwYDVQQK # ExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENvZGUgU2ln # bmluZyBSb290IFI0NTAeFw0yMDAzMTgwMDAwMDBaFw00NTAzMTgwMDAwMDBaMFMx # CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQD # EyBHbG9iYWxTaWduIENvZGUgU2lnbmluZyBSb290IFI0NTCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBALYtxTDdeuirkD0DcrA6S5kWYbLl/6VnHTcc5X7s # k4OqhPWjQ5uYRYq4Y1ddmwCIBCXp+GiSS4LYS8lKA/Oof2qPimEnvaFE0P31PyLC # o0+RjbMFsiiCkV37WYgFC5cGwpj4LKczJO5QOkHM8KCwex1N0qhYOJbp3/kbkbuL # ECzSx0Mdogl0oYCve+YzCgxZa4689Ktal3t/rlX7hPCA/oRM1+K6vcR1oW+9YRB0 # RLKYB+J0q/9o3GwmPukf5eAEh60w0wyNA3xVuBZwXCR4ICXrZ2eIq7pONJhrcBHe # OMrUvqHAnOHfHgIB2DvhZ0OEts/8dLcvhKO/ugk3PWdssUVcGWGrQYP1rB3rdw1G # R3POv72Vle2dK4gQ/vpY6KdX4bPPqFrpByWbEsSegHI9k9yMlN87ROYmgPzSwwPw # jAzSRdYu54+YnuYE7kJuZ35CFnFi5wT5YMZkobacgSFOK8ZtaJSGxpl0c2cxepHy # 1Ix5bnymu35Gb03FhRIrz5oiRAiohTfOB2FXBhcSJMDEMXOhmDVXR34QOkXZLaRR # kJipoAc3xGUaqhxrFnf3p5fsPxkwmW8x++pAsufSxPrJ0PBQdnRZ+o1tFzK++Ol+ # A/Tnh3Wa1EqRLIUDEwIrQoDyiWo2z8hMoM6e+MuNrRan097VmxinxpI68YJj8S4O # JGTfAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G # A1UdDgQWBBQfAL9GgAr8eDm3pbRD2VZQu86WOzANBgkqhkiG9w0BAQwFAAOCAgEA # Xiu6dJc0RF92SChAhJPuAW7pobPWgCXme+S8CZE9D/x2rdfUMCC7j2DQkdYc8pzv # eBorlDICwSSWUlIC0PPR/PKbOW6Z4R+OQ0F9mh5byV2ahPwm5ofzdHImraQb2T07 # alKgPAkeLx57szO0Rcf3rLGvk2Ctdq64shV464Nq6//bRqsk5e4C+pAfWcAvXda3 # XaRcELdyU/hBTsz6eBolSsr+hWJDYcO0N6qB0vTWOg+9jVl+MEfeK2vnIVAzX9Rn # m9S4Z588J5kD/4VDjnMSyiDN6GHVsWbcF9Y5bQ/bzyM3oYKJThxrP9agzaoHnT5C # JqrXDO76R78aUn7RdYHTyYpiF21PiKAhoCY+r23ZYjAf6Zgorm6N1Y5McmaTgI0q # 41XHYGeQQlZcIlEPs9xOOe5N3dkdeBBUO27Ql28DtR6yI3PGErKaZND8lYUkqP/f # obDckUCu3wkzq7ndkrfxzJF0O2nrZ5cbkL/nx6BvcbtXv7ePWu16QGoWzYCELS/h # AtQklEOzFfwMKxv9cW/8y7x1Fzpeg9LJsy8b1ZyNf1T+fn7kVqOHp53hWVKUQY9t # W76GlZr/GnbdQNJRSnC0HzNjI3c/7CceWeQIh+00gkoPP/6gHcH1Z3NFhnj0qinp # J4fGGdvGExTDOUmHTaCX4GUT9Z13Vunas1jHOvLAzYIwggboMIIE0KADAgECAhB3 # vQ4Ft1kLth1HYVMeP3XtMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAkJFMRkw # FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENv # ZGUgU2lnbmluZyBSb290IFI0NTAeFw0yMDA3MjgwMDAwMDBaFw0zMDA3MjgwMDAw # MDBaMFwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTIw # MAYDVQQDEylHbG9iYWxTaWduIEdDQyBSNDUgRVYgQ29kZVNpZ25pbmcgQ0EgMjAy # MDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMsg75ceuQEyQ6BbqYoj # /SBerjgSi8os1P9B2BpV1BlTt/2jF+d6OVzA984Ro/ml7QH6tbqT76+T3PjisxlM # g7BKRFAEeIQQaqTWlpCOgfh8qy+1o1cz0lh7lA5tD6WRJiqzg09ysYp7ZJLQ8LRV # X5YLEeWatSyyEc8lG31RK5gfSaNf+BOeNbgDAtqkEy+FSu/EL3AOwdTMMxLsvUCV # 0xHK5s2zBZzIU+tS13hMUQGSgt4T8weOdLqEgJ/SpBUO6K/r94n233Hw0b6nskEz # IHXMsdXtHQcZxOsmd/KrbReTSam35sOQnMa47MzJe5pexcUkk2NvfhCLYc+YVaMk # oog28vmfvpMusgafJsAMAVYS4bKKnw4e3JiLLs/a4ok0ph8moKiueG3soYgVPMLq # 7rfYrWGlr3A2onmO3A1zwPHkLKuU7FgGOTZI1jta6CLOdA6vLPEV2tG0leis1Ult # 5a/dm2tjIF2OfjuyQ9hiOpTlzbSYszcZJBJyc6sEsAnchebUIgTvQCodLm3HadNu # twFsDeCXpxbmJouI9wNEhl9iZ0y1pzeoVdwDNoxuz202JvEOj7A9ccDhMqeC5LYy # AjIwfLWTyCH9PIjmaWP47nXJi8Kr77o6/elev7YR8b7wPcoyPm593g9+m5XEEofn # GrhO7izB36Fl6CSDySrC/blTAgMBAAGjggGtMIIBqTAOBgNVHQ8BAf8EBAMCAYYw # EwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E # FgQUJZ3Q/FkJhmPF7POxEztXHAOSNhEwHwYDVR0jBBgwFoAUHwC/RoAK/Hg5t6W0 # Q9lWULvOljswgZMGCCsGAQUFBwEBBIGGMIGDMDkGCCsGAQUFBzABhi1odHRwOi8v # b2NzcC5nbG9iYWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUwRgYIKwYBBQUH # MAKGOmh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2NvZGVzaWdu # aW5ncm9vdHI0NS5jcnQwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5nbG9i # YWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUuY3JsMFUGA1UdIAROMEwwQQYJ # KwYBBAGgMgECMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24u # Y29tL3JlcG9zaXRvcnkvMAcGBWeBDAEDMA0GCSqGSIb3DQEBCwUAA4ICAQAldaAJ # yTm6t6E5iS8Yn6vW6x1L6JR8DQdomxyd73G2F2prAk+zP4ZFh8xlm0zjWAYCImbV # YQLFY4/UovG2XiULd5bpzXFAM4gp7O7zom28TbU+BkvJczPKCBQtPUzosLp1pnQt # pFg6bBNJ+KUVChSWhbFqaDQlQq+WVvQQ+iR98StywRbha+vmqZjHPlr00Bid/XSX # hndGKj0jfShziq7vKxuav2xTpxSePIdxwF6OyPvTKpIz6ldNXgdeysEYrIEtGiH6 # bs+XYXvfcXo6ymP31TBENzL+u0OF3Lr8psozGSt3bdvLBfB+X3Uuora/Nao2Y8nO # ZNm9/Lws80lWAMgSK8YnuzevV+/Ezx4pxPTiLc4qYc9X7fUKQOL1GNYe6ZAvytOH # X5OKSBoRHeU3hZ8uZmKaXoFOlaxVV0PcU4slfjxhD4oLuvU/pteO9wRWXiG7n9dq # cYC/lt5yA9jYIivzJxZPOOhRQAyuku++PX33gMZMNleElaeEFUgwDlInCI2Oor0i # xxnJpsoOqHo222q6YV8RJJWk4o5o7hmpSZle0LQ0vdb5QMcQlzFSOTUpEYck08T7 # qWPLd0jV+mL8JOAEek7Q5G7ezp44UCb0IXFl1wkl1MkHAHq4x/N36MXU4lXQ0x72 # f1LiSY25EXIMiEQmM2YBRN/kMw4h3mKJSAfa9TCCB6gwggWQoAMCAQICDF3VjaKN # us83AvC1UTANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQ # R2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVW # IENvZGVTaWduaW5nIENBIDIwMjAwHhcNMjUxMTI3MTcwNDI2WhcNMjcxMTI4MTcw # NDI2WjCCAQwxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRIwEAYDVQQF # EwlIUkIgMTIzODExEzARBgsrBgEEAYI3PAIBAxMCREUxFzAVBgsrBgEEAYI3PAIB # AhMGSGVzc2VuMSIwIAYLKwYBBAGCNzwCAQETEU9mZmVuYmFjaCBhbSBNYWluMQsw # CQYDVQQGEwJERTEPMA0GA1UECBMGSGVzc2VuMRowGAYDVQQHExFPZmZlbmJhY2gg # YW0gTWFpbjEZMBcGA1UECQwQS2Fpc2Vyc3RyYcOfZSAzOTEXMBUGA1UEChMOZ2x1 # ZWNra2FuamEgQUcxFzAVBgNVBAMTDmdsdWVja2thbmphIEFHMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAkQoXi0dUFVttodx+Ydj1O6EZZqgDdlSGDA/6 # x1UCkMrWNVEW+LdbUGU8KW7fUcKPCAcDJNrXfXxZeBht2G4pPvhaMz/kBdSK6bI1 # sqo1WSN//beapdUefQpq/wgnUneq13tEJQAke6EWdLyidObcogBSp9wCXBbMWsTO # utgCONjyu8AilmzRY+94lO7VwUA2LGGPX8FRAEt5AMzifsEo2lIEKiDou2H8HUUC # PibiChiuT3oGIDYYnCA/RzS44E0cAuAzlD3NQNCeIDzfoFiUD8mAC1gYU6i8yIej # jUGl8+kpbpBYjgzwbsiCBn0rDhrlpJ3MHkZCrp82kzWK0l7c3ukNvdlGcU4tKdXk # AHgpJecdYUDvz9iaYFvYEivF+Jg+Tc8ZnzsP5/q3KKw4g0QiJ+MXgvwJx8OSvAKW # tkwkLxgE9oxufs3Y8xsmwyWqxWDBcyzzvs6yISnUaeTtGmyB8BsEbahDFrxHhV6U # nwxNpJ+iM+j08J1tNIW0AXjY6ojGOIC8IIL+EiK34MXJ6Jxy22mntMnc6ztK6c7H # IKiRHIPX4jXtg7IYRS/k5muuIt/xKzN7qtF9xJbaZi8jRE6fgWDwszLJUMHSLthh # yKTsUEvuqZ79WnSHErg26EPQYirAY/IFt7Z7+3SDW2WI8uG2qY6hkpE0hm+/F3uS # M+s98jUCAwEAAaOCAbYwggGyMA4GA1UdDwEB/wQEAwIHgDCBnwYIKwYBBQUHAQEE # gZIwgY8wTAYIKwYBBQUHMAKGQGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20v # Y2FjZXJ0L2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMC5jcnQwPwYIKwYBBQUHMAGG # M2h0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNh # MjAyMDBVBgNVHSAETjBMMEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUFBwIBFiZodHRw # czovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBAzAJBgNV # HRMEAjAAMEcGA1UdHwRAMD4wPKA6oDiGNmh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5j # b20vZ3NnY2NyNDVldmNvZGVzaWduY2EyMDIwLmNybDATBgNVHSUEDDAKBggrBgEF # BQcDAzAfBgNVHSMEGDAWgBQlndD8WQmGY8Xs87ETO1ccA5I2ETAdBgNVHQ4EFgQU # q/cn5ijjtp0mG1yoiF02hg4dx4IwDQYJKoZIhvcNAQELBQADggIBAJ1TZv/rvy2w # jANcL/kb6rTk+/6L7l49UghLghUKFVfrdEEc+21iexA7zlkvhM0TrhdiFU7TjDky # InPctzsDlqwUhawEx4PT8ZkZkZzm25YWaqtZH44st/Fz59KiG+85NUdRd+0cL3Y8 # NR66z3xfI6K3W/nrIcE6RHm/opOM+L02Hd2MBligLnoFYcTvR3NPCA21A6+IOaYM # n5YZzNKFXWry8ZHpWjnE4u9mxHYpS1zu2aIkwL8mfYM5moYoh0PAcp9XA5Sm4KrV # LeIzZ3HIy4EzLCbFBP+OGFpkqq8pTtmYItG+g1rYEg5a8egrY83zJMHazaTFBgRI # MNXCgeMZhC8O6NsAtbj3FSbiYKg1hNwZzHYL+uL3jcPZjuUoOpmvXu67xWs4ZfdT # Mluy5E7FyWwtnOjr/04EXWyKATYMDIkd47Wqam/ZB7umF5T5YPnmTlv18ArEXuVQ # EEpS/cN90DtRz2OGruu+V9bg3fk6NKDJLve8detDOTTBN0C/bFGxI5YLHmwVAdaq # pz3t14ShRjVcxP7aN0bEL3YOuQvjnjQGe29H6n/MPf8UG4WYMd+a8qIP4HROLJq0 # YJylzYBglqoQeQC/OG+PtWTvL9oByPVYNc+llAuap/xmWSLZgAqPbi+PAfow69Lg # bppHUCnJhNkXD/mJ4qB0KvPG+bzL19dEMYIX1DCCF9ACAQEwbDBcMQswCQYDVQQG # EwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFs # U2lnbiBHQ0MgUjQ1IEVWIENvZGVTaWduaW5nIENBIDIwMjACDF3VjaKNus83AvC1 # UTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkG # CSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEE # AYI3AgEVMC8GCSqGSIb3DQEJBDEiBCA2MvWSHMN+RxR6CcPMb8SySHs+YhEBNpXq # oCeugxrR2DANBgkqhkiG9w0BAQEFAASCAgCPFX0qc/QrtT9Qq7zjNVIc5xngv85T # NkmfFErxljiSJKNVdyuLtXvAMpx2+0WmL+b7iFgsJqwbTVMMKf0DM3P84QQllDrb # 4d+kcy/XiURwfBQeKi+7QAp+lQVct0tA7S7JCXsdBSL3CXu6+7797q5vEKkNtvsb # 4kP5N9Eo1bQaoM5owIHvS1ogcrgzqN3RrZIN7jC/axbOLtyVJ+EUdiK23uOT0xYq # tIpE6GqCxatDaY50iwiCjcrA1dKAf2+TE1nbmOyHNAIRCA7CG18bnIQR4N8QF6Dz # ZHKDhwSK4hs70u73TnNDFvhPPQZVA6ivfszzM1bcxwU8QyoNta9Qe+Q6PezF0a4c # W1xNr7Vt90RIO/VAwlVPbJEai6DKNGM6c51LNM5eUxHoDmfIn6TCzdsOnUHO0ruC # knamS1GT1fmpbdylD32sh37wWda1GMRJjEU8NcxtGQyPiFLSzB8b0Rzu4NW37YiH # trg6UplTZOnOMWAHWC6sdAQvohVyMoIWDS54Oq2Q7oBah2TLlv13sGJs7J4Wugjh # HOBz2KDAfy6coSH9VyM+SuCF0MuJDfEbe+o37v4Qlc4EAgT29920LBQ3pIQfd/HM # XqzZBoeHeIIudq7md0CXAhbz/0CaUhmIqW+AAAm4TUPITYPTtoXhKdN7nujxjGTR # I9FVYR5ZcyTMiqGCFLIwghSuBgorBgEEAYI3AwMBMYIUnjCCFJoGCSqGSIb3DQEH # AqCCFIswghSHAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFqBgsqhkiG9w0BCRABBKCC # AVkEggFVMIIBUQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCAT/rel # DHuqmfMhVLsDez7DZePsbk4CjCTDFmSb9FT9vAIGacZuHa9EGBMyMDI2MDMzMTEw # MTgwNy4wOThaMASAAgH0oIHppIHmMIHjMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRp # b25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3QTFBLTA1RTAt # RDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGlu # ZyBBdXRob3JpdHmggg8pMIIHgjCCBWqgAwIBAgITMwAAAAXlzw//Zi7JhwAAAAAA # BTANBgkqhkiG9w0BAQwFADB3MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMUgwRgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkgVmVy # aWZpY2F0aW9uIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjAx # MTE5MjAzMjMxWhcNMzUxMTE5MjA0MjMxWjBhMQswCQYDVQQGEwJVUzEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVi # bGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQAD # ggIPADCCAgoCggIBAJ5851Jj/eDFnwV9Y7UGIqMcHtfnlzPREwW9ZUZHd5HBXXBv # f7KrQ5cMSqFSHGqg2/qJhYqOQxwuEQXG8kB41wsDJP5d0zmLYKAY8Zxv3lYkuLDs # fMuIEqvGYOPURAH+Ybl4SJEESnt0MbPEoKdNihwM5xGv0rGofJ1qOYSTNcc55EbB # T7uq3wx3mXhtVmtcCEr5ZKTkKKE1CxZvNPWdGWJUPC6e4uRfWHIhZcgCsJ+sozf5 # EeH5KrlFnxpjKKTavwfFP6XaGZGWUG8TZaiTogRoAlqcevbiqioUz1Yt4FRK53P6 # ovnUfANjIgM9JDdJ4e0qiDRm5sOTiEQtBLGd9Vhd1MadxoGcHrRCsS5rO9yhv2fj # JHrmlQ0EIXmp4DhDBieKUGR+eZ4CNE3ctW4uvSDQVeSp9h1SaPV8UWEfyTxgGjOs # RpeexIveR1MPTVf7gt8hY64XNPO6iyUGsEgt8c2PxF87E+CO7A28TpjNq5eLiiun # hKbq0XbjkNoU5JhtYUrlmAbpxRjb9tSreDdtACpm3rkpxp7AQndnI0Shu/fk1/rE # 3oWsDqMX3jjv40e8KN5YsJBnczyWB4JyeeFMW3JBfdeAKhzohFe8U5w9WuvcP1E8 # cIxLoKSDzCCBOu0hWdjzKNu8Y5SwB1lt5dQhABYyzR3dxEO/T1K/BVF3rV69AgMB # AAGjggIbMIICFzAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYD # VR0OBBYEFGtpKDo1L0hjQM972K9J6T7ZPdshMFQGA1UdIARNMEswSQYEVR0gADBB # MD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0Rv # Y3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGC # NxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTI # ftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHegdYZzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSWRlbnRpdHkl # MjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHkl # MjAyMDIwLmNybDCBlAYIKwYBBQUHAQEEgYcwgYQwgYEGCCsGAQUFBzAChnVodHRw # Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElk # ZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0 # aG9yaXR5JTIwMjAyMC5jcnQwDQYJKoZIhvcNAQEMBQADggIBAF+Idsd+bbVaFXXn # THho+k7h2ESZJRWluLE0Oa/pO+4ge/XEizXvhs0Y7+KVYyb4nHlugBesnFqBGEdC # 2IWmtKMyS1OWIviwpnK3aL5JedwzbeBF7POyg6IGG/XhhJ3UqWeWTO+Czb1c2NP5 # zyEh89F72u9UIw+IfvM9lzDmc2O2END7MPnrcjWdQnrLn1Ntday7JSyrDvBdmgbN # nCKNZPmhzoa8PccOiQljjTW6GePe5sGFuRHzdFt8y+bN2neF7Zu8hTO1I64XNGqs # t8S+w+RUdie8fXC1jKu3m9KGIqF4aldrYBamyh3g4nJPj/LR2CBaLyD+2BuGZCVm # oNR/dSpRCxlot0i79dKOChmoONqbMI8m04uLaEHAv4qwKHQ1vBzbV/nG89LDKbRS # SvijmwJwxRxLLpMQ/u4xXxFfR4f/gksSkbJp7oqLwliDm/h+w0aJ/U5ccnYhYb7v # PKNMN+SZDWycU5ODIRfyoGl59BsXR/HpRGtiJquOYGmvA/pk5vC1lcnbeMrcWD/2 # 6ozePQ/TWfNXKBOmkFpvPE8CH+EeGGWzqTCjdAsno2jzTeNSxlx3glDGJgcdz5D/ # AAxw9Sdgq/+rY7jjgs7X6fqPTXPmaCAJKVHAP19oEjJIBwD1LyHbaEgBxFCogYSO # iUIr0Xqcr1nJfiWG2GwYe6ZoAF1bMIIHnzCCBYegAwIBAgITMwAAAFtKtY1BMm3c # dAAAAAAAWzANBgkqhkiG9w0BAQwFADBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGlj # IFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMDAeFw0yNjAxMDgxODU5MDVaFw0yNzAx # MDcxODU5MDVaMIHjMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ # MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u # MS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQx # JzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3QTFBLTA1RTAtRDk0NzE1MDMGA1UE # AxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHkw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCQVMwW255Q13ntAdCg+RuP # +O+bYRcn3LQsrhEk1kF75S4uFsf7XdqlHXquInXnoOlVoYjh37t8CVeE1Bkkbaof # QnK9QZogSr/YrhaYB8iAbuUMd/GbMcJRXl1UvmaiSSp10WwzUHXGEqAv+nNIUCfz # x+dAwUQ0JD11cMhYsy60R/QJayXlIOwSnk9t837UvPyjiS7xBGxzheqUjmN2Vaa2 # VFm1o1sEU5qB2kPxPL61rSzchCfm9PPVVtSJK2t7eBkweVm8twi9Sts2JwMQSL2n # 7CjBco/Trlx3EzyjA6BUjHmphvTCjjG+rqBtT43Zw4LCz+hDjEUs6yy+4xA9Zmwf # UUnfX4bcvh0K+r2YLAZ+qFMvmE6TVS7JMHbVDPNlmAJD87ZTrdwIi9Ksle/1N4/7 # qt7xzIzzNMNN+NDOezXotIOAQnDLdHW6qHPdVYAm9/9+rB0ADaJ7Z9RzhdqC5PNf # dEEUuN4rB1a2vB/LH+fhpaiGLGIgil9OB2Yjs2VvNup1SOnfvvJck3lpqY/dFGvb # j2yYVY8BN6IerTuddMkqpkjEixDdO6dyG3txOgQG9sPd61s29uvnaUrYWyheJAKa # H6gbFj1+DBLRykjn7T5lUwkOO7YIa1bh4mvY2Ph7I9NZuCluFrZJlZty+oTGRAjG # uLIzMQF8/m1/wCYVk3uk2QIDAQABo4IByzCCAccwHQYDVR0OBBYEFO/y6lJVlmIV # yXV8IGCseG/Br9K2MB8GA1UdIwQYMBaAFGtpKDo1L0hjQM972K9J6T7ZPdshMGwG # A1UdHwRlMGMwYaBfoF2GW2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # Y3JsL01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENB # JTIwMjAyMC5jcmwweQYIKwYBBQUHAQEEbTBrMGkGCCsGAQUFBzAChl1odHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFB1Ymxp # YyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5jcnQwDAYDVR0TAQH/ # BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwZgYD # VR0gBF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMAgGBmeB # DAEEAjANBgkqhkiG9w0BAQwFAAOCAgEAAB/s3flyoeDsV2DFhZrYIpVwEBnLTowl # AdcP7gYgvzl3B9yGuP123VISsxW2ok2yBOr2GSndaeLu5yji5GsMpgDFcrjuy0pe # qyyrbWSMi4Vo0ytM1zs9LuMS6vfm0bQRCibwOrA+ZycB9SDus9WIs8riEaGpTAp2 # 61IsX1sUJ+EwJje7fbpPl9hVE4RGt3sM0cIbRvscGgGyzJMUZkduCZ313dVcSqPd # Ppu1s7qL/elLoMecGXXsIiCJtWVk4+JQiR7qeu/S3Dmu7QMSTIqVWkpbUB/X5vUz # inM5X8bVrgXC1OHbmX6sILCC7B+zzJHF9c8EM0A9MgLT4Z2M/SjRtduW1/oopTnt # UvER6r9m2waTKWqOJHFL0COnTICkbxZptXi24UjTkKZQzExg9bTVXTRpCPeo1Lvr # a6FI1jDIuOk0HwQB8bQ06UYSLv/O7wFUPGekR4RcXrM+BHeSU4WiEEQMuhnDvyZP # kMw86GdGq0SJCLBie62YDlQI8fXLX8PJR/UX43MAd8HRgWDTDVSakKVGotk2nXX+ # aV802RByKixBed0qwYyHiJ6EKz+1OVZV4jELMXsC3SDawBNpdk0dygYpG/kUEcoG # 06fI49sogtDQlMBvivp3YJTeUTG14xVumimufV6vm/F8yvwyvgCbYDqR4Cb/EK5O # tgPrcDlSzqYxggPUMIID0AIBATB4MGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMg # UlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAW0q1jUEybdx0AAAAAABbMA0G # CWCGSAFlAwQCAQUAoIIBLTAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJ # KoZIhvcNAQkEMSIEIGwd7aPlX4D6C9MDzYrBlmGAYFro+vQQhuzCXgemUpv1MIHd # BgsqhkiG9w0BCRACLzGBzTCByjCBxzCBoAQgLzEDVV2dG9McZRsPF/9yBMmzm7k+ # muVtXetQlvnBg+8wfDBlpGMwYTELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBSU0Eg # VGltZXN0YW1waW5nIENBIDIwMjACEzMAAABbSrWNQTJt3HQAAAAAAFswIgQgXF5R # tLGcLwuYd/7BXi+0+tVXcRXfIJsV5E65O5EvL1swDQYJKoZIhvcNAQELBQAEggIA # gIisuId0s8dWU7sCYOSlwbVvrhdVsVTEx9ZR+YWwBbi6sZ8pN31lQ85BnIA7VRym # aa6CgzJiJGSiQhTMdvUu3l+lFcxg4udr51vTqmzzmeH5rWDOUzG/xQNvrTx2l5qd # 749MeSGcpBX1TT9B1l7sCEj6gSY8o0NJSUIpJuHjJaQEWgfnCu9WBG8ixKL9mBHi # MGZFyX4b1BXVfJRnZnYvaIzY/ryZ3HsQEg6zHQAd6Xxuyp7C0nPLZf+HfaFxc6WY # 2leOYZskGUHJgojuFu4pd3Rz9u2LqHyIZD62zrTs9L2ztjDLAc635d9lY8LXXPrH # AVIcTvXZneA/iEqFhwi94wEWVq3dTB5bngpU5Oz4XqSkg1QN0wNnRkQym5JWyDvi # 7BBZ1uGNXCRdSqJGtNpFjYpd2tLVchjpaSYQgwmIgfBmgV0VA9PiubAvqRGDNBLV # aP0V1QkKHguLHzV1Ncalk7e4lG0aN4Zga/+WyX0OL7F4kmkN8G1dwnQl6FgKnwNO # TrP373BZdnvCgpYODHexPKtdthlaQhJQEo8VSJGsgg0eC30nQbQjnnZTYVTphUwE # 2aoFJfVU19eBWYfxDy2P/stDCbNkViSZEqdEe3IZ+CT//s5KxCr9ejwm+OsAg3Ki # cw+8BjWt6W37X+TtQcupkZFDb41xTQHjihVcLluBJGo= # SIG # End signature block |