Framework/Core/SVT/ADO/ADO.AgentPool.ps1
Set-StrictMode -Version Latest class AgentPool: ADOSVTBase { hidden [PSObject] $AgentObj; # This is used for fetching agent pool details hidden [PSObject] $ProjectId; hidden [PSObject] $AgentPoolId; hidden [PSObject] $agentPool; # This is used to fetch agent details in pool hidden [PSObject] $agentPoolActivityDetail = @{isAgentPoolActive = $true; agentPoolLastRunDate = $null; agentPoolCreationDate = $null; message = $null; isComputed = $false; errorObject = $null}; hidden [string] $checkInheritedPermissionsPerAgentPool = $false hidden static [PSObject] $regexListForSecrets; hidden [PSObject] $AgentPoolOrgObj; #This will contain org level agent pool details AgentPool([string] $organizationName, [SVTResource] $svtResource): Base($organizationName,$svtResource) { $this.AgentPoolId = ($this.ResourceContext.ResourceId -split "agentpool/")[-1] $this.ProjectId = ($this.ResourceContext.ResourceId -split "project/")[-1].Split('/')[0] $apiURL = "https://dev.azure.com/$($this.OrganizationContext.OrganizationName)/_apis/securityroles/scopes/distributedtask.agentqueuerole/roleassignments/resources/$($this.ProjectId)_$($this.AgentPoolId)"; $this.AgentObj = @([WebRequestHelper]::InvokeGetWebRequest($apiURL)); # if agent pool activity check function is not computed, then first compute the function to get the correct status of agent pool. if($this.agentPoolActivityDetail.isComputed -eq $false) { $this.CheckActiveAgentPool() } # overiding the '$this.isResourceActive' global variable based on the current status of agent pool. if ($this.agentPoolActivityDetail.isAgentPoolActive) { $this.isResourceActive = $true } else { $this.isResourceActive = $false } # calculating the inactivity period in days for the agent pool. If there is no use history, then setting it with negative value. # This will ensure inactive period is always computed irrespective of whether inactive control is scanned or not. if ($null -ne $this.agentPoolActivityDetail.agentPoolLastRunDate) { $this.InactiveFromDays = ((Get-Date) - $this.agentPoolActivityDetail.agentPoolLastRunDate).Days } if ([Helpers]::CheckMember($this.ControlSettings, "Agentpool.CheckForInheritedPermissions") -and $this.ControlSettings.Agentpool.CheckForInheritedPermissions) { $this.checkInheritedPermissionsPerAgentPool = $true } [AgentPool]::regexListForSecrets = @($this.ControlSettings.Patterns | Where-Object {$_.RegexCode -eq "SecretsInBuild"} | Select-Object -Property RegexList); } hidden [ControlResult] CheckRBACAccess([ControlResult] $controlResult) { <#{ "ControlID": "ADO_AgentPool_AuthZ_Grant_Min_RBAC_Access", "Description": "All teams/groups must be granted minimum required permissions on agent pool.", "Id": "AgentPool110", "ControlSeverity": "High", "Automated": "Yes", "MethodName": "CheckRBACAccess", "Rationale": "Granting minimum access by leveraging RBAC feature ensures that users are granted just enough permissions to perform their tasks. This minimizes exposure of the resources in case of user/service account compromise.", "Recommendation": "Refer: https://docs.microsoft.com/en-us/azure/devops/pipelines/policies/permissions?view=vsts", "Tags": [ "SDL", "TCP", "Automated", "AuthZ", "RBAC" ], "Enabled": true }#> if($this.AgentObj.Count -gt 0) { $roles = @(); $roles += ($this.AgentObj | Select-Object -Property @{Name="Name"; Expression = {$_.identity.displayName}},@{Name="Role"; Expression = {$_.role.displayName}}); $controlResult.AddMessage("Total number of identities that have access to agent pool: ", ($roles | Measure-Object).Count); $controlResult.AddMessage([VerificationResult]::Verify,"Validate whether following identities have been provided with minimum RBAC access to agent pool.", $roles); $controlResult.SetStateData("Validate whether following identities have been provided with minimum RBAC access to agent pool.", $roles); $controlResult.AdditionalInfo += "Total number of identities that have access to agent pool: " + ($roles | Measure-Object).Count; } elseif($this.AgentObj.Count -eq 0) { $controlResult.AddMessage([VerificationResult]::Passed,"No role assignment found") } return $controlResult } hidden [ControlResult] CheckInheritedPermissions([ControlResult] $controlResult) { if($this.AgentObj.Count -gt 0) { $inheritedRoles = $this.AgentObj | Where-Object {$_.access -eq "inherited"} if( ($inheritedRoles | Measure-Object).Count -gt 0) { $roles = @(); $roles += ($inheritedRoles | Select-Object -Property @{Name="Name"; Expression = {$_.identity.displayName}},@{Name="Role"; Expression = {$_.role.displayName}}); $controlResult.AddMessage("Total number of inherited role assignments on agent pool: ", ($roles | Measure-Object).Count); $controlResult.AddMessage([VerificationResult]::Failed,"Found inherited role assignments on agent pool.", $roles); $controlResult.SetStateData("Found inherited role assignments on agent pool.", $roles); $controlResult.AdditionalInfo += "Total number of inherited role assignments on agent pool: " + ($roles | Measure-Object).Count; } else { $controlResult.AddMessage([VerificationResult]::Passed,"No inherited role assignments found.") } } elseif($this.AgentObj.Count -eq 0) { $controlResult.AddMessage([VerificationResult]::Passed,"No role assignment found.") } return $controlResult } hidden [ControlResult] CheckOrgAgtAutoProvisioning([ControlResult] $controlResult) { $controlResult.VerificationResult = [VerificationResult]::Failed try { #Only agent pools created from org setting has this settings.. if($null -eq $this.AgentPoolOrgObj) { $agentPoolsURL = "https://dev.azure.com/{0}/_apis/distributedtask/pools?poolName={1}&api-version=6.0" -f $($this.OrganizationContext.OrganizationName), $this.ResourceContext.resourcename; $this.AgentPoolOrgObj = @([WebRequestHelper]::InvokeGetWebRequest($agentPoolsURL)); } if($this.AgentPoolOrgObj.Count -gt 0) { if ($this.AgentPoolOrgObj.autoProvision -eq $true) { $controlResult.AddMessage([VerificationResult]::Failed,"Auto-provisioning is enabled for the $($this.AgentPoolOrgObj.name) agent pool."); } else { $controlResult.AddMessage([VerificationResult]::Passed,"Auto-provisioning is not enabled for the agent pool."); } } else { $controlResult.AddMessage([VerificationResult]::Error,"Could not fetch auto-update details of agent pool."); } } catch{ $controlResult.AddMessage([VerificationResult]::Error,"Could not fetch agent pool details."); $controlResult.LogException($_) } return $controlResult } hidden [ControlResult] CheckAutoUpdate([ControlResult] $controlResult) { $controlResult.VerificationResult = [VerificationResult]::Failed try { if($null -eq $this.AgentPoolOrgObj) { #autoUpdate setting is available only at org level settings. $agentPoolsURL = "https://dev.azure.com/{0}/_apis/distributedtask/pools?poolName={1}&api-version=6.0" -f $($this.OrganizationContext.OrganizationName), $this.ResourceContext.resourcename; $this.AgentPoolOrgObj = @([WebRequestHelper]::InvokeGetWebRequest($agentPoolsURL)); } if($this.AgentPoolOrgObj.Count -gt 0) { if($this.AgentPoolOrgObj.autoUpdate -eq $true) { $controlResult.AddMessage([VerificationResult]::Passed,"Auto-update of agents is enabled for [$($this.AgentPoolOrgObj.name)] agent pool."); } else { $controlResult.AddMessage([VerificationResult]::Failed,"Auto-update of agents is disabled for [$($this.AgentPoolOrgObj.name)] agent pool."); } } else { $controlResult.AddMessage([VerificationResult]::Error,"Could not fetch auto-update details of agent pool."); } } catch { $controlResult.AddMessage([VerificationResult]::Error,"Could not fetch agent pool details."); $controlResult.LogException($_) } return $controlResult } hidden [ControlResult] CheckPrjAllPipelineAccess([ControlResult] $controlResult) { try { $controlResult.VerificationResult = [VerificationResult]::Failed $agentPoolsURL = "https://dev.azure.com/{0}/{1}/_apis/build/authorizedresources?type=queue&id={2}&api-version=6.0-preview.1" -f $($this.OrganizationContext.OrganizationName),$this.ProjectId ,$this.AgentPoolId; $agentPoolsObj = @([WebRequestHelper]::InvokeGetWebRequest($agentPoolsURL)); if([Helpers]::CheckMember($agentPoolsObj[0],"authorized")) { $controlResult.AddMessage([VerificationResult]::Failed,"Agent pool is marked as accessible to all pipelines."); } else { $controlResult.AddMessage([VerificationResult]::Passed,"Agent pool is not marked as accessible to all pipelines."); } $controlResult.AdditionalInfoInCSV = "NA"; $agentPoolsObj =$null; } catch{ $controlResult.AddMessage($_); $controlResult.AddMessage([VerificationResult]::Error,"Could not fetch agent pool details."); $controlResult.LogException($_) } return $controlResult } hidden [ControlResult] CheckInactiveAgentPool([ControlResult] $controlResult) { $controlResult.VerificationResult = [VerificationResult]::Failed try { if ($this.agentPoolActivityDetail.message -eq 'Could not fetch agent pool details.') { $controlResult.AddMessage([VerificationResult]::Error, $this.agentPoolActivityDetail.message); if ($null -ne $this.agentPoolActivityDetail.errorObject) { $controlResult.LogException($this.agentPoolActivityDetail.errorObject) } } elseif($this.agentPoolActivityDetail.isAgentPoolActive) { $controlResult.AddMessage([VerificationResult]::Passed, $this.agentPoolActivityDetail.message); } else { if ($null -ne $this.agentPoolActivityDetail.agentPoolCreationDate) { $inactiveLimit = $this.ControlSettings.AgentPool.AgentPoolHistoryPeriodInDays if ((((Get-Date) - $this.agentPoolActivityDetail.agentPoolCreationDate).Days) -lt $inactiveLimit) { $controlResult.AddMessage([VerificationResult]::Passed, "Agent pool was created within last $inactiveLimit days but never queued."); } else { $controlResult.AddMessage([VerificationResult]::Failed, "Agent pool has not been queued from last $inactiveLimit days."); } $formattedDate = $this.agentPoolActivityDetail.agentPoolCreationDate.ToString("d MMM yyyy") $controlResult.AddMessage("The agent pool was created on: $($formattedDate)"); $controlResult.AdditionalInfo += "The agent pool was created on: " + $formattedDate; } else { $controlResult.AddMessage([VerificationResult]::Failed, $this.agentPoolActivityDetail.message); } } if ($null -ne $this.agentPoolActivityDetail.agentPoolLastRunDate) { $formattedDate = $this.agentPoolActivityDetail.agentPoolLastRunDate.ToString("d MMM yyyy") $controlResult.AddMessage("Last queue date of agent pool: $($formattedDate)"); $controlResult.AdditionalInfo += "Last queue date of agent pool: " + $formattedDate; $agentPoolInactivePeriod = ((Get-Date) - $this.agentPoolActivityDetail.agentPoolLastRunDate).Days $controlResult.AddMessage("The agent pool has been inactive from last $($agentPoolInactivePeriod) days."); } } catch { $controlResult.AddMessage([VerificationResult]::Error, "Could not fetch agent pool details."); $controlResult.LogException($_) } #clearing memory space. $this.agentPool = $null; return $controlResult } hidden [ControlResult] CheckCredInEnvironmentVariables([ControlResult] $controlResult) { $controlResult.VerificationResult = [VerificationResult]::Failed; try { if($null -eq $this.agentPool) { $agentPoolsURL = "https://dev.azure.com/{0}/{1}/_settings/agentqueues?queueId={2}&__rt=fps&__ver=2" -f $($this.OrganizationContext.OrganizationName), $this.ProjectId ,$this.AgentPoolId; $this.agentPool = [WebRequestHelper]::InvokeGetWebRequest($agentPoolsURL); } $patterns = [AgentPool]::regexListForSecrets if($patterns.RegexList.Count -gt 0) { $noOfCredFound = 0; $agentsWithSecretsInEnv=@() if (([Helpers]::CheckMember($this.agentPool[0],"fps.dataproviders.data") ) -and ($this.agentPool[0].fps.dataProviders.data."ms.vss-build-web.agent-pool-data-provider") -and [Helpers]::CheckMember($this.agentPool[0].fps.dataProviders.data."ms.vss-build-web.agent-pool-data-provider","agents") ) { $agents = $this.agentpool.fps.dataproviders.data."ms.vss-build-web.agent-pool-data-provider".agents $agents | ForEach-Object { $currentAgent = "" | Select-Object "AgentName","Capabilities" $currentAgent.AgentName = $_.name $envVariablesContainingSecret=@() $secretsFoundInCurrentAgent = $false if([Helpers]::CheckMember($_,"userCapabilities")) { $userCapabilities=$_.userCapabilities $secretsHashTable=@{} $userCapabilities.PSObject.properties | ForEach-Object { $secretsHashTable[$_.Name] = $_.Value } $secretsHashTable.Keys | ForEach-Object { for ($i = 0; $i -lt $patterns.RegexList.Count; $i++) { if($secretsHashTable.Item($_) -cmatch $patterns.RegexList[$i]) { $noOfCredFound += 1 $secretsFoundInCurrentAgent = $true $envVariablesContainingSecret += $_ break; } } } } $currentAgent.Capabilities = $envVariablesContainingSecret if ($secretsFoundInCurrentAgent -eq $true) { $agentsWithSecretsInEnv += $currentAgent } } if($noOfCredFound -eq 0) { $controlResult.AddMessage([VerificationResult]::Passed, "No secrets found in user-defined capabilities of agents."); } else { $controlResult.AddMessage([VerificationResult]::Failed, "Found secrets in user-defined capabilities of agents."); $count = $agentsWithSecretsInEnv.Count $controlResult.AddMessage("`nCount of agents that contain secrets: $count") $controlResult.AdditionalInfo += "Count of agents that contain secrets: "+ $count; $controlResult.AddMessage("`nAgent-wise list of user-defined capabilities with secrets: "); $display=($agentsWithSecretsInEnv | FT AgentName,Capabilities -AutoSize | Out-String -Width 512) $controlResult.AddMessage($display) $controlResult.SetStateData("Agent-wise list of user-defined capabilities with secrets: ", $agentsWithSecretsInEnv ); } } else { $controlResult.AddMessage([VerificationResult]::Passed, "There are no agents in the pool."); } } else { $controlResult.AddMessage([VerificationResult]::Error, "Regular expressions for detecting credentials in environment variables for agents are not defined in your organization."); } } catch { $controlResult.AddMessage([VerificationResult]::Error, "Could not fetch details of user-defined capabilities of agents."); $controlResult.LogException($_) } return $controlResult } hidden CheckActiveAgentPool() { try { $agentPoolsURL = "https://dev.azure.com/{0}/{1}/_settings/agentqueues?queueId={2}&__rt=fps&__ver=2" -f $($this.OrganizationContext.OrganizationName), $this.ProjectId ,$this.AgentPoolId; $this.agentPool = [WebRequestHelper]::InvokeGetWebRequest($agentPoolsURL); if (([Helpers]::CheckMember($this.agentPool[0], "fps.dataProviders.data") ) -and ($this.agentPool[0].fps.dataProviders.data."ms.vss-build-web.agent-jobs-data-provider")) { # $inactiveLimit denotes the upper limit on number of days of inactivity before the agent pool is deemed inactive. $inactiveLimit = $this.ControlSettings.AgentPool.AgentPoolHistoryPeriodInDays #Filtering agent pool jobs specific to the current project. $agentPoolJobs = $this.agentPool[0].fps.dataProviders.data."ms.vss-build-web.agent-jobs-data-provider".jobs | Where-Object {$_.scopeId -eq $this.ProjectId}; #Arranging in descending order of run time. $agentPoolJobs = $agentPoolJobs | Sort-Object queueTime -Descending #If agent pool has been queued at least once if (($agentPoolJobs | Measure-Object).Count -gt 0) { #Get the last queue timestamp of the agent pool if ([Helpers]::CheckMember($agentPoolJobs[0], "finishTime")) { $agtPoolLastRunDate = $agentPoolJobs[0].finishTime; if ((((Get-Date) - $agtPoolLastRunDate).Days) -gt $inactiveLimit) { $this.agentPoolActivityDetail.isAgentPoolActive = $false; $this.agentPoolActivityDetail.message = "Agent pool has not been queued in the last $inactiveLimit days."; } else { $this.agentPoolActivityDetail.isAgentPoolActive = $true; $this.agentPoolActivityDetail.message = "Agent pool has been queued in the last $inactiveLimit days."; } $this.agentPoolActivityDetail.agentPoolLastRunDate = $agtPoolLastRunDate; } else { $this.agentPoolActivityDetail.isAgentPoolActive = $true; $this.agentPoolActivityDetail.message = "Agent pool was being queued during control evaluation."; } } else { #[else] Agent pool is created but nenver run, check creation date greated then 180 $this.agentPoolActivityDetail.isAgentPoolActive = $false; if (([Helpers]::CheckMember($this.agentPool, "fps.dataProviders.data") ) -and ($this.agentPool.fps.dataProviders.data."ms.vss-build-web.agent-pool-data-provider")) { $agentPoolDetails = $this.agentPool.fps.dataProviders.data."ms.vss-build-web.agent-pool-data-provider" $this.agentPoolActivityDetail.agentPoolCreationDate = $agentPoolDetails.selectedAgentPool.createdOn; } else { $this.agentPoolActivityDetail.message = "Could not fetch agent pool details."; } } } else { $this.agentPoolActivityDetail.message = "Could not fetch agent pool details."; } } catch { $this.agentPoolActivityDetail.message = "Could not fetch agent pool details."; $this.agentPoolActivityDetail.errorObject = $_ } $this.agentPoolActivityDetail.isComputed = $true } hidden [ControlResult] CheckBroaderGroupAccess ([ControlResult] $controlResult) { try { $controlResult.VerificationResult = [VerificationResult]::Failed $restrictedBroaderGroups = @{} $restrictedBroaderGroupsForAgentPool = $this.ControlSettings.AgentPool.RestrictedBroaderGroupsForAgentPool; $restrictedBroaderGroupsForAgentPool.psobject.properties | foreach { $restrictedBroaderGroups[$_.Name] = $_.Value } if (($this.AgentObj.Count -gt 0) -and [Helpers]::CheckMember($this.AgentObj, "identity")) { # match all the identities added on agentpool with defined restricted list $roleAssignmentsToCheck = $this.AgentObj $restrictedGroups = @() if ($this.checkInheritedPermissionsPerAgentPool -eq $false) { $roleAssignmentsToCheck = @($this.AgentObj | where-object { $_.access -ne "inherited" }) } $roleAssignments = @($roleAssignmentsToCheck | Select-Object -Property @{Name="Name"; Expression = {$_.identity.displayName}},@{Name="Id"; Expression = {$_.identity.id}}, @{Name="Role"; Expression = {$_.role.displayName}}); # Checking whether the broader groups have User/Admin permissions $restrictedGroups = @($roleAssignments | Where-Object { $restrictedBroaderGroups.keys -contains $_.Name.split('\')[-1] -and ($_.Role -in $restrictedBroaderGroups[$_.Name.split('\')[-1]])}) if ($this.ControlSettings.CheckForBroadGroupMemberCount -and $restrictedGroups.Count -gt 0) { $broaderGroupsWithExcessiveMembers = @([ControlHelper]::FilterBroadGroupMembers($restrictedGroups, $true)) $restrictedGroups = @($restrictedGroups | Where-Object {$broaderGroupsWithExcessiveMembers -contains $_.Name}) } $restrictedGroupsCount = $restrictedGroups.Count # fail the control if restricted group found on agentpool if ($restrictedGroupsCount -gt 0) { $controlResult.AddMessage([VerificationResult]::Failed, "Count of broader groups that have excessive permissions on agent pool: $($restrictedGroupsCount)"); $formattedGroupsData = $restrictedGroups | Select @{l = 'Group'; e = { $_.Name} }, @{l = 'Role'; e = { $_.Role } } $backupDataObject = $restrictedGroups | Select @{l = 'Group'; e = { $_.Name} },@{l = 'Id'; e = { $_.Id } }, @{l = 'Role'; e = { $_.Role } } $formattedGroupsTable = ($formattedGroupsData | FT -AutoSize | Out-String -width 512) $controlResult.AddMessage("`nList of groups: `n$formattedGroupsTable") $controlResult.SetStateData("List of groups: ", $restrictedGroups) $controlResult.AdditionalInfo += "Count of broader groups that have excessive permissions on agent pool: $($restrictedGroupsCount)"; $groups = $restrictedGroups | ForEach-Object { $_.name + ': ' + $_.role } $controlResult.AdditionalInfoInCSV = $groups -join ' ; ' if ($this.ControlFixBackupRequired) { #Data object that will be required to fix the control $controlResult.BackupControlState = $backupDataObject; } } else { $controlResult.AddMessage([VerificationResult]::Passed, "No broader groups have excessive permissions on agent pool."); $controlResult.AdditionalInfoInCSV = "NA"; } } else { $controlResult.AddMessage([VerificationResult]::Passed, "No groups have given access to agent pool."); $controlResult.AdditionalInfoInCSV = "NA"; } $displayObj = $restrictedBroaderGroups.Keys | Select-Object @{Name = "Broader Group"; Expression = {$_}}, @{Name = "Excessive Permissions"; Expression = {$restrictedBroaderGroups[$_] -join ', '}} $controlResult.AddMessage("Note:`nThe following groups are considered 'broad' which should not excessive permissions: `n$($displayObj | FT -AutoSize| out-string -width 512)"); } catch { $controlResult.AddMessage([VerificationResult]::Error, "Could not fetch the agent pool permissions."); $controlResult.LogException($_) } return $controlResult; } hidden [ControlResult] CheckBroaderGroupAccessAutomatedFix ([ControlResult] $controlResult) { try { $RawDataObjForControlFix = @(); $RawDataObjForControlFix = ([ControlHelper]::ControlFixBackup | where-object {$_.ResourceId -eq $this.ResourceId}).DataObject $body = "[" if (-not $this.UndoFix) { foreach ($identity in $RawDataObjForControlFix) { if ($body.length -gt 1) {$body += ","} $body += @" { "userId": "$($identity.id)", "roleName": "Reader" } "@; } $RawDataObjForControlFix | Add-Member -NotePropertyName NewRole -NotePropertyValue "Reader" $RawDataObjForControlFix = @($RawDataObjForControlFix | Select-Object @{Name="DisplayName"; Expression={$_.group}}, @{Name="OldRole"; Expression={$_.Role}},@{Name="NewRole"; Expression={$_.NewRole}}) } else { foreach ($identity in $RawDataObjForControlFix) { if ($body.length -gt 1) {$body += ","} $body += @" { "userId": "$($identity.id)", "roleName": "$($identity.role)" } "@; } $RawDataObjForControlFix | Add-Member -NotePropertyName OldRole -NotePropertyValue "Reader" $RawDataObjForControlFix = @($RawDataObjForControlFix | Select-Object @{Name="DisplayName"; Expression={$_.group}}, @{Name="OldRole"; Expression={$_.OldRole}},@{Name="NewRole"; Expression={$_.Role}}) } $body += "]" #Put request $url = "https://dev.azure.com/$($this.OrganizationContext.OrganizationName)/_apis/securityroles/scopes/distributedtask.agentqueuerole/roleassignments/resources/$($this.ProjectId)_$($this.AgentPoolId)?api-version=6.1-preview.1"; $rmContext = [ContextHelper]::GetCurrentContext(); $user = ""; $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$rmContext.AccessToken))) $webRequestResult = Invoke-RestMethod -Uri $url -Method Put -ContentType "application/json" -Headers @{Authorization = ("Basic {0}" -f $base64AuthInfo) } -Body $body $controlResult.AddMessage([VerificationResult]::Fixed, "Permission for broader groups have been changed as below: "); $display = ($RawDataObjForControlFix | FT -AutoSize | Out-String -Width 512) $controlResult.AddMessage("`n$display"); } catch{ $controlResult.AddMessage([VerificationResult]::Error, "Could not apply fix."); $controlResult.LogException($_) } return $controlResult } } # SIG # Begin signature block # MIIjiAYJKoZIhvcNAQcCoIIjeTCCI3UCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAAc0LT9Z1UR/oi # IOACnpdXM+zZQCaDoA/xL/Xrzx8WRKCCDYEwggX/MIID56ADAgECAhMzAAAB32vw # LpKnSrTQAAAAAAHfMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ1WhcNMjExMjAyMjEzMTQ1WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQC2uxlZEACjqfHkuFyoCwfL25ofI9DZWKt4wEj3JBQ48GPt1UsDv834CcoUUPMn # s/6CtPoaQ4Thy/kbOOg/zJAnrJeiMQqRe2Lsdb/NSI2gXXX9lad1/yPUDOXo4GNw # PjXq1JZi+HZV91bUr6ZjzePj1g+bepsqd/HC1XScj0fT3aAxLRykJSzExEBmU9eS # yuOwUuq+CriudQtWGMdJU650v/KmzfM46Y6lo/MCnnpvz3zEL7PMdUdwqj/nYhGG # 3UVILxX7tAdMbz7LN+6WOIpT1A41rwaoOVnv+8Ua94HwhjZmu1S73yeV7RZZNxoh # EegJi9YYssXa7UZUUkCCA+KnAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUOPbML8IdkNGtCfMmVPtvI6VZ8+Mw # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDYzMDA5MB8GA1UdIwQYMBaAFEhu # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAnnqH # tDyYUFaVAkvAK0eqq6nhoL95SZQu3RnpZ7tdQ89QR3++7A+4hrr7V4xxmkB5BObS # 0YK+MALE02atjwWgPdpYQ68WdLGroJZHkbZdgERG+7tETFl3aKF4KpoSaGOskZXp # TPnCaMo2PXoAMVMGpsQEQswimZq3IQ3nRQfBlJ0PoMMcN/+Pks8ZTL1BoPYsJpok # t6cql59q6CypZYIwgyJ892HpttybHKg1ZtQLUlSXccRMlugPgEcNZJagPEgPYni4 # b11snjRAgf0dyQ0zI9aLXqTxWUU5pCIFiPT0b2wsxzRqCtyGqpkGM8P9GazO8eao # mVItCYBcJSByBx/pS0cSYwBBHAZxJODUqxSXoSGDvmTfqUJXntnWkL4okok1FiCD # Z4jpyXOQunb6egIXvkgQ7jb2uO26Ow0m8RwleDvhOMrnHsupiOPbozKroSa6paFt # VSh89abUSooR8QdZciemmoFhcWkEwFg4spzvYNP4nIs193261WyTaRMZoceGun7G # CT2Rl653uUj+F+g94c63AhzSq4khdL4HlFIP2ePv29smfUnHtGq6yYFDLnT0q/Y+ # Di3jwloF8EWkkHRtSuXlFUbTmwr/lDDgbpZiKhLS7CBTDj32I0L5i532+uHczw82 # oZDmYmYmIUSMbZOgS65h797rj5JJ6OkeEUJoAVwwggd6MIIFYqADAgECAgphDpDS # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVXTCCFVkCAQEwgZUwfjELMAkG # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAd9r8C6Sp0q00AAAAAAB3zAN # BglghkgBZQMEAgEFAKCBsDAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgIJD71CaX # 4E66Sw6bHSNfIBOsCEzGs1u6VLoPBQqgZwYwRAYKKwYBBAGCNwIBDDE2MDSgFIAS # AE0AaQBjAHIAbwBzAG8AZgB0oRyAGmh0dHBzOi8vd3d3Lm1pY3Jvc29mdC5jb20g # MA0GCSqGSIb3DQEBAQUABIIBAA4c7XnPZoa0SjWLK274KwpH3M/F6YT69IhNZUGr # 7hO0XHuJ1hO3Tx85oQIauJOtZXCVYVqUOoJplYbDjACiPFvSOfs52u5nE5ft5spq # fusgz58e7gxiyYUwsBq0w29BYcRg6WiOYymh3W95nbHuICtDHsRjT63418w0Uem/ # jfeNlJRF/+sa7VKXGlxAPIA1pNSwFTtfjx4HZEei+aSi3FGf5Ix6gWq2Ct6MvNdY # qGfCGiA0YVcwLZSlqmLoM8PYu+QEdf1QPOwpNgt5HsFqvFuYzprKEdKiY/MqUFzw # TvlQYm5gYIBJ3pBne6V8Mda3ZuEH3rSHaHayjOK6krmav2uhghLlMIIS4QYKKwYB # BAGCNwMDATGCEtEwghLNBgkqhkiG9w0BBwKgghK+MIISugIBAzEPMA0GCWCGSAFl # AwQCAQUAMIIBUQYLKoZIhvcNAQkQAQSgggFABIIBPDCCATgCAQEGCisGAQQBhFkK # AwEwMTANBglghkgBZQMEAgEFAAQgcfRIEpa2JqtFcPMWTOlb8yXe8gVBqfPDc/Sk # NEMfCgECBmFDqWTE7BgTMjAyMTEwMTMwOTE5MzMuNDc4WjAEgAIB9KCB0KSBzTCB # yjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMc # TWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRT # UyBFU046REQ4Qy1FMzM3LTJGQUUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFNlcnZpY2Wggg48MIIE8TCCA9mgAwIBAgITMwAAAU6Msevt17LjAAAAAAAB # TjANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAe # Fw0yMDExMTIxODI2MDFaFw0yMjAyMTExODI2MDFaMIHKMQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmlj # YSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpERDhDLUUzMzct # MkZBRTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCASIw # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAIb7m+j1Sv2TucITpqVT2TUC/8Pk # bRtEs5JBEt+Xvr+yInANW+Umz2uyfGZeirZW7/kEJWcCLr1vSdQisk1dBE+vEFvL # WQvZZaOADLg5Y2WFPNhY3xJgsDU6rCO8E2dyvVV6N4cjTXwbV7nDxjCrAGG4r8hq # EgIz+3xShMEiEo+xsbc0IidzNTkaAd6sbQzKnu6D37wSzqOgCXam7zwZ58eDjxE6 # cIYC+ZvfE+ml2FQfOlLA+GMu8wc+eKVAA3YiNBycCvF0FDcjqWU4QhbAl2iKfYYb # 8WJUzK8r3ZtY4LBlKPjalwFc02yhvRKj3LFEld8dK7JT98yB+tdM6rSGjakCAwEA # AaOCARswggEXMB0GA1UdDgQWBBSiNVETJkLj9rLr5+bCaWrapmAZ4TAfBgNVHSME # GDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVodHRw # Oi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1TdGFQ # Q0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5o # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBDQV8y # MDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMI # MA0GCSqGSIb3DQEBCwUAA4IBAQCjiZzIrZKvgWUXlWBORF3U855V5sRYK8mOGzUi # ptV9Il581ZcvmJgvFzZ8mxw17uLzrKtsF+xOGPy69BXuXHQkQa381PqeVSdjHIkH # Zko3Wk8AJwoyYct5dQvoEyuBoT1WXnMlDKvmEZ9roYtB5d6u3/xbErjl+6wA1cWr # MQ4HymDDJ2WHFoWv5Htgfx5z74Qmb7IggXq0LWfli9bLiZA0oGQW6TnYXEMqghJD # Ta63HMtWYrfBETdJVtoZDQ6LEXrlzKZU5aYsgQWbKLSYaQjmS8pAGluCXx+g4o2v # DQXz5DlSzoB+gnXWtsrkdSbdS2r3vlIrBwBXMAkJ4zphlbmXMIIGcTCCBFmgAwIB # AgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2Vy # dGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcNMjUwNzAx # MjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw # JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIwDQYJKoZI # hvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0VBDVpQoA # goX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEwRA/xYIiE # VEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQedGFnkV+B # VLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKxXf13Hz3w # V3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4GkbaICDXo # eByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEAAaOCAeYw # ggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7fEYbxTNo # WoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW # BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH # AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0gAQH/BIGV # MIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93d3cubWlj # cm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYBBQUHAgIw # NB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUAbQBlAG4A # dAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOhIW+z66bM # 9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS+7lTjMz0 # YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlKkVIArzgP # F/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon/VWvL/62 # 5Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOiPPp/fZZq # kHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/fmNZJQ96 # LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCIIYdqwUB5v # vfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0cs0d9LiF # AR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7aKLixqduW # sqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQcdeh0sVV # 42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+NR4Iuto2 # 29Nfj950iEkSoYICzjCCAjcCAQEwgfihgdCkgc0wgcoxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNh # IE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOkREOEMtRTMzNy0y # RkFFMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEw # BwYFKw4DAhoDFQCDy4/EvT/6w74073FYPHlRLxB+AqCBgzCBgKR+MHwxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m # dCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA5REW8TAiGA8y # MDIxMTAxMzE2MjcyOVoYDzIwMjExMDE0MTYyNzI5WjB3MD0GCisGAQQBhFkKBAEx # LzAtMAoCBQDlERbxAgEAMAoCAQACAiMgAgH/MAcCAQACAhFJMAoCBQDlEmhxAgEA # MDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAI # AgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAe5T6hWEH29q6fjQ+yjpLlzS0hxuA # nG6eW1M5UO3yHyWVuj0hpGuHHr00eB6ZzpUV/hHdLBQ0rJbrvim97nkHHEJ/2j/H # /j0G3fz0flPqQeQVXup/Qihhrzg8dG/nqb/DO7ZgihD9Y2l3l3O/435ShQj5SsY5 # 3bh6vRHkYH99vGExggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ # Q0EgMjAxMAITMwAAAU6Msevt17LjAAAAAAABTjANBglghkgBZQMEAgEFAKCCAUow # GgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCCMMP+k # fgm/xXi6xjXHo/cjJVlaCwHpw7TZuGKAL1L73DCB+gYLKoZIhvcNAQkQAi8xgeow # gecwgeQwgb0EIAj+DeKYS4uB5zD+uh1CCkTd7zIxK4gCjv7qfePKJS+SMIGYMIGA # pH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAFOjLHr7dey4wAA # AAAAAU4wIgQgxiV0YZ7dXfLWppmZp+ZtTomtL7guL3iCRjLeDOJJvy0wDQYJKoZI # hvcNAQELBQAEggEAZJNBvkHmgtrQZdXdmTVrn345eKNZwgfRf3EEfTmZ+aZZjvPs # zKNRW9TLnKqT4Zme/pQBZ+nwD5rH7Acse+p7zEALCdHiuV9oDxJZ8m3K8w8hWGot # XObXWkyGHStZrjGmJJFpS0+SrFMEXCOS2lpCW4LsKZfTFpRNu7mHA5A8od24qmV6 # 4vI4knliwg/TJWkK2cqZzMjzaLGy8KNlKVSfQX7gQQmutP4pfv38U1i3WHAq9TJ9 # aj+Zwwjoa8+D9TAY5Hns3m+MyMoOH6xbZTJz1ENs2ThKAsvwffZxPMZaVEpxoGaJ # og93ASazAEUXem8efLHCLXuxcGikT3LIfVZjKQ== # SIG # End signature block |