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