Framework/BugLog/AutoCloseBugManager.ps1
Set-StrictMode -Version Latest class AutoCloseBugManager { hidden [string] $OrganizationName; hidden [PSObject] $ControlSettings; hidden [string] $ScanSource; hidden [bool] $UseAzureStorageAccount = $false; hidden [BugLogHelper] $BugLogHelperObj; static [SVTEventContext []] $ClosedBugs=$null; hidden $ClosedBugTemplate= $null; AutoCloseBugManager([string] $orgName) { $this.OrganizationName = $orgName; $this.ControlSettings = [ConfigurationManager]::LoadServerConfigFile("ControlSettings.json"); $this.ScanSource = [AzSKSettings]::GetInstance().GetScanSource(); if ([Helpers]::CheckMember($this.ControlSettings.BugLogging, "UseAzureStorageAccount", $null)) { $this.UseAzureStorageAccount = $this.ControlSettings.BugLogging.UseAzureStorageAccount; if ($this.UseAzureStorageAccount) { $this.BugLogHelperObj = [BugLogHelper]::BugLogHelperInstance if (!$this.BugLogHelperObj) { $this.BugLogHelperObj = [BugLogHelper]::GetInstance($this.OrganizationName); } } } } #function to auto close resolved bugs hidden [void] AutoCloseBug([SVTEventContext []] $ControlResults) { #tags that need to be searched $TagSearchKeyword = "" #flag to check number of current keywords in the tag $QueryKeyWordCount = 0; #maximum no of keywords that need to be checked per batch $MaxKeyWordsToQuery=0; #all passing control results go here $PassedControlResults = @(); $autoCloseOrgBugFlag=$true $autoCloseProjBugFlag=$true; [AutoCloseBugManager]::ClosedBugs=$null try { $MaxKeyWordsToQuery = $this.ControlSettings.BugLogging.MaxKeyWordsToQueryForBugClose; $autoCloseOrgBugFlag=$this.ControlSettings.BugLogging.AutoCloseOrgBug $autoCloseProjBugFlag=$this.ControlSettings.BugLogging.AutoCloseProjectBug } catch { $MaxKeyWordsToQuery=30 $autoCloseOrgBugFlag=$true $autoCloseProjBugFlag=$true; } #collect all passed control results $ControlResults | ForEach-Object { if ($_.ControlResults[0].VerificationResult -eq "Passed") { #to check if org level bugs should be auto closed based on control settings if($_.FeatureName -eq "Organization"){ if($autoCloseOrgBugFlag -eq $true){ $PassedControlResults += $_ } } #to check if proj level bugs should be auto closed based on control settings elseif($_.FeatureName -eq "Project"){ if($autoCloseProjBugFlag -eq $true){ $PassedControlResults += $_ } } else { $PassedControlResults += $_ } } } #number of passed controls $PassedControlResultsLength = ($PassedControlResults | Measure-Object).Count #This Hash map is used to map an ADOScan hashtag value to a control. $hashToControlIDMap=@{} #the following loop will call api for bug closing in batches of size as defined in control settings, #first check if passed controls length is less than the batch size, if yes then we have to combine all tags in one go #and call the api #if length is more divide the control results in chunks of batch size, after a particular batch is made call the api #reinitialize the variables for the next batch $PassedControlResults | ForEach-Object { $control = $_; #if control results are less than the maximum no of tags per batch #ToDo add common method for both if and else condition if ($PassedControlResultsLength -lt $MaxKeyWordsToQuery) { #check for number of tags in current query $QueryKeyWordCount++; if ($this.UseAzureStorageAccount -and $this.ScanSource -eq "CA") { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); #complete the query $TagSearchKeyword += "(ADOScannerHashId eq '" + $tagHash + "') or " #if the query count equals the passing control results, search for bugs for this batch if ($QueryKeyWordCount -eq $PassedControlResultsLength) { #to remove OR from the last tag keyword. Ex: Tags: Tag1 OR Tags: Tag2 OR. Remove the last OR from this keyword $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $closedBugsResponse = $this.BugLogHelperObj.GetTableEntityAndCloseBug($TagSearchKeyword) if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } } } else { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); $TagSearchKeyword += "Tags: " + $tagHash + " OR " #if the query count equals the passing control results, search for bugs for this batch if ($QueryKeyWordCount -eq $PassedControlResultsLength) { #to remove OR from the last tag keyword. Ex: Tags: Tag1 OR Tags: Tag2 OR. Remove the last OR from this keyword $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $response = $this.GetWorkItemByHash($TagSearchKeyword,$MaxKeyWordsToQuery) #if bug was present if ($response[0].results.count -gt 0) { $ids = @(); $ids += $response.results.fields."system.id"; $closedBugsResponse = $this.CloseBugsInBulk($ids); #$response.results | ForEach-Object { # #close the bug # $id = $_.fields."system.id" # $Project = $_.project.name # $this.CloseBug($id, $Project) #} if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } } } } } #if the number of control results was more than batch size else { $QueryKeyWordCount++; if ($this.UseAzureStorageAccount -and $this.ScanSource -eq "CA") { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); $TagSearchKeyword += "(ADOScannerHashId eq '" + $tagHash + "') or " #if number of tags reaches batch limit if ($QueryKeyWordCount -eq $MaxKeyWordsToQuery) { #query for all these tags and their bugs $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $closedBugsResponse = $this.BugLogHelperObj.GetTableEntityAndCloseBug($TagSearchKeyword); if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } #Reinitialize for the next batch $QueryKeyWordCount = 0; $TagSearchKeyword = ""; $PassedControlResultsLength -= $MaxKeyWordsToQuery $hashToControlIDMap.Clear(); } } else { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); $TagSearchKeyword += "Tags: " + $tagHash + " OR " #if number of tags reaches batch limit if ($QueryKeyWordCount -eq $MaxKeyWordsToQuery) { #query for all these tags and their bugs $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $response = $this.GetWorkItemByHash($TagSearchKeyword,$MaxKeyWordsToQuery) if ($response[0].results.count -gt 0) { $ids = @(); $ids += $response.results.fields."system.id"; $closedBugsResponse = $this.CloseBugsInBulk($ids); #$response.results | ForEach-Object { # $id = $_.fields."system.id" # $Project = $_.project.name # $this.CloseBug($id, $Project) #} if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } } #Reinitialize for the next batch $QueryKeyWordCount = 0; $TagSearchKeyword = ""; $PassedControlResultsLength -= $MaxKeyWordsToQuery $hashToControlIDMap.Clear(); } } } } $hashToControlIDMap.Clear(); $hashToControlIDMap=$null Remove-Variable hashToControlIDMap; } #function to auto close resolved bugs hidden [void] AutoCloseBugCSV([SVTEventContext []] $PassedControlResults) { #tags that need to be searched $TagSearchKeyword = "" #flag to check number of current keywords in the tag $QueryKeyWordCount = 0; #maximum no of keywords that need to be checked per batch $MaxKeyWordsToQuery=0; $autoCloseOrgBugFlag=$true $autoCloseProjBugFlag=$true; [AutoCloseBugManager]::ClosedBugs=$null try { $MaxKeyWordsToQuery = $this.ControlSettings.BugLogging.MaxKeyWordsToQueryForBugClose; $autoCloseOrgBugFlag=$this.ControlSettings.BugLogging.AutoCloseOrgBug $autoCloseProjBugFlag=$this.ControlSettings.BugLogging.AutoCloseProjectBug } catch { $MaxKeyWordsToQuery=30 $autoCloseOrgBugFlag=$true $autoCloseProjBugFlag=$true; } #number of passed controls $PassedControlResultsLength = ($PassedControlResults | Measure-Object).Count #This Hash map is used to map an ADOScan hashtag value to a control. $hashToControlIDMap=@{} $PassedControlResults | ForEach-Object { $control = $_; #if control results are less than the maximum no of tags per batch #ToDo add common method for both if and else condition if ($PassedControlResultsLength -lt $MaxKeyWordsToQuery) { #check for number of tags in current query $QueryKeyWordCount++; if ($this.UseAzureStorageAccount ) { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); #complete the query $TagSearchKeyword += "(ADOScannerHashId eq '" + $tagHash + "') or " #if the query count equals the passing control results, search for bugs for this batch if ($QueryKeyWordCount -eq $PassedControlResultsLength) { #to remove OR from the last tag keyword. Ex: Tags: Tag1 OR Tags: Tag2 OR. Remove the last OR from this keyword $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $closedBugsResponse = $this.BugLogHelperObj.GetTableEntityAndCloseBug($TagSearchKeyword) if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } } } else { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); $TagSearchKeyword += "Tags: " + $tagHash + " OR " #if the query count equals the passing control results, search for bugs for this batch if ($QueryKeyWordCount -eq $PassedControlResultsLength) { #to remove OR from the last tag keyword. Ex: Tags: Tag1 OR Tags: Tag2 OR. Remove the last OR from this keyword $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $response = $this.GetWorkItemByHash($TagSearchKeyword,$MaxKeyWordsToQuery) #if bug was present if ($response[0].results.count -gt 0) { $ids = @(); $ids += $response.results.fields."system.id"; $closedBugsResponse = $this.CloseBugsInBulk($ids); if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } } } } } #if the number of control results was more than batch size else { $QueryKeyWordCount++; if ($this.UseAzureStorageAccount ) { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); $TagSearchKeyword += "(ADOScannerHashId eq '" + $tagHash + "') or " #if number of tags reaches batch limit if ($QueryKeyWordCount -eq $MaxKeyWordsToQuery) { #query for all these tags and their bugs $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $closedBugsResponse = $this.BugLogHelperObj.GetTableEntityAndCloseBug($TagSearchKeyword); if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } #Reinitialize for the next batch $QueryKeyWordCount = 0; $TagSearchKeyword = ""; $PassedControlResultsLength -= $MaxKeyWordsToQuery $hashToControlIDMap.Clear(); } } else { $tagHash=$this.GetHashedTag($control.ControlItem.Id, $control.ResourceContext.ResourceId) $hashToControlIDMap.add($tagHash,$control); $TagSearchKeyword += "Tags: " + $tagHash + " OR " #if number of tags reaches batch limit if ($QueryKeyWordCount -eq $MaxKeyWordsToQuery) { #query for all these tags and their bugs $TagSearchKeyword = $TagSearchKeyword.Substring(0, $TagSearchKeyword.length - 3) $response = $this.GetWorkItemByHash($TagSearchKeyword,$MaxKeyWordsToQuery) if ($response[0].results.count -gt 0) { $ids = @(); $ids += $response.results.fields."system.id"; $closedBugsResponse = $this.CloseBugsInBulk($ids); if ($closedBugsResponse){ $this.closedBugInfoCollect($closedBugsResponse, $hashToControlIDMap) } } #Reinitialize for the next batch $QueryKeyWordCount = 0; $TagSearchKeyword = ""; $PassedControlResultsLength -= $MaxKeyWordsToQuery $hashToControlIDMap.Clear(); } } } } $hashToControlIDMap.Clear(); $hashToControlIDMap=$null Remove-Variable hashToControlIDMap; } #function to close an active bug hidden [void] CloseBug([string] $id, [string] $Project) { $url = "https://dev.azure.com/{0}/{1}/_apis/wit/workitems/{2}?api-version=6.0" -f $this.OrganizationName, $Project, $id #load the closed bug template $BugTemplate = [ConfigurationManager]::LoadServerConfigFile("TemplateForClosedBug.Json") $BugTemplate = $BugTemplate | ConvertTo-Json -Depth 10 $header = [WebRequestHelper]::GetAuthHeaderFromUriPatch($url) try { $responseObj = Invoke-RestMethod -Uri $url -Method Patch -ContentType "application/json-patch+json ; charset=utf-8" -Headers $header -Body $BugTemplate } catch { Write-Host "Could not close the bug" -ForegroundColor Red } } #function to close an active bugs in bulk hidden [object] CloseBugsInBulk([string[]] $ids) { try { $closeBugTemplate = @(); if($PSCmdlet.MyInvocation.BoundParameters["ClosedBugTemplateFilePath"]){ $this.ClosedBugTemplate = Get-Content $PSCmdlet.MyInvocation.BoundParameters["ClosedBugTemplateFilePath"] | ConvertFrom-Json foreach ($id in $ids) { $closeBugTemplate += [PSCustomObject] @{ method = 'PATCH'; uri = "/_apis/wit/workitems/$($id)?api-version=4.1"; headers = @{"Content-Type" = 'application/json-patch+json'}; body =@($this.ClosedBugTemplate) } } } else{ foreach ($id in $ids) { $closeBugTemplate += [PSCustomObject] @{ method = 'PATCH'; uri = "/_apis/wit/workitems/$($id)?api-version=4.1"; headers = @{"Content-Type" = 'application/json-patch+json'}; body = @(@{op = "add"; "path"= "/fields/System.State"; "value"= "Closed"}; @{op = "add"; "path"= "/fields/Microsoft.VSTS.Common.ResolvedReason"; "value"= ""};@{op = "add"; "path"= "/fields/System.History"; "value"= "<div><span style=\\'display:inline !important;\\'>The control has been evaluated to be passing in the most recent scans. Hence the bug has been closed.</span><br> </div>"}) } } } if ($closeBugTemplate.count -gt 0) { $body = $null; if ($closeBugTemplate.count -eq 1) { $body = "[$($closeBugTemplate | ConvertTo-Json -depth 10)]" } else { $body = $closeBugTemplate | ConvertTo-Json -depth 10 } $uri = 'https://{0}.visualstudio.com/_apis/wit/$batch?api-version=4.1' -f $this.OrganizationName $header = [WebRequestHelper]::GetAuthHeaderFromUriPatch($uri) $adoResult = Invoke-RestMethod -Uri $uri -Method Patch -ContentType "application/json" -Headers $header -Body $body if ($adoResult -and $adoResult.count -gt 0) { return $adoResult.value; } } return $false; } catch { Write-Host $_ Write-Host "Could not close the bug." -ForegroundColor Red return $false } } hidden [void] closedBugInfoCollect([object] $closedBugsResponse, [hashtable] $hashToControlIDMap){ # Hash map checks for duplicate work items $hashClosedBugs=@{} $closedBugsResponse| ForEach-Object{ #Store closed bug details $bug=$_.body |ConvertFrom-Json $controlHashValue=$null #Fetch hash From storage account CA response if($this.UseAzureStorageAccount -and $this.ScanSource -eq "CA"){ $controlHashValue=$bug.ADOScannerHashID } #Fetch hash for regular scan else{ $controlHashValue=$bug.fields.'System.Tags' #in case the bug has multiple tags, even if bug is closed, CSV will not be generated if we dont find the tag explicit to scan id $controlHashValue = $controlHashValue.Split(";") | where {$_.Trim() -like "ADOScanID: *"} $controlHashValue = $controlHashValue.Trim(); } $bugState = 'Closed' if($null -ne $this.ClosedBugTemplate){ $bugState = ($this.ClosedBugTemplate | where {$_.path -eq "/fields/System.State"}).value } if ($hashToControlIDMap.ContainsKey($controlHashValue) -and $bug.fields.'System.State' -eq $bugState) { $id=$bug.id $project=$bug.fields.'System.TeamProject' $urlClose= "https://dev.azure.com/{0}/{1}/_workitems/edit/{2}" -f $this.OrganizationName, $project , $id; $hashToControlIDMap[$controlHashValue].ControlResults.AddMessage("Closed Bug",$urlClose); # duplicate work items do not populate static variable $ClosedBugs multiple times if(!$hashClosedBugs.ContainsKey($controlHashValue)){ [AutoCloseBugManager]::ClosedBugs+=$hashToControlIDMap[$controlHashValue] $hashClosedBugs.add($controlHashValue,$true) } } } $hashClosedBugs.Clear() } #function to retrieve all new/active/resolved bugs hidden [object] GetWorkItemByHash([string] $hash,[int] $MaxKeyWordsToQuery) { $url = "https://almsearch.dev.azure.com/{0}/_apis/search/workitemsearchresults?api-version=6.0-preview.1" -f $this.OrganizationName #take results have been doubled, as their might be chances for a bug to be logged more than once, if the tag id is copied. #in this case we want all the instances of this bug to be closed #sprint 2201: added new states for standalone bug logging #TODO: in case we need custom system states for partner teams, fetch system states to check from org policy $body = '{"searchText": "{0}","$skip": 0,"$top": 60,"filters": {"System.TeamProject": [],"System.WorkItemType": ["Bug"],"System.State": ["New","Active","Resolved","Approved","Committed","In Progress","In Review"]}}'| ConvertFrom-Json $body.searchText = $hash $response = [WebRequestHelper]:: InvokePostWebRequest($url, $body) return $response } #function to create hash for bug tag hidden [string] GetHashedTag([string] $ControlId, [string] $ResourceId) { $hashedTag = $null $stringToHash = "$ResourceId#$ControlId"; #return the bug tag if ($this.UseAzureStorageAccount -and $this.ScanSource -eq "CA") { return [AutoBugLog]::ComputeHashX($stringToHash); } else { return "ADOScanID: " + [AutoBugLog]::ComputeHashX($stringToHash) } } } # SIG # Begin signature block # MIInogYJKoZIhvcNAQcCoIInkzCCJ48CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC8CIKeP2jpXaOY # 2ilOXpTFYytOr5oMUCLwxjj0TrIv1qCCDYUwggYDMIID66ADAgECAhMzAAACzfNk # v/jUTF1RAAAAAALNMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjIwNTEyMjA0NjAyWhcNMjMwNTExMjA0NjAyWjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDrIzsY62MmKrzergm7Ucnu+DuSHdgzRZVCIGi9CalFrhwtiK+3FIDzlOYbs/zz # HwuLC3hir55wVgHoaC4liQwQ60wVyR17EZPa4BQ28C5ARlxqftdp3H8RrXWbVyvQ # aUnBQVZM73XDyGV1oUPZGHGWtgdqtBUd60VjnFPICSf8pnFiit6hvSxH5IVWI0iO # nfqdXYoPWUtVUMmVqW1yBX0NtbQlSHIU6hlPvo9/uqKvkjFUFA2LbC9AWQbJmH+1 # uM0l4nDSKfCqccvdI5l3zjEk9yUSUmh1IQhDFn+5SL2JmnCF0jZEZ4f5HE7ykDP+ # oiA3Q+fhKCseg+0aEHi+DRPZAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU0WymH4CP7s1+yQktEwbcLQuR9Zww # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ3MDUzMDAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AE7LSuuNObCBWYuttxJAgilXJ92GpyV/fTiyXHZ/9LbzXs/MfKnPwRydlmA2ak0r # GWLDFh89zAWHFI8t9JLwpd/VRoVE3+WyzTIskdbBnHbf1yjo/+0tpHlnroFJdcDS # MIsH+T7z3ClY+6WnjSTetpg1Y/pLOLXZpZjYeXQiFwo9G5lzUcSd8YVQNPQAGICl # 2JRSaCNlzAdIFCF5PNKoXbJtEqDcPZ8oDrM9KdO7TqUE5VqeBe6DggY1sZYnQD+/ # LWlz5D0wCriNgGQ/TWWexMwwnEqlIwfkIcNFxo0QND/6Ya9DTAUykk2SKGSPt0kL # tHxNEn2GJvcNtfohVY/b0tuyF05eXE3cdtYZbeGoU1xQixPZAlTdtLmeFNly82uB # VbybAZ4Ut18F//UrugVQ9UUdK1uYmc+2SdRQQCccKwXGOuYgZ1ULW2u5PyfWxzo4 # BR++53OB/tZXQpz4OkgBZeqs9YaYLFfKRlQHVtmQghFHzB5v/WFonxDVlvPxy2go # a0u9Z+ZlIpvooZRvm6OtXxdAjMBcWBAsnBRr/Oj5s356EDdf2l/sLwLFYE61t+ME # iNYdy0pXL6gN3DxTVf2qjJxXFkFfjjTisndudHsguEMk8mEtnvwo9fOSKT6oRHhM # 9sZ4HTg/TTMjUljmN3mBYWAWI5ExdC1inuog0xrKmOWVMIIHejCCBWKgAwIBAgIK # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGXMwghlvAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAALN82S/+NRMXVEAAAAA # As0wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIPXT # hZIK3NMdsV88a1e4p2si0qASMpqQUzojSS4WfK+eMEIGCisGAQQBgjcCAQwxNDAy # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20wDQYJKoZIhvcNAQEBBQAEggEAD3gPCfyPC+4vEkZEfNZLiiFwcXGd6NmDABJd # dWAMDBn7/YrFsksqtz2wC/ldYEzmc4MmRcnzlCCYaQDMzTTKdxyFWHnZ9cLcga5M # 6Hcm0H3IhHdDT67C0iMVLjOLv4lvBYCGeR0Lgqty+Y6u57D+EV8GNLneZGWFS/V9 # OVpwT3i51KXFLKIdHrL54GzWVhR0hNOTIZ9PFBJc7XR/gPYaZtAO+BPF/w9pcUuW # BZ3TKHuDObqwpTOBVeEQgX+BllBpDRdsRpQly/nHcLsuVEYvINHK5wq8PVQzsYuT # Q/A72I6+RNZILcsUX28iM6OsCShGcoge6zi6tYAvxN4UFjVJE6GCFv0wghb5Bgor # BgEEAYI3AwMBMYIW6TCCFuUGCSqGSIb3DQEHAqCCFtYwghbSAgEDMQ8wDQYJYIZI # AWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGE # WQoDATAxMA0GCWCGSAFlAwQCAQUABCCQj6OZC6IUK50s1Hd36JuTZthxhlqJWQyD # n4xSb/I4dwIGZDfpEuN3GBMyMDIzMDQxNzEwMzAxMi43OTlaMASAAgH0oIHQpIHN # MIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL # ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMg # VFNTIEVTTjo3QkYxLUUzRUEtQjgwODElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt # U3RhbXAgU2VydmljZaCCEVQwggcMMIIE9KADAgECAhMzAAAByPmw7mft6mtGAAEA # AAHIMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw # MB4XDTIyMTEwNDE5MDEzN1oXDTI0MDIwMjE5MDEzN1owgcoxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjdCRjEtRTNF # QS1CODA4MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAucudfihPgyRWwnnIuJCqc3TC # tFk0XOimFcKjU9bS6WFng2l+FrIid0mPZ7KWs6Ewj21X+ZkGkM6x+ozHlmNtnHSQ # 48pjIFdlKXIoh7fSo41A4n0tQIlwhs8uIYIocp72xwDBHKSZxGaEa/0707iyOw+a # XZXNcTxgNiREASb9thlLZM75mfJIgBVvUmdLZc+XOUYwz/8ul7IEztPNH4cn8Cn0 # tJhIFfp2netr8GYNoiyIqxueG7+sSt2xXl7/igc5cHPZnWhfl9PaB4+SutrA8zAh # zVHTnj4RffxA4R3k4BRbPdGowQfOf95ZeYxLTHf5awB0nqZxOY+yuGWhf6hp5RGR # ouc9beVZv98M1erYa55S1ahZgGDQJycVtEy82RlmKfTYY2uNmlPLWtnD7sDlpVkh # YQGKuTWnuwQKq9ZTSE+0V2cH8JaWBYJQMIuWWM83vLPo3IT/S/5jT2oZOS9nsJgw # wCwRUtYtwtq8/PJtvt1V6VoG4Wd2/MAifgEJOkHF7ARPqI9Xv28+riqJZ5mjLGz8 # 4dP2ryoe0lxYSz3PT5ErKoS0+zJpYNAcxbv2UXiTk3Wj/mZ3tulz6z4XnSl5gy0P # Ler+EVjz4G96GcZgK2d9G+uYylHWwBneIv9YFQj6yMdW/4sEpkEbrpiJNemcxUCm # BipZ7Sc35rv4utkJ4/UCAwEAAaOCATYwggEyMB0GA1UdDgQWBBS1XC9JgbrSwLDT # iJJT4iK7NUvk9TAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNV # HR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Ny # bC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYI # KwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy # MDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0G # CSqGSIb3DQEBCwUAA4ICAQDD1nJSyEPDqSgnfkFifIbteJb7NkZCbRj5yBGiT1f9 # fTGvUb5CW7k3eSp3uxUqom9LWykcNfQa/Yfw0libEim9YRjUNcL42oIFqtp/7rl9 # gg61oiB8PB+6vLEmjXkYxUUR8WjKKC5Q5dx96B21faSco2MOmvjYxGUR7An+4529 # lQPPLqbEKRjcNQb+p+mkQH2XeMbsh5EQCkTuYAimFTgnui2ZPFLEuBpxBK5z2HnK # neHUJ9i4pcKWdCqF1AOVN8gXIH0R0FflMcCg5TW8v90Vwx/mP3aE2Ige1uE8M9YN # Bn5776PxmA16Z+c2s+hYI+9sJZhhRA8aSYacrlLz7aU/56OvEYRERQZttuAFkrV+ # M/J+tCeGNv0Gd75Y4lKLMp5/0xoOviPBdB2rD5C/U+B8qt1bBqQLVZ1wHRy0/6Hh # JxbOi2IgGJaOCYLGX2zz0VAT6mZ2BTWrJmcK6SDv7rX7psgC+Cf1t0R1aWCkCHJt # pYuyKjf7UodRazevOf6V01XkrARHKrI7bQoHFL+sun2liJCBjN51mDWoEgUCEvwB # 3l+RFYAL0aIisc5cTaGX/T8F+iAbz+j2GGVum85gEQS9uLzSedoYPyEXxTblwewG # dAxqIZaKozRBow49OnL+5CgooVMf3ZSqpxc2QC0E03l6c/vChkYyqMXq7Lwd4PnH # qjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL # BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV # BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X # DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM # 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm # 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB # RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb # fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO # Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw # XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW # /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w # EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK # Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2 # BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH # CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB # BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v # BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM # KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF # BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW # BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH # AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF # AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx # Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+ # iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2 # pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw # C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7 # T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO # Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL # mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L # wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5 # m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE # 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggLLMIICNAIB # ATCB+KGB0KSBzTCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UE # CxMdVGhhbGVzIFRTUyBFU046N0JGMS1FM0VBLUI4MDgxJTAjBgNVBAMTHE1pY3Jv # c29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoBATAHBgUrDgMCGgMVAN/OE1C7xjU0 # ClIDXQBiucAY7suyoIGDMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh # c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD # b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw # MTAwDQYJKoZIhvcNAQEFBQACBQDn5wR3MCIYDzIwMjMwNDE3MDczNDE1WhgPMjAy # MzA0MTgwNzM0MTVaMHQwOgYKKwYBBAGEWQoEATEsMCowCgIFAOfnBHcCAQAwBwIB # AAICHOowBwIBAAICEacwCgIFAOfoVfcCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYK # KwYBBAGEWQoDAqAKMAgCAQACAwehIKEKMAgCAQACAwGGoDANBgkqhkiG9w0BAQUF # AAOBgQDX/DJtVSLIdxQlJ5ajDCFM+OHk6M95kTjThuiKlA7QZBj63sB7U0zksii4 # 6B2Ab5EnDbgv8wR2Ghow0j4tNDsuxsFle6RU8V/DsPJsboT6Xjf0v1r9VQr4C0oE # lRJ2G16OVZN9kr0oIsee4UEF8AqXKMKLwlRrdBZzf2XJGXOSizGCBA0wggQJAgEB # MIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAByPmw7mft6mtG # AAEAAAHIMA0GCWCGSAFlAwQCAQUAoIIBSjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcN # AQkQAQQwLwYJKoZIhvcNAQkEMSIEIEFTV7pgTlSffsju+fSTwom3R5pJVjE0KHYh # AyjExOq5MIH6BgsqhkiG9w0BCRACLzGB6jCB5zCB5DCBvQQgYgCYz80/baMvxw6j # cqSvL0FW4TdvA09nxHfsPhuEA2YwgZgwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEG # A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt # cCBQQ0EgMjAxMAITMwAAAcj5sO5n7eprRgABAAAByDAiBCDuo9n7TvYKmENWu6vc # EorQ4emADypFqEaSCmEiVqs6qjANBgkqhkiG9w0BAQsFAASCAgB2YjusL5FyFpcW # 4joyVJqADA+iAagSHa345xBSpaKTx/gNyvvP1nydv3Yq7mZ6PTr6O26cp0RyDnQf # tW6A+lUcSGu5YZdsNVoGk56jksbpHjaL0cKbPy2su1v0CdLCvxXPAnA+BCkE6NTs # TShdTHlkGBrFJ2xwPmob/+hArKiIfcgrG3JNtH54rE0+H6nX/hvwadui4NaceuQB # c4fXayPA/KGHLRcg44uunJKR8WgX1PzOmZhsCV0GLPIwa69TZECkJsjPp0TQD+0f # hCjjpgncxXRz3eUhGE0p99JI5E2h13yn/qQbbpPv4JnymQqR9JWmHGwzYyAO1LUW # a1M+E3c1tdcKnki7uuC6Ko7SduYtSv4VL9cxTxRKyCD+0BhiP/4TPsjdQ5rXDPsm # PffbZjQiJoK4Floe/j+OJm4jlCrxI2llIIe+ZFu4F/MRpqCziuvuq2lRDZajVYhN # E3zODaIUnuSXCN9Gi6jfPCezCBzU8MJTBS+N9/QvEjUvF2MqSYRi38pa18C7dEZD # wPo+thuzWh/HcNuXA6TfuL1rnmIMN1qXBTZHRc2aDlgv43OaYJE6c4gmqQClJWfj # bh6FCIP0z9Vl8rcCzIZ8lybTs+aapdyAmBfleIKcxb7ti9TGLyAwH5j/bqeVVrSa # 6nG3BVBKeYEdjDXrp12FgiG0c8HcfA== # SIG # End signature block |