private/InvokeGCS.ps1
|
<# .Synopsis Script for making GCS API calls. .Description The primary function (Call-Url) within this script is crafted to interact with the GCS API, returning a response if any, and allowing a maximum of 3 retry attempts. .Parameter CommandType A mandatory parameter indicating the CommandType for the API call. .Parameter Token A necessary parameter specifying the OAuth2 token used in the API call. .Parameter Method A mandatory parameter specifying the API call method (e.g., Get, Post, Put, Delete). .Parameter UrlPath An required parameter specifying the URL path. For example, if the URL is https://www.example.com/v1.0/admin/connection/connectionid, then /v1.0/admin/connection/connectionid is the URL path. .Parameter TenantId A required parameter specifying the TenantId for which the API call is intended. #> function GetEnvironmentFromTenant { param( [parameter(Mandatory=$true)] [string]$TenantId ) Write-Host "GetEnvironmentFromTenant for Tenantid: $($TenantId)" New-Variable -Name GccSubRegion -Value "gcc" -Option Constant New-Variable -Name UsgRegion -Value "usg" -Option Constant New-Variable -Name UsGovRegion -Value "usgov" -Option Constant New-Variable -Name DodSubRegion -Value "dod" -Option Constant New-Variable -Name DodConSubRegion -Value "dodcon" -Option Constant New-Variable -Name GCCTenantRegionScope -Value "na" -Option Constant $headers = @{"Accept" = "application/json"} $tenantCloudInfo = Invoke-RestMethodWithRetries -ApiName "GetTenantCloudInfo" -Uri "https://login.microsoftonline.com/$TenantId/.well-known/openid-configuration" -Headers $headers -Method Get | ConvertFrom-Json $regionScope = "" $regionSubScope = "" if( -not ([string]::IsNullOrEmpty($tenantCloudInfo.tenant_region_scope)) ) { $regionScope = ([string]$tenantCloudInfo.tenant_region_scope).ToLower() } if( -not ([string]::IsNullOrEmpty($tenantCloudInfo.tenant_region_sub_scope)) ) { $regionSubScope = ([string]$tenantCloudInfo.tenant_region_sub_scope).ToLower() } if(($regionScope -eq $GCCTenantRegionScope) -and ($regionSubScope -eq $GccSubRegion)) { return "GCC" } elseif (($regionScope -eq $UsgRegion) -or ($regionScope -eq $UsGovRegion)) { if($regionSubScope -eq $DodConSubRegion) { return "GCCH" } elseif($regionSubScope -eq $DodSubRegion) { return "DoD" } } return "PROD" } function Invoke-RestMethodWithRetries { param ( [parameter(Mandatory=$true)] [string]$apiName, [parameter(Mandatory=$true)] [string]$uri, [parameter(Mandatory=$true)] [hashtable]$headers, [parameter(Mandatory=$true)] [string]$method, [parameter(Mandatory=$false)] [object]$requestBody = $null, [parameter(Mandatory=$false)] [int]$maxRetries = 3, [parameter(Mandatory=$false)] [bool]$ShouldBrowserHandleRedirects = $false ) $retryCount = 0 $errorMessage = "" do { try { Write-Host "Request Made for $($apiName)" if($ShouldBrowserHandleRedirects -eq $true) { if ($requestBody) { # Send the request $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method $method -Body $requestBody -MaximumRedirection 0 -ErrorAction SilentlyContinue # Extract the redirect URL $redirectUrl = $response.Headers.Location # Open the redirect URL in the default browser Start-Process -FilePath "msedge.exe" -ArgumentList "$redirectUrl -inprivate" return } else { # Send the request $response = Invoke-WebRequest -Uri $uri -Headers $headers -Method $method -MaximumRedirection 0 -ErrorAction SilentlyContinue # Extract the redirect URL $redirectUrl = $response.Headers.Location # Open the redirect URL in the default browser Start-Process -FilePath "msedge.exe" -ArgumentList "$redirectUrl -inprivate" return } } else { if ($requestBody) { return Invoke-WebRequest -Uri $uri -Headers $headers -Method $method -Body $requestBody } else { return Invoke-WebRequest -Uri $uri -Headers $headers -Method $method } } } catch { $errorMessage = $_ $retryCount++ $exponentialBackoff = [int]([Math]::Pow(2,$retryCount)) Write-Warning "Request failed for $apiName. Retrying (Attempt $retryCount)..." Start-Sleep -Seconds $exponentialBackoff # Increase the wait time with each retry } } while ($retryCount -lt $maxRetries) throw "Request failed for $apiName. All the retries are exhausted. `n$errorMessage" } # Select BaseUrl on the basis of Environment function SelectBaseUrl { param ( [Parameter(Mandatory=$true)] [string]$selectedEnvironment ) if ($selectedEnvironment -eq "GCC") { return "https://gcsgcc.office.com" } elseif ($selectedEnvironment -eq "GCCH") { return "https://gcs.office365.us" } elseif ($selectedEnvironment -eq "PROD") { return "https://gcs.office.com" } throw "Tenant Environment is not supported" } function Call-Url{ param( # cmdlet type [Parameter(Mandatory=$true)] [string] $CommandType, # token details [Parameter(Mandatory=$true)] [PSCustomObject] $Token, #Method [Parameter(Mandatory=$true)] [string] $Method, #Url Path [Parameter(Mandatory=$true)] [string] $UrlPath, #Request Body [parameter(Mandatory=$false)] [object] $RequestBody = $null, # Tenant id [Parameter(Mandatory=$true)] [string] $TenantId, # Content type Header [Parameter(Mandatory=$false)] [string] $ContentTypeHeader = "application/json", [Parameter(Mandatory=$false)] [bool] $ShouldBrowserHandleRedirects = $false ) try{ $culture = Get-Culture $languageCode = $culture.Name $baseUrl = SelectBaseUrl -SelectedEnvironment (GetEnvironmentFromTenant -TenantId $TenantId) $headers = @{"authorization"="Bearer $($Token.AccessToken)"; "Content-Type"=$ContentTypeHeader; "Accept" = "application/json"; "Accept-Language" = "$languageCode"} $uri = $baseUrl + $UrlPath return Invoke-RestMethodWithRetries -ApiName $CommandType -Uri $uri -Headers $headers -Method $Method -RequestBody $RequestBody -ShouldBrowserHandleRedirects $ShouldBrowserHandleRedirects } catch{ throw "error happen while calling API for $($CommandType), Error Message: $($_)" } } # SIG # Begin signature block # MIIngQYJKoZIhvcNAQcCoIIncjCCJ24CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCABCY0OXiu9YJ4O # uZGoUvXb2W7UtrDUvfGjktZIIQC3v6CCDLowggX1MIID3aADAgECAhMzAAACHU0Z # yE7XD1dIAAAAAAIdMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQzWhcNMjcwNDE1MTg1 # OTQzWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDQvewXxx9gZZFC6Ys1WBay8BJ8kGA4JQnH5CMafqOASlTpK9H8 # o5ZXTXt0caVQTNMUPt445wXYD+dFtaKWTwDn1I52oUSrC9vJin1Gsqt+zyKJL5Dg # 3eQXbQNR61DmMy20GLTIO3SFed9Rfi/ophgCLGFLDR3r0KvHjwMb/jYWS0celV/4 # Lz27LfAekm8v9E5IXaeiXbAUYZKK090n4CVl3JBtbN+9DtI9SNu/yjvozW52/u7R # X/Ttpa/KDlpuokZ+Zcbvmtd9ur9gFLvZzh41o9MsE/clQtdaFWGvuo6Jua/ntpgk # ey3E5/vBFe+MJPG6phdnuo6r57ZudCudiI1bAgMBAAGjggGbMIIBlzAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFH6QuMwqcPG0hQlQ6c5jCtTTLrVeMEUGA1UdEQQ+MDykOjA4MR4wHAYDVQQL # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xFjAUBgNVBAUTDTIzMDAxMis1MDc1NTkw # HwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEwYAYDVR0fBFkwVzBVoFOg # UYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0 # JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNybDBtBggrBgEFBQcBAQRh # MF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # Y2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # dDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQBKTbYOjzwTG/DXGaz9 # s6+fQeaTtDcFmMY+5UyVFCyj7Pv+5i37qfX8lSL/tBIfYQfWsMuBQlfZurJD6r4H # VJ2CeH+1fgiq8dcHdVKoZ3Sa2qXoX3cq9iS8cVb06B7+5/XJ7I0OxHH9fDsvJ3T3 # w5V/ZtAIFmLrl+P0CtG+92uzRsn0nTbdFjOkLMLWPLAU3THohKRlSEMgFJpPkm5n # 5UAZ35xX6FWCrDLsSKb555bTifwa8mJBwdlof0bmfYidH+dxZ1FdDxvLnNl9zeKs # A4kejaaIqqIPguhwAti5Ql7BlTNoJNwxCvBmqW2MQLnCkYN/VVUsR3V2x/rcTNzo # Bf/Z/SpROvdaA2ZOOd1uioXJt3tdLQ7vHpqpib0KfWr/FWXW10q38VxfCnRQBqzb # SuztR7nEMuzX7Ck+B/XaPDXd1qh72+QYyB0Z2VzWmO9zsnb9Uq/dwu8LGeQqnyu6 # 7SDGACvnXii2fb9+US492VTnXSnFKyqwgzUyFMtZK1/sHYTv6bG4TtQUygQxTN+Z # V+aJIlKO2MqZ7bKrAnOzS9m6NgoTdWOq11bTOZwKlIEV/EhV9SWkDmdpR/hPPT2v # 6TEj4F8PT/zHjRezIU5c/DGlt/VhY/pK0XkJtEyMmmS1BMtjU/rqBZVMIm3dnxQs # /TBByr+Cf8Z1r7aifQVQ+WSqzjCCBr0wggSloAMCAQICEzMAAAA5O7Y3Gb8GHWcA # AAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRl # IEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoXDTM2MDMyMjIyMTMwNFow # VzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEo # MCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAyNDCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeqlRYHNa265v4IY9fH8TKh # emHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo0dtS/EW6I/yEL/bLSY8h # KpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATvQVL4tcf03aTycsz8QeCd # M0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a1uv1zerOYMnsneRRwCbp # yW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1FyQfK0fVkaya8SmVHQ/t # Of23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfOGSWHIIV4YrTJTT6PNty5 # REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7ttOu1bVnXfHaqPYl2rPs # 20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJuz2MXMCt7iw7lFPG9LXK # Gjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxSCwyoGIq0PhaA7Y+VPct5 # pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOmVQop36wUVUYklUy++vDW # eEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3SkE/xIkgpfl22MM1itkZ # 35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGC # NxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPXLQaUEggxMBkGCSsGAQQB # gjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # ci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAwTgYIKwYBBQUHMAKGQmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAFJQfOChP7onn6fLI # MKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D5W4wMwYeLystcEqfkjz4 # NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBYnbu0+THSuVHTe0VTTPVh # ily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSIvgn0JksVBVMYVI5QFu/q # hnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6aR9y34aiM1qmxaxBi6OU # nyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4wPKC5OmHm1DQIt/MNokbb # H3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7RTX8AdBPo0I6OEojf39z # uFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK/fg8B2qjW88MT/WF5V5u # vZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSKYBv0VisCzfxgeU+dquXW # 9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkwYTu/9dLeH2pDqeJZAABV # DWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVTQl0v4q8J/AUmQN5W4n10 # 1cY2L4A7GTQG1h32HHAvfQESWP0xghodMIIaGQIBATBuMFcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jv # c29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIdTRnITtcPV0gAAAAAAh0w # DQYJYIZIAWUDBAIBBQCggeYwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIACvtKQ+ # EDpfm49U0Cw+ZktpWYiLN8AKM5/pQL2V4inkMHoGCisGAQQBgjcCAQwxbDBqoEyA # SgBNAGkAYwByAG8AcwBvAGYAdAAuAEcAcgBhAHAAaAAuAEMAbwBuAG4AZQBjAHQA # bwByAHMALgBDAG0AZABsAGUAdAAuAGQAbABsoRqAGGh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbTANBgkqhkiG9w0BAQEFAASCAQB1jL6qRZ37QOkWAoCUYwaQHGiJXQPf # yxQrbrGMpJmKmFH7QV715hGrs/wfhpYG/z6UnWndR4513ycfqeaooX2EV/2YEzXU # tkPCU/NjDepY8Q7idkfgK09cEL+Ib30GBgIxT2q1+mUJdmWtQ+FlbbLI3jfz/fHn # +S1iELeXnF+2z9ZIvm/dGmqYCMXsCReWZMopQZsYd91cRc4ikPTYvxESzXe8VvVA # lZ6+XiAIgUm1DNbJkbbnEPxg3GEpBK+gFTHS2nqjpAcgpay+qowMy12tjB5d53je # PoPSy6GqzzuRKMcJC/neyDargQcEyTdyWup10SFnnkxLWTALs5J1AXhNoYIXlzCC # F5MGCisGAQQBgjcDAwExgheDMIIXfwYJKoZIhvcNAQcCoIIXcDCCF2wCAQMxDzAN # BglghkgBZQMEAgEFADCCAVIGCyqGSIb3DQEJEAEEoIIBQQSCAT0wggE5AgEBBgor # BgEEAYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEILpTvItBNIuN8nkmyWeGySYJ12xy # F3cPE+oT/i7utFFoAgZqWim2TEQYEzIwMjYwNzIwMTM0NzIzLjQzMlowBIACAfSg # gdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAj # BgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5T # aGllbGQgVFNTIEVTTjo4OTAwLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgU2VydmljZaCCEe0wggcgMIIFCKADAgECAhMzAAACIkHS9qr/ # yLX/AAEAAAIiMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD # QSAyMDEwMB4XDTI2MDIxOTE5Mzk1NloXDTI3MDUxNzE5Mzk1NlowgcsxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29m # dCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo4 # OTAwLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2Vy # dmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALW54om6Qi5SwAAm # j8BjkNlGoftuGC/sJYY2UR1tEaghOt0Tpayfns1o27UFN2MFsVy/tF+LG17TH4dG # 9dKqwP5Z5Jf/r/L3ATQzP7FE9MYhjbQrtpANrrw7LNXJR5QLKnJkL+Bb/fK079k6 # dT0fauLvuQk/wAGurLLVTFf86x4SC8eyPzKKRZPQBG2uNZtcwcXNI6jmFBx9SYxc # qpZbPr43T5TKeEbLWf52hbhZmCkfxjlbuGlKiRaPUz8u7jCLejoPP29Va6RyBQUa # MsCXhhmk6FqHse6IL9qVciYxB/wLcDyr/r/WEWh4hkHhQaTLDEH85JM5Kwvr7f2k # OrMzsKA6l/hXv32Q33jIz25ckjlP9KIDkx0hkiERbT5uHzlGoOHlhbf+hq/nhE/H # Dk4+UfrhBXoomSXQUgSUxWgs2jxRZFBwwPXv3HtYBKMLouxo1nvIrSpwRIiwvXCJ # CZ19AHFyqsUKkhB+eZAWQ6n0jJdRarNry2anPwTppeD1vV6IBPc9VOCs6U+L+Fhk # J8/Ff/qMa3I+PLUKLA6YlqaiGZJT/8I4B6d9FPYbYcxFSkJfXOz4CYOZ1AzVdFpv # hhIAssCUPMYKyAjvuee4mOhcCWIma/s1+u9YBwDkqoJQ5ZDqRI+3mvbwx8pdYkml # Je0V5L8yQPMnL+IlFXIdwXL8H4y3AgMBAAGjggFJMIIBRTAdBgNVHQ4EFgQUWQfA # agMnllsQSK7wqy2K6ypqjNAwHwYDVR0jBBgwFoAUn6cVXQBeYl2D9OXSZacbUzUZ # 6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br # aW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSku # Y3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDovL3d3dy5taWNy # b3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIw # UENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggr # BgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQADggIBAGIAz6eq # unAbb23FJe/jaj4KxN7YLhuhpF8WO70lpaQtMfCrumSc040vef5QbfH8HTzcQpeI # VisCa6XsFMcIZdTrf/FGxnbCPdmZHQDh32d/2xoIlWbiO49UUFqL+iS045gfaP7X # 7MzvTCg3mieAH+m/LtfwB9jokHhc+9vzRDPt9jl511ufCPODWxmFQ8VttzB5Z4AI # g2vOoUrraYx5cqaG258ytqiiAl4ld9ZjfHj+lu5uAQ1Pf6ldPrnbTcI8X2R90oTs # YoAhFjLfGQFMO8V3x25+M6kKffycrqoyVW2cGMOFZAbQ8zcT+jEGzlQGsjqkFiSY # ge1uOJ8Oq4dP5OFpVXvEdzoiehJzdo3Nfj0kdSBCa68N0yMuRthd4DT/WrkjFKDZ # T7JxkE68CLe51k8qEDlXM4ON/+5y7+8W1ethxGSYYo3eO6Norf/IxmLYm7k0Qvch # JaivCntGN5mD4kwgrR+iy5WP5gKbmvrgsf8P1AkMCP5d9lo14V2/3QrkDRBFEY/+ # mgH3JMhWMReP+4nOnwvgN3jiwCq6oM6Id2QuDF8ryc+qkJJY9n0b5EI+bzmj1wB/ # EQ22tK47BynIrPGxEJgIv48rj73yiuK30RUn8sugJ4b6MuWPQpoPhDLqxl7itYyv # VutAuixMFk3AWdfE2MicJYF3SLuKzXJNL/ipMIIHcTCCBVmgAwIBAgITMwAAABXF # 52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2Vy # dGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1WhcNMzAwOTMw # MTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw # JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCAiIwDQYJKoZI # hvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O1YLT/e6cBwfS # qWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZnhUYjDLWNE893 # MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t1w/YJlN8OWEC # esSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxqD89d9P6OU8/W # 7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmPfrVUj9z6BVWY # bWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSWrAFKu75xqRdb # Z2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv231fgLrbqn42 # 7DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zbr17C89XYcz1D # TsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYctenIPDC+hIK12Nv # DMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQcxWv2XFJRXRLb # JbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17aj54WcmnGrnu3 # tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQABMCMGCSsGAQQB # gjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQUn6cVXQBeYl2D # 9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEF # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9z # aXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQBgjcUAgQMHgoA # UwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY # MBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6 # Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1 # dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIw # MTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3hLB9nATEkW+Ge # ckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x5MKP+2zRoZQY # Iu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74py27YP0h1AdkY # 3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1AoL8ZthISEV09 # J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbCHcNhcy4sa3tu # PywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB9s7GdP32THJv # EKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNtyo4JvbMBV0lU # ZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3rsjoiV5PndLQ # THa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcVv7TOPqUxUYS8 # vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A245oyZ1uEi6vAn # Qj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lwY1NNje6CbaUF # EMFxBmoQtB1VM1izoXBm8qGCA1AwggI4AgEBMIH5oYHRpIHOMIHLMQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQg # QW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046ODkw # MC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZp # Y2WiIwoBATAHBgUrDgMCGgMVALvJxdVnHduwOkmSvtW5yCmSyjO4oIGDMIGApH4w # fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd # TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQELBQACBQDu # CJxkMCIYDzIwMjYwNzIwMTMwODUyWhgPMjAyNjA3MjExMzA4NTJaMHcwPQYKKwYB # BAGEWQoEATEvMC0wCgIFAO4InGQCAQAwCgIBAAICLcUCAf8wBwIBAAICF7MwCgIF # AO4J7eQCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQAC # AwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0BAQsFAAOCAQEAGN5FIzsYeGbqMnbS # ZthkUFFy5tmLO9M5NpRc1MrQRzrHgVRLMkI4eqyPEu0Ws0bjm/F/fSB2iuM3DcOM # hItexjqA4OuXi0us/D39HrN7Ezq6y2M5kYPX7t8y6QLD5k4PriW6x2SsZw56UCEP # YKr0GNPWiF47dXiy9ay/cd5jLQbHspufeEVAVrEGezCBzfHU8oKFBb4kCZQpYJsF # 66y6WWDXYQ6CImMlUXgsrY1LhA1v1dmGIMO3H9w0PR7oA1UnRTpBJbUMV4jjwvrf # XMvm2cml5WqZimlXgaIwKu+iXyAjDj0du1NoYXdyow7Qw5oKqZ5mhYYDEvTjci/L # 15uzlTGCBA0wggQJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw # AhMzAAACIkHS9qr/yLX/AAEAAAIiMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG # 9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIDhu3CZNQpsgBDL3 # JyhRKpITAjDdOUAz2CrcbMvTKd3rMIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCB # vQQgBWBdAQoE58aCM2ySYM6ZtwQg6ccY3AD5BxG58NHkCRMwgZgwgYCkfjB8MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy # b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAiJB0vaq/8i1/wABAAACIjAi # BCA5Yd7hQrn9O+54/O9XG4pv8zDcZUEa3iTq2JhM2k3+gzANBgkqhkiG9w0BAQsF # AASCAgCgPl9DonRBmjH9WxzJhvYdpHM/JODob+K8UU1MRPHSz+7IScEI6+vptQzq # MBgyejtZGVWYFZ10CuNhCgaOiusbh7JjtvsKYBBCkONJt5o9qQtIjRmLrT6qC/fK # IX6LbBL6miuTZ/7GfIiyOCbH6E/9Yhi1M+j9KhqOE4vfNYhJv7KsrBk3YhT+EV4x # 3N0f6cWemi5SsNIAOwXwOdeNBFGta/Az/SpqSRBgtdINa/2da80ageNoP/3CEgqa # dvmae8peEcYlJ8G0HeJd9NiR0SnIhdbYaBJPet2xmAgj9VYyU+T1rtPhE36DQWQJ # cqUkdQyxybiNfMbtWxusG1l5VUhIMrVb9sSo6Ch/8Bq9jbvxAOT9KksLDLP1fAba # TEaJCWdbu4OhbYbusKgBJMMvCpcoa9g0S4T8fuk6fBJE7GYwa1y6kYlvc5mau5c1 # LgMqTUu4yuBM8TG78d0PCu6zX/6l/lSnrmQDgSx9xAxnvMWn6HDL7niv7LwGxoFP # 0j0iecaMmAwUuVQsVej0C4jkJqgPUKgagiE1uJHRdcgnmWhblo8oaoNzyGIvTlf6 # DkxZEQNJYV26glqAwZxeEAGFLRQwfh5/eVxxzML411LXPVDpHEwbza1ZS7eRc9EF # e9WnUjF0uHjq7d6cm32HO2r27fozSloHi+mogq3VvyuA5o9/tQ== # SIG # End signature block |