DSInternals.Bootstrap.psm1

#
# Script module file for the 'DSInternals' module.
#
# Copyright (c) Michael Grafnetter
#

#
# Check if the current OS is Windows.
#

if ($env:OS -ne 'Windows_NT')
{
    Write-Error -Message 'The DSInternals PowerShell module is only supported on Windows.' `
                -Category ([System.Management.Automation.ErrorCategory]::NotImplemented)
}

#
# Load the platform-specific libraries.
# Note: This operation cannot be done in the module manifest,
# as it only supports restricted language mode.
#

# Default to PowerShell 5.1 Desktop and earlier
[string] $basePath = Join-Path -Path $PSScriptRoot -ChildPath 'net48'

if ($PSVersionTable.PSVersion.Major -ge 6) {
    # PowerShell Core
    $basePath = Join-Path -Path $PSScriptRoot -ChildPath 'net8.0-windows'
}

# Import the main module file.
[string] $modulePath = Join-Path -Path $basePath -ChildPath 'DSInternals.PowerShell.dll'
Import-Module -Name $modulePath -ErrorAction Stop

[string] $architectureSpecificPath = Join-Path -Path $basePath -ChildPath $env:PROCESSOR_ARCHITECTURE

# Try to locate the interop assembly for the current architecture.
[string] $interopAssemblyName = 'DSInternals.Replication.Interop.dll'
[string] $interopAssemblyPath = Join-Path -Path $architectureSpecificPath -ChildPath $interopAssemblyName

if(-not (Test-Path -Path $interopAssemblyPath -PathType Leaf))
{
    # Fallback to the parent directory
    $interopAssemblyPath = Join-Path -Path $basePath -ChildPath $interopAssemblyName
}

try
{
    Add-Type -Path $interopAssemblyPath -ErrorAction Stop
}
catch [System.IO.IOException]
{
    #
    # Make the error message more meaningful by checking common failure reasons.
    #

    [string] $message = 'The Get-ADRepl* cmdlets will not work properly, because the "{0}" assembly could not be loaded.' -f $interopAssemblyPath
    [System.Management.Automation.ErrorCategory] $errorCategory = [System.Management.Automation.ErrorCategory]::OpenError

    # Check the presence of the Universal C Runtime
    [string] $ucrtPath = Join-Path ([System.Environment]::SystemDirectory) 'ucrtbase.dll'
    [bool] $ucrtPresent = Test-Path -Path $ucrtPath

    if(-not $ucrtPresent)
    {
        # This can happen on systems prior to Windows 10 with missing updates.
        $message += ' The Universal C Runtime is missing. Run Windows Update or install it manually and reload the DSInternals module afterwards.'
        $errorCategory = [System.Management.Automation.ErrorCategory]::NotInstalled
    }

    # Check if the interop assembly is blocked
    [object] $zoneIdentifier = Get-Item -Path $interopAssemblyPath -Stream 'Zone.Identifier' -ErrorAction SilentlyContinue

    if($null -ne $zoneIdentifier)
    {
        # This usually happens to users of the ZIP distribution who forget to unblock it before extracting the files.
        $message += ' Unblock the assembly using either the Properties dialog or the Unblock-File cmdlet and reload the DSInternals module afterwards.'
        $errorCategory = [System.Management.Automation.ErrorCategory]::SecurityError
    }

    # Build the error report
    Write-Error -Message $message `
                -Exception $PSItem.Exception `
                -Category $errorCategory `
                -CategoryTargetName $interopAssemblyPath `
                -CategoryActivity $PSItem.CategoryInfo.Activity `
                -CategoryReason $PSItem.CategoryInfo.Reason
}

#
# Check if the MD5 hash function is available.
#

if([System.Security.Cryptography.CryptoConfig]::AllowOnlyFipsAlgorithms)
{
    [string] $message = 'Only FIPS certified cryptographic algorithms are enabled in .NET. DSInternals cmdlets that require the MD5 hash function will not work as expected.'
    [string] $configPath = [System.Diagnostics.Process]::GetCurrentProcess().Path + '.config'
    [string] $recommendedAction = 'Add the <enforceFIPSPolicy enabled="false"/> directive to the "{0}" file.' -f $configPath

    Write-Error -Message $message `
                -RecommendedAction $recommendedAction `
                -Category ([System.Management.Automation.ErrorCategory]::SecurityError)
}

#
# Type Data
# Note: *.types.ps1xml cannot be processed before the platform-specific assemblies are loaded.
#

[string] $typesFilePath = Join-Path -Path $PSScriptRoot -ChildPath 'DSInternals.types.ps1xml'

Update-TypeData -PrependPath $typesFilePath

#
# Cmdlet aliases
#

New-Alias -Name Set-ADAccountPasswordHash              -Value Set-SamAccountPasswordHash
New-Alias -Name Set-WinUserPasswordHash                -Value Set-SamAccountPasswordHash
New-Alias -Name Get-ADPasswordPolicy                   -Value Get-SamPasswordPolicy
New-Alias -Name Get-ADDefaultPasswordPolicy            -Value Get-SamPasswordPolicy
New-Alias -Name ConvertFrom-UnattendXmlPassword        -Value ConvertFrom-UnicodePassword
New-Alias -Name ConvertTo-AADHash                      -Value ConvertTo-OrgIdHash
New-Alias -Name ConvertTo-MsoPasswordHash              -Value ConvertTo-OrgIdHash
New-Alias -Name Get-ADReplicationAccount               -Value Get-ADReplAccount
New-Alias -Name ConvertFrom-ManagedPasswordBlob        -Value ConvertFrom-ADManagedPasswordBlob
New-Alias -Name Get-SysKey                             -Value Get-BootKey
New-Alias -Name Get-SystemKey                          -Value Get-BootKey
New-Alias -Name Set-ADDBSysKey                         -Value Set-ADDBBootKey
New-Alias -Name Test-ADPasswordQuality                 -Value Test-PasswordQuality
New-Alias -Name Test-ADDBPasswordQuality               -Value Test-PasswordQuality
New-Alias -Name Test-ADReplPasswordQuality             -Value Test-PasswordQuality
New-Alias -Name Get-KeyCredential                      -Value Get-ADKeyCredential
New-Alias -Name Get-KeyCredentialLink                  -Value Get-ADKeyCredential
New-Alias -Name Get-ADKeyCredentialLink                -Value Get-ADKeyCredential
New-Alias -Name New-ADKeyCredential                    -Value Get-ADKeyCredential
New-Alias -Name New-ADKeyCredentialLink                -Value Get-ADKeyCredential
New-Alias -Name New-ADNgcKey                           -Value Get-ADKeyCredential
New-Alias -Name Get-LsaPolicy                          -Value Get-LsaPolicyInformation
New-Alias -Name Set-LsaPolicy                          -Value Set-LsaPolicyInformation
New-Alias -Name Write-ADReplNgcKey                     -Value Add-ADReplNgcKey
New-Alias -Name Write-ADNgcKey                         -Value Add-ADReplNgcKey
New-Alias -Name Add-ADNgcKey                           -Value Add-ADReplNgcKey
New-Alias -Name Get-ADDBGroupManagedServiceAccount     -Value Get-ADDBServiceAccount
New-Alias -Name Get-ADDBDelegatedManagedServiceAccount -Value Get-ADDBServiceAccount
New-Alias -Name Get-ADDBBitLockerRecoveryInfo          -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBBitLockerRecoveryKey           -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBBitLockerKey                   -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBBitLockerKeyProtector          -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBBitLockerRecoveryPassword      -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBFVERecoveryInformation         -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBFVERecoveryInfo                -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBFVERecoveryKey                 -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBFVERecoveryPassword            -Value Get-ADDBBitLockerRecoveryInformation
New-Alias -Name Get-ADDBDnsRecord                      -Value Get-ADDBDnsResourceRecord

# Export the aliases
Export-ModuleMember -Alias * -Cmdlet *

# SIG # Begin signature block
# MIIt6AYJKoZIhvcNAQcCoIIt2TCCLdUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCFLcmQ3HvMb6c+
# /Hc3yDq3OyQggQ8iwIcsfhDX/h6v8qCCEg8wggV4MIIDYKADAgECAhBLLDsBAYut
# KryMe1s+7ZBXMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQK
# Ew9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENvZGUg
# U2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw00NjAzMjEyMzU5NTla
# MFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNV
# BAMTJFNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBSb290IFI0NjCCAiIwDQYJ
# KoZIhvcNAQEBBQADggIPADCCAgoCggIBAI3nlBIiBCR0Lv8WIwKSirauNoWsR9Qj
# kSs+3H3iMaBRb6yEkeNSirXilt7Qh2MkiYr/7xKTO327toq9vQV/J5trZdOlDGmx
# vEk5mvFtbqrkoIMn2poNK1DpS1uzuGQ2pH5KPalxq2Gzc7M8Cwzv2zNX5b40N+OX
# G139HxI9ggN25vs/ZtKUMWn6bbM0rMF6eNySUPJkx6otBKvDaurgL6en3G7X6P/a
# IatAv7nuDZ7G2Z6Z78beH6kMdrMnIKHWuv2A5wHS7+uCKZVwjf+7Fc/+0Q82oi5P
# MpB0RmtHNRN3BTNPYy64LeG/ZacEaxjYcfrMCPJtiZkQsa3bPizkqhiwxgcBdWfe
# beljYx42f2mJvqpFPm5aX4+hW8udMIYw6AOzQMYNDzjNZ6hTiPq4MGX6b8fnHbGD
# dGk+rMRoO7HmZzOatgjggAVIQO72gmRGqPVzsAaV8mxln79VWxycVxrHeEZ8cKqU
# G4IXrIfptskOgRxA1hYXKfxcnBgr6kX1773VZ08oXgXukEx658b00Pz6zT4yRhMg
# NooE6reqB0acDZM6CWaZWFwpo7kMpjA4PNBGNjV8nLruw9X5Cnb6fgUbQMqSNenV
# etG1fwCuqZCqxX8BnBCxFvzMbhjcb2L+plCnuHu4nRU//iAMdcgiWhOVGZAA6RrV
# wobx447sX/TlAgMBAAGjQjBAMB0GA1UdDgQWBBQy65Ka/zWWSC8oQEJwIDaRXBeF
# 5jAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zANBgkqhkiG9w0BAQwF
# AAOCAgEAdmXC49ciStcdiV7/aV7GFAJNc6bNzSjKsDfqv6fJIaqqX9q/9oNs0IDR
# ClwApMvzzDkPnkFxiNU86Ip7jBcj98o0dJFsBq5QPwBZsiY8PBeDVwM+LdEaPdTP
# B1SyQwtScqiI9cQX8m/RWKXRaOQ9mAgY7jb0SEia+lRw8IjUcBYwQknQ2T91S0Vx
# 2K6iu2EOiIVQV7m6ESs2KR+PIHKeXJ6J0YLaRY1qmdqEcWszpRC7efCX9nSBoD9X
# x4aMMIwOOJWuAcYeq9yoH28v1/92Hq4Xc23luXWzYQaolTPCTm+yN/KVvoVUErnI
# vWJCdvcq/PU3MQMmV/7R5tvwFgJyg4wIs4SsqeQH+KGIxBNaUEdUQqbt0EE0LJix
# PqI0oQxdvaz3f3mnv20MVjKFG0uXuOGs5KQ8cfGj4U5j1vRGuvULCOFjPO2iWS8K
# 1CxrI6KeoU3u0RLNGDNQ7UFuy389QWALYwt49XXvQxW3NgsQr9xcGKmY2TbZHdiE
# swaKguN7GySnQs7uDz5WXDJ97EveVis7O7r5eljQUbZs1vZYolIkekSGoRxgP0nT
# /Pr5hBwFwjS/4ubxGSqZL1ZXNZy19QfDRi/eOD0ZDfuj8d8Tnuepclgxr73q2tfW
# bXczM470rP3Bv0mH0nAFZ3QGpvZ4QC0WBJEPH9MWxLh6Fw0kybIwggYaMIIEAqAD
# AgECAhBiHW0MUgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYT
# AkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28g
# UHVibGljIENvZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0z
# NjAzMjEyMzU5NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExp
# bWl0ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBS
# MzYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rA
# z/V/9shTUxjIztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZ
# hXkZ6Pg2A2NVDgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbi
# MXhSOtbam+/36F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPb
# PuYkRdkP05ZwmRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZ
# YAENHNX9SJDm+qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq
# 4TpxtwfvjsUedyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3F
# pOFMbmPj8pz44MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uM
# SWymR8r2oQBMdlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFg
# MB8GA1UdIwQYMBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssg
# hyi47G9IritUpimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB
# /wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYG
# Z4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20v
# U2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEE
# bzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29Q
# dWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8v
# b2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUg
# mxP/BP6YdURhw1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AK
# K+cMcXIBD0ZdOaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hps
# aqBBIZOtBajjcw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2A
# mtsbpVn0OhNcWbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Ml
# izg0bUMbOalOhOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7
# VLwELKxAMcJszkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEote
# SiabkPVSZ2z76mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1
# L90Y1KWN/Y5JKdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQd
# ULUvrxjUYbHHj95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698Y
# ADR7TNx8X8z2Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hl
# cPmVoa1oDE5/L9Uo2bC5a4CH2RwwggZxMIIE2aADAgECAhBsg5osz2x/Auy2idY5
# 0JFYMA0GCSqGSIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0
# aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmlu
# ZyBDQSBSMzYwHhcNMjIxMTA0MDAwMDAwWhcNMjUxMTAzMjM1OTU5WjBnMQswCQYD
# VQQGEwJDWjEeMBwGA1UECAwVUHJhaGEsIEhsYXZuw60gbcSbc3RvMRswGQYDVQQK
# DBJNaWNoYWVsIEdyYWZuZXR0ZXIxGzAZBgNVBAMMEk1pY2hhZWwgR3JhZm5ldHRl
# cjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMHVk5c8z27bjQ82tQNj
# cU+ilNAnWJwrb0Pa2Z643b7M+wAKi1DhCsavzRWwPYGKKpPLuSWTipw5P7Tag7i9
# H580wR+mxr1jX8Kd7Qr1Eyt3QRsqXLDAwj67ExDrzcOFcIkSK3UKgZFQL+rFy2HB
# quQsHaGQQ8Jm2sWjGZod88/cmxOGUO0w7qvsysmY0QzzRNbUPpeJMPyzuq8zo2+P
# JYP6qQS535bVGaOaCRcXz3XtpvJt8BMVOUVSjb7cEwfBgDoOL72EP6lqJrMV42TI
# VpjR/rB/zT849lJtkvyAEfEr6UiOAiH9o5hm+GahTqPNMAPovb8hDPQRdu2QUpLg
# W+KHicuQWwoFABqsMIF7Oo00xDuD+J52VU12LwobKINFDJB3BdU3L2aYQRFt3YJQ
# gwH50gh1yNqaTcd78CNb2A5VwNvzTCZ0vhBaKdCK/BsLsu9atLld6FwBI8Pak6iA
# NXuFY0W/whPwlVYzMeTdELzr/m53Fk8DQFcd48SvaYt4dbgU3Q3ySbDDnnBgn/TB
# 5E+DRg7+tZgMH4ep8XXL8F/0gmIvhFXNJGXX9f8A2ox7G7Drj2Guf34P1UKZYjs7
# D2aJ71aPtZKPmXOPpTacuhNhdSVLX4ciwJOaRcZOt9pg2lwzjQVa5kw/GOs5Epeb
# OtHry/SsgiDBiCXVxXxxE9E3AgMBAAGjggGqMIIBpjAfBgNVHSMEGDAWgBQPKssg
# hyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQUnRBKK1Ym2UQhxb0SetlSGK5huJMw
# DgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUH
# AwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAjBggrBgEFBQcCARYXaHR0
# cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkGA1UdHwRCMEAwPqA8oDqG
# OGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5n
# Q0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEFBQcwAoY4aHR0cDovL2Ny
# dC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNpZ25pbmdDQVIzNi5jcnQw
# IwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMB8GA1UdEQQYMBaB
# FGluZm9AZHNpbnRlcm5hbHMuY29tMA0GCSqGSIb3DQEBDAUAA4IBgQAuRlAwdZ32
# WVvW4tsRBmmPtse5BOqYjCP4OkxCYn47Sc+zajMgqDj8M5kGSx6SYexUbBcVssAu
# pkpIW7YDGRDo4mGJWY6zFqTXLthtRL14TfiFTTwtpLLSWsRkHbwCbRXbhchpH3nA
# pPshTMvd49gKKRT+AtDr5RrPVnh1LMYZdwuvQpWhkPgT/P0OYKTYtiieW5hSebdl
# /IaGVx1KJi/FrC9MaXj72nvjAaCk5drri7QSsf8R+ghRy5mUJShX11L1nJrGW80s
# hjaRBroT7ktr3WKryuc1cHvkXkKWZq78JosUWfGOtSQ0TJ9AiT+wBAbqtyv1H2X7
# wYNrrcq5cT543yO+SVhiuH+OQZZFjkYdhG5OoZgzABz/mXeHY4VnJHY+SuHJV3oy
# kb4NajXiID4+iy3bgQOdghwMARNUMwsdYlpXqw13iD/Li4B4weFq8d/1ZEa1BFtV
# DALXqV5+ZB4FJ/8CmonbGFIeHZfjj2PhcPL5rgGeMnFOwBjpZyvW4FUxghsvMIIb
# KwIBATBoMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQx
# KzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYCEGyD
# mizPbH8C7LaJ1jnQkVgwDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEK
# MAigAoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3
# AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgQ0inZtk8SxGGw2kz
# d5WuASp7FebF7rMLqw5IWoKDYuUwDQYJKoZIhvcNAQEBBQAEggIAkDNB1yh3UsSd
# LodyerrJWGOZap+bd/WcDZRUa8YS2tXCUT3OrNYXBPIjCeebEP0Qv/Cb5XYaV8l+
# /GAbDDw0RljXbtQqjTrN9nKC8rnKp+VqBT3QdTl/qAl7warFhF3FjEeGw/DpWsWU
# rm66Ledr3PfYQflfSSIoO48Sf3sNv+RY5fWKvisRb+b9vn7MZZAgwqAqF3uCxBZV
# HLxhQVv6AzmB+zid4u/wJpPcCgF/zjGW1vkmRYi/CUFLUWailXZfmWHPGtIVmBIn
# VA39rvpoG/Rz9EfYndMIrl8oFpmCUnSTjpXIsUjJEuklGu/bcA+iwr66IDioTQwV
# 1UEclrhP3FcyJXNNcQzhpyXIIQ9hL6WvRpbsPzLFEJYB5ty/9oXcDIGCRSz4OJ8Y
# P/V461h/wn+WMrLVnQvx/B3BqKqnKO7Vo2CufrDDTnwaGSpqcRy7CAix73AORHzG
# f92i3MuIc8N54QpioN261TCw1+m7BAWF852Fe9yKWupxpEyijvPfgUgxticqr2e0
# R0zEz8+7Z8iFm3hXYL0g1mvMDzFS8zHKxy2ey8Hn9DrTkDUDWKgZw0ASfA4lmZ6n
# 5T2bVkryz804336wwCYno2Nq0J+AlyHdJ43IP4eiNzyBUTZLOcTowPRalohttSxI
# //d7TI8/X8eBAs1rFkMm6/6AVEJthFmhghgRMIIYDQYKKwYBBAGCNwMDATGCF/0w
# ghf5BgkqhkiG9w0BBwKgghfqMIIX5gIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBYgYL
# KoZIhvcNAQkQAQSgggFRBIIBTTCCAUkCAQEGCisGAQQBhFkKAwEwMTANBglghkgB
# ZQMEAgEFAAQgcxLqUl8s1cd6ttEbXOz7rLBUlko56ftzjhShS0Qw8RsCBmibuI6C
# ghgTMjAyNTA4MTQwOTA1MjEuMTE3WjAEgAIB9KCB4aSB3jCB2zELMAkGA1UEBhMC
# VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFt
# ZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjdBMDAt
# MDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lIFN0
# YW1waW5nIEF1dGhvcml0eaCCDyEwggeCMIIFaqADAgECAhMzAAAABeXPD/9mLsmH
# AAAAAAAFMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVudGl0
# eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAe
# Fw0yMDExMTkyMDMyMzFaFw0zNTExMTkyMDQyMzFaMGExCzAJBgNVBAYTAlVTMR4w
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29m
# dCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMIICIjANBgkqhkiG9w0B
# AQEFAAOCAg8AMIICCgKCAgEAnnznUmP94MWfBX1jtQYioxwe1+eXM9ETBb1lRkd3
# kcFdcG9/sqtDlwxKoVIcaqDb+omFio5DHC4RBcbyQHjXCwMk/l3TOYtgoBjxnG/e
# ViS4sOx8y4gSq8Zg49REAf5huXhIkQRKe3Qxs8Sgp02KHAznEa/Ssah8nWo5hJM1
# xznkRsFPu6rfDHeZeG1Wa1wISvlkpOQooTULFm809Z0ZYlQ8Lp7i5F9YciFlyAKw
# n6yjN/kR4fkquUWfGmMopNq/B8U/pdoZkZZQbxNlqJOiBGgCWpx69uKqKhTPVi3g
# VErnc/qi+dR8A2MiAz0kN0nh7SqINGbmw5OIRC0EsZ31WF3Uxp3GgZwetEKxLms7
# 3KG/Z+MkeuaVDQQheangOEMGJ4pQZH55ngI0Tdy1bi69INBV5Kn2HVJo9XxRYR/J
# PGAaM6xGl57Ei95HUw9NV/uC3yFjrhc087qLJQawSC3xzY/EXzsT4I7sDbxOmM2r
# l4uKK6eEpurRduOQ2hTkmG1hSuWYBunFGNv21Kt4N20AKmbeuSnGnsBCd2cjRKG7
# 9+TX+sTehawOoxfeOO/jR7wo3liwkGdzPJYHgnJ54UxbckF914AqHOiEV7xTnD1a
# 69w/UTxwjEugpIPMIIE67SFZ2PMo27xjlLAHWW3l1CEAFjLNHd3EQ79PUr8FUXet
# Xr0CAwEAAaOCAhswggIXMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIB
# ADAdBgNVHQ4EFgQUa2koOjUvSGNAz3vYr0npPtk92yEwVAYDVR0gBE0wSzBJBgRV
# HSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lv
# cHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkr
# BgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQY
# MBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGEBgNVHR8EfTB7MHmgd6B1hnNodHRw
# Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJZGVu
# dGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUyMEF1dGhv
# cml0eSUyMDIwMjAuY3JsMIGUBggrBgEFBQcBAQSBhzCBhDCBgQYIKwYBBQUHMAKG
# dWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0
# JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUl
# MjBBdXRob3JpdHklMjAyMDIwLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAX4h2x35t
# tVoVdedMeGj6TuHYRJklFaW4sTQ5r+k77iB79cSLNe+GzRjv4pVjJviceW6AF6yc
# WoEYR0LYhaa0ozJLU5Yi+LCmcrdovkl53DNt4EXs87KDogYb9eGEndSpZ5ZM74LN
# vVzY0/nPISHz0Xva71QjD4h+8z2XMOZzY7YQ0Psw+etyNZ1CesufU211rLslLKsO
# 8F2aBs2cIo1k+aHOhrw9xw6JCWONNboZ497mwYW5EfN0W3zL5s3ad4Xtm7yFM7Uj
# rhc0aqy3xL7D5FR2J7x9cLWMq7eb0oYioXhqV2tgFqbKHeDick+P8tHYIFovIP7Y
# G4ZkJWag1H91KlELGWi3SLv10o4KGag42pswjybTi4toQcC/irAodDW8HNtX+cbz
# 0sMptFJK+KObAnDFHEsukxD+7jFfEV9Hh/+CSxKRsmnuiovCWIOb+H7DRon9Tlxy
# diFhvu88o0w35JkNbJxTk4MhF/KgaXn0GxdH8elEa2Imq45gaa8D+mTm8LWVydt4
# ytxYP/bqjN49D9NZ81coE6aQWm88TwIf4R4YZbOpMKN0CyejaPNN41LGXHeCUMYm
# Bx3PkP8ADHD1J2Cr/6tjuOOCztfp+o9Nc+ZoIAkpUcA/X2gSMkgHAPUvIdtoSAHE
# UKiBhI6JQivRepyvWcl+JYbYbBh7pmgAXVswggeXMIIFf6ADAgECAhMzAAAAR+OV
# CzehYN3HAAAAAABHMA0GCSqGSIb3DQEBDAUAMGExCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQ
# dWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMB4XDTI0MTEyNjE4NDg1MFoX
# DTI1MTExOTE4NDg1MFowgdsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
# dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAl
# BgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3QTAwLTA1RTAtRDk0NzE1MDMGA1UEAxMs
# TWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHkwggIi
# MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDocLpu99z/+NeIZmR32GJg2VT/
# jd96pYLsvNngeH4qXwK1qVmFaXXkkVbxb1fOQJMukYkba3WEc69W/Z4BszAuxguT
# hDVlY9sk4ZYkGMgxoq1Z5inUPvj4Qh8xVvlhiAS6Of/uLwDsbsKlg2fGpmvztiPS
# OL9P15k00I4bsl1vlmRSut2tNwJQ5sXpoT7GI/2T2A0GnWbFECKRCyGW9rsny9o0
# LNIUl4NYAd4awGSs6OIzKPpIK1JfK90wXHvaXwGJcN9P8QPRJIHKuFoVGzIUG/C0
# jQC4rQ62yTGvc2sZ4AxTQwflfVBBaiHq8gn/YDHpZileGkB2IQazZEiEc5Or5Xer
# 9mUDU+2FEe66w8e2WkLXanqxaD5+Zco+E+QdwcTYGo78jFxPDvNraTr5QAgITc4d
# Y/PBC3cYFzcgDyUx2xOVCBvgabqJxj7rXrj4Bhd2S/ZTYOVHhi8cDWBaefM8JgiO
# 8GCIIRvlNWng8FKFt09ZfNxmsSdCJlWw3rNAwsBY1xp8pmmv9r2M9rNIRkZ+sh0x
# d3GuASWs2bOrqBi0aTzgY9b3CxY+/m+RU+UTim5JkmpJM/AIP68/S+1NwFqXK5yx
# TJBIInhoEgdEHi+a2JR2SlV3AkpJa0/B6sZaoEa+zgshIfFa66XBmnnsydV4uG7W
# 1INoaNVwxBKDdmqNRwIDAQABo4IByzCCAccwHQYDVR0OBBYEFORUdlggOj7vT7m2
# XvFhSEW8ht1oMB8GA1UdIwQYMBaAFGtpKDo1L0hjQM972K9J6T7ZPdshMGwGA1Ud
# HwRlMGMwYaBfoF2GW2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3Js
# L01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIw
# MjAyMC5jcmwweQYIKwYBBQUHAQEEbTBrMGkGCCsGAQUFBzAChl1odHRwOi8vd3d3
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFB1YmxpYyUy
# MFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5jcnQwDAYDVR0TAQH/BAIw
# ADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwZgYDVR0g
# BF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5t
# aWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMAgGBmeBDAEE
# AjANBgkqhkiG9w0BAQwFAAOCAgEADSJUQ9XamDh0gkC1XvrhVz6AMwGVKuKJA+tk
# lJzBa4UVYP3Y9r1RLU08RYJIjPEkpwiwDWitK58gsZxwNh4Nc4fFiQrZUJZ9BInf
# nodv8WOO83zY8YQdJMcpgBzeYVXiNCedumqFKXj0mMMuWaBynv7wwn7FnHJwzLru
# 4jt4VLeef+BycnYwPoMa75LF/9xZo/0TJ371qtBYdbsceKmNhQUTD2vIvvPkHTPH
# /NA2IkLsQ1Am51nzh52WEDzRCoXeld6+/KClnfsEB1/vfR6pYPxwZTvTZ7uh7y8D
# 6g4hDpEcjIses754W2aRpxTPru6n+z2EzkvHF70B/g5oAodmVTUBb+pxpu77UHm0
# TraVodjfXJJNs+h1RjnCu9Miku2KhPmpBrsSne31y3gXstm5vctp1tFox9amTWvh
# IV88l1EIC3yX+BN9cGKtL65REl/y8yqa2PIW2i18JMRIr4T7liHfX0A6sdPsl7Gu
# dLyEVHAWsW8NFVzt/vdyRhzMUpsxhPL1qGQgD45Q+3bgTlel5MWlWgYG+b+LLUXR
# 5uiybbIswnORTU/jDycNAx8u4c5+14sen5/fmqcrQa316l7WqcQ6rOcoxDFym7k2
# RVuEhZNQ4XNXCKI7kb8PMrRtMbobV0mryd0UlbQUbPsJuN9nUE2ADmgnO3bQGyER
# vppedCExggdDMIIHPwIBATB4MGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNB
# IFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAR+OVCzehYN3HAAAAAABHMA0GCWCG
# SAFlAwQCAQUAoIIEnDARBgsqhkiG9w0BCRACDzECBQAwGgYJKoZIhvcNAQkDMQ0G
# CyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNTA4MTQwOTA1MjFaMC8GCSqG
# SIb3DQEJBDEiBCALeme7S4HqUK25LXSXeQpR8tTyRUMsfn0FOcVDJl+NiDCBuQYL
# KoZIhvcNAQkQAi8xgakwgaYwgaMwgaAEIJNm85ZyhQAGGe9QPhd3+xvmMKCvfjHh
# f8tl6mRICsynMHwwZaRjMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRp
# bWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAR+OVCzehYN3HAAAAAABHMIIDXgYLKoZI
# hvcNAQkQAhIxggNNMIIDSaGCA0UwggNBMIICKQIBATCCAQmhgeGkgd4wgdsxCzAJ
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jv
# c29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT
# Tjo3QTAwLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0Eg
# VGltZSBTdGFtcGluZyBBdXRob3JpdHmiIwoBATAHBgUrDgMCGgMVACAF09m+ILyM
# NydZT7P3lOLNVFzdoGcwZaRjMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNB
# IFRpbWVzdGFtcGluZyBDQSAyMDIwMA0GCSqGSIb3DQEBCwUAAgUA7EeIhTAiGA8y
# MDI1MDgxMzIxNTYyMVoYDzIwMjUwODE0MjE1NjIxWjB0MDoGCisGAQQBhFkKBAEx
# LDAqMAoCBQDsR4iFAgEAMAcCAQACAhF2MAcCAQACAhMXMAoCBQDsSNoFAgEAMDYG
# CisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEA
# AgMBhqAwDQYJKoZIhvcNAQELBQADggEBAAB3r308E42WDzdNLbbZ1AZoTOKIQRmf
# Uu/5Uh0FMhOBmUHA5vrOA2HqLShzWTr42WvpkQxbkFHos1MB5rilV0U7Cqk6XIoY
# nvqIRMDo72DZnpGUTAQbIuC3i1ncOz+XrPJnswFp6YyU3tbQYgXSK4SiEhzvNZTF
# //OIViv03xFgvtWBHiEJwvnPGrgYENdeBUDCw1Oqi2vL5tb8subz7qAyJAneP/EX
# hS2wTq0DTeUQpDurRUNvzYKbuH8K8BF0B/3K1UpPITW2NcRMjht/JhzygBEbA/sV
# W5NdnYEKrxwd/oU8YsjIEpI6m+gGdfgdwEz761wQPCYXa5n2R8SmFV8wDQYJKoZI
# hvcNAQEBBQAEggIAdTdWQhzjC5Af9Eo/xAoZ7Am3zsZg7qg0znluTyMfVjCRc5LR
# tg2urSRUtcsmZbzCchQML1Mtmh+HOgQQvMFx3RKVJ8q+qrMcCFlCCwH9JUdD97p2
# ameGwU7zzk6PoZBfT2cT9BKrewjWujpdHM/u95T9SOH94ejIlKjI79BvHbpQgkHs
# 7v/pF+xIK4rHDMEw1p1TJhjlusf4GVSDmLRIZgBXAxd9G0+WHdCCxEbDCgev1JuC
# 0ygfQmkgmVXlQN2tITzjRI7DCrfvJ/b+EJLUyfiwOW1aAr1t56JB72TDsNsnW3R8
# mI3L2U008ac5I79aDpZVf8TUjmOyY5MztG4TtZeR5R64QsU5K3+Tq4rnaWoqN0ct
# Vrvpukqri2kkvFXK6R7FF9NNc4ek0wgTVAwqjykeIrsVJVGcvEk9QSplpcuGW7nE
# YX6ZF+XVWIdfWlvl6TZonoCR6OiX9OoH1+4Hscfz1/LdJjBYk1iVo4NExS2W79VZ
# Ni1yvo0npwgDCxwBs9JoFc++ds7jz09w46w1B+PzBcZI7VBdVKQ8gaAbfXogpxo3
# JDW0Ei4lnyLm7wQxA4ZFA6nyZkqwfM/Jhi1WqLBT3GqscWIHanNpRmCwAmFoPOFT
# Hn+nEz9BtRHaRN8dOh7Bd3hjGjRMCh19Cw3S3EpUlTWTBuOtHQdKdo4Q5Mc=
# SIG # End signature block