Framework/BugLog/BugMetaInfoProvider.ps1
Set-StrictMode -Version Latest class BugMetaInfoProvider { hidden [PSObject] $ControlSettingsBugLog hidden [string] $ServiceId hidden static [PSObject] $ServiceTreeInfo hidden [PSObject] $InvocationContext BugMetaInfoProvider() { } hidden [string] GetAssignee([SVTEventContext[]] $ControlResult, $controlSettingsBugLog, $isBugLogCustomFlow, $serviceIdPassedInCMD, $invocationContext) { $this.ControlSettingsBugLog = $controlSettingsBugLog; #flag to check if pluggable bug logging interface (service tree) if ($isBugLogCustomFlow) { $this.InvocationContext = $invocationContext; return $this.BugLogCustomFlow($ControlResult, $serviceIdPassedInCMD) } else { return $this.GetAssigneeFallback($ControlResult); } } hidden [string] BugLogCustomFlow($ControlResult, $serviceIdPassedInCMD) { $resourceType = $ControlResult.ResourceContext.ResourceTypeName $projectName = $ControlResult[0].ResourceContext.ResourceGroupName; $assignee = ""; try { #assign to the person running the scan, as to reach at this point of code, it is ensured the user is PCA/PA and only they or other PCA #PA members can fix the control if($ResourceType -eq 'Organization' -or $ResourceType -eq 'Project') { $assignee = [ContextHelper]::GetCurrentSessionUser(); } else { $rscId = ($ControlResult.ResourceContext.ResourceId -split "$resourceType/")[-1]; $assignee = $this.CalculateAssignee($rscId, $projectName, $resourceType, $serviceIdPassedInCMD); if (!$assignee) { $assignee = $this.GetAssigneeFallback($ControlResult) } } } catch { return ""; } return $assignee; } hidden [string] CalculateAssignee($rscId, $projectName, $resourceType, $serviceIdPassedInCMD) { $metaInfo = [MetaInfoProvider]::Instance; $assignee = ""; try { #If serviceid based scan then get servicetreeinfo details only once. #First condition if not serviceid based scan then go inside every time. #Second condition if serviceid based scan and [BugMetaInfoProvider]::ServiceTreeInfo not null then only go inside. if (!$serviceIdPassedInCMD -or ($serviceIdPassedInCMD -and ![BugMetaInfoProvider]::ServiceTreeInfo)) { [BugMetaInfoProvider]::ServiceTreeInfo = $metaInfo.FetchResourceMappingWithServiceData($rscId, $projectName, $resourceType); } if([BugMetaInfoProvider]::ServiceTreeInfo) { #Filter based on area path match project name and take first items (if duplicate service tree entry found). #Split areapath to match with projectname [BugMetaInfoProvider]::ServiceTreeInfo = ([BugMetaInfoProvider]::ServiceTreeInfo | Where {($_.areaPath).Split('\')[0] -eq $projectName})[0] $this.ServiceId = [BugMetaInfoProvider]::ServiceTreeInfo.serviceId; #Check if area path is not supplied in command parameter then only set from service tree. if (!$this.InvocationContext.BoundParameters["AreaPath"]) { [BugLogPathManager]::AreaPath = [BugMetaInfoProvider]::ServiceTreeInfo.areaPath.Replace("\", "\\"); } $domainNameForAssignee = "" if([Helpers]::CheckMember($this.ControlSettingsBugLog, "DomainName")) { $domainNameForAssignee = $this.ControlSettingsBugLog.DomainName; } $assignee = [BugMetaInfoProvider]::ServiceTreeInfo.devOwner.Split(";")[0] + "@"+ $domainNameForAssignee } } catch { Write-Host "Could not find service tree data file." -ForegroundColor Yellow } return $assignee; } hidden [string] GetAssigneeFallback([SVTEventContext[]] $ControlResult) { $ResourceType = $ControlResult.ResourceContext.ResourceTypeName $ResourceName = $ControlResult.ResourceContext.ResourceName $organizationName = $ControlResult.OrganizationContext.OrganizationName; switch -regex ($ResourceType) { #assign to the creator of service connection 'ServiceConnection' { return $ControlResult.ResourceContext.ResourceDetails.createdBy.uniqueName } #assign to the creator of agent pool 'AgentPool' { $apiurl = "https://dev.azure.com/{0}/_apis/distributedtask/pools?poolName={1}&api-version=6.0" -f $organizationName, $ResourceName try { $response = [WebRequestHelper]::InvokeGetWebRequest($apiurl) return $response.createdBy.uniqueName } catch { return ""; } } #assign to the creator of variable group 'VariableGroup' { return $ControlResult.ResourceContext.ResourceDetails.createdBy.uniqueName } #assign to the person who recently triggered the build pipeline, or if the pipeline is empty assign it to the creator 'Build' { $definitionId = $ControlResult.ResourceContext.ResourceDetails.id; try { $apiurl = "https://dev.azure.com/{0}/{1}/_apis/build/builds?definitions={2}&api-version=6.0" -f $organizationName, $ControlResult.ResourceContext.ResourceGroupName , $definitionId; $response = [WebRequestHelper]::InvokeGetWebRequest($apiurl) #check for recent trigger if ([Helpers]::CheckMember($response, "requestedBy")) { return $response[0].requestedBy.uniqueName } #if no triggers found assign to the creator else { $apiurl = "https://dev.azure.com/{0}/{1}/_apis/build/definitions/{2}?api-version=6.0" -f $organizationName, $ControlResult.ResourceContext.ResourceGroupName , $definitionId; $response = [WebRequestHelper]::InvokeGetWebRequest($apiurl) return $response.authoredBy.uniqueName } } catch { return ""; } } #assign to the person who recently triggered the release pipeline, or if the pipeline is empty assign it to the creator 'Release' { $definitionId = ($ControlResult.ResourceContext.ResourceId -split "release/")[-1]; try { $apiurl = "https://vsrm.dev.azure.com/{0}/{1}/_apis/release/releases?definitionId={2}&api-version=6.0" -f $organizationName, $ControlResult.ResourceContext.ResourceGroupName , $definitionId; $response = [WebRequestHelper]::InvokeGetWebRequest($apiurl) #check for recent trigger if ([Helpers]::CheckMember($response, "modifiedBy")) { return $response[0].modifiedBy.uniqueName } #if no triggers found assign to the creator else { $apiurl = "https://vsrm.dev.azure.com/{0}/{1}/_apis/release/definitions/{2}?&api-version=6.0" -f $organizationName, $ControlResult.ResourceContext.ResourceGroupName , $definitionId; $response = [WebRequestHelper]::InvokeGetWebRequest($apiurl) return $response.createdBy.uniqueName } } catch { return ""; } } 'Repository' { try { $url = 'https://dev.azure.com/{0}/{1}/_apis/git/repositories/{2}/commits?searchCriteria.showOldestCommitsFirst=true&searchCriteria.$top=1&api-version=6.0' -f $organizationName, $ControlResult.ResourceContext.ResourceGroupName, $ControlResult.ResourceContext.ResourceDetails.Id; $repoFirstCommit = @([WebRequestHelper]::InvokeGetWebRequest($url)); if ($repoFirstCommit.count -gt 0 -and [Helpers]::CheckMember($repoFirstCommit[0],"author")) { return $repoFirstCommit[0].author.email; } } catch { return ""; } } 'SecureFile' { return $ControlResult.ResourceContext.ResourceDetails.createdBy.uniqueName } 'Feed' { try { $url = 'https://{0}.feeds.visualstudio.com/{1}/_apis/Packaging/Feeds/{2}/Permissions?includeIds=true&excludeInheritedPermissions=true' -f $organizationName, $ControlResult.ResourceContext.ResourceGroupName, $ControlResult.ResourceContext.ResourceDetails.Id; $feedPermissionList = @([WebRequestHelper]::InvokeGetWebRequest($url)); if ($feedPermissionList.count -gt 0 -and [Helpers]::CheckMember($feedPermissionList[0],"identityDescriptor")) { $resourceOwnerWithDescriptor = $feedPermissionList[0].identityDescriptor.Split('\'); if ($resourceOwnerWithDescriptor.count -ge 1) { return $resourceOwnerWithDescriptor[1]; } } } catch { return ""; } } 'Environment' { return $ControlResult.ResourceContext.ResourceDetails.createdBy.uniqueName } #assign to the person running the scan, as to reach at this point of code, it is ensured the user is PCA/PA and only they or other PCA #PA members can fix the control 'Organization' { return [ContextHelper]::GetCurrentSessionUser(); } 'Project' { return [ContextHelper]::GetCurrentSessionUser(); } } return ""; } } # SIG # Begin signature block # MIIjiwYJKoZIhvcNAQcCoIIjfDCCI3gCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCA6piCgr5mcvy9u # ASYbWXIjmmEb7Q9OSBtC17i+jEr186CCDYUwggYDMIID66ADAgECAhMzAAAB4HFz # JMpcmPgZAAAAAAHgMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjAxMjE1MjEzMTQ2WhcNMjExMjAyMjEzMTQ2WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDRXpc9eiGRI/2BlmU7OMiQPTKpNlluodjT2rltPO/Gk47bH4gBShPMD4BX/4sg # NvvBun6ZOG2dxUW30myWoUJJ0iRbTAv2JFzjSpVQvPE+D5vtmdu6WlOR2ahF4leF # 5Vvk4lPg2ZFrqg5LNwT9gjwuYgmih+G2KwT8NMWusBhO649F4Ku6B6QgA+vZld5S # G2XWIdvS0pmpmn/HFrV4eYTsl9HYgjn/bPsAlfWolLlEXYTaCljK7q7bQHDBrzlR # ukyyryFpPOR9Wx1cxFJ6KBqg2jlJpzxjN3udNJPOqarnQIVgB8DUm3I5g2v5xTHK # Ovz9ucN21467cYcIxjPC4UkDAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUVBWIZHrG4UIX3uX4142l+8GsPXAw # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ2MzAxMDAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AE5msNzmYzYbNgpnhya6YsrM+CIC8CXDu10nwzZtkgQciPOOqAYmFcWJCwD5VZzs # qFwad8XIOrfCylWf4hzn09mD87yuazpuCstLSqfDLNd3740+254vEZqdGxOglAGU # ih2IiF8S0GDwucpLGzt/OLXPFr/d4MWxPuX0L+HB5lA3Y/CJE673dHGQW2DELdqt # ohtkhp+oWFn1hNDDZ3LP++HEZvA7sI/o/981Sh4kaGayOp6oEiQuGeCXyfrIC9KX # eew0UlYX/NHVDqr4ykKkqpHtzbUbuo7qovUHPbYKcRGWrrEtBS5SPLFPumqsRtzb # LgU9HqfRAN36bMsd2qynGyWBVFOM7NMs2lTCGM85Z/Fdzv/8tnYT36Cmbue+IM+6 # kS86j6Ztmx0VIFWbOvNsASPT6yrmYiecJiP6H0TrYXQK5B3jE8s53l+t61ab0Eul # 7DAxNWX3lAiUlzKs3qZYQEK1LFvgbdTXtBRnHgBdABALK3RPrieIYqPln9sAmg3/ # zJZi4C/c2cWGF6WwK/w1Nzw08pj7jaaZZVBpCeDe+y7oM26QIXxracot7zJ21/TL # 70biK36YybSUDkjhQPP/uxT0yebLNBKk7g8V98Wna2MsHWwk0sgqpkjIp02TrkVz # 26tcF2rml2THRSDrwpBa4x9c8rM8Qomiyeh2tEJnsx2LMIIHejCCBWKgAwIBAgIK # 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/Xmfwb1tbWrJUnMTDXpQzTGCFVwwghVYAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAHgcXMkylyY+BkAAAAA # AeAwDQYJYIZIAWUDBAIBBQCggbAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIASU # UuUpnyrqPTTyyEv2rErKTLnGjFbVoZsftJ+oxh73MEQGCisGAQQBgjcCAQwxNjA0 # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEcgBpodHRwczovL3d3dy5taWNyb3NvZnQu # Y29tIDANBgkqhkiG9w0BAQEFAASCAQAbVkMUqTQpBZZxi0i+HWZ6R9+FdamgB7n4 # 5YeS+cVv/DXGZMcm/n075LMkz9Cn10cMFYL6P2CEuWECnyiqmbi4zUOFSH9woUug # MGZxGRHw03QP4mKDHuiLn5eamKLYDroStRPUtQMZfxtl8lLAG5qH3ycXmFJdIbmL # /91OWo2nBohoXbCVLZXfEehfcOo7/BoL6s1mP778WBjhVCvvlczCOFOYw3WNd9Ha # kDSPrnGVY242iVwt+zhwg9CmHhGjVpHOU73q0wd9l7dNUBSP4GkQx+/jhDoyHlTg # 6LEOR6L9PmPL4B5nnBUtHRechnY8QbWEqQ1fgId3IbR2C7UMSIeeoYIS5DCCEuAG # CisGAQQBgjcDAwExghLQMIISzAYJKoZIhvcNAQcCoIISvTCCErkCAQMxDzANBglg # hkgBZQMEAgEFADCCAVAGCyqGSIb3DQEJEAEEoIIBPwSCATswggE3AgEBBgorBgEE # AYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEIEtSVqDlq+skFeVeiHj46z3+KkEAf+C1 # wixHuvxEmBipAgZg+Zx280EYEjIwMjEwODE2MDU1MzQzLjEzWjAEgAIB9KCB0KSB # zTCByjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UE # CxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVz # IFRTUyBFU046N0JGMS1FM0VBLUI4MDgxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1l # LVN0YW1wIFNlcnZpY2Wggg48MIIE8TCCA9mgAwIBAgITMwAAAVHDUOdZbKrGpwAA # AAABUTANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx # MDAeFw0yMDExMTIxODI2MDRaFw0yMjAyMTExODI2MDRaMIHKMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l # cmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjo3QkYxLUUz # RUEtQjgwODElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC # ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ/Sh++qhK477ziJI1mx6bTJ # GA45hviRJs4Lsq/1cY2YGf4oPDJOO46kiT+UcR/7A8qoWLu4z0jvOrImYfLuwwV/ # S/CPgAfvHzz7w+LqCyg9tgaaBZeAfBcOSu0rom728Rje2nS9f81vrFl5Vb6Q4RDy # CgyArxHTYxky4ZLX37Y3n4PZbpgTFASdhuP4OGndHQ70TZiojGV13vy5eEIP6D0s # 1wlBGKEkqmuQ/uTEYplXuf2Ey49I1a/IheOVdIU+1R/DiTuGCJnJ2Yaug8NRvsOg # AkRnjxZjlqlvLRGdd0jJjqria05MMsvM8jbVbbSQF+3YhS20dErzJWyWVitCh3cC # AwEAAaOCARswggEXMB0GA1UdDgQWBBTFd//jaFBikzRoOjjMhOnzdUTqbTAfBgNV # HSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVo # dHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1T # dGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAC # hj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBD # QV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUF # BwMIMA0GCSqGSIb3DQEBCwUAA4IBAQAr/fXAFYOZ8dEqo7y30M5roDI+XCfTROtH # bkh9S6cR2IpvS7N1H4mHe7dCb8hMP60UxCh2851eixS5V/vpRyTBis2Zx7U3tjiO # mRxZzYhYbYMlrmAya5uykMpDYtRtS27lYnvTHoZqCvoQYmZ563H2UpwUqJK7ztkB # FhwtcZ2ecDPNlBI6axWDpHIVPukXKAo45iBRn4EszY9TCG3+JXCeRaFdTIOhcBeO # Qoozlx1V685IrDGfabg6RY4xFekwGOiDYDJIS3r/wFaMNLBfDH0M7SSJRWHRRJGe # TRfyMs6AtmG/YsOGwinQa3Q9wLOpr6BkjYwgupTnc+hHqyStzYRYMIIGcTCCBFmg # AwIBAgIKYQmBKgAAAAAAAjANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3Qg # Q2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcNMjUw # NzAxMjE0NjU1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ # MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u # MSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIwDQYJ # KoZIhvcNAQEBBQADggEPADCCAQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0VBDV # pQoAgoX77XxoSyxfxcPlYcJ2tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEwRA/x # YIiEVEMM1024OAizQt2TrNZzMFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQedGFn # kV+BVLHPk0ySwcSmXdFhE24oxhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKxXf13 # Hz3wV3WsvYpCTUBR0Q+cBj5nf/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4GkbaI # CDXoeByw6ZnNPOcvRLqn9NxkvaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEAAaOC # AeYwggHiMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7fEYb # xTNoWoVtVTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYw # DwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoY # xDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtp # L2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYB # BQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v # cGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0gAQH/ # BIGVMIGSMIGPBgkrBgEEAYI3LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93d3cu # bWljcm9zb2Z0LmNvbS9QS0kvZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYBBQUH # AgIwNB4yIB0ATABlAGcAYQBsAF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUAbQBl # AG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOhIW+z # 66bM9TG+zwXiqf76V20ZMLPCxWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS+7lT # jMz0YBKKdsxAQEGb3FwX/1z5Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlKkVIA # rzgPF/UveYFl2am1a+THzvbKegBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon/VWv # L/625Y4zu2JfmttXQOnxzplmkIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOiPPp/ # fZZqkHimbdLhnPkd/DjYlPTGpQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/fmNZ # JQ96LjlXdqJxqgaKD4kWumGnEcua2A5HmoDF0M2n0O99g/DhO3EJ3110mCIIYdqw # UB5vvfHhAN/nMQekkzr3ZUd46PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0cs0d # 9LiFAR6A+xuJKlQ5slvayA1VmXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7aKLix # qduWsqdCosnPGUFN4Ib5KpqjEWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQcdeh # 0sVV42neV8HR3jDA/czmTfsNv11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+NR4I # uto229Nfj950iEkSoYICzjCCAjcCAQEwgfihgdCkgc0wgcoxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVy # aWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjdCRjEtRTNF # QS1CODA4MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMK # AQEwBwYFKw4DAhoDFQCgoq9z8T+kQgslTCUgFaDFetcjXqCBgzCBgKR+MHwxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv # c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBBQUAAgUA5MRm7DAi # GA8yMDIxMDgxNjEyMjQxMloYDzIwMjEwODE3MTIyNDEyWjB3MD0GCisGAQQBhFkK # BAExLzAtMAoCBQDkxGbsAgEAMAoCAQACAg2NAgH/MAcCAQACAhFGMAoCBQDkxbhs # AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSCh # CjAIAgEAAgMBhqAwDQYJKoZIhvcNAQEFBQADgYEAA5w8yLuZvelfbwZ1Yn4fGjsr # Dp6d02w0aYXRodKm0aSB5TJ77cXPJ/iER0YUmTGzxVREGsvhqcXIywZOljlVN32O # 83F7nfgJrfxN4uDpvBg7WOg888M6syg4eVCJI2X8GZRGSnI5OlSIgCAXRvLFm7EX # /CyQP5LtwGRi0KfZ16MxggMNMIIDCQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEG # A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj # cm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFt # cCBQQ0EgMjAxMAITMwAAAVHDUOdZbKrGpwAAAAABUTANBglghkgBZQMEAgEFAKCC # AUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCCF # A8EsR6OnZf+Oec4V6y3v+uOQ5+rWf6HDzaK4uPh16jCB+gYLKoZIhvcNAQkQAi8x # geowgecwgeQwgb0EIC7NXJmI+NbBWQcAphb7/UnD+bbrlIcbL/7dAfVxeuVBMIGY # MIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG # A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAFRw1DnWWyq # xqcAAAAAAVEwIgQgs4ynLVtonj1K7FfBIHF0QFH48IoRo97lvv7tiRuMCVcwDQYJ # KoZIhvcNAQELBQAEggEAWLwlEf+CC7b0I+eEMAwKyWIZ7gswE6onpZJZupoMhZt+ # svsaiWdg84qLsqar0dBgftylZ5DAIwr0J4u6nozrV/Ix9uBs5cWdC2aklU+F8tRo # lsrULMmwBBvSv81xZrTLHRbvJHPV0H+IaWVBEnJG252+bYq5BRSrd2IjMOTOOA4E # tWpbWcnvhL0JiufDPfSbp45wGaIduhNOMHcA7xQJ8/zgY1MBiTcdy14Fuj1h6Pox # ZpkNEKmY2bg9hos0RJS08nrO1l83lDKHhVGMc7QL9JAualGLEmK7RG/7cngx5m3x # r8FG105EXuzIDmmtha7BiHrqVesTVJQKVzRNbJ2LMA== # SIG # End signature block |