Public/Reportings/New-EntraOpsPrivilegedEamDashboardData.ps1
|
<# .SYNOPSIS Generate (refresh) the embedded dataset for the EntraOps EAM Dashboard static web app. .DESCRIPTION Transforms EntraOps Privileged EAM data into the EAM Dashboard (Enterprise Access Model Dashboard) dataset. The dashboard is the static-web counterpart of the "EntraOps Privileged EAM - Overview" Azure workbook and reuses the same visualizations, filters and drill-downs. Generates data/eam-dashboard-data.js exposing `window.ENTRAOPS_EAM_DATA` so the static web app works both when served over HTTP (for example Azure Static Web Apps) and when opened directly from the file system (no fetch / CORS required). Source data is the Privileged EAM export written by Save-EntraOpsPrivilegedEAMJson: PrivilegedEAM/<RbacSystem>/<RbacSystem>.json (only JSON files directly in the RBAC system folder are read, not the per-object subfolders user/, group/, serviceprincipal/, ...). Computed columns follow the PrivilegedEAM parsers (Parsers/PrivilegedEAM_WatchLists) and the Overview workbook: * EligibilityBy - "PIM for Entra ID Roles and Groups", "PIM for Entra ID Roles", "PIM for Azure Roles", "PIM for Groups" or "N/A" derived from RoleSystem, PIMAssignmentType and RoleAssignmentSubType. * RestrictedManagement - "Applied", "Conflict", "Not applied" or "Not available" derived from ObjectType, ObjectSubType and the RestrictedManagementByAadRole/RAG/RMAU flags (same case logic as the workbook grid). * SyncSource - "Cloud-Only" / "Hybrid" from OnPremSynchronized. * PrivilegedType - "Tenant Governance" (foreign object whose role assignments all originate from a Tenant Governance delegation), "Multi-Tenant Apps" (service principal from another tenant), "B2B Collaboration" (external user from another tenant with at least one non-Tenant-Governance role assignment) or "Local Identities" (everything else) derived from ObjectTenantId, ObjectType and RoleAssignmentSubType. * scopeReasoning - why an Azure, Entra ID, or Identity Governance assignment scope was classified, sourced from the matching ScopeReasoning_<RbacSystem>.json artifact written by Update-EntraOpsClassificationControlPlaneScope. * controlPlaneReasoning - why an object entered the Control Plane input set, sourced from Classification/<TenantName>/ScopeReasoning_ControlPlane.json. This function requires the module to be imported from a repository checkout that contains the Reports/EamDashboard folder. .PARAMETER RepoRoot Path to the EntraOps repository root that contains the PrivilegedEAM export folder. Defaults to the repository this module lives in. .PARAMETER ImportPath Folder with the Privileged EAM export. Defaults to <RepoRoot>/PrivilegedEAM. .PARAMETER AppRoot Path to the EamDashboard app folder (where the generated content is written). Defaults to Reports/EamDashboard in the EntraOps repository. .PARAMETER OutFile Output file. Defaults to <AppRoot>/data/eam-dashboard-data.js. .PARAMETER TenantId Home tenant id used to detect foreign objects for the PrivilegedType column (Multi-Tenant Apps, B2B Collaboration, Tenant Governance). Defaults to the most common ObjectTenantId in the export among objects that are neither guest users nor Tenant Governance delegated admins. .PARAMETER ResolveLinkedIdentityObjectIds Resolve linked-identity object IDs outside the Privileged EAM export to display names with batched Microsoft Graph getByIds requests. Defaults to the EamDashboard.ResolveLinkedIdentityObjectIds config setting, or $true. .PARAMETER PassThru Emit the generated payload object to the pipeline. .EXAMPLE New-EntraOpsPrivilegedEamDashboardData Regenerates the EAM Dashboard dataset from the PrivilegedEAM folder of this repository. .EXAMPLE New-EntraOpsPrivilegedEamDashboardData -ImportPath "C:\Exports\PrivilegedEAM" -Verbose -WhatIf Shows what would be generated from an explicit Privileged EAM export without changing any files. #> function New-EntraOpsPrivilegedEamDashboardData { [CmdletBinding(SupportsShouldProcess = $true)] param ( [Parameter(Mandatory = $false)] [System.String]$RepoRoot, [Parameter(Mandatory = $false)] [System.String]$ImportPath, [Parameter(Mandatory = $false)] [System.String]$AppRoot, [Parameter(Mandatory = $false)] [System.String]$OutFile, [Parameter(Mandatory = $false)] [System.String]$TenantId, [Parameter(Mandatory = $false)] [System.Boolean]$ResolveLinkedIdentityObjectIds = $true, [Parameter(Mandatory = $false)] [switch]$PassThru ) # Resolve the app/repository location relative to the module location: # <repo>/EntraOps/Public/<subfolder> -> <repo>/Reports/EamDashboard # Prefer the module's own ModuleBase (always populated for exported module # functions) over $PSScriptRoot, which can be empty depending on how the # function was invoked/loaded. $ModuleRoot = $MyInvocation.MyCommand.Module.ModuleBase if ([string]::IsNullOrWhiteSpace($ModuleRoot) -and -not [string]::IsNullOrWhiteSpace($PSScriptRoot)) { $ModuleRoot = Split-Path -Parent (Split-Path -Parent $PSScriptRoot) } if ([string]::IsNullOrWhiteSpace($ModuleRoot)) { throw "Unable to resolve the EntraOps module location. Import the module with 'Import-Module <path-to-EntraOps> -Force' and try again." } $RepositoryRoot = Split-Path -Parent $ModuleRoot if ([string]::IsNullOrWhiteSpace($RepoRoot)) { $RepoRoot = $RepositoryRoot } if ([string]::IsNullOrWhiteSpace($AppRoot)) { $AppRoot = Join-Path $RepositoryRoot 'Reports/EamDashboard' } if (-not (Test-Path -LiteralPath $AppRoot -PathType Container)) { throw "EAM Dashboard app folder not found: $AppRoot. Import the EntraOps module from a repository checkout that contains Reports/EamDashboard." } if ([string]::IsNullOrWhiteSpace($ImportPath)) { $ImportPath = Join-Path $RepoRoot 'PrivilegedEAM' } if ([string]::IsNullOrWhiteSpace($OutFile)) { $OutFile = Join-Path $AppRoot 'data/eam-dashboard-data.js' } if (-not (Test-Path -LiteralPath $ImportPath)) { throw "Privileged EAM import path not found: $ImportPath. Run Save-EntraOpsPrivilegedEAMJson first or pass -ImportPath." } if (-not $PSBoundParameters.ContainsKey('ResolveLinkedIdentityObjectIds')) { $EamDashboardConfigFilePath = Join-Path $RepoRoot 'EntraOpsConfig.json' if (Test-Path -LiteralPath $EamDashboardConfigFilePath -PathType Leaf) { try { $EamDashboardConfig = Get-Content -LiteralPath $EamDashboardConfigFilePath -Raw | ConvertFrom-Json if ($null -ne $EamDashboardConfig.EamDashboard -and $null -ne $EamDashboardConfig.EamDashboard.ResolveLinkedIdentityObjectIds) { $ResolveLinkedIdentityObjectIds = [bool]$EamDashboardConfig.EamDashboard.ResolveLinkedIdentityObjectIds } } catch { Write-Warning "Failed to read EamDashboard settings from ${EamDashboardConfigFilePath}: $($_.Exception.Message). Defaulting -ResolveLinkedIdentityObjectIds to `$true." } } } $previousPayload = $null if (Test-Path -LiteralPath $OutFile -PathType Leaf) { try { $previousText = Get-Content -LiteralPath $OutFile -Raw -Encoding UTF8 $previousJson = $previousText -replace '(?s)^.*?window\.ENTRAOPS_EAM_DATA\s*=\s*', '' -replace ';\s*$', '' $previousPayload = $previousJson | ConvertFrom-Json -Depth 15 -ErrorAction Stop } catch { Write-Warning "Existing EAM Dashboard dataset could not be used as a notification baseline; change notifications will not be generated for this run: $($_.Exception.Message)" } } $sourceFilesRef = [ref]@() $scopeReasoningDetails = Import-EntraOpsDashboardScopeReasoning -RepoRoot $RepoRoot $controlPlaneReasoningDetails = Import-EntraOpsControlPlaneReasoning -RepoRoot $RepoRoot $objects = Get-EntraOpsPrivilegedEamDashboardObjects -ImportPath $ImportPath -TenantId $TenantId -ScopeReasoningDetails $scopeReasoningDetails -ControlPlaneReasoningDetails $controlPlaneReasoningDetails -SourceFiles $sourceFilesRef $files = $sourceFilesRef.Value $roleDefinitions = [System.Collections.Generic.List[object]]::new() # The classified directory roles file lives in the AzurePrivilegedIAM repository, so it is # not found under the default -RepoRoot (the EntraOps repository). Probe the explicit # -RepoRoot first, then the temporary sparse AzurePrivilegedIAM checkout used by the # Push-EntraOpsPrivilegedReporting workflow (.reporting/AzurePrivilegedIAM). $directoryRoleClassificationCandidates = @( (Join-Path $RepoRoot 'Classification/Classification_EntraIdDirectoryRoles.json'), (Join-Path (Join-Path $RepoRoot '.reporting/AzurePrivilegedIAM') 'Classification/Classification_EntraIdDirectoryRoles.json') ) $directoryRoleClassificationPath = @($directoryRoleClassificationCandidates | Where-Object { Test-Path -LiteralPath $_ -PathType Leaf } | Select-Object -First 1)[0] if ($directoryRoleClassificationPath) { try { foreach ($role in @([System.IO.File]::ReadAllText($directoryRoleClassificationPath) | ConvertFrom-Json)) { try { $classifications = @($role.Classification | Where-Object { $_ -and $_.EAMTierLevelName } | Sort-Object { Get-EntraOpsTierSortOrder -TierValue $_.EAMTierLevelTagValue }) $effective = $classifications | Select-Object -First 1 if (-not $role.RoleId -or -not $effective) { continue } $roleDefinitions.Add([ordered]@{ roleDefinitionId = "$($role.RoleId)" displayName = "$($role.RoleName)" tierName = "$($effective.EAMTierLevelName)" service = "$($effective.Category)" classifications = @($classifications | ForEach-Object { [ordered]@{ tierName = "$($_.EAMTierLevelName)"; service = "$($_.Category)" } }) }) | Out-Null } catch { Write-Warning "Skipping directory role classification '$($role.RoleId)' ($($role.RoleName)): $($_.Exception.Message)" } } } catch { Write-Warning "Could not import directory role classifications from ${directoryRoleClassificationPath}: $($_.Exception.Message)" } } else { Write-Warning "Directory role classification file not found; PIM role tiers will use classified assignment evidence only. Paths tried: $($directoryRoleClassificationCandidates -join ', ')" } $linkedIdentityDisplayNames = @{} foreach ($object in @($objects)) { if ($object.objectId -and $object.objectDisplayName) { $linkedIdentityDisplayNames[$object.objectId] = $object.objectDisplayName } } if ($ResolveLinkedIdentityObjectIds) { $GuidPattern = '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$' $linkedIds = @($objects | ForEach-Object { @($_.associatedWorkAccount) } | Where-Object { $_ -and $_ -match $GuidPattern } | Sort-Object -Unique) $idsToResolve = @($linkedIds | Where-Object { -not $linkedIdentityDisplayNames.ContainsKey($_) }) if ($idsToResolve.Count -gt 0) { Write-Verbose "Resolving $($idsToResolve.Count) linked identity object id(s) outside the Privileged EAM export via Microsoft Graph..." $GraphBatchSize = 999 # directoryObjects/getByIds accepts up to 1000 IDs per request. for ($index = 0; $index -lt $idsToResolve.Count; $index += $GraphBatchSize) { $idBatch = @($idsToResolve[$index..([Math]::Min($index + $GraphBatchSize - 1, $idsToResolve.Count - 1))]) $body = @{ ids = $idBatch; types = @('user', 'group', 'servicePrincipal') } | ConvertTo-Json try { foreach ($resolvedObject in @(Invoke-EntraOpsMsGraphQuery -Method POST -Uri '/v1.0/directoryObjects/getByIds' -Body $body -OutputType PSObject)) { if ($resolvedObject.id -and $resolvedObject.displayName) { $linkedIdentityDisplayNames["$($resolvedObject.id)"] = "$($resolvedObject.displayName)" } } } catch { Write-Warning "Failed to resolve $($idBatch.Count) linked identity object id(s) via Microsoft Graph: $($_.Exception.Message)" } } } } if (-not $files) { Write-Warning "No Privileged EAM JSON files found under $ImportPath (expected <RbacSystem>/<RbacSystem>.json). Generating an empty dataset." } $repoRootFull = (Resolve-Path -LiteralPath $RepoRoot).Path $tenantName = Get-EntraOpsReportingTenantName -RepoRoot $RepoRoot $generatedAt = (Get-Date).ToUniversalTime().ToString('o') $notifications = [System.Collections.Generic.List[object]]::new() if ($null -ne $previousPayload -and $null -ne $previousPayload.objects) { $previousObjects = @{} $currentObjects = @{} $previousAssignments = @{} $currentAssignments = @{} function Get-AssignmentKey { param($Assignment) if ($Assignment.roleAssignmentInstanceId) { return "$($Assignment.roleAssignmentInstanceId)" } return "$($Assignment.roleAssignmentId)" } foreach ($object in @($previousPayload.objects)) { if ($object.objectId -and -not $previousObjects.ContainsKey($object.objectId)) { $previousObjects[$object.objectId] = $object } foreach ($assignment in @($object.roleAssignments)) { $assignmentKey = Get-AssignmentKey $assignment if ($assignmentKey -and -not $previousAssignments.ContainsKey($assignmentKey)) { $previousAssignments[$assignmentKey] = $assignment } } } foreach ($object in @($objects)) { if ($object.objectId -and -not $currentObjects.ContainsKey($object.objectId)) { $currentObjects[$object.objectId] = $object } foreach ($assignment in @($object.roleAssignments)) { $assignmentKey = Get-AssignmentKey $assignment if ($assignmentKey -and -not $currentAssignments.ContainsKey($assignmentKey)) { $currentAssignments[$assignmentKey] = $assignment } } } foreach ($objectId in @($currentObjects.Keys | Sort-Object)) { $current = $currentObjects[$objectId] if (-not $previousObjects.ContainsKey($objectId)) { $notifications.Add([ordered]@{ id = "asset-added:$objectId"; kind = 'Asset'; change = 'Added'; severity = 'info' title = "Privileged asset added: $($current.objectDisplayName)" detail = "$($current.objectType) is now classified as $($current.objectAdminTierLevelName)." href = "#asset=$([uri]::EscapeDataString($objectId))" }) | Out-Null } elseif ($previousObjects[$objectId].objectAdminTierLevelName -ne $current.objectAdminTierLevelName) { $notifications.Add([ordered]@{ id = "asset-tier:$objectId"; kind = 'Asset'; change = 'Changed'; severity = 'warning' title = "Asset access level changed: $($current.objectDisplayName)" detail = "$($previousObjects[$objectId].objectAdminTierLevelName) -> $($current.objectAdminTierLevelName)" href = "#asset=$([uri]::EscapeDataString($objectId))" }) | Out-Null } } foreach ($objectId in @($previousObjects.Keys | Where-Object { -not $currentObjects.ContainsKey($_) } | Sort-Object)) { $previous = $previousObjects[$objectId] $notifications.Add([ordered]@{ id = "asset-removed:$objectId"; kind = 'Asset'; change = 'Removed'; severity = 'info' title = "Privileged asset removed: $($previous.objectDisplayName)" detail = 'Open Privilege History to inspect the previous classified resource.' href = '../PrivilegeHistory/index.html' }) | Out-Null } foreach ($assignmentId in @($currentAssignments.Keys | Where-Object { -not $previousAssignments.ContainsKey($_) } | Sort-Object)) { $assignment = $currentAssignments[$assignmentId] $notifications.Add([ordered]@{ id = "assignment-added:$assignmentId"; kind = 'Role assignment'; change = 'Added'; severity = 'info' title = "Role assignment added: $($assignment.roleDefinitionName)" detail = "Scope: $($assignment.roleAssignmentScopeName)" href = "#assignment=$([uri]::EscapeDataString($assignmentId))" }) | Out-Null } foreach ($assignmentId in @($previousAssignments.Keys | Where-Object { -not $currentAssignments.ContainsKey($_) } | Sort-Object)) { $assignment = $previousAssignments[$assignmentId] $notifications.Add([ordered]@{ id = "assignment-removed:$assignmentId"; kind = 'Role assignment'; change = 'Removed'; severity = 'info' title = "Role assignment removed: $($assignment.roleDefinitionName)" detail = 'Open Privilege History to inspect the previous assignment.' href = '../PrivilegeHistory/index.html' }) | Out-Null } } # Serialize the linked identity display names with sorted keys so repeated runs produce a # stable dataset (plain hashtable enumeration order is nondeterministic). $sortedLinkedIdentityDisplayNames = [ordered]@{} foreach ($linkedIdentityId in @($linkedIdentityDisplayNames.Keys | Sort-Object)) { $sortedLinkedIdentityDisplayNames[$linkedIdentityId] = $linkedIdentityDisplayNames[$linkedIdentityId] } $payload = [ordered]@{ tenantName = $tenantName generatedAt = $generatedAt changeSetId = $generatedAt notifications = @($notifications) generatedFrom = @(@($files) | ForEach-Object { if ($_.FullName.StartsWith($repoRootFull)) { $_.FullName.Substring($repoRootFull.Length).TrimStart('\', '/') -replace '\\', '/' } else { $_.Name } }) objects = $objects roleDefinitions = @($roleDefinitions) linkedIdentityDisplayNames = $sortedLinkedIdentityDisplayNames } $json = $payload | ConvertTo-Json -Depth 12 -Compress $content = "// Auto-generated by New-EntraOpsPrivilegedEamDashboardData - do not edit by hand.`n" + "window.ENTRAOPS_EAM_DATA = $json;`n" if ($PSCmdlet.ShouldProcess($OutFile, 'Write EAM Dashboard dataset')) { Save-EntraOpsReportDataFile -Content $content -LiteralPath $OutFile $nAssignments = 0 foreach ($obj in $objects) { $nAssignments += @($obj.roleAssignments).Count } Write-Host "Privileged objects: $($objects.Count)" Write-Host "Role assignments: $nAssignments" Write-Host "Role definitions: $($roleDefinitions.Count)" Write-Host "Wrote $OutFile" } if ($PassThru) { $payload } } # SIG # Begin signature block # MIIniAYJKoZIhvcNAQcCoIIneTCCJ3UCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC9AZHHCjuxdLo6 # zEHH5028DOGFhcaKR6ocCu71tvkoQaCCIDwwggXJMIIEsaADAgECAhAbtY8lKt8j # AEkoya49fu0nMA0GCSqGSIb3DQEBDAUAMH4xCzAJBgNVBAYTAlBMMSIwIAYDVQQK # ExlVbml6ZXRvIFRlY2hub2xvZ2llcyBTLkEuMScwJQYDVQQLEx5DZXJ0dW0gQ2Vy # dGlmaWNhdGlvbiBBdXRob3JpdHkxIjAgBgNVBAMTGUNlcnR1bSBUcnVzdGVkIE5l # dHdvcmsgQ0EwHhcNMjEwNTMxMDY0MzA2WhcNMjkwOTE3MDY0MzA2WjCBgDELMAkG # A1UEBhMCUEwxIjAgBgNVBAoTGVVuaXpldG8gVGVjaG5vbG9naWVzIFMuQS4xJzAl # BgNVBAsTHkNlcnR1bSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEkMCIGA1UEAxMb # Q2VydHVtIFRydXN0ZWQgTmV0d29yayBDQSAyMIICIjANBgkqhkiG9w0BAQEFAAOC # Ag8AMIICCgKCAgEAvfl4+ObVgAxknYYblmRnPyI6HnUBfe/7XGeMycxca6mR5rlC # 5SBLm9qbe7mZXdmbgEvXhEArJ9PoujC7Pgkap0mV7ytAJMKXx6fumyXvqAoAl4Va # qp3cKcniNQfrcE1K1sGzVrihQTib0fsxf4/gX+GxPw+OFklg1waNGPmqJhCrKtPQ # 0WeNG0a+RzDVLnLRxWPa52N5RH5LYySJhi40PylMUosqp8DikSiJucBb+R3Z5yet # /5oCl8HGUJKbAiy9qbk0WQq/hEr/3/6zn+vZnuCYI+yma3cWKtvMrTscpIfcRnNe # GWJoRVfkkIJCu0LW8GHgwaM9ZqNd9BjuiMmNF0UpmTJ1AjHuKSbIawLmtWJFfzcV # WiNoidQ+3k4nsPBADLxNF8tNorMe0AZa3faTz1d1mfX6hhpneLO/lv403L3nUlbl # s+V1e9dBkQXcXWnjlQ1DufyDljmVe2yAWk8TcsbXfSl6RLpSpCrVQUYJIP4ioLZb # MI28iQzV13D4h1L92u+sUS4Hs07+0AnacO+Y+lbmbdu1V0vc5SwlFcieLnhO+Nqc # noYsylfzGuXIkosagpZ6w7xQEmnYDlpGizrrJvojybawgb5CAKT41v4wLsfSRvbl # jnX98sy50IdbzAYQYLuDNbdeZ95H7JlI8aShFf6tjGKOOVVPORa5sWOd/7cCAwEA # AaOCAT4wggE6MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFLahVDkCw6A/joq8 # +tT4HKbROg79MB8GA1UdIwQYMBaAFAh2zcsH/yT2xc3tu5C84oQ3RnX3MA4GA1Ud # DwEB/wQEAwIBBjAvBgNVHR8EKDAmMCSgIqAghh5odHRwOi8vY3JsLmNlcnR1bS5w # bC9jdG5jYS5jcmwwawYIKwYBBQUHAQEEXzBdMCgGCCsGAQUFBzABhhxodHRwOi8v # c3ViY2Eub2NzcC1jZXJ0dW0uY29tMDEGCCsGAQUFBzAChiVodHRwOi8vcmVwb3Np # dG9yeS5jZXJ0dW0ucGwvY3RuY2EuY2VyMDkGA1UdIAQyMDAwLgYEVR0gADAmMCQG # CCsGAQUFBwIBFhhodHRwOi8vd3d3LmNlcnR1bS5wbC9DUFMwDQYJKoZIhvcNAQEM # BQADggEBAFHCoVgWIhCL/IYx1MIy01z4S6Ivaj5N+KsIHu3V6PrnCA3st8YeDrJ1 # BXqxC/rXdGoABh+kzqrya33YEcARCNQOTWHFOqj6seHjmOriY/1B9ZN9DbxdkjuR # mmW60F9MvkyNaAMQFtXx0ASKhTP5N+dbLiZpQjy6zbzUeulNndrnQ/tjUoCFBMQl # lVXwfqefAcVbKPjgzoZwpic7Ofs4LphTZSJ1Ldf23SIikZbr3WjtP6MZl9M7JYjs # NhI9qX7OAo0FmpKnJ25FspxihjcNpDOO16hO0EoXQ0zF8ads0h5YbBRRfopUofbv # n3l6XYGaFpAP4bvxSgD5+d2+7arszgowggZrMIIEU6ADAgECAhBX5gfP8LabvnxC # XoItEBa/MA0GCSqGSIb3DQEBCwUAMFYxCzAJBgNVBAYTAlBMMSEwHwYDVQQKExhB # c3NlY28gRGF0YSBTeXN0ZW1zIFMuQS4xJDAiBgNVBAMTG0NlcnR1bSBDb2RlIFNp # Z25pbmcgMjAyMSBDQTAeFw0yNjEwMDYwODI4MjNaFw0yNzEwMDYwODI4MjJaMIGQ # MQswCQYDVQQGEwJERTEdMBsGA1UECAwUUmhpbmVsYW5kLVBhbGF0aW5hdGUxEjAQ # BgNVBAcMCUxhaG5zdGVpbjEeMBwGA1UECgwVT3BlbiBTb3VyY2UgRGV2ZWxvcGVy # MS4wLAYDVQQDDCVPcGVuIFNvdXJjZSBEZXZlbG9wZXIgVGhvbWFzIE5hdW5oZWlt # MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAphp2ljSmVsRB6gvkEq7A # DUMENpKZiDFoAfF1ktD1nCwaVyI+bJ0ROjHwAn4iJgS+vlBDPOUIw2GLHkiqUhOg # HSwzg6gj45GNmt6zxsKP0zPlhMB/fb0zmz7/F7e3yfKCXLfhbHuk0Es9gJ+8Wmet # 9StVwwSE/K0MpW06GKA9nPWyE4N/ADwigDIj9rsTKJR4cve9w8G1b3zohpUc/qMr # onab+HVw5r9b3sOBnnaXC6zvrX4fovRz1ztwfWjRjILLoFG6mW/TuK5F2ICD3Rhl # 9R2rJWWWhzTDMsQlzvX+/SaM74q3OFpIVNdhvtmWU9pKUBRAyYMijcDqKEFGSzrc # 8JFmGMpP5TuroWF+N21d3px2eARvW1mV0DCfFAH+Og20SH/gVW6/ltQQEkH/z/Zt # 49ARyJrgESLOQtlMCIYSoKISdkk4ml4VUS1E/PcbzXEYj3a7m6DOxcd3WuY03UT9 # cnk3p0LMN6LeLYAZgVY+HRloZlH+kW2SkOHNuWgtXvZhAgMBAAGjggF4MIIBdDAM # BgNVHRMBAf8EAjAAMD0GA1UdHwQ2MDQwMqAwoC6GLGh0dHA6Ly9jY3NjYTIwMjEu # Y3JsLmNlcnR1bS5wbC9jY3NjYTIwMjEuY3JsMHMGCCsGAQUFBwEBBGcwZTAsBggr # BgEFBQcwAYYgaHR0cDovL2Njc2NhMjAyMS5vY3NwLWNlcnR1bS5jb20wNQYIKwYB # BQUHMAKGKWh0dHA6Ly9yZXBvc2l0b3J5LmNlcnR1bS5wbC9jY3NjYTIwMjEuY2Vy # MB8GA1UdIwQYMBaAFN10XUwA23ufoHTKsW73PMAywHDNMB0GA1UdDgQWBBTBvGyH # MXj1dMbVnxuof9oP4PY7cDBLBgNVHSAERDBCMAgGBmeBDAEEATA2BgsqhGgBhvZ3 # AgUBBDAnMCUGCCsGAQUFBwIBFhlodHRwczovL3d3dy5jZXJ0dW0ucGwvQ1BTMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsF # AAOCAgEAkC165c7/r6y3VeEEpNXas9bQs6ZpKPdJffHkf9xoPi4kWvAIWGc4ocG1 # DJLb18RXiDYShDmT5sb/6I08FeipKi2DNJkuOq6yOTJ3S7+hNFIZCyd6i7WKO8ea # P5I+FAbyJP4+5coZoMg45bUa9JoocaJCm+5n7WiCfN7/EQpClW5Trm4+ZMbp7EMN # F1uLJgGCMnN0SsoUarp7PHlqupMxMC4Uhhe+lAP2ytcSIU81L97/qjrADbLWqICk # 9il5iGM+aZndguq/cmfH9rJj4GRZHWnG6WwnzYD9+KgYlRI6em+/9dq+IRiXe2Bs # thUuIaFW7U2gWw8tBTEYm1UBLHdJx+L1gjJCLs5KT/wy5wU32wZxNDqPUQejUC1x # GvU3cKqmLgRq+yNf3gFVfzqIoggyM3U9wQvnk7nBtCkpjXS2hdx4yxzcmrlWsDHr # z6+6/jeyQySzbYUlFmKnc4n9Mw2soHOajEua5poFARVRS5KgUBuiiQ21YFNYzWBo # qGuECaaAI/C5rGxapMJ3dAOBnHw6NLqBet+ZXBJEccX5y89MLlOQu+jDmJP8HieR # qDLlwfhVZnw4RY8Rus43NZBwhNlVuOUXqocHKmJhKNlekda3qsJj93eQBQOxKJcc # w5O08q9jukpH2+yzFAj+7ll33DuNUgWptogc4Awtbx3glzcEvJQwggaCMIIEaqAD # AgECAhAo8HfBHDa9/l90MkdwJy4DMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYT # AlBMMSEwHwYDVQQKExhBc3NlY28gRGF0YSBTeXN0ZW1zIFMuQS4xJDAiBgNVBAMT # G0NlcnR1bSBUaW1lc3RhbXBpbmcgMjAyMSBDQTAeFw0yNjAzMTEwNzM0NTRaFw0z # NjAyMjcwNzM0NTRaMFAxCzAJBgNVBAYTAlBMMSEwHwYDVQQKDBhBc3NlY28gRGF0 # YSBTeXN0ZW1zIFMuQS4xHjAcBgNVBAMMFUNlcnR1bSBUaW1lc3RhbXAgMjAyNjCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALi9zfBw+xI12hi2F9uNQBNO # STkTIi13fuh3DiWybI5392bBfJw6tO7zDs7UqP/rejVf4xFTU3XNOPsuOFkP5SPF # snWwn3VJL+NhNhsuujvYsQtaQnvNo1wk46reTgws1L8OFEdKaxgyqT4zOQx81mLw # NZSqXNU9Rrb9oAJWJF4Mydz+C1ebu0D0+vgM3tqAQ8TU203fqgKCPqIdHloaFqH9 # eyR+8tnpmy2hnnN59ZOtmsuHeRwf5iTOhlhf0d/qqquLOSIGPgGVL1Hj5XBUox2O # E7tQRr+l/xxNbL6OuwBO4Aa2EbuxYg37cpXv5i2/lTL4NASB/duf9W4fjA3Ro+GP # +bC54n2OYiM3Cq8z92ejx8F5HWO2e4/75eC95B9tMw/eq7109GDyW2+2ut5Bn0o8 # MXJTERkyystWbqcnUkomA97qfiDCwvpWuOMdfTOksXe9S+xDxOJaCbiyTivgPulx # cT+tfQTRXBr5UwtPvc+INnafOEilzVHA11tv+pHcylryxBc08cUihf/ttqkZS0bm # x3VxQay8uohaTp0//ECA9vYGW51SKdJMJhXvKyIdBLy8WYNchTt8yRITv9Adxg9J # qGujh+TnP1bW3aQjFtlEl7SzgNeI8OVA/CJAWWUuRT3Au9ToOpHy/flrrknhN4he # Ew7/6ILMv4HSsj0YZ4otAgMBAAGjggFQMIIBTDB1BggrBgEFBQcBAQRpMGcwOwYI # KwYBBQUHMAKGL2h0dHA6Ly9zdWJjYS5yZXBvc2l0b3J5LmNlcnR1bS5wbC9jdHNj # YTIwMjEuY2VyMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0dW0u # Y29tMB8GA1UdIwQYMBaAFL5UAi+/QGxzQ86sCSVOnkNEGu7gMAwGA1UdEwEB/wQC # MAAwOQYDVR0fBDIwMDAuoCygKoYoaHR0cDovL3N1YmNhLmNybC5jZXJ0dW0ucGwv # Y3RzY2EyMDIxLmNybDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8E # BAMCB4AwIgYDVR0gBBswGTAIBgZngQwBBAIwDQYLKoRoAYb2dwIFAQswHQYDVR0O # BBYEFCM5aiirmhKnpKfyH/lFmr+N/oIDMA0GCSqGSIb3DQEBDAUAA4ICAQBm/pOb # rAveTqYFPCSthxNVwBHTW4TfuBQY2KGCdMlH6ALjVPYf2XARNGMTXScR0JQ2/c2L # xLpoHHhRwxFf3d933DhFS165rYj6iPSQKm41rc9AMpTCjMdmai1aK9o870pOzTzL # RhWFVIxm+5Qf+t4V5z14tPoUsAWdfRKD1Zzvzfe5AHlE9rxOZcGROiULxs3Edf7Z # J8RZI0jzD9juj2oEX2XS7BVKuNCK1W0h1mjapv028yqo8UtZh5/1Ib48Yyp88BDY # Shh5PSGUUuS5tYXVfcduIPBe3PdNTYRYdT5VNxkwLgjMzIcr/6SH2fejFJDjnCxj # vXLuarErJg/IdI+hXdGIBDVOGv1zrkF4ktoQvFZIp5DIAYh0GwyUhc87qqn5UaYT # j2+iyiBDSNh7aGCrkuAnqg7Qh7frhX+QhMGeJ9SpLpnG76qN85hLyjvYR6gRYiLT # j8G4fxjqV400/buPw0rBo9yJZyq/8cGdCOLPOYf9qpefTcrZKeO9pg+UJHx8UABb # aTqizRxm8sUSEycccCCFhIit3AI/3wGuSOADeiA676NcQ7+dsP04YvzvdN7pTZNy # g672WpBDJdg0eItHl4yomvNeIOWh1qs4QqOW6TI8Ocsi4uSDTLorxLUDnBTwKQzz # pxd1YUctEgRh32R0J9FkFkeEruJU94RljFr1uDCCBrkwggShoAMCAQICEQCZo4AK # JlU7ZavcboSms+o5MA0GCSqGSIb3DQEBDAUAMIGAMQswCQYDVQQGEwJQTDEiMCAG # A1UEChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVt # IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3Rl # ZCBOZXR3b3JrIENBIDIwHhcNMjEwNTE5MDUzMjE4WhcNMzYwNTE4MDUzMjE4WjBW # MQswCQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEu # MSQwIgYDVQQDExtDZXJ0dW0gQ29kZSBTaWduaW5nIDIwMjEgQ0EwggIiMA0GCSqG # SIb3DQEBAQUAA4ICDwAwggIKAoICAQCdI88EMCM7wUYs5zNzPmNdenW6vlxNur3r # Lfi+5OZ+U3iZIB+AspO+CC/bj+taJUbMbFP1gQBJUzDUCPx7BNLgid1TyztVLn52 # NKgxxu8gpyTr6EjWyGzKU/gnIu+bHAse1LCitX3CaOE13rbuHbtrxF2tPU8f253Q # gX6eO8yTbGps1Mg+yda3DcTsOYOhSYNCJiL+5wnjZ9weoGRtvFgMHtJg6i671OPX # IciiHO4Lwo2p9xh/tnj+JmCQEn5QU0NxzrOiRna4kjFaA9ZcwSaG7WAxeC/xoZSx # F1oK1UPZtKVt+yrsGKqWONoK6f5EmBOAVEK2y4ATDSkb34UD7JA32f+Rm0wsr5aj # zftDhA5mBipVZDjHpwzv8bTKzCDUSUuUmPo1govD0RwFcTtMXcfJtm1i+P2UNXad # PyYVKRxKQATHN3imsfBiNRdN5kiVVeqP55piqgxOkyt+HkwIA4gbmSc3hD8ke66t # 9MjlcNg73rZZlrLHsAIV/nJ0mmgSjBI/TthoGJDydekOQ2tQD2Dup/+sKQptalDl # ui59SerVSJg8gAeV7N/ia4mrGoiez+SqV3olVfxyLFt3o/OQOnBmjhKUANoKLYlK # mUpKEFI0PfoT8Q1W/y6s9LTI6ekbi0igEbFUIBE8KDUGfIwnisEkBw5KcBZ3XwnH # mfznwlKo8QIDAQABo4IBVTCCAVEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQU # 3XRdTADbe5+gdMqxbvc8wDLAcM0wHwYDVR0jBBgwFoAUtqFUOQLDoD+Oirz61Pgc # ptE6Dv0wDgYDVR0PAQH/BAQDAgEGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMDAGA1Ud # HwQpMCcwJaAjoCGGH2h0dHA6Ly9jcmwuY2VydHVtLnBsL2N0bmNhMi5jcmwwbAYI # KwYBBQUHAQEEYDBeMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0 # dW0uY29tMDIGCCsGAQUFBzAChiZodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwv # Y3RuY2EyLmNlcjA5BgNVHSAEMjAwMC4GBFUdIAAwJjAkBggrBgEFBQcCARYYaHR0 # cDovL3d3dy5jZXJ0dW0ucGwvQ1BTMA0GCSqGSIb3DQEBDAUAA4ICAQB1iFgP5Y9Q # KJpTnxDsQ/z0O23JmoZifZdEOEmQvo/79PQg9nLF/GJe6ZiUBEyDBHMtFRK0mXj3 # Qv3gL0sYXe+PPMfwmreJHvgFGWQ7XwnfMh2YIpBrkvJnjwh8gIlNlUl4KENTK5DL # qsYPEtRQCw7R6p4s2EtWyDDr/M58iY2UBEqfUU/ujR9NuPyKk0bEcEi62JGxauFY # zZ/yld13fHaZskIoq2XazjaD0pQkcQiIueL0HKiohS6XgZuUtCKA7S6CHttZEsOb # QJ1j2s0urIDdqF7xaXFVaTHKtAuMfwi0jXtF3JJphrJfc+FFILgCbX/uYBPBlbBI # P4Ht4xxk2GmfzMn7oxPITpigQFJFWuzTMUUgdRHTxaTSKRJ/6Uh7ki/pFjf9sUAS # WgxT69QF9Ki4JF5nBIujxZ2sOU9e1HSCJwOfK07t5nnzbs1LbHuAIGJsRJiQ6HX/ # DW1XFOlXY1rc9HufFhWU+7Uk+hFkJsfzqBz3pRO+5aI6u5abI4Qws4YaeJH7H7M8 # X/YNoaArZbV4Ql+jarKsE0+8XvC4DJB+IVcvC9Ydqahi09mjQse4fxfef0L7E3hh # o2O3bLDM6v60rIRUCi2fJT2/IRU5ohgyTch4GuYWefSBsp5NPJh4QRTP9DC3gc5Q # EKtbrTY0Ka87Web7/zScvLmvQBm8JDFpDjCCBrkwggShoAMCAQICEQDn/2nHOzXO # S5Em2HR8aKWHMA0GCSqGSIb3DQEBDAUAMIGAMQswCQYDVQQGEwJQTDEiMCAGA1UE # ChMZVW5pemV0byBUZWNobm9sb2dpZXMgUy5BLjEnMCUGA1UECxMeQ2VydHVtIENl # cnRpZmljYXRpb24gQXV0aG9yaXR5MSQwIgYDVQQDExtDZXJ0dW0gVHJ1c3RlZCBO # ZXR3b3JrIENBIDIwHhcNMjEwNTE5MDUzMjA3WhcNMzYwNTE4MDUzMjA3WjBWMQsw # CQYDVQQGEwJQTDEhMB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMSQw # IgYDVQQDExtDZXJ0dW0gVGltZXN0YW1waW5nIDIwMjEgQ0EwggIiMA0GCSqGSIb3 # DQEBAQUAA4ICDwAwggIKAoICAQDpEh8ENe25XXrFppVBvoplf0530W0lddNmjtv4 # YSh/f7eDQKFaIqc7tHj7ox+u8vIsJZlroakUeMS3i3T8aJRC+eQs4FF0GqvkM6+W # ZO8kmzZfxmZaBYmMLs8FktgFYCzywmXeQ1fEExflee2OpbHVk665eXRHjH7MYZIz # Nnjl2m8Hy8ulB9mR8wL/W0v0pjKNT6G0sfrx1kk+3OGosFUb7yWNnVkWKU4qSxLv # 16kJ6oVJ4BSbZ4xMak6JLeB8szrK9vwGDpvGDnKCUMYL3NuviwH1x4gZG0JAXU3x # 2pOAz91JWKJSAmRy/l0s0l5bEYKolg+DMqVhlOANd8Yh5mkQWaMEvBRE/kAGzIqg # WhwzN2OsKIVtO8mf5sPWSrvyplSABAYa13rMYnzwfg08nljZHghquCJYCa/xHK9a # cev9UD7Y+usr15d7mrszzxhF1JOr1Mpup2chNSBlyOObhlSO16rwrffVrg/SzaKf # SndS5swRhr8bnDqNJY9TNyEYvBYpgF95K7p0g4LguR4A++Z1nFIHWVY5v0fNVZmg # zxD9uVo/gta3onGOQj3JCxgYx0KrCXu4yc9QiVwTFLWbNdHFSjBCt5/8Q9pLuRhV # ocdCunhcHudMS1CGQ/Rn0+7P+fzMgWdRKfEOh/hjLrnQ8BdJiYrZNxvIOhM2aa3z # EDHNwwIDAQABo4IBVTCCAVEwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUvlQC # L79AbHNDzqwJJU6eQ0Qa7uAwHwYDVR0jBBgwFoAUtqFUOQLDoD+Oirz61PgcptE6 # Dv0wDgYDVR0PAQH/BAQDAgEGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMDAGA1UdHwQp # MCcwJaAjoCGGH2h0dHA6Ly9jcmwuY2VydHVtLnBsL2N0bmNhMi5jcmwwbAYIKwYB # BQUHAQEEYDBeMCgGCCsGAQUFBzABhhxodHRwOi8vc3ViY2Eub2NzcC1jZXJ0dW0u # Y29tMDIGCCsGAQUFBzAChiZodHRwOi8vcmVwb3NpdG9yeS5jZXJ0dW0ucGwvY3Ru # Y2EyLmNlcjA5BgNVHSAEMjAwMC4GBFUdIAAwJjAkBggrBgEFBQcCARYYaHR0cDov # L3d3dy5jZXJ0dW0ucGwvQ1BTMA0GCSqGSIb3DQEBDAUAA4ICAQC4k1l3yUwV/ZQH # CKCneqAs8EGTnwEUJLdDpokN/dMhKjK0rR5qX8nIIHzxpQR3TAw2IRw1Uxsr2Pli # G3bCFqSdQTUbfaTq6V3vBzEebDru9QFjqlKnxCF2h1jhLNFFplbPJiW+JSnJTh1f # KEqEdKdxgl9rVTvlxfEJ7exOn25MGbd/wGPwuSmMxRJVO0wnqgS7kmoJjNF9zqee # hFSDDP8ZVkWg4EZ2tIS0M3uZmByRr+1Lkwjjt8AtW83mVnZTyTsOb+FNfwJY7DS4 # FmWhkRbgcHRetreoTirPOr/ozyDKhT8MTSTf6Lttg6s6T/u08mDWw6HK04ZRDfQ9 # sb77QV8mKgO44WGP31vXnVKoWVJpFBjPvjL8/Zck/5wXX2iqjOaLStFOR/IQki+E # hn4zlcgVm22ZVCBPF+l8nAwUUShCtKuSU7GmZLKCmmxQMkSiWILTm8EtVD6AxnJh # oq8EnhjEEyUoflkeRF2WhFiVQOmWTwZRr44IxWGkNJC6tTorW5rl2Zl+2e9JLPYf # 3pStAPMDoPKIjVXd6NW2+fZrNUBeDo2eOa5Fn7Brs/HLQff5Xgris5MeUbdVgDrF # 8uxO6cLPvZPo63j62SsNg55pTWk9fUIF9iPoRbb4QurjoY/woI1RAOKtYtTic6aA # Jq3u83RIPpGXBSJKwx4KJAOZnCDCtTGCBqIwggaeAgEBMGowVjELMAkGA1UEBhMC # UEwxITAfBgNVBAoTGEFzc2VjbyBEYXRhIFN5c3RlbXMgUy5BLjEkMCIGA1UEAxMb # Q2VydHVtIENvZGUgU2lnbmluZyAyMDIxIENBAhBX5gfP8LabvnxCXoItEBa/MA0G # CWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZI # hvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcC # ARUwLwYJKoZIhvcNAQkEMSIEILBnsPBIvy6p8DPkYCLUtiKEDfMmZPpHYRHlvU/D # s9e2MA0GCSqGSIb3DQEBAQUABIIBgKJLyT0FiI7Ty7/HBaXJVjfzzfyQyUA3aEYZ # TklUwlI8buIXT/hkMtAbwJSawmahc++fxksnyqRxnOuDHcoVtpU7DTUELCu8tyKz # 0sYmVHC+LEvlvNqqemUco77b3Ukn9ct226EK9S8r5a1hTcwCxtJFzWunub0fAvrz # dRDTk0eqVIRHO6ctC1sNklwoTseGzSx+Zs3tNdx9IHc4zEw2FnBHbN2EykLDAyVT # JbpmcgRQpgRquKkCS9xsp1UhToXoNXDE8b6PL/ypbnloiLef+DgiuW8RPauhjmzF # XX8/nr78jr0QAkTMQEB9XAbxIsYgICgMV9XH08uhmmX5t4dysaKnlCb6AyrCU7Ie # ONLvLEjnON+Rv55ImJwvD79S1HONMTwGjjsEOqo7vyK4Ej96mz+rgpGqVUPvc3K/ # lxkXk7gg0l0SUAtu0ToRqQsuVtPaj2UuW0CJ+zSeaGgraROijOFwsZ8CZLjizCsl # lwSfq4UXaQ4kQeVU2mEXr9hOr4X0/qGCBAIwggP+BgkqhkiG9w0BCQYxggPvMIID # 6wIBATBqMFYxCzAJBgNVBAYTAlBMMSEwHwYDVQQKExhBc3NlY28gRGF0YSBTeXN0 # ZW1zIFMuQS4xJDAiBgNVBAMTG0NlcnR1bSBUaW1lc3RhbXBpbmcgMjAyMSBDQQIQ # KPB3wRw2vf5fdDJHcCcuAzANBglghkgBZQMEAgIFAKCCAVYwGgYJKoZIhvcNAQkD # MQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNjEwMTMwOTQxNTJaMDcG # CyqGSIb3DQEJEAIvMSgwJjAkMCIEIIW+kOEK0kONfMkotq9IsJqyCBd87PiwEmxY # 05EFJcQ8MD8GCSqGSIb3DQEJBDEyBDDizGpm/vuY+s1eMXKedMGp8+yU+4hgzXU0 # RbMOntVMWjMQHVCGR7WyZzYdYzjTb9YwgZ8GCyqGSIb3DQEJEAIMMYGPMIGMMIGJ # MIGGBBRXFGhBDKha80JO+RZKUTYQ9NONmDBuMFqkWDBWMQswCQYDVQQGEwJQTDEh # MB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMSQwIgYDVQQDExtDZXJ0 # dW0gVGltZXN0YW1waW5nIDIwMjEgQ0ECECjwd8EcNr3+X3QyR3AnLgMwDQYJKoZI # hvcNAQEBBQAEggIAMGzWw5E0FL2JEBbzVS/90np8guqwCLpt3S8Fw1RDYDKi0rFJ # gxmljRbH3A6nCLKGfZkh5U9tuTeNccjoJpbPsW+Pb066KqEbHtbCxjM0rwhWHcT2 # MDR4QF7KTNmbNlMMWcXg+7kxlUDjvNck+xdDcPxTMkivPBIoCzcbV4B+ZklATL8N # KIZQ1DoADjwIBm5/UFPIqzFyLCexoVdXtCj5XeHhZ8g74KPnPIv11c2p5eoYMfOr # kX4x++dtJ93WJbCP8L3pCJvLiOEjrcbVkbupuJe6l+bxZ7tVItos77lgiOkuKW0R # yIjZ59vsXxhfUektOz/gwH5trUXMcxDbYSoaIPktL/BmWEDT07pO2fx1c4C+BQq8 # CMUojLE6TWWuWKheRSRptL/qyxHbhDpDcvvAP+JLfXF7l3mEba/1TRQPqEaV4e3Y # mNfY4reAsXWAMWhMkL90zjtg0KvW03ByD1qMDxNbIavOmKhpSZCv/DzGLTyp5Nok # GdJilK/ag6IIgQ/yc/gWZ4MtyWKkpfz457fFWpvI4tGK0GUoRgwTucYZctEOur7Q # BfE8kScj3RcImhUpbrhmzgXLWlN5U//oDVjxBucl6CBXGFYQg6g/WbfBRHr1UPJY # /rZlZgkVfqk4cRsQEGqTWYmNpQbXcUFN+0QUb1T+Ra7PH3znr+xhljlQHY0= # SIG # End signature block |