NetScalerToolkit.Common/Public/New-NSACMECertificateUser.ps1

function New-NSACMECertificateUser {
    <#
    .SYNOPSIS
        Creates or updates a NetScaler user for certificate automation.
 
    .DESCRIPTION
        Creates the limited command policies used by Request-NSACMECertificate and,
        optionally, creates or updates a NetScaler system user and binds those
        policies to the user. This is the module replacement for the legacy
        GenLeCertForNS -CreateUserPermissions and -CreateApiUser bootstrap path.
 
        The function is idempotent. Existing command policies are updated with the
        current command specification, existing users are updated when ApiPassword is
        provided, and missing policy bindings are added.
 
    .PARAMETER Session
        Existing NetScaler session returned by Connect-NSNode.
 
    .PARAMETER ManagementURL
        NetScaler management URL. Used when Session is not supplied.
 
    .PARAMETER Credential
        Credential used to connect when Session is not supplied.
 
    .PARAMETER SkipCertificateCheck
        Skips TLS certificate validation when connecting to the NetScaler.
 
    .PARAMETER PolicyName
        Base name for the three command policies. The effective base is truncated to
        24 characters when needed so the suffixed policy names stay within NetScaler
        limits. Alias: NSCPName.
 
    .PARAMETER ApiUsername
        Optional NetScaler system user to create or update.
 
    .PARAMETER ApiPassword
        Password for ApiUsername. Accepts plain text, SecureString, PSCredential, or
        legacy GenLeCertForNS secret objects.
 
    .PARAMETER CsVipName
        Content switching vServers that the generated command policy should permit.
        Required unless UseLbVip is used.
 
    .PARAMETER UseLbVip
        Indicates that HTTP validation uses an existing load balancing vServer instead
        of content switching vServers.
 
    .PARAMETER LbName
        Load balancing vServer name used by HTTP validation.
 
    .PARAMETER SvcName
        Service name used by HTTP validation.
 
    .PARAMETER RspName
        Responder policy name prefix.
 
    .PARAMETER RsaName
        Responder action name prefix.
 
    .PARAMETER CspName
        Content switching policy name.
 
    .PARAMETER CsaName
        Content switching action name.
 
    .PARAMETER EnableVipBefore
        Adds enable permission for configured CS vServers.
 
    .PARAMETER DisableVipAfter
        Adds disable permission for configured CS vServers.
 
    .PARAMETER UseNetScalerDNS
        Adds DNS TXT record permissions for NetScaler-hosted DNS validation.
 
    .PARAMETER UpdateGlobalVPNCertBinding
        Adds VPN global binding permissions.
 
    .PARAMETER Partitions
        Optional NetScaler partitions to bind to the created user. Partition command
        policy permissions are included when non-default partitions are specified.
 
    .PARAMETER PruneExistingPolicyBindings
        Removes command policy bindings from ApiUsername that do not match the three
        generated policies or have the wrong priority.
 
    .PARAMETER SaveADCConfig
        Saves the NetScaler configuration after changes.
 
    .PARAMETER PassThru
        Returns a result object.
 
    .EXAMPLE
        PS C:\> New-NSACMECertificateUser -ManagementURL https://adc.example.com -Credential (Get-Credential) -PolicyName script-GenLeCertForNS -CsVipName cs_example_http -ApiUsername GenLEUser -ApiPassword 'P@ssw0rd!' -SaveADCConfig
 
        Creates or updates the certificate automation policies, creates/updates
        GenLEUser, binds the policies, and saves the ADC configuration.
 
    .NOTES
        Function : New-NSACMECertificateUser
        Author : John Billekens
        Copyright : Copyright (c) John Billekens Consultancy
        Version : 2026.0526.0001
 
    .LINK
        https://netscalertoolkit.j81.nl/module/reference/common/nsacmecertificate-user/new/
 
    .LINK
        https://netscalertoolkit.j81.nl/
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'Connect')]
    param(
        [Parameter(ParameterSetName = 'Session', Mandatory)]
        [object]$Session,

        [Parameter(ParameterSetName = 'Connect', Mandatory)]
        [Alias('URL', 'NSManagementURL')]
        [string]$ManagementURL,

        [Parameter(ParameterSetName = 'Connect', Mandatory)]
        [Alias('NSCredential', 'ADCCredential')]
        [System.Management.Automation.PSCredential]$Credential,

        [Alias('NSCPName')]
        [string]$PolicyName = 'script-GenLeCertForNS',

        [string]$ApiUsername,

        [object]$ApiPassword,

        [Alias('NSCsVipName')]
        [string[]]$CsVipName,

        [switch]$UseLbVip,

        [Alias('NSLbName')]
        [string]$LbName = 'lb_letsencrypt_cert',

        [Alias('NSSvcName')]
        [string]$SvcName = 'svc_letsencrypt_cert_dummy',

        [Alias('NSRspName')]
        [string]$RspName = 'rsp_letsencrypt',

        [Alias('NSRsaName')]
        [string]$RsaName = 'rsa_letsencrypt',

        [Alias('NSCspName')]
        [string]$CspName = 'csp_letsencrypt',

        [string]$CsaName = 'csa_letsencrypt',

        [switch]$EnableVipBefore,

        [switch]$DisableVipAfter,

        [switch]$UseNetScalerDNS,

        [switch]$UpdateGlobalVPNCertBinding,

        [string[]]$Partitions = @('default'),

        [switch]$PruneExistingPolicyBindings,

        [Alias('SaveNSConfig')]
        [switch]$SaveADCConfig,

        [Parameter(ParameterSetName = 'Connect')]
        [switch]$SkipCertificateCheck,

        [switch]$PassThru
    )

    process {
        if (-not $UseLbVip -and (-not $CsVipName -or @($CsVipName).Count -lt 1)) {
            throw 'CsVipName is required when creating request-certificate user permissions unless UseLbVip is specified.'
        }

        $null = Import-NSConsoleStatus
        Write-NSStatusTitle -Title 'New-NSACMECertificateUser' -Subtitle @(
            'Policy base : {0}' -f $PolicyName
            'API user : {0}' -f $(if ($ApiUsername) { $ApiUsername } else { 'not requested' })
        )

        if (-not $Session) {
            Write-NSStatusSection -Title 'Setup'
            Write-NSStatusItem -Label 'Connect to NetScaler' -Value $ManagementURL
            try {
                $normalizedUrl = ([string]$ManagementURL).TrimEnd('/') + '/'
                $Session = Connect-NSNode -ManagementURL $normalizedUrl -Credential $Credential -SkipCertificateCheck:$SkipCertificateCheck -HA -PassThru -ErrorAction Stop
                if ($Session.IsHA -and -not $Session.IsPrimary) {
                    throw "Connected NetScaler HA session is '$($Session.ConnectedNodeState)', expected Primary."
                }
                $connectDetail = @($Session.ConnectedNodeState, $(if ($Session.Version) { "v$($Session.Version)" })) | Where-Object { $_ }
                Write-NSStatusResult -Status OK -Detail ($connectDetail -join ', ')
            } catch {
                Write-NSStatusResult -Status FAIL -ErrorRecord $_
                throw
            }
        }

        $effectivePolicyBase = if ($PolicyName.Length -ge 24) { $PolicyName.Substring(0, 24) } else { $PolicyName }
        $csVipExtraActions = ''
        if ($EnableVipBefore) { $csVipExtraActions += '|enable' }
        if ($DisableVipAfter) { $csVipExtraActions += '|disable' }

        $csVipString = ''
        if (-not $UseLbVip) {
            foreach ($vipName in @($CsVipName | Where-Object { $_ })) {
                $escapedVip = [regex]::Escape($vipName)
                $escapedCsp = [regex]::Escape($CspName)
                $escapedCsa = [regex]::Escape($CsaName)
                $csVipString += "|(^(set|show|bind|unbind$csVipExtraActions)\s+cs\s+vserver(\s+$escapedVip.*))|(^\S+\s+cs\s+(policy\s+$escapedCsp|action\s+$escapedCsa).*)"
            }
        }

        $cmdSpec = [ordered]@{
            Basics = "(^show\s+ns\s+license)|(^show\s+ns\s+license\s+.*)|(^(create|show)\s+system\s+backup)|(^(create|show)\s+system\s+backup\s+.*)|(^convert\s+ssl\s+pkcs12)|(^show\s+ns\s+feature)|(^show\s+ns\s+feature\s+.*)|(^show\s+responder\s+action)|(^show\s+responder\s+policy)|(^(show|add|rm)\s+system\s+file.*-fileLocation.*nsconfig.*ssl.*)|(^show\s+ssl\s+certKey)|(^(add|link|unlink|update)\s+ssl\s+certKey\s+.*)|(^show\s+HA\s+node)|(^show\s+HA\s+node\s+.*)|(^(save|show)\s+ns\s+config)|(^(save|show)\s+ns\s+config\s+.*)|(^show\s+ns\s+trafficDomain)|(^show\s+ns\s+trafficDomain\s+.*)|(^show\s+ssl\s+certChain)|(^show\s+ssl\s+certChain\s+.*)|(^add\s+ssl\s+certificateChain)|(^add\s+ssl\s+certificateChain\s+.*)|(^show\s+ssl\s+certificateChain)|(^show\s+ssl\s+certificateChain\s+.*)|(^show\s+ssl\s+certLink)|(^show\s+ssl\s+certLink\s+.*)"
            LEBkEd = "(^show\s+ns\s+version)|(^\S+\s+Service\s+$([regex]::Escape($SvcName)).*)|(^\S+\s+lb\s+vserver\s+$([regex]::Escape($LbName)).*)|(^\S+\s+responder\s+action\s+$([regex]::Escape($RsaName)).*)|(^\S+\s+responder\s+policy\s+$([regex]::Escape($RspName)).*)"
            LEFtEd = "(^show\s+ns\s+version)$csVipString"
        }
        $cmdSpecPriority = @{
            Basics = 10
            LEBkEd = 20
            LEFtEd = 30
        }
        if ($UseNetScalerDNS) {
            $cmdSpec['LEFtEd'] += "|(^\S+\s+dns\s+txtRec)|(^\S+\s+dns\s+txtRec\s+.*)"
        }
        if ($UpdateGlobalVPNCertBinding) {
            $cmdSpec['LEBkEd'] += "|(^\S+\s+vpn\s+global)|(^\S+\s+vpn\s+global\s+.*)"
        }
        if (@($Partitions | Where-Object { $_ -and $_ -ne 'default' }).Count -gt 0) {
            $cmdSpec['Basics'] += "|(^(show|switch)\s+ns\s+partition)|(^(show|switch)\s+ns\s+partition\s+.*)"
        }

        Write-NSStatusSection -Title 'Command policies'

        $policyResults = @()
        foreach ($item in $cmdSpec.GetEnumerator()) {
            $itemPolicyName = "$effectivePolicyBase-$($item.Name)"
            Write-NSStatusItem -Label $itemPolicyName -Value "priority $($cmdSpecPriority[$item.Name])"
            try {
                $existing = Invoke-NSGetSystemCmdPolicy -Session $Session -PolicyName $itemPolicyName -ReturnNullOnNotFound -ErrorAction Stop

                if ($existing) {
                    if ($PSCmdlet.ShouldProcess($itemPolicyName, 'Update NetScaler system command policy')) {
                        Invoke-NSUpdateSystemCmdPolicy -Session $Session -PolicyName $itemPolicyName -Action 'ALLOW' -CmdSpec $item.Value | Out-Null
                    }
                    $policyResults += [PSCustomObject]@{ PolicyName = $itemPolicyName; Priority = $cmdSpecPriority[$item.Name]; Action = 'Updated' }
                    Write-NSStatusResult -Status OK -Detail 'updated'
                } else {
                    if ($PSCmdlet.ShouldProcess($itemPolicyName, 'Create NetScaler system command policy')) {
                        Invoke-NSAddSystemCmdPolicy -Session $Session -PolicyName $itemPolicyName -Action 'ALLOW' -CmdSpec $item.Value | Out-Null
                    }
                    $policyResults += [PSCustomObject]@{ PolicyName = $itemPolicyName; Priority = $cmdSpecPriority[$item.Name]; Action = 'Created' }
                    Write-NSStatusResult -Status OK -Detail 'created'
                }
            } catch {
                Write-NSStatusResult -Status FAIL -ErrorRecord $_
                throw
            }
        }

        $userResult = $null
        $bindingResults = @()
        if ($ApiUsername) {
            if (-not $ApiPassword) { throw 'ApiPassword is required when ApiUsername is specified.' }

            Write-NSStatusSection -Title 'API user'
            Write-NSStatusItem -Label 'System user' -Value $ApiUsername
            try {
                $apiPasswordText = ConvertFrom-NSACMECertificateLegacySecret -Object $ApiPassword -AsClearText
                $existingUser = Invoke-NSGetSystemUser -Session $Session -Username $ApiUsername -ReturnNullOnNotFound -ErrorAction Stop

                if ($existingUser) {
                    if ($PSCmdlet.ShouldProcess($ApiUsername, 'Update NetScaler system user')) {
                        try {
                            Invoke-NSUpdateSystemUser -Session $Session -Username $ApiUsername -Password $apiPasswordText -Externalauth 'DISABLED' -Allowedmanagementinterface @('API') | Out-Null
                        } catch {
                            Invoke-NSUpdateSystemUser -Session $Session -Username $ApiUsername -Password $apiPasswordText -Externalauth 'DISABLED' | Out-Null
                        }
                    }
                    $userResult = [PSCustomObject]@{ Username = $ApiUsername; Action = 'Updated' }
                    Write-NSStatusResult -Status OK -Detail 'updated'
                } else {
                    if ($PSCmdlet.ShouldProcess($ApiUsername, 'Create NetScaler system user')) {
                        Invoke-NSAddSystemUser -Session $Session -Username $ApiUsername -Password $apiPasswordText -Externalauth 'DISABLED' | Out-Null
                        try {
                            Invoke-NSUpdateSystemUser -Session $Session -Username $ApiUsername -Externalauth 'DISABLED' -Allowedmanagementinterface @('API') | Out-Null
                        } catch {
                            Write-Verbose "Could not restrict allowed management interface to API: $($_.Exception.Message)"
                        }
                    }
                    $userResult = [PSCustomObject]@{ Username = $ApiUsername; Action = 'Created' }
                    Write-NSStatusResult -Status OK -Detail 'created'
                }
            } catch {
                Write-NSStatusResult -Status FAIL -ErrorRecord $_
                throw
            }

            Write-NSStatusSection -Title 'Policy bindings'

            $existingBindings = @()
            $bindingResponse = Invoke-NSGetSystemUserSystemCmdPolicyBinding -Session $Session -Username $ApiUsername -ReturnNullOnNotFound -ErrorAction Stop
            $existingBindings = @($bindingResponse)

            $expectedNames = @($policyResults.PolicyName)
            if ($PruneExistingPolicyBindings) {
                $bindingsToRemove = @($existingBindings | Where-Object {
                        $bindingPolicyName = $_.policyname
                        $expectedPolicy = $policyResults | Where-Object { $_.PolicyName -eq $bindingPolicyName } | Select-Object -First 1
                        ($_.policyname -notin $expectedNames) -or
                        ($_.policyname -in $expectedNames -and $expectedPolicy -and [int]$_.priority -ne [int]$expectedPolicy.Priority)
                    })
                foreach ($binding in $bindingsToRemove) {
                    Write-NSStatusItem -Label $binding.policyname -Value "priority $($binding.priority)"
                    if ($PSCmdlet.ShouldProcess("$ApiUsername/$($binding.policyname)", 'Remove NetScaler system user command policy binding')) {
                        Invoke-NSDeleteSystemUserSystemCmdPolicyBinding -Session $Session -Username $ApiUsername -Policyname $binding.policyname | Out-Null
                    }
                    $bindingResults += [PSCustomObject]@{ Username = $ApiUsername; PolicyName = $binding.policyname; Priority = $binding.priority; Action = 'Removed' }
                    Write-NSStatusResult -Status OK -Detail 'unbound'
                }
                if ($bindingsToRemove.Count -gt 0) {
                    $bindingResponse = Invoke-NSGetSystemUserSystemCmdPolicyBinding -Session $Session -Username $ApiUsername -ReturnNullOnNotFound -ErrorAction Stop
                    $existingBindings = @($bindingResponse)
                }
            }

            foreach ($policy in $policyResults) {
                Write-NSStatusItem -Label $policy.PolicyName -Value "priority $($policy.Priority)"
                $present = @($existingBindings | Where-Object { $_.policyname -ieq $policy.PolicyName -and [int]$_.priority -eq [int]$policy.Priority }).Count -gt 0
                if ($present) {
                    $bindingResults += [PSCustomObject]@{ Username = $ApiUsername; PolicyName = $policy.PolicyName; Priority = $policy.Priority; Action = 'Present' }
                    Write-NSStatusResult -Status SKIP -Detail 'already bound'
                } else {
                    if ($PSCmdlet.ShouldProcess("$ApiUsername/$($policy.PolicyName)", 'Create NetScaler system user command policy binding')) {
                        Invoke-NSAddSystemUserSystemCmdPolicyBinding -Session $Session -Username $ApiUsername -Policyname $policy.PolicyName -Priority ([double]$policy.Priority) | Out-Null
                    }
                    $bindingResults += [PSCustomObject]@{ Username = $ApiUsername; PolicyName = $policy.PolicyName; Priority = $policy.Priority; Action = 'Bound' }
                    Write-NSStatusResult -Status OK -Detail 'bound'
                }
            }

            foreach ($partition in @($Partitions | Where-Object { $_ -and $_ -ne 'default' })) {
                Write-NSStatusItem -Label 'Partition binding' -Value $partition
                try {
                    $partitionBindings = Invoke-NSGetSystemUserNSPartitionBinding -Session $Session -Username $ApiUsername -ErrorAction Stop
                    $partitionPresent = @($partitionBindings | Where-Object { $_.partitionname -eq $partition }).Count -gt 0
                    if (-not $partitionPresent -and $PSCmdlet.ShouldProcess("$ApiUsername/$partition", 'Create NetScaler system user partition binding')) {
                        Invoke-NSAddSystemUserNSPartitionBinding -Session $Session -Username $ApiUsername -Partitionname $partition | Out-Null
                    }
                    Write-NSStatusResult -Status $(if ($partitionPresent) { 'SKIP' } else { 'OK' }) -Detail $(if ($partitionPresent) { 'already bound' } else { 'bound' })
                } catch {
                    Write-Warning "Could not bind partition '$partition' to '$ApiUsername': $($_.Exception.Message)"
                    Write-NSStatusResult -Status WARN -Detail $_.Exception.Message
                }
            }
        }

        if ($SaveADCConfig) {
            Write-NSStatusSection -Title 'Save'
            Write-NSStatusItem -Label 'Save NetScaler config' -Value 'nsconfig'
            try {
                if ($PSCmdlet.ShouldProcess('nsconfig', 'Save NetScaler configuration')) {
                    Invoke-NSSaveNSConfig -Session $Session | Out-Null
                }
                Write-NSStatusResult -Status OK
            } catch {
                Write-NSStatusResult -Status FAIL -ErrorRecord $_
                throw
            }
        }

        # The item labels are too narrow for a full policy name, so report the effective
        # names once the base has been truncated and the suffixes applied.
        Write-NSStatusSection -Title 'Results'

        $resultLines = @()
        $resultLines += [PSCustomObject]@{
            Label  = 'Policy base'
            Detail = if ($effectivePolicyBase -ne $PolicyName) {
                # The supplied name is already in the title block, so only note the cut.
                '{0} (truncated to {1} characters)' -f $effectivePolicyBase, $effectivePolicyBase.Length
            } else {
                $effectivePolicyBase
            }
        }
        foreach ($policy in $policyResults) {
            $resultLines += [PSCustomObject]@{
                Label  = 'Command policy'
                Detail = '{0} (priority {1}, {2})' -f $policy.PolicyName, $policy.Priority, $policy.Action.ToLower()
            }
        }
        if ($userResult) {
            $resultLines += [PSCustomObject]@{
                Label  = 'API user'
                Detail = '{0} ({1})' -f $userResult.Username, $userResult.Action.ToLower()
            }
        }

        foreach ($line in $resultLines) {
            # NoRecord: data lines, not outcomes, so they stay out of the summary counts.
            Write-NSStatusItem -Label $line.Label
            Write-NSStatusResult -Status OK -Detail $line.Detail -NoRecord
        }

        Write-NSStatusSummary

        $result = [PSCustomObject]@{
            PolicyBase       = $effectivePolicyBase
            Policies         = $policyResults
            User             = $userResult
            PolicyBindings   = $bindingResults
            SaveADCConfig    = [bool]$SaveADCConfig
            PrunedBindings   = [bool]$PruneExistingPolicyBindings
        }

        if ($PassThru) {
            return $result
        }
    }
}

# SIG # Begin signature block
# MII6AgYJKoZIhvcNAQcCoII58zCCOe8CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBUnZEELcfMyA2Y
# cy1cai348BFB+XpiDXK8l4s5tGBD3aCCIiYwggXMMIIDtKADAgECAhBUmNLR1FsZ
# lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu
# dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy
# MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv
# c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo
# b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD
# Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH
# or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD
# PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV
# qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70
# ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1
# vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3
# W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK
# xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg
# trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj
# O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7
# swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ
# T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn
# LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c
# Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF
# xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx
# AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8
# FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY
# lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2
# 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY
# uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al
# GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk
# ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggbAMIIEqKADAgECAhMzAAS405bY
# qvWOnUNsAAAABLjTMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQwHhcNMjYwODEyMjAwNzA0WhcNMjYwODE1
# MjAwNzA0WjCBgzELMAkGA1UEBhMCTkwxFjAUBgNVBAgTDU5vb3JkLUJyYWJhbnQx
# EjAQBgNVBAcTCVNjaGlqbmRlbDEjMCEGA1UEChMaSm9obiBCaWxsZWtlbnMgQ29u
# c3VsdGFuY3kxIzAhBgNVBAMTGkpvaG4gQmlsbGVrZW5zIENvbnN1bHRhbmN5MIIB
# ojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAi56FBfwzf5vShzPjNpAFDlIx
# rP+WNwkHmP1Ca70ZVfvy+KP7+SJg61G0oDAs401zvQ84SQ+vpU8/DLCA66MphoTa
# 0lynwbUy7I4gX/Ei+x1PnFa7O+XlkkAkU/S8AS8+MD7SZN258+t0r9dv+6aDiIZi
# se826v+dg7qk2zhWUC77gLaTxYxUUP0aJsCd6ma6Wk073Hlro33++lgZe9wFs/Wv
# jyvOi7hdbvNVoYrbmbumwqx4VXFhqeozGkZipsw7q3TE5zhsiKaNjsnMfoReiVe9
# XcgBV1zpyLB10atYXKnA58jzrJrBf1plp9JFlmRRdyPLddK+QAPDdod74OAuVyui
# zZAgxJEOiXpiwUiiR4wt5LIZWBrnHkBIX3n6avnMoPIUfWAHNoz3JB7tnYUeupQP
# 4KFoKDJjqAnD+gnpEkqT5pKu1sVDU5tOhTppB5OGtULEwUToj3c3Twprl6P48u2x
# BPvHdbRNfZSkEEjqOIUAZRzgTBW2vAdq5TJKQA8jAgMBAAGjggHTMIIBzzAMBgNV
# HRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDA6BgNVHSUEMzAxBgorBgEEAYI3YQEA
# BggrBgEFBQcDAwYZKwYBBAGCN2HK9PELgrHSgxH33KNOluu6MTAdBgNVHQ4EFgQU
# iG7CwBXCUdrbg+i9vMzoTbq78g4wHwYDVR0jBBgwFoAUayVB3vtrfP0YgAotf492
# XapzPbgwZwYDVR0fBGAwXjBcoFqgWIZWaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIwQU9D
# JTIwQ0ElMjAwNC5jcmwwdAYIKwYBBQUHAQEEaDBmMGQGCCsGAQUFBzAChlhodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElE
# JTIwVmVyaWZpZWQlMjBDUyUyMEFPQyUyMENBJTIwMDQuY3J0MFQGA1UdIARNMEsw
# SQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wDQYJKoZIhvcNAQEMBQADggIBAKjO
# LANEbvVcXnVYrx4NjQmly/9j4fNQvIBC3OxcnOR2ioVCrTfraGPFcVBYr0yl5G/m
# Aj7anDfPVghMcTfMkqbd+WZ0Rt099iOuyZBELH5T4K2lOPT3fHr/jAPTZnF5x0eo
# eftM2dJldo4n1hauwudmLrC9sv6K95lolW+ZNC19L96/xJBvXHjFQKeLs8XiMOBz
# OCOzT2g0TiUut5I6XbwGDy9Jjr7vh8WRruFTLHFN5RD2+svsFQwUihUdOSNY7iBm
# 4FLVVoRGB6JnbueJJkmLDqfjx9h+FjUoVgRVNLXCmUJDe6PZJKpx4WyAlH2eLjtG
# S/xu/R9eXN/fk5YJl3eNhRMQ05j+7XFk8YpJKAkpX24Zitf8LPDZlIiEbl2RSAom
# 23ib878A+MhkT5zvIFAXQglL4ydbkRDow5BNJYk2QNODgVm5KadMH2kQnZHAVNx+
# d72G1Q5OEdGi1A2D+nhWB36P66FFKUlNvZ5zNdDxewSeWnNczGQoOrxykYckymdh
# w/Po58mkeGeyKxd4ofvkurfhVJocrRg3/ytLk+jXLTXUCy5hgXb9cb7eybhSC7Rt
# v83aXsk5ZpSCKnZ6KNRSJXo6u8UWLPrbqR4M4diIHBv6szF4XYynCiV+vqgYn1tf
# R8PWV/zHIz92zHXqyd0dZVF6numJlaJS7dl7/L0jMIIGwDCCBKigAwIBAgITMwAE
# uNOW2Kr1jp1DbAAAAAS40zANBgkqhkiG9w0BAQwFADBaMQswCQYDVQQGEwJVUzEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSswKQYDVQQDEyJNaWNyb3Nv
# ZnQgSUQgVmVyaWZpZWQgQ1MgQU9DIENBIDA0MB4XDTI2MDgxMjIwMDcwNFoXDTI2
# MDgxNTIwMDcwNFowgYMxCzAJBgNVBAYTAk5MMRYwFAYDVQQIEw1Ob29yZC1CcmFi
# YW50MRIwEAYDVQQHEwlTY2hpam5kZWwxIzAhBgNVBAoTGkpvaG4gQmlsbGVrZW5z
# IENvbnN1bHRhbmN5MSMwIQYDVQQDExpKb2huIEJpbGxla2VucyBDb25zdWx0YW5j
# eTCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAIuehQX8M3+b0ocz4zaQ
# BQ5SMaz/ljcJB5j9Qmu9GVX78vij+/kiYOtRtKAwLONNc70POEkPr6VPPwywgOuj
# KYaE2tJcp8G1MuyOIF/xIvsdT5xWuzvl5ZJAJFP0vAEvPjA+0mTdufPrdK/Xb/um
# g4iGYrHvNur/nYO6pNs4VlAu+4C2k8WMVFD9GibAnepmulpNO9x5a6N9/vpYGXvc
# BbP1r48rzou4XW7zVaGK25m7psKseFVxYanqMxpGYqbMO6t0xOc4bIimjY7JzH6E
# XolXvV3IAVdc6ciwddGrWFypwOfI86yawX9aZafSRZZkUXcjy3XSvkADw3aHe+Dg
# Llcros2QIMSRDol6YsFIokeMLeSyGVga5x5ASF95+mr5zKDyFH1gBzaM9yQe7Z2F
# HrqUD+ChaCgyY6gJw/oJ6RJKk+aSrtbFQ1ObToU6aQeThrVCxMFE6I93N08Ka5ej
# +PLtsQT7x3W0TX2UpBBI6jiFAGUc4EwVtrwHauUySkAPIwIDAQABo4IB0zCCAc8w
# DAYDVR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwOgYDVR0lBDMwMQYKKwYBBAGC
# N2EBAAYIKwYBBQUHAwMGGSsGAQQBgjdhyvTxC4Kx0oMR99yjTpbrujEwHQYDVR0O
# BBYEFIhuwsAVwlHa24PovbzM6E26u/IOMB8GA1UdIwQYMBaAFGslQd77a3z9GIAK
# LX+Pdl2qcz24MGcGA1UdHwRgMF4wXKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUy
# MEFPQyUyMENBJTIwMDQuY3JsMHQGCCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZY
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQl
# MjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBBT0MlMjBDQSUyMDA0LmNydDBUBgNVHSAE
# TTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4IC
# AQCoziwDRG71XF51WK8eDY0Jpcv/Y+HzULyAQtzsXJzkdoqFQq0362hjxXFQWK9M
# peRv5gI+2pw3z1YITHE3zJKm3flmdEbdPfYjrsmQRCx+U+CtpTj093x6/4wD02Zx
# ecdHqHn7TNnSZXaOJ9YWrsLnZi6wvbL+iveZaJVvmTQtfS/ev8SQb1x4xUCni7PF
# 4jDgczgjs09oNE4lLreSOl28Bg8vSY6+74fFka7hUyxxTeUQ9vrL7BUMFIoVHTkj
# WO4gZuBS1VaERgeiZ27niSZJiw6n48fYfhY1KFYEVTS1wplCQ3uj2SSqceFsgJR9
# ni47Rkv8bv0fXlzf35OWCZd3jYUTENOY/u1xZPGKSSgJKV9uGYrX/Czw2ZSIhG5d
# kUgKJtt4m/O/APjIZE+c7yBQF0IJS+MnW5EQ6MOQTSWJNkDTg4FZuSmnTB9pEJ2R
# wFTcfne9htUOThHRotQNg/p4Vgd+j+uhRSlJTb2eczXQ8XsEnlpzXMxkKDq8cpGH
# JMpnYcPz6OfJpHhnsisXeKH75Lq34VSaHK0YN/8rS5Po1y011AsuYYF2/XG+3sm4
# Ugu0bb/N2l7JOWaUgip2eijUUiV6OrvFFiz626keDOHYiBwb+rMxeF2Mpwolfr6o
# GJ9bX0fD1lf8xyM/dsx16sndHWVRep7piZWiUu3Ze/y9IzCCBygwggUQoAMCAQIC
# EzMAAAAWMZKNkgJle5oAAAAAABYwDQYJKoZIhvcNAQEMBQAwYzELMAkGA1UEBhMC
# VVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE0MDIGA1UEAxMrTWlj
# cm9zb2Z0IElEIFZlcmlmaWVkIENvZGUgU2lnbmluZyBQQ0EgMjAyMTAeFw0yNjAz
# MjYxODExMjlaFw0zMTAzMjYxODExMjlaMFoxCzAJBgNVBAYTAlVTMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJRCBW
# ZXJpZmllZCBDUyBBT0MgQ0EgMDQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
# AoICAQDKVfrI2+gJMM/0bQ5OVKNdvOASzLbUUMvXuf+Vl7YGuofPaZHVo3gMHF5i
# nT+GMSpIcfIZ9qtXU1UG68ry8vNbQtOL4Nm30ifXpqI1+ByiAWLO1YT0WnzG7XPO
# uoTeeWsNZv5FmjxCsReBZvyzyzCyXZbu1EQfJxWTH4ebUwtAiW9rqMf9eDj/wYhi
# EfNteJV3ZFeibD2ztCHr9JhFdd97XbnCHgQoTIqc02X5xlRKtUGBa++OtHBBjiJ/
# uwBnzTkqu4FjpZjQeJtrmda+ur1CT2jflWIB/ypn7u7V9tvW9wJbJYt/H2EtJ0GO
# NWxJZ7TEu8jWPindOO3lzPP7UtzS/mVDV94HucWaltmsra6zSG8BoEJ87IM8QSb7
# vfm/O41FhYkUv89WIj5ES2O4kxyiMSfe95CMivCuYrRP2hKvx7egPMrWgDDBkxML
# grKZO9hRNUMm8vk3w5b9SogHOyJVhxyFm8aFXfIxgqDF4S0g4bhbhnzljmSlCLlu
# mMZcXFGDjpF2tNoAu3VGFGYtHtTSNVKvZpgB3b4ynaoDkbPf+Wg4523jt4VneasB
# gZhC1srZI2NCnCBBfgjLq04pqEKAWEohyW2K29KSkkHvt5VaE1ac3Yt+oyiOzMS5
# 7tXwQDJLGvLg/OXFO0VNvczDndfIfXYExB/ab2PuMSwd5VIBOwIDAQABo4IB3DCC
# AdgwDgYDVR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRr
# JUHe+2t8/RiACi1/j3ZdqnM9uDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9z
# aXRvcnkuaHRtMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMBIGA1UdEwEB/wQI
# MAYBAf8CAQAwHwYDVR0jBBgwFoAU2UEpsA8PY2zvadf1zSmepEhqMOYwcAYDVR0f
# BGkwZzBloGOgYYZfaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwv
# TWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENB
# JTIwMjAyMS5jcmwwfQYIKwYBBQUHAQEEcTBvMG0GCCsGAQUFBzAChmFodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIw
# VmVyaWZpZWQlMjBDb2RlJTIwU2lnbmluZyUyMFBDQSUyMDIwMjEuY3J0MA0GCSqG
# SIb3DQEBDAUAA4ICAQAG1VBeVHTVRBljlcZD3IiMxwPyMjQyLNaEnVu5mODm2hRB
# JfH8GsBLATmrHAc8F47jmk5CnpUPiIguCbw6Z/KVj4Dsoiq228NSLMLewFfGMri7
# uwNGLISC5ccp8vUdADDEIsS2dE+QI9OwkDpv3XuUD7d+hAgcLVcMOl1AsfEZtsZe
# nhGvSYUrm/FuLq0BqEGL9GXM5c+Ho9q8o+Vn/S+GWQN2y+gkRO15s0kI05nUpq/d
# OD4ri9rgVs6tipEd0YZqGgD+CZNiaZWrDTOQbNPncd2F9qOsUa20miYruoT5PwJA
# aI+QQiTE2ZJeMJOkOpzhTUgqVMZwZidEUZKCqudaeQA08WwnkQMfKyHzaU8j48UL
# cU4hUwvMsv7fSurOe9GAdRQCPvF8WcSK5oDHe8VVJM4tv6KKCm91HqLx9JamBgRI
# 6R2SfY3nu26EGznu0rCg/769z8xWm4PVcC2ZaL6VlKVqFp1NsN8YqMyf5t+bbGVb
# 09noFKcJG/UwyGlxRmQBlfeBUQx5/ytlzZzsEnhrJF9fTAfje8j3OdX5lEnePTFQ
# LRlvzZFBqUXnIeQKv3fHQjC9m2fo/Z01DII/qp3d8LhGVUW0BCG04fRwHJNH8iqq
# CG/qofMv+kym2AxBDnHzNgRjL60JOFiBgiurvLhYQNhB95KWojFA6shQnggkMTCC
# B54wggWGoAMCAQICEzMAAAAHh6M0o3uljhwAAAAAAAcwDQYJKoZIhvcNAQEMBQAw
# dzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjFI
# MEYGA1UEAxM/TWljcm9zb2Z0IElkZW50aXR5IFZlcmlmaWNhdGlvbiBSb290IENl
# cnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMB4XDTIxMDQwMTIwMDUyMFoXDTM2MDQw
# MTIwMTUyMFowYzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjE0MDIGA1UEAxMrTWljcm9zb2Z0IElEIFZlcmlmaWVkIENvZGUgU2ln
# bmluZyBQQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALLw
# wK8ZiCji3VR6TElsaQhVCbRS/3pK+MHrJSj3Zxd3KU3rlfL3qrZilYKJNqztA9OQ
# acr1AwoNcHbKBLbsQAhBnIB34zxf52bDpIO3NJlfIaTE/xrweLoQ71lzCHkD7A4A
# s1Bs076Iu+mA6cQzsYYH/Cbl1icwQ6C65rU4V9NQhNUwgrx9rGQ//h890Q8JdjLL
# w0nV+ayQ2Fbkd242o9kH82RZsH3HEyqjAB5a8+Ae2nPIPc8sZU6ZE7iRrRZywRmr
# KDp5+TcmJX9MRff241UaOBs4NmHOyke8oU1TYrkxh+YeHgfWo5tTgkoSMoayqoDp
# HOLJs+qG8Tvh8SnifW2Jj3+ii11TS8/FGngEaNAWrbyfNrC69oKpRQXY9bGH6jn9
# NEJv9weFxhTwyvx9OJLXmRGbAUXN1U9nf4lXezky6Uh/cgjkVd6CGUAf0K+Jw+GE
# /5VpIVbcNr9rNE50Sbmy/4RTCEGvOq3GhjITbCa4crCzTTHgYYjHs1NbOc6brH+e
# KpWLtr+bGecy9CrwQyx7S/BfYJ+ozst7+yZtG2wR461uckFu0t+gCwLdN0A6cFtS
# RtR8bvxVFyWwTtgMMFRuBa3vmUOTnfKLsLefRaQcVTgRnzeLzdpt32cdYKp+dhr2
# ogc+qM6K4CBI5/j4VFyC4QFeUP2YAidLtvpXRRo3AgMBAAGjggI1MIICMTAOBgNV
# HQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNlBKbAPD2Ns
# 72nX9c0pnqRIajDmMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNo
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5o
# dG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAf
# BgNVHSMEGDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHeg
# dYZzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0
# JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUl
# MjBBdXRob3JpdHklMjAyMDIwLmNybDCBwwYIKwYBBQUHAQEEgbYwgbMwgYEGCCsG
# AQUFBzAChnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p
# Y3Jvc29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRp
# ZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwLQYIKwYBBQUHMAGGIWh0dHA6
# Ly9vbmVvY3NwLm1pY3Jvc29mdC5jb20vb2NzcDANBgkqhkiG9w0BAQwFAAOCAgEA
# fyUqnv7Uq+rdZgrbVyNMul5skONbhls5fccPlmIbzi+OwVdPQ4H55v7VOInnmezQ
# EeW4LqK0wja+fBznANbXLB0KrdMCbHQpbLvG6UA/Xv2pfpVIE1CRFfNF4XKO8XYE
# a3oW8oVH+KZHgIQRIwAbyFKQ9iyj4aOWeAzwk+f9E5StNp5T8FG7/VEURIVWArbA
# zPt9ThVN3w1fAZkF7+YU9kbq1bCR2YD+MtunSQ1Rft6XG7b4e0ejRA7mB2IoX5hN
# h3UEauY0byxNRG+fT2MCEhQl9g2i2fs6VOG19CNep7SquKaBjhWmirYyANb0RJSL
# WjinMLXNOAga10n8i9jqeprzSMU5ODmrMCJE12xS/NWShg/tuLjAsKP6SzYZ+1Ry
# 358ZTFcx0FS/mx2vSoU8s8HRvy+rnXqyUJ9HBqS0DErVLjQwK8VtsBdekBmdTbQV
# oCgPCqr+PDPB3xajYnzevs7eidBsM71PINK2BoE2UfMwxCCX3mccFgx6UsQeRSdV
# VVNSyALQe6PT12418xon2iDGE81OGCreLzDcMAZnrUAx4XQLUz6ZTl65yPUiOh3k
# 7Yww94lDf+8oG2oZmDh5O1Qe38E+M3vhKwmzIeoB1dVLlz4i3IpaDcR+iuGjH2Td
# aC1ZOmBXiCRKJLj4DT2uhJ04ji+tHD6n58vhavFIrmcxghcyMIIXLgIBATBxMFox
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzAp
# BgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQCEzMABLjT
# ltiq9Y6dQ2wAAAAEuNMwDQYJYIZIAWUDBAIBBQCgXjAQBgorBgEEAYI3AgEMMQIw
# ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAvBgkqhkiG9w0BCQQxIgQggMr7
# TeI2wOOTGhbi86cyUs5uNB/0LnEiXRnSbv9CDscwDQYJKoZIhvcNAQEBBQAEggGA
# JN9kh7T1AF9nAVXnGL9MPBWEojHZZvcV8hQ+7zqOIyNehW/wS/UeIOeWczHPv5kV
# pDr2Z3Mp4MrqvoJw8ylSRqafiaOl/PeA/DOydpaTYScrjeKHzpaqSRXAwounVkdU
# iLGrsZPIDhkDScHGN9HWInLkM1LlMB1fAVEUmdip0zccYAcXCKTXz0b7TtUtULx/
# uCDGOKcAgkxhQmE+EO8irV9mTrU5JgWuy0XD7bR3YulMHJFAY6LmEuxVRc5d3+Pf
# GbD1KyxLwAyvBBIgar0wA3fbprBpAuBmHUQSUSKH8gOEzdhvkOw7lfrbHvJ4bPaw
# DXXKifqplcDbSPK5ZapDFKUH/bIyZN9axnEyBWY9NahHSIH7YXKd6VClKHL2Hm6I
# lfyV7W/92ZKwhGKGsHJl0UKygsnCKil8ngQsmUCyWuHq3CmbV+InwCcnp0slKQPl
# m+KV2xv02Vv/5ooBxH5T7KRhgJDk3VSJMDyugZtsGrtcF0DocxNezOz3uRIR+6ly
# oYIUsjCCFK4GCisGAQQBgjcDAwExghSeMIIUmgYJKoZIhvcNAQcCoIIUizCCFIcC
# AQMxDzANBglghkgBZQMEAgEFADCCAWoGCyqGSIb3DQEJEAEEoIIBWQSCAVUwggFR
# AgEBBgorBgEEAYRZCgMBMDEwDQYJYIZIAWUDBAIBBQAEIP+Ew/WJyAqA7+bD7c8y
# 7MdVGJoMQMZ3sQBV1RkptSmwAgZqNTB/BuwYEzIwMjYwODE0MTU0MzM1LjIyM1ow
# BIACAfSggemkgeYwgeMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
# MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
# b24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRl
# ZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjQ5MUEtMDVFMC1EOTQ3MTUwMwYD
# VQQDEyxNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0
# eaCCDykwggeCMIIFaqADAgECAhMzAAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3
# DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24g
# Um9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFa
# Fw0zNTExMTkyMDQyMzFaMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRp
# bWVzdGFtcGluZyBDQSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
# AgEAnnznUmP94MWfBX1jtQYioxwe1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIc
# aqDb+omFio5DHC4RBcbyQHjXCwMk/l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49RE
# Af5huXhIkQRKe3Qxs8Sgp02KHAznEa/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1W
# a1wISvlkpOQooTULFm809Z0ZYlQ8Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMo
# pNq/B8U/pdoZkZZQbxNlqJOiBGgCWpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0k
# N0nh7SqINGbmw5OIRC0EsZ31WF3Uxp3GgZwetEKxLms73KG/Z+MkeuaVDQQheang
# OEMGJ4pQZH55ngI0Tdy1bi69INBV5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9N
# V/uC3yFjrhc087qLJQawSC3xzY/EXzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTk
# mG1hSuWYBunFGNv21Kt4N20AKmbeuSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/j
# R7wo3liwkGdzPJYHgnJ54UxbckF914AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE6
# 7SFZ2PMo27xjlLAHWW3l1CEAFjLNHd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIX
# MA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2ko
# OjUvSGNAz3vYr0npPtk92yEwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUH
# AgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0
# b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMA
# dQBiAEMAQTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgE
# ByfPUBBPaKiiMIGEBgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29m
# dC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNh
# dGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3Js
# MIGUBggrBgEFBQcBAQSBhzCBhDCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWlj
# cm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBW
# ZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAy
# MDIwLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJkl
# FaW4sTQ5r+k77iB79cSLNe+GzRjv4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi
# +LCmcrdovkl53DNt4EXs87KDogYb9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71Qj
# D4h+8z2XMOZzY7YQ0Psw+etyNZ1CesufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9
# xw6JCWONNboZ497mwYW5EfN0W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9
# cLWMq7eb0oYioXhqV2tgFqbKHeDick+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3
# SLv10o4KGag42pswjybTi4toQcC/irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsu
# kxD+7jFfEV9Hh/+CSxKRsmnuiovCWIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxT
# k4MhF/KgaXn0GxdH8elEa2Imq45gaa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81co
# E6aQWm88TwIf4R4YZbOpMKN0CyejaPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tj
# uOOCztfp+o9Nc+ZoIAkpUcA/X2gSMkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+
# JYbYbBh7pmgAXVswggefMIIFh6ADAgECAhMzAAAAWvYNZ4yF7d0IAAAAAABaMA0G
# CSqGSIb3DQEBDAUAMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVz
# dGFtcGluZyBDQSAyMDIwMB4XDTI2MDEwODE4NTkwM1oXDTI3MDEwNzE4NTkwM1ow
# geMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsT
# JE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMe
# blNoaWVsZCBUU1MgRVNOOjQ5MUEtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3Nv
# ZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eTCCAiIwDQYJKoZI
# hvcNAQEBBQADggIPADCCAgoCggIBAO/0O0eWjgUb9rnHcQLRdfWPN4H+91a3Ynla
# P46E1m4uD+JKx6csWMStX79fxLJUAqHJqQWE19UlNMhS9jEB32dAJ4yuWsHyUuM+
# dphjDz4E5jl4gYGZEmaOrKvNt+KqlFayyg/oTg3BlLRu4aBq8668A5qlHcfsuh6D
# dSqFID1ixJFZzHrZFG1iGBG7U1Bn2ONLDo7jbwX5rMcPduTAUw/c7M3WhSxQBuZp
# Qiz8RQGKIqCKfIxgQkKdzpCpU0SWQOE/DgTXbz3c15KMRCdkGlL2zb+lnuSV4sse
# Qm3qflZiZckLyn2xJI8ZXDkq+Ig+b/rsPPIfI8di228WvK1j67JXpyeVCaSUO9Er
# zlLnTrnjQkeXVQIp73xuVBVrmvoTf/v4a7MnrmuKSyIXc5vJUHEGB345+O8omFt1
# w8b+Xg9D9PKIRqDPEv7HRk0C+Yvxu8FvHJvSocSIZK+v/FmKFOipYnpP76yAmJNn
# yheucShOgk8QiU53USn/+AyMb7xW905gZnyNqb29HeVdQ175pDHJGEz8Cx5wiHeV
# liGz5hABucFDylR9z3LSTmB6+3ZuIxeG9BZS46P6ANPkuVuD5m8wgc7GLLzg73Cs
# DF09ukt8Uf8dTcMBX3ro+7/k9M6Xt8WPG7IL9v/4DvyMY03tkb9Y9Ri6HWavXRPY
# RCUePspPAgMBAAGjggHLMIIBxzAdBgNVHQ4EFgQUjmOyQ6twMcP1ZbRytJxI4fnX
# mcIwHwYDVR0jBBgwFoAUa2koOjUvSGNAz3vYr0npPtk92yEwbAYDVR0fBGUwYzBh
# oF+gXYZbaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9z
# b2Z0JTIwUHVibGljJTIwUlNBJTIwVGltZXN0YW1waW5nJTIwQ0ElMjAyMDIwLmNy
# bDB5BggrBgEFBQcBAQRtMGswaQYIKwYBBQUHMAKGXWh0dHA6Ly93d3cubWljcm9z
# b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwUHVibGljJTIwUlNBJTIw
# VGltZXN0YW1waW5nJTIwQ0ElMjAyMDIwLmNydDAMBgNVHRMBAf8EAjAAMBYGA1Ud
# JQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDBmBgNVHSAEXzBdMFEG
# DCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29m
# dC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wCAYGZ4EMAQQCMA0GCSqG
# SIb3DQEBDAUAA4ICAQCAlM8r+t3hIb2h1lDTAx+iYkQlxFuU7QONeyIFIBZ29xvG
# l8pehKxErDzIniOpIX/eluUAwQKoaI0zwuKAdR0mrSHXCniMoLNko5W+5r7sXNam
# KX7QMV3BfGOX3gi9qVfxyUe7AHXbqQ8KBQHNYCnNFtQQHgARrlYhtyAKol5ctM0C
# Ac/y3oY7bTMsVJvnA5u7DVWPeXoST2KEMDeLBvJYq0IJZ6yMpDOWLZ4UP82bksyS
# hIB/XdawirIGLdseudryRxVMk313mAcjGRb59+Ittt6otVvYQWqH+PGrTUzEcez8
# aQuO3umoNZjKuFoX5VsPP/gSZse+orhG3zfZk9IDyE3DfUFrhvkv6H0tijK1D0uI
# GhwMBWSm9ktQ6oeU+aurZFx3MI+LODnHsbRFZAy11uMvwKq+ZNC1Se4tIM1u9piW
# AhnTPoh6mULKikHOVhHaO953tkzDCtjsse5GUKOx9yg9nqHKWMgnODp62/uPPzC/
# yDEISrXCcU7UB7tATr3zWNEdtM4d009iXWI6dV/SdcIIX44rpoLyCLw+nXjxp+fY
# /dygLO7UdSQaVaUFVj3K2nVyuujPspt5Lunc5FvuYPqmi/z8kASmmwbiF+W0P0UT
# WFaC84MWfU2h6MDg5s0oxmdNFK76jXr3wZfdSoV7FCKfq5GdeGoy5UwDQwMC0DGC
# A9QwggPQAgEBMHgwYTELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZXN0
# YW1waW5nIENBIDIwMjACEzMAAABa9g1njIXt3QgAAAAAAFowDQYJYIZIAWUDBAIB
# BQCgggEtMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQx
# IgQgUq30TxeJMWEbE0cL6ZwAnxvbn+ROk64FoMkl7f97/cUwgd0GCyqGSIb3DQEJ
# EAIvMYHNMIHKMIHHMIGgBCBiuWRAi+p96PRsBt3TwW3jNozgPQS+Qco1CVm/NaU0
# QzB8MGWkYzBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBp
# bmcgQ0EgMjAyMAITMwAAAFr2DWeMhe3dCAAAAAAAWjAiBCBZpUyQOVsWq4KUwKfM
# 3TKYU5v1wAVksV44QW5LY9OsrTANBgkqhkiG9w0BAQsFAASCAgBY2IKRPGCRrh7K
# 2isoZc/lZQBZmGychGlN7QKirq/zFZcsmEXL5gnrNOx2lQ4U63BgP1GezKzWdfs6
# QA3BxlKm3gNXwM2Iw0rfBbgyRsW2TwAPp1e/9p9igvnsGB/rxcuIrtAQd0OQmRag
# Smk6wOPIIc/fsBEkLYurgpQD4Wn8bgvhoKhRur5H+I+PGGArSB+Kz7mo1gaXGtq4
# XFmlL52dSLF65kjqdLQ/SWGbXkBMvsDo10N5Xa28c2V4WXH7UCANYqUbxKdQAG5A
# 6gyM302SbMxdLqxWN6GRn8kcCmJyLk1GYRUjN7lVLX5VGzIRWwHQnZGmaYElAOiR
# s7UUgEMhi4Vxu7WiWLGokVRMJRgj7Vgbp7y7xdFaI1VonugZwPm6s+St7aMuZzk5
# 5vlvlGhTSjm645Xj8tEYBHfZAkhGFgtgNsWlp+3rd2sJ5+IGD1vDPaIoFSvfQBZe
# WhUyV7H2wqXtUxkk4V+31LRcj0HXxPbsWvzAPjd8jYgNnjUm+oOxtsXUpMWEfo+H
# aLYvpY1Ve9/NA+dFWgnyQVFqAr6Uke4n0udBVfKof7gt8O+20JXgK+QmBP3c8qcV
# VkSiLmfZTiQRstzwOXDBSdfv6RT6cjNoDmStm/LvCK6P2lKep/HceUa6LE0cirjr
# 9NdcZ44fDvaFggyr3HdXH5CasqeWgQ==
# SIG # End signature block