Private/Resolve-EntraOpsAzureConstrainedDelegationTier.ps1

function Resolve-EntraOpsAzureConstrainedDelegationTier {
    <#
    .SYNOPSIS
        Downgrades the Authorization (roleAssignments write/delete) classification of an Azure RBAC
        assignment when an ABAC RoleAssignmentCondition limits which roles can be delegated.
    .DESCRIPTION
        Azure RBAC supports condition-based (ABAC) constrained delegation, where a role that can write
        role assignments (e.g. Role Based Access Control Administrator, User Access Administrator, Owner)
        is restricted so the principal can only assign a specific allow-list of roles, or any role except
        a deny-list. Such a delegation is not itself "Control Plane" if it cannot be used to grant
        control-plane access. This helper re-tiers the Authorization classification of the assignment by
        classifying the RoleDefinitionIds referenced in the condition against the same RoleAssignmentScopeId,
        using the same classification rules used for normal role-assignment tiering.

                Behavior:
                - Only applies when an assignment- or role-definition-level condition constrains
                    "Microsoft.Authorization/roleAssignments" write/delete by RoleDefinitionId, the assignment already
                    has an Authorization Control Plane (Tier 0) entry, and the RoleAssignmentScopeId is not itself a
                    concrete control-plane scope.
                - The negated ActionMatches guards ("(!(ActionMatches{'...roleAssignments/write'})) OR (...)") decide
                    WHICH actions the RoleDefinitionId allow-list applies to: only guarded actions are re-tiered, an
                    unguarded write/delete stays Control Plane. Expressions without a recognizable guard for a
                    roleAssignments write/delete action are not interpreted - the assignment keeps Control Plane.
                - A recognized GuidEquals allow-list is downgraded to the most privileged tier that its allowed roles
                    classify to at the assignment scope; per-action allow-lists intersect across multiple conditions
                    (assignment + role definition) since the conditions combine with AND at evaluation time.
                - GuidNotEquals deny-lists, unknown role definitions, unsupported condition versions and unrecognized
                    constraints remain Control Plane because they cannot prove all Control Plane delegation is prevented.

        Note: the downgrade targets only the roleAssignments-write/delete portion of the Authorization
        classification. If the same Tier 0 entry also matched other Authorization powers the condition does
        not restrict (e.g. roleDefinitions/write, elevateAccess/action, PIM policy writes - directly or via
        a broad role action such as "*" or "Microsoft.Authorization/*"), the entry is split: those matched
        actions remain Control Plane and only the constrained roleAssignments actions are re-tiered.
        Classification entries that come from the role's own actions (e.g. key/secret read) are left unchanged.
    .PARAMETER Assignment
        The Azure RBAC assignment object. Must expose RoleAssignmentCondition, RoleAssignmentScopeId and a
        Classification array (as produced by Get-EntraOpsPrivilegedEAMAzure Stage 3).
    .PARAMETER ClassificationDefinitions
        The expanded Classification_Azure.json entries (EAMTierLevelName, EAMTierLevelTagValue, Service,
        RoleAssignmentScopeName, ExcludedRoleAssignmentScopeName, RoleDefinitionActions, ExcludedRoleDefinitionActions).
    .PARAMETER RoleDefinitionCache
        Hashtable keyed by role definition GUID with values exposing .properties.permissions[].actions/.dataActions/.notActions/.notDataActions.
    .PARAMETER TierNameByTag
        Hashtable mapping tier tag value (as string, e.g. "0") to the tier name (e.g. "ControlPlane").
    .OUTPUTS
        [array] The (possibly modified) classification array for the assignment.
    #>

    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [PSObject]$Assignment,

        [Parameter(Mandatory = $true)]
        [AllowNull()]
        [object]$ClassificationDefinitions,

        [Parameter(Mandatory = $true)]
        [hashtable]$RoleDefinitionCache,

        [Parameter(Mandatory = $true)]
        [hashtable]$TierNameByTag
    )

    $Classification = @($Assignment.Classification)
    if ($Classification.Count -eq 0) {
        return $Classification
    }

    # The assignment must contain an Authorization Control Plane (Tier 0) classification to downgrade.
    $AuthorizationEntries = @($Classification | Where-Object {
            "$($_.AdminTierLevel)" -eq "0" -and (
                $_.Service -eq "Authorization" -or
                (@($_.MatchedActions) | Where-Object {
                        -not [string]::IsNullOrEmpty($_) -and (
                            $_ -like "*roleAssignments/write" -or
                            $_ -like "*roleAssignments/delete" -or
                            ($_ -like "Microsoft.Authorization/*" -and ($_ -like "*/write" -or $_ -like "*/delete"))
                        )
                    }).Count -gt 0
            )
        })
    if ($AuthorizationEntries.Count -eq 0) {
        return $Classification
    }

    # --- Parse the RoleDefinitionId constraints from assignment and role-definition conditions ---
    # Azure built-in constrained-delegation roles (for example Key Vault Data Access Administrator)
    # define their ABAC condition on the role definition. An assignment can add another condition.
    $ConditionPattern = "RoleDefinitionId\]\s*\w+:(Guid(?:Not)?Equals)\s*\{([^}]*)\}"
    # Canonical ABAC guard form for role-assignment conditions: "IF the request action is X THEN the
    # RoleDefinitionId constraint applies" is expressed as (!(ActionMatches{'X'})) OR (<constraint>).
    $GuardPattern = "!\s*\(\s*ActionMatches\s*\{\s*'([^']+)'\s*\}\s*\)"
    $ConditionExpressions = [System.Collections.Generic.List[PSCustomObject]]::new()
    if (-not [string]::IsNullOrEmpty($Assignment.RoleAssignmentCondition)) {
        $ConditionExpressions.Add([PSCustomObject]@{ Expression = $Assignment.RoleAssignmentCondition; Version = $Assignment.RoleAssignmentConditionVersion }) | Out-Null
    }
    $AssignedRoleDefinition = $RoleDefinitionCache[$Assignment.RoleDefinitionId]
    foreach ($Permission in @($AssignedRoleDefinition.properties.permissions)) {
        if (-not [string]::IsNullOrEmpty($Permission.condition)) {
            $ConditionExpressions.Add([PSCustomObject]@{ Expression = $Permission.condition; Version = $Permission.conditionVersion }) | Out-Null
        }
    }
    if ($ConditionExpressions.Count -eq 0) {
        return $Classification
    }

    # Allow-list per constrained action ('write'/'delete'). The RoleDefinitionId constraint only
    # applies to the actions named in an expression's negated ActionMatches guards; multiple
    # expressions (assignment + role definition) combine with AND at evaluation time, so per-action
    # allow-lists intersect across expressions.
    $AllowedByAction = @{}
    foreach ($ConditionExpression in $ConditionExpressions) {
        if (-not [string]::IsNullOrEmpty($ConditionExpression.Version) -and $ConditionExpression.Version -ne '2.0') {
            return $Classification
        }
        if ($ConditionExpression.Expression -notlike '*Microsoft.Authorization/roleAssignments*') {
            continue
        }
        $ConditionMatches = [regex]::Matches($ConditionExpression.Expression, $ConditionPattern)
        if ($ConditionMatches.Count -eq 0) {
            return $Classification
        }

        # Which roleAssignments actions does this expression's allow-list actually constrain? Without a
        # recognizable negated guard the boolean structure cannot be interpreted - keep Control Plane
        # (fail closed) instead of assuming the constraint covers both write and delete.
        $GuardedActions = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
        foreach ($GuardMatch in [regex]::Matches($ConditionExpression.Expression, $GuardPattern)) {
            $GuardAction = $GuardMatch.Groups[1].Value
            if ($GuardAction -like "*roleAssignments/write") { [void]$GuardedActions.Add('write') }
            elseif ($GuardAction -like "*roleAssignments/delete") { [void]$GuardedActions.Add('delete') }
        }
        if ($GuardedActions.Count -eq 0) {
            return $Classification
        }

        $ConditionAllowedRoleDefIds = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
        foreach ($Match in $ConditionMatches) {
            # A deny-list still permits every role not named in it. Do not downgrade unless
            # the expression proves a closed allow-list of delegable role definitions.
            if ($Match.Groups[1].Value -ieq 'GuidNotEquals') {
                return $Classification
            }
            foreach ($Guid in @($Match.Groups[2].Value -split ',' | ForEach-Object { $_.Trim() } | Where-Object { -not [string]::IsNullOrEmpty($_) })) {
                [void]$ConditionAllowedRoleDefIds.Add($Guid)
            }
        }
        if ($ConditionAllowedRoleDefIds.Count -eq 0) {
            return $Classification
        }
        foreach ($GuardedAction in $GuardedActions) {
            if (-not $AllowedByAction.ContainsKey($GuardedAction)) {
                # Copy via UnionWith; the 2-arg HashSet ctor fails overload resolution on some pwsh versions.
                $ActionSet = [System.Collections.Generic.HashSet[string]]::new([System.StringComparer]::OrdinalIgnoreCase)
                $ActionSet.UnionWith([string[]]@($ConditionAllowedRoleDefIds))
                $AllowedByAction[$GuardedAction] = $ActionSet
            } else {
                $AllowedByAction[$GuardedAction].IntersectWith([string[]]@($ConditionAllowedRoleDefIds))
            }
        }
    }
    if ($AllowedByAction.Count -eq 0) { return $Classification }

    # --- Control-plane scope guard ---
    # If the assignment scope is itself a concrete (non-wildcard) Tier 0 control-plane scope, keep Control Plane.
    # Only scope patterns without a wildcard count: a wildcard pattern such as "/subscriptions/*" describes the
    # tier of control-plane *actions*, not a specific control-plane resource path.
    $Scope = $Assignment.RoleAssignmentScopeId
    foreach ($ClassEntry in @($ClassificationDefinitions)) {
        if ("$($ClassEntry.EAMTierLevelTagValue)" -ne "0") { continue }
        $ScopePattern = $ClassEntry.RoleAssignmentScopeName
        if ([string]::IsNullOrWhiteSpace($ScopePattern) -or $ScopePattern -eq "/" -or $ScopePattern.Contains("*")) { continue }
        if ($Scope -like $ScopePattern) {
            $IsExcludedScope = $false
            foreach ($ExcludedScope in @($ClassEntry.ExcludedRoleAssignmentScopeName)) {
                if (-not [string]::IsNullOrEmpty($ExcludedScope) -and ($Scope -like $ExcludedScope)) { $IsExcludedScope = $true; break }
            }
            if (-not $IsExcludedScope) {
                # Scope is a concrete control-plane resource; do not downgrade.
                return $Classification
            }
        }
    }

    # --- Local helper: classify a single role definition at the assignment scope (returns tier tags) ---
    $GetRoleTierTags = {
        param($RoleDef, $ScopeId, $Defs)
        $Tags = [System.Collections.Generic.List[int]]::new()
        if ($null -eq $RoleDef) { return $Tags }
        foreach ($ClassEntry in @($Defs)) {
            if (-not ($ScopeId -like $ClassEntry.RoleAssignmentScopeName)) { continue }
            $IsExcludedScope = $false
            foreach ($ExcludedScope in @($ClassEntry.ExcludedRoleAssignmentScopeName)) {
                if (-not [string]::IsNullOrEmpty($ExcludedScope) -and ($ScopeId -like $ExcludedScope)) { $IsExcludedScope = $true; break }
            }
            if ($IsExcludedScope) { continue }

            $IsDataActionRule = "$($ClassEntry.ActionType)" -ieq 'DataAction'
            $TierMatched = $false
            foreach ($ClassAction in @($ClassEntry.RoleDefinitionActions)) {
                if ($TierMatched) { break }
                if ([string]::IsNullOrEmpty($ClassAction)) { continue }
                foreach ($Permission in @($RoleDef.properties.permissions)) {
                    if ($TierMatched) { break }
                    $RoleActions = if ($IsDataActionRule) { @($Permission.dataActions) } else { @($Permission.actions) }
                    $NotRoleActions = if ($IsDataActionRule) { @($Permission.notDataActions) } else { @($Permission.notActions) }
                    foreach ($RoleAction in $RoleActions) {
                        if ([string]::IsNullOrEmpty($RoleAction)) { continue }
                        if ($RoleAction -eq '*/read' -and $ClassAction -ne '*/read') { continue }
                        if ($RoleAction -like $ClassAction -or $ClassAction -like $RoleAction) {
                            $IsExcludedByClassification = @($ClassEntry.ExcludedRoleDefinitionActions | Where-Object {
                                    -not [string]::IsNullOrEmpty($_) -and $RoleAction -like $_
                                }).Count -gt 0
                            if ($IsExcludedByClassification) { continue }
                            $IsNotActioned = $false
                            foreach ($NotAction in $NotRoleActions) {
                                if (-not [string]::IsNullOrEmpty($NotAction) -and ($ClassAction -like $NotAction)) { $IsNotActioned = $true; break }
                            }
                            if (-not $IsNotActioned) { $TierMatched = $true; break }
                        }
                    }
                }
            }
            if ($TierMatched) { [void]$Tags.Add([int]$ClassEntry.EAMTierLevelTagValue) }
        }
        return @($Tags | Select-Object -Unique)
    }

    # --- Determine downgrade tier per constrained action ---
    # An action whose allow-list still reaches a Control Plane role, cannot be fully resolved, or
    # intersected to nothing is effectively unproven and stays Control Plane; only provably-limited
    # actions are re-tiered, to the most privileged tier reachable through their allow-list.
    $DowngradeTagByAction = @{}
    foreach ($ActionName in @($AllowedByAction.Keys)) {
        $ActionAllowedRoleDefIds = $AllowedByAction[$ActionName]
        if ($ActionAllowedRoleDefIds.Count -eq 0) { continue }
        $AllowedTags = [System.Collections.Generic.List[int]]::new()
        $Resolvable = $true
        foreach ($Guid in $ActionAllowedRoleDefIds) {
            $AllowedRoleDefinition = $RoleDefinitionCache[$Guid]
            if ($null -eq $AllowedRoleDefinition) { $Resolvable = $false; break }
            $RoleTags = @(& $GetRoleTierTags $AllowedRoleDefinition $Scope $ClassificationDefinitions)
            if ($RoleTags.Count -eq 0) { $Resolvable = $false; break }
            foreach ($Tag in $RoleTags) { [void]$AllowedTags.Add($Tag) }
        }
        if (-not $Resolvable -or $AllowedTags.Count -eq 0) { continue }
        $ActionTag = ($AllowedTags | Measure-Object -Minimum).Minimum
        if ([int]$ActionTag -le 0) { continue }
        $DowngradeTagByAction[$ActionName] = [int]$ActionTag
    }
    if ($DowngradeTagByAction.Count -eq 0) {
        return $Classification
    }

    # Single conservative downgrade tier: the most privileged tier among the constrained actions.
    $DowngradeTag = ($DowngradeTagByAction.Values | Measure-Object -Minimum).Minimum
    if (-not $TierNameByTag.ContainsKey("$DowngradeTag")) {
        return $Classification
    }
    $WriteConstrained = $DowngradeTagByAction.ContainsKey('write')
    $DeleteConstrained = $DowngradeTagByAction.ContainsKey('delete')

    # --- Apply the downgrade to the constrained roleAssignments actions only ---
    # The ABAC RoleDefinitionId condition constrains solely Microsoft.Authorization/roleAssignments
    # write/delete. Other Authorization powers aggregated in the same Tier 0 entry (roleDefinitions/write,
    # elevateAccess/action, PIM policy/schedule writes) are unaffected by the condition and must stay
    # Control Plane, so entries are split instead of re-tiered wholesale.
    $Changed = $false
    $UpdatedClassification = foreach ($Entry in $Classification) {
        $IsAuthorizationEntry = "$($Entry.AdminTierLevel)" -eq "0" -and (
            $Entry.Service -eq "Authorization" -or
            (@($Entry.MatchedActions) | Where-Object {
                    -not [string]::IsNullOrEmpty($_) -and (
                        $_ -like "*roleAssignments/write" -or
                        $_ -like "*roleAssignments/delete" -or
                        ($_ -like "Microsoft.Authorization/*" -and ($_ -like "*/write" -or $_ -like "*/delete"))
                    )
                }).Count -gt 0
        )
        if (-not $IsAuthorizationEntry) {
            $Entry
            continue
        }

        # Partition the matched classification patterns: a pattern is constrained when every role action
        # granting it is itself a roleAssignments write/delete. A wider grant (e.g. "*",
        # "Microsoft.Authorization/*") keeps powers the condition does not restrict, so such patterns
        # (and patterns unverifiable because the role definition is not cached) remain Control Plane.
        $ConstrainedPatterns = [System.Collections.Generic.List[string]]::new()
        $RemainderPatterns = [System.Collections.Generic.List[string]]::new()
        foreach ($Pattern in @($Entry.MatchedActions)) {
            if ([string]::IsNullOrEmpty($Pattern)) { continue }
            if ($Pattern -like "*roleAssignments/write") {
                if ($WriteConstrained) { $ConstrainedPatterns.Add($Pattern) } else { $RemainderPatterns.Add($Pattern) }
                continue
            }
            if ($Pattern -like "*roleAssignments/delete") {
                if ($DeleteConstrained) { $ConstrainedPatterns.Add($Pattern) } else { $RemainderPatterns.Add($Pattern) }
                continue
            }
            $HasAnyGrant = $false
            $HasUnconstrainedGrant = $false
            foreach ($Permission in @($AssignedRoleDefinition.properties.permissions)) {
                foreach ($RoleAction in @($Permission.actions)) {
                    if ([string]::IsNullOrEmpty($RoleAction)) { continue }
                    if ($RoleAction -eq '*/read' -and $Pattern -ne '*/read') { continue }
                    if ($RoleAction -like $Pattern -or $Pattern -like $RoleAction) {
                        $HasAnyGrant = $true
                        $IsConstrainedGrant = ($RoleAction -like "*roleAssignments/write" -and $WriteConstrained) -or
                            ($RoleAction -like "*roleAssignments/delete" -and $DeleteConstrained)
                        if (-not $IsConstrainedGrant) {
                            $HasUnconstrainedGrant = $true
                        }
                    }
                }
            }
            if ($HasAnyGrant -and -not $HasUnconstrainedGrant) {
                $ConstrainedPatterns.Add($Pattern)
            } else {
                $RemainderPatterns.Add($Pattern)
            }
        }

        if ($ConstrainedPatterns.Count -eq 0) {
            # Nothing in this entry is provably limited by the condition; keep it Control Plane.
            $Entry
            continue
        }

        $Changed = $true
        if ($RemainderPatterns.Count -gt 0) {
            [PSCustomObject]@{
                'AdminTierLevel'             = $Entry.AdminTierLevel
                'AdminTierLevelName'         = $Entry.AdminTierLevelName
                'Service'                    = $Entry.Service
                'MatchedActions'             = @($RemainderPatterns)
                'ScopedObjects'              = $Entry.ScopedObjects
                'TaggedBy'                   = $Entry.TaggedBy
                'TaggedByObjectIds'          = $Entry.TaggedByObjectIds
                'TaggedByObjectDisplayNames' = $Entry.TaggedByObjectDisplayNames
                'TaggedByRoleSystem'         = $Entry.TaggedByRoleSystem
            }
        }
        [PSCustomObject]@{
            'AdminTierLevel'             = "$DowngradeTag"
            'AdminTierLevelName'         = $TierNameByTag["$DowngradeTag"]
            'Service'                    = $Entry.Service
            'MatchedActions'             = @($ConstrainedPatterns)
            'ScopedObjects'              = $Entry.ScopedObjects
            'TaggedBy'                   = "JSONwithConditionInScope"
            'TaggedByObjectIds'          = $Entry.TaggedByObjectIds
            'TaggedByObjectDisplayNames' = $Entry.TaggedByObjectDisplayNames
            'TaggedByRoleSystem'         = $Entry.TaggedByRoleSystem
        }
    }

    if ($Changed) { return @($UpdatedClassification) }
    return $Classification
}

# SIG # Begin signature block
# MIIniAYJKoZIhvcNAQcCoIIneTCCJ3UCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBlF8G/1tzepSOM
# /ecqLlLSFNzkyt9oTK6izdphZ0Z3m6CCIDwwggXJMIIEsaADAgECAhAbtY8lKt8j
# 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
# ARUwLwYJKoZIhvcNAQkEMSIEIB7/+KSkeVc49KnaGlleYj5ihq2Vy6ddAOvWxzsF
# Mp1JMA0GCSqGSIb3DQEBAQUABIIBgHGFTnRtyqU7BJDcoUUZHlbEMJlMca4SwoV4
# YOf10ba61NLGCaN1plorff7/Vvt8dk9t+mzaEpY8hfudfjEOhsYGgRsbhrDDtwuz
# 8ubBWEP4okGV/cA65MW3Xmca20wllcNUhX3JWmt8WoPCb46CxnLfkmWAP+hMzxev
# pBLRZjYeINmYBdghxltbQBwV/nCOTJ8xsPLhV4904fp199ONnmLSUcbu/rwGke1Q
# 4nBuMUCYPPuC6dPqjLnKq73wqh3P56xUb+C0PAiJ/lrVkLTNkuvD+/Dk1z80mNPV
# mi6W9ky/hdaVktmsqDa2W11n4+a0dRSFEsg2wP/AIuP9wk+xUpaZ/oUsG4twzWUf
# 8EB4n+wkQ7wmeL6tylHhtGD1RGCIBPypJwp1s8kyX0XDs0WU9s/GFxXNJM6sDDrS
# z+GlB19THLoUy+j0BkKGWIMvWzn2N62MdccTiOJlOMaLc2PMbwyD0stE0PPNDHat
# mUqweCOS2Y+NweqQVdmAP+4fS9wSraGCBAIwggP+BgkqhkiG9w0BCQYxggPvMIID
# 6wIBATBqMFYxCzAJBgNVBAYTAlBMMSEwHwYDVQQKExhBc3NlY28gRGF0YSBTeXN0
# ZW1zIFMuQS4xJDAiBgNVBAMTG0NlcnR1bSBUaW1lc3RhbXBpbmcgMjAyMSBDQQIQ
# KPB3wRw2vf5fdDJHcCcuAzANBglghkgBZQMEAgIFAKCCAVYwGgYJKoZIhvcNAQkD
# MQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNjEwMTMwOTQwMDdaMDcG
# CyqGSIb3DQEJEAIvMSgwJjAkMCIEIIW+kOEK0kONfMkotq9IsJqyCBd87PiwEmxY
# 05EFJcQ8MD8GCSqGSIb3DQEJBDEyBDCibRwJqH7r/8pMGdXW0d3xNtmgkO1mVmaJ
# WaKCgrw/9Qwq7VfgmmvPcCyY4KRaUYIwgZ8GCyqGSIb3DQEJEAIMMYGPMIGMMIGJ
# MIGGBBRXFGhBDKha80JO+RZKUTYQ9NONmDBuMFqkWDBWMQswCQYDVQQGEwJQTDEh
# MB8GA1UEChMYQXNzZWNvIERhdGEgU3lzdGVtcyBTLkEuMSQwIgYDVQQDExtDZXJ0
# dW0gVGltZXN0YW1waW5nIDIwMjEgQ0ECECjwd8EcNr3+X3QyR3AnLgMwDQYJKoZI
# hvcNAQEBBQAEggIANftDxRjXQ+0RKOP2GX/+vOoU2Q8CIiVsfKgZKh4LI8JDLHlU
# z4F5Ur/f3LTWBPAIrzVdtmIgJglTKOzHNLqVp1fnecAIXCkbFy0vQ2wIToVQNzT8
# 4hHB4oSRMh70t3RM21dWbakFlPpHAWpniHK9djcsg8xLIvy558QoZKbbynsoptry
# JgXwMFc0bJ9F2LuwJcFiCrVMOouPM8v4ztFVY3bSpD8RIaUamzxicQhpydV+gcnk
# hjcm7OakGaKPy6gMhU9EnrLgLe0NzNeQIyScHRcEgvuc2dGbqMCTkNeyWsVOzMKP
# ENM6/SkKH0csxmYt2eO7dkMhGf2SM+HrUnDhjLxAaRf23KJDXOFb5FuBogjcC94R
# PVIxLvUiCyOlYlvoGE43+XczJpFXrHal7zqZ8HbMq4absBaPZAi2BnSh98gLszwE
# OSkRpW5Rq4chwjrInrKiwkJbwFThmxZtLF3gr/vXkws77iplaDCvQ8ItD0viNY09
# R68W7ZKqn5xhCNHt8gNZtVPdHKMUHz2hzcDJAA/euEwShs1aMeWtXsUfrzD+4dod
# DQ35tBVM9a0wyZf7oTnSSIeVT5dTd97G88uip7FefreFsJnSdkDjzQDkaY9numpW
# z/vt7Nla6kX6pO73xtFUmAlF0eE/AMeIypXzgvZomnfpt9lKeOrDUSKMOBg=
# SIG # End signature block