Src/Public/Get-LabStatus.ps1

function Get-LabStatus {
<#
    .SYNOPSIS
        Queries computers' LCM state to determine whether an existing DSC configuration has applied.
    .EXAMPLE
        Get-LabStatus -ComputerName CONTROLLER, XENAPP

        Queries the CONTROLLER and XENAPP computers' LCM state using the current user credential.
    .EXAMPLE
        Get-LabStatus -ComputerName CONTROLLER, EXCHANGE -Credential (Get-Credential)

        Prompts for credentials to connect to the CONTROLLER and EXCHANGE computers to query the LCM state.
    .EXAMPLE
        Get-LabStatus -ConfigurationData .\TestLabGuide.psd1 -Credential (Get-Credential)

        Prompts for credentials to connect to the computers defined in the DSC configuration document (.psd1) and query
        the LCM state.
    .EXAMPLE
        Get-LabStatus -ConfigurationData .\TestLabGuide.psd1 -PreferNodeProperty IPAddress -Credential (Get-Credential)

        Prompts for credentials to connect to the computers by their IPAddress node property as defined in the DSC
        configuration document (.psd1) and query the LCM state.
#>

    [CmdletBinding()]
    param (
        ## Connect to the computer name(s) specified.
        [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName, ParameterSetName = 'ComputerName')]
        [System.String[]]
        $ComputerName,

        ## Connect to all nodes defined in the a Desired State Configuration (DSC) configuration (.psd1) document.
        [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ConfigurationData')]
        [System.Collections.Hashtable]
        [Microsoft.PowerShell.DesiredStateConfiguration.ArgumentToConfigurationDataTransformationAttribute()]
        $ConfigurationData,

        ## Use an alternative property for the computer name to connect to. Use this option when a configuration document's
        ## node name does not match the computer name, e.g. use the IPAddress property instead of the NodeName property.
        [Parameter(ValueFromPipelineByPropertyName, ParameterSetName = 'ConfigurationData')]
        [System.String]
        $PreferNodeProperty,

        ## Specifies the application name in the connection. The default value of the ApplicationName parameter is WSMAN.
        ## The complete identifier for the remote endpoint is in the following format:
        ##
        ## <transport>://<server>:<port>/<ApplicationName>
        ##
        ## For example: `http://server01:8080/WSMAN`
        ##
        ## Internet Information Services (IIS), which hosts the session, forwards requests with this endpoint to the
        ## specified application. This default setting of WSMAN is appropriate for most uses. This parameter is designed
        ## to be used if many computers establish remote connections to one computer that is running Windows PowerShell.
        ## In this case, IIS hosts Web Services for Management (WS-Management) for efficiency.
        [Parameter(ValueFromPipelineByPropertyName)]
        [System.String] $ApplicationName,

        ## Specifies the authentication mechanism to be used at the server. The acceptable values for this parameter are:
        ##
        ## - Basic. Basic is a scheme in which the user name and password are sent in clear text to the server or proxy.
        ## - Default. Use the authentication method implemented by the WS-Management protocol. This is the default. -
        ## Digest. Digest is a challenge-response scheme that uses a server-specified data string for the challenge. -
        ## Kerberos. The client computer and the server mutually authenticate by using Kerberos certificates. -
        ## Negotiate. Negotiate is a challenge-response scheme that negotiates with the server or proxy to determine the
        ## scheme to use for authentication. For example, this parameter value allows for negotiation to determine
        ## whether the Kerberos protocol or NTLM is used. - CredSSP. Use Credential Security Support Provider (CredSSP)
        ## authentication, which lets the user delegate credentials. This option is designed for commands that run on one
        ## remote computer but collect data from or run additional commands on other remote computers.
        ##
        ## Caution: CredSSP delegates the user credentials from the local computer to a remote computer. This practice
        ## increases the security risk of the remote operation. If the remote computer is compromised, when credentials
        ## are passed to it, the credentials can be used to control the network session.
        ##
        ## Important: If you do not specify the Authentication parameter,, the Test-WSMan request is sent to the remote
        ## computer anonymously, without using authentication. If the request is made anonymously, it returns no
        ## information that is specific to the operating-system version. Instead, this cmdlet displays null values for
        ## the operating system version and service pack level (OS: 0.0.0 SP: 0.0).
        [Parameter(ValueFromPipelineByPropertyName)]
        [ValidateSet('None','Default','Digest','Negotiate','Basic','Kerberos','ClientCertificate','Credssp')]
        [System.String] $Authentication = 'Default',

        ## Specifies the digital public key certificate (X509) of a user account that has permission to perform this
        ## action. Enter the certificate thumbprint of the certificate.
        ##
        ## Certificates are used in client certificate-based authentication. They can be mapped only to local user
        ## accounts; they do not work with domain accounts.
        ##
        ## To get a certificate thumbprint, use the Get-Item or Get-ChildItem command in the Windows PowerShell Cert:
        ## drive.
        [Parameter(ValueFromPipelineByPropertyName)]
        [System.String] $CertificateThumbprint,

        ## Specifies the port to use when the client connects to the WinRM service. When the transport is HTTP, the
        ## default port is 80. When the transport is HTTPS, the default port is 443.
        ##
        ## When you use HTTPS as the transport, the value of the ComputerName parameter must match the server's
        ## certificate common name (CN).
        [Parameter(ValueFromPipelineByPropertyName)]
        [System.Int32] $Port,

        ## Specifies that the Secure Sockets Layer (SSL) protocol is used to establish a connection to the remote
        ## computer. By default, SSL is not used.
        ##
        ## WS-Management encrypts all the Windows PowerShell content that is transmitted over the network. The UseSSL
        ## parameter lets you specify the additional protection of HTTPS instead of HTTP. If SSL is not available on the
        ## port that is used for the connection, and you specify this parameter, the command fails.
        [Parameter(ValueFromPipelineByPropertyName)]
        [System.Management.Automation.SwitchParameter] $UseSSL,

        ## Credential used to connect to the remote computer.
        [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName)]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.CredentialAttribute()]
        $Credential
    )
    begin {

        ## Authentication might not be explicitly passed, add it so it gets splatted
        $PSBoundParameters['Authentication'] = $Authentication;

    }
    process {

        if ($PSCmdlet.ParameterSetName -eq 'ConfigurationData') {

            $nodes = $ConfigurationData.AllNodes | Where-Object { $_.NodeName -ne '*' };

            foreach ($node in $nodes) {

                $nodeName = $node.NodeName;
                if (($PSBoundParameters.ContainsKey('PreferNodeProperty')) -and
                    (-not [System.String]::IsNullOrEmpty($node[$PreferNodeProperty]))) {

                    $nodeName = $node[$PreferNodeProperty];
                }

                $ComputerName += $nodeName;
            }
        }

        $sessions = Get-PSSession;
        $activeSessions = @();
        $inactiveSessions = @();

        ## Remove parameters that aren't supported by Get-PSSession, Test-WSMan and New-PSSession
        [ref] $null = $PSBoundParameters.Remove('ComputerName');
        [ref] $null = $PSBoundParameters.Remove('ConfigurationData');
        [ref] $null = $PSBoundParameters.Remove('PreferNodeProperty');
        [ref] $null = $PSBoundParameters.Remove('ErrorAction');

        foreach ($computer in $ComputerName) {

            $session = $sessions |
                            Where-Object { $_.ComputerName -eq $computer -and $_.State -eq 'Opened' } |
                                Select-Object -First 1;

            if (-not $session) {

                Write-Verbose -Message ($localized.TestingWinRMConnection -f $computer);
                try {

                   if (Test-WSMan -ComputerName $computer -ErrorAction Stop @PSBoundParameters) {

                        ## WSMan is up so we should be able to connect, if not throw..
                        Write-Verbose -Message ($localized.ConnectingRemoteSession -f $computer);
                        $activeSessions += New-PSSession -ComputerName $computer -ErrorAction Stop @PSBoundParameters;
                    }
                }
                catch {

                    $inactiveSessions += $computer;
                    Write-Error $_;
                }

            }
            else {

                Write-Verbose -Message ($localized.ReusingExistingRemoteSession -f $computer);
                $activeSessions += $session
            }

        } #end foreach computer

        if ($activeSessions.Count -gt 0) {

            Write-Verbose -Message ($localized.QueryingActiveSessions -f ($activeSessions.ComputerName -join "','"));
            $results = Invoke-Command -Session $activeSessions -ScriptBlock {
                            Get-DscLocalConfigurationManager |
                                Select-Object -Property LCMVersion, LCMState;
                        };
        }

        foreach ($computer in $ComputerName) {

            if ($computer -in $inactiveSessions) {

                $labState = [PSCustomObject] @{
                    ComputerName = $computer;
                    LCMVersion = '';
                    LCMState = 'Unknown';
                    Completed = $false;
                }
                Write-Output -InputObject $labState;
            }
            else {

                $result = $results | Where-Object { $_.PSComputerName -eq $computer };
                $labState = [PSCustomObject] @{
                    ComputerName = $result.PSComputerName;
                    LCMVersion = $result.LCMVersion;
                    LCMState = $result.LCMState;
                    Completed = $result.LCMState -eq 'Idle';
                }
                Write-Output -InputObject $labState;
            }

        } #end foreach computer

    } #end process
} #end function

# SIG # Begin signature block
# MIIm9AYJKoZIhvcNAQcCoIIm5TCCJuECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUx/aqwYSjVV0AkDv1O/f6muVF
# IzyggiCcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0B
# AQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz
# 7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS
# 5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7
# bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfI
# SKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jH
# trHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14
# Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2
# h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt
# 6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPR
# iQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ER
# ElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4K
# Jpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAd
# BgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SS
# y4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAk
# BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAC
# hjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS
# b290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRV
# HSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyh
# hyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO
# 0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo
# 8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++h
# UD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5x
# aiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIGrjCCBJag
# AwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQG
# EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl
# cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIw
# MzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UE
# ChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQg
# UlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEF
# AAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCw
# zIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFz
# sbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ
# 7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7
# QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/teP
# c5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCY
# OjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9K
# oRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6
# dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM
# 1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbC
# dLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbEC
# AwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1N
# hS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9P
# MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcB
# AQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggr
# BgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1
# c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAI
# BgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7Zv
# mKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI
# 2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/ty
# dBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVP
# ulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmB
# o1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc
# 6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3c
# HXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0d
# KNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZP
# J/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLe
# Mt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDy
# Divl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBrAwggSYoAMCAQICEAitQLJg0pxM
# n17Nqb2TrtkwDQYJKoZIhvcNAQEMBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoT
# DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UE
# AxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIxMDQyOTAwMDAwMFoXDTM2
# MDQyODIzNTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
# bmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBS
# U0E0MDk2IFNIQTM4NCAyMDIxIENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC
# AgoCggIBANW0L0LQKK14t13VOVkbsYhC9TOM6z2Bl3DFu8SFJjCfpI5o2Fz16zQk
# B+FLT9N4Q/QX1x7a+dLVZxpSTw6hV/yImcGRzIEDPk1wJGSzjeIIfTR9TIBXEmtD
# mpnyxTsf8u/LR1oTpkyzASAl8xDTi7L7CPCK4J0JwGWn+piASTWHPVEZ6JAheEUu
# oZ8s4RjCGszF7pNJcEIyj/vG6hzzZWiRok1MghFIUmjeEL0UV13oGBNlxX+yT4Us
# SKRWhDXW+S6cqgAV0Tf+GgaUwnzI6hsy5srC9KejAw50pa85tqtgEuPo1rn3MeHc
# reQYoNjBI0dHs6EPbqOrbZgGgxu3amct0r1EGpIQgY+wOwnXx5syWsL/amBUi0nB
# k+3htFzgb+sm+YzVsvk4EObqzpH1vtP7b5NhNFy8k0UogzYqZihfsHPOiyYlBrKD
# 1Fz2FRlM7WLgXjPy6OjsCqewAyuRsjZ5vvetCB51pmXMu+NIUPN3kRr+21CiRshh
# WJj1fAIWPIMorTmG7NS3DVPQ+EfmdTCN7DCTdhSmW0tddGFNPxKRdt6/WMtyEClB
# 8NXFbSZ2aBFBE1ia3CYrAfSJTVnbeM+BSj5AR1/JgVBzhRAjIVlgimRUwcwhGug4
# GXxmHM14OEUwmU//Y09Mu6oNCFNBfFg9R7P6tuyMMgkCzGw8DFYRAgMBAAGjggFZ
# MIIBVTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRoN+Drtjv4XxGG+/5h
# ewiIZfROQjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8B
# Af8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYIKwYBBQUHAQEEazBpMCQG
# CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKG
# NWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290
# RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv
# bS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMBwGA1UdIAQVMBMwBwYFZ4EMAQMw
# CAYGZ4EMAQQBMA0GCSqGSIb3DQEBDAUAA4ICAQA6I0Q9jQh27o+8OpnTVuACGqX4
# SDTzLLbmdGb3lHKxAMqvbDAnExKekESfS/2eo3wm1Te8Ol1IbZXVP0n0J7sWgUVQ
# /Zy9toXgdn43ccsi91qqkM/1k2rj6yDR1VB5iJqKisG2vaFIGH7c2IAaERkYzWGZ
# gVb2yeN258TkG19D+D6U/3Y5PZ7Umc9K3SjrXyahlVhI1Rr+1yc//ZDRdobdHLBg
# XPMNqO7giaG9OeE4Ttpuuzad++UhU1rDyulq8aI+20O4M8hPOBSSmfXdzlRt2V0C
# FB9AM3wD4pWywiF1c1LLRtjENByipUuNzW92NyyFPxrOJukYvpAHsEN/lYgggnDw
# zMrv/Sk1XB+JOFX3N4qLCaHLC+kxGv8uGVw5ceG+nKcKBtYmZ7eS5k5f3nqsSc8u
# pHSSrds8pJyGH+PBVhsrI/+PteqIe3Br5qC6/To/RabE6BaRUotBwEiES5ZNq0RA
# 443wFSjO7fEYVgcqLxDEDAhkPDOPriiMPMuPiAsNvzv0zh57ju+168u38HcT5uco
# P6wSrqUvImxB+YJcFWbMbA7KxYbD9iYzDAdLoNMHAmpqQDBISzSoUSC7rRuFCOJZ
# DW3KBVAr6kocnqX9oKcfBnTn8tZSkP2vhUgh+Vc7tJwD7YZF9LRhbr9o4iZghurI
# r6n+lB3nYxs6hlZ4TjCCBsIwggSqoAMCAQICEAVEr/OUnQg5pr/bP1/lYRYwDQYJ
# KoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ
# bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2
# IFRpbWVTdGFtcGluZyBDQTAeFw0yMzA3MTQwMDAwMDBaFw0zNDEwMTMyMzU5NTla
# MEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4GA1UE
# AxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjMwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQCjU0WHHYOOW6w+VLMj4M+f1+XS512hDgncL0ijl3o7Kpxn3GIV
# WMGpkxGnzaqyat0QKYoeYmNp01icNXG/OpfrlFCPHCDqx5o7L5Zm42nnaf5bw9Yr
# IBzBl5S0pVCB8s/LB6YwaMqDQtr8fwkklKSCGtpqutg7yl3eGRiF+0XqDWFsnf5x
# XsQGmjzwxS55DxtmUuPI1j5f2kPThPXQx/ZILV5FdZZ1/t0QoRuDwbjmUpW1R9d4
# KTlr4HhZl+NEK0rVlc7vCBfqgmRN/yPjyobutKQhZHDr1eWg2mOzLukF7qr2JPUd
# vJscsrdf3/Dudn0xmWVHVZ1KJC+sK5e+n+T9e3M+Mu5SNPvUu+vUoCw0m+PebmQZ
# BzcBkQ8ctVHNqkxmg4hoYru8QRt4GW3k2Q/gWEH72LEs4VGvtK0VBhTqYggT02ke
# fGRNnQ/fztFejKqrUBXJs8q818Q7aESjpTtC/XN97t0K/3k0EH6mXApYTAA+hWl1
# x4Nk1nXNjxJ2VqUk+tfEayG66B80mC866msBsPf7Kobse1I4qZgJoXGybHGvPrhv
# ltXhEBP+YUcKjP7wtsfVx95sJPC/QoLKoHE9nJKTBLRpcCcNT7e1NtHJXwikcKPs
# CvERLmTgyyIryvEoEyFJUX4GZtM7vvrrkTjYUQfKlLfiUKHzOtOKg8tAewIDAQAB
# o4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
# BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcB
# MB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSltu8T
# 5+/N0GSh1VapZTGj3tXjSTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0
# YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0
# cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0
# cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGlt
# ZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCBGtbeoKm1mBe8cI1P
# ijxonNgl/8ss5M3qXSKS7IwiAqm4z4Co2efjxe0mgopxLxjdTrbebNfhYJwr7e09
# SI64a7p8Xb3CYTdoSXej65CqEtcnhfOOHpLawkA4n13IoC4leCWdKgV6hCmYtld5
# j9smViuw86e9NwzYmHZPVrlSwradOKmB521BXIxp0bkrxMZ7z5z6eOKTGnaiaXXT
# UOREEr4gDZ6pRND45Ul3CFohxbTPmJUaVLq5vMFpGbrPFvKDNzRusEEm3d5al08z
# jdSNd311RaGlWCZqA0Xe2VC1UIyvVr1MxeFGxSjTredDAHDezJieGYkD6tSRN+9N
# UvPJYCHEVkft2hFLjDLDiOZY4rbbPvlfsELWj+MXkdGqwFXjhr+sJyxB0JozSqg2
# 1Llyln6XeThIX8rC3D0y33XWNmdaifj2p8flTzU8AL2+nCpseQHc2kTmOt44Owde
# OVj0fHMxVaCAEcsUDH6uvP6k63llqmjWIso765qCNVcoFstp8jKastLYOrixRoZr
# uhf9xHdsFWyuq69zOuhJRrfVf8y2OMDY7Bz1tqG4QyzfTkx9HmhwwHcK1ALgXGC7
# KP845VJa1qwXIiNO9OzTF/tQa/8Hdx9xl0RBybhG02wyfFgvZ0dl5Rtztpn5aywG
# Ru9BHvDwX+Db2a2QgESvgBBBijCCBtswggTDoAMCAQICEATKzAo8VGv2qBgLEa7N
# zyYwDQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD
# ZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2ln
# bmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMTAeFw0yMTEwMTkwMDAwMDBaFw0y
# MzExMDQyMzU5NTlaMGAxCzAJBgNVBAYTAkdCMQ8wDQYDVQQHEwZMb25kb24xHzAd
# BgNVBAoTFlZpcnR1YWwgRW5naW5lIExpbWl0ZWQxHzAdBgNVBAMTFlZpcnR1YWwg
# RW5naW5lIExpbWl0ZWQwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC1
# ubejnuZBjG7SJ1KJ+GXJloNU7Rm7QGcZMVk61kuJsGi2CkqnsF7eT1YPIhs6JQdV
# oVjsMbxovySukCuP7colHj1Tmktdx681RAUsvXymL2Vn57bD51wEB+4nfQnvrRW0
# 8PAADueYB9/d/2j60QHVmch5fOU9HIzPthlLjewN4B+3ynyMXOYzSNG231Jc3Epw
# LSCdfoLHS/DgCTGYy2t5f8iC+PlVWrgzzUTzgJ59axT8imogvbjGnGXc47BnnfDO
# f6s8DdP1uPQ9TIj/pW841QhEP8R84PG6tV1IN24sexFqDj5DfEW9mb9Y2qyvaoa/
# ssdPe4o+yO48GjUzP18z8B8/B0R8zfEn5jWsGpTGcOHBhL3sXDcszreVMqXds3hM
# 4UQlfxg+ALTYni/NhIg/R/AEE/J3sy1uJfMW9KheeXQRCaMf6Th+M4LCfW2Bacjv
# s0RPTkl3ToXc53nYif2ognkGG7jOUwURCATsk404jj8eX90HN82TIi0wxFw2I8kC
# AwEAAaOCAgYwggICMB8GA1UdIwQYMBaAFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB0G
# A1UdDgQWBBQSv6nVtbCtP7OXr5NeEdbP17Bi4DAOBgNVHQ8BAf8EBAMCB4AwEwYD
# VR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0cDovL2Ny
# bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0
# MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0
# LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIw
# MjFDQTEuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0
# dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBlAYIKwYBBQUHAQEEgYcwgYQwJAYI
# KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBcBggrBgEFBQcwAoZQ
# aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29k
# ZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQwDAYDVR0TAQH/BAIwADAN
# BgkqhkiG9w0BAQsFAAOCAgEAHfkR7a+g8eOt0OUHzSShxbZmtVwo7n885yE86/Ev
# V69c92hp7E0MLBfMz/oZdrhTVWFX4apt5D4kJkVdZuLJzGpcR+Ll/GPaxHN0XcIO
# ii0WKrErV6rPZbzYpHkVfjktOxAyuDo7yQDadvZ4HGTpNZhS1L7eO11L+fAOn8H8
# D6iXQJoPnWGXOr1BjQ02TCxtn58qYjGKeoQUXqe1o6ZA1ZLQQ601AFh2V/Sk1OEG
# 4/EQ2wO1ZFLnqmDep+Xf6SG1553ywWjJj/2DVKh9tzsMBCJi1OKSZ6QD6zlaQdjV
# 7CJIX81xdI00w2Bu4CyLOgxD02Qn+8yGzz36E1R7pOWT1sV984/2iHnPoN/9ccmy
# WE1jcPFZhBDG2rNmkCT/gYInwv2p14QO+26U+nenpWo0HFA+73wLjql9eAJfS8iJ
# 5XLdFk6EcPYkLK1Y0VZckW+ijTdqRzJO6aKrb6Z7DoAvBcoq0V6gMd+fMORWxlE+
# pjj2AQJUqJ9jtntSy5/dIE4Hq3E6XMrXl4xHYQhGwFII9VkJ69T3PnUM/8Ytnr+Q
# IMbqFy7qKx6chYDFbDXCIa/ocmlxrve6aZFihR4q01XyGDsi2U+Ka2uOOhP7RyIT
# w6G6/kYMGorQYTiKQIhRnIWDvimmQdXir5iCFe+5uTAxJXvKYVEqGBwZAuUNc/45
# pVAxggXCMIIFvgIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy
# dCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25p
# bmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEATKzAo8VGv2qBgLEa7NzyYwCQYF
# Kw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkD
# MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJ
# KoZIhvcNAQkEMRYEFHKUw2CL/KlSfFGGiznD4p8qVbfSMA0GCSqGSIb3DQEBAQUA
# BIIBgDAetRng666ZkMBul71BHg5RYHUrFxmxeoTvB1WwS4V2kTEH04qUXtzmUgAc
# AUvTHK1/uwV1e9BP+yNlAC8Gto9dFpcUzW/6zhHbsxNA4RVqquXOmY5fnP+nd9Y+
# dDwximNIC3GksEsdxFxg/OJ0UzVdysNwYODNRclWFqOS9j4VwJqcwQrvYIq9zj6M
# rGsRKKbUfGt28G/UB7PNDxlhitFg5JxhfUmMja0BUTMqir7y0g/Bb3EtRDxOJ+j8
# BlKaTSdGc21cLOo8eo5k8UJ5EutmVQNtbqyhMofnl3GsjmTyhK/0TrmktaYUHu+6
# 6clfIDZvf22wvmTvZXZ8IAneknKVC/Vyx1Sl8hAr/P8kwZFQ33+PkZjLg1QReboc
# Xf5X9A+F46JChe5VEr4aU8FHXlgGC8XxGnkTziVcGYxaMvbZ1zz4LXzwkcPy/hNP
# etj+W9PQLnZDUi0S5cb8ekzBR6VVyWzbTkfnNeE7rSaJxobv4UDBMyXq+Vv3s//Z
# IFad/qGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYT
# AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQg
# VHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OU
# nQg5pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZI
# hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMzExMDExMjAyNDlaMC8GCSqGSIb3DQEJ
# BDEiBCD9lXb7PxjTi14TD2rYASlv8Eg/MgfRhycX790JqLbvFTANBgkqhkiG9w0B
# AQEFAASCAgBNBd7QijIAmdR35DnEjK8j1XwYCeu94XQUpdQ+tp8TcnBTUbfrCrLy
# mdnuVUDPgp5dIQ+kF/mVcj4JEZNXbbz6YgsIuvxdFEb4xKMB53SEHKTBTnTfAhBm
# osGBo+oTnt2/zhbQpkheDLtM4UzMQoCseLUTXDYptzmo1urtJxkEZd0D/5GbIbrm
# NFSsrqkP4H0HJZ7vdfE4oEodSP6xg8sgK/5u+tWypbsyouTbwh6h86IUHFbLtMZ/
# +1r6QcTzvLRT5dw7bM8fOFJIltcjGF3lDqpBbQsug5GT4aIZ1H/+vxsYdIS4GgAz
# m2XuFM6+PjS5y3tKIMN0L0+lWDpzhGIC79NW2aZ8hCjBAElcmF9q6xqj5ljeaR1Z
# bnSoEnqSw6iH3VNA9ztmfEXu7wgINvzQ3RtJArcz/Y2f6PPAcipHpHL4vrxEw9Vc
# fW6qZm0o61U+q4rjxKrpUL+NiQ0cE0MZsMdg6hJcDg+O05/GUaVNSvorp3NEkrMk
# cUWykrbi/BqrN04TiCdpDZtGJ4o2jpYsDrCnjkFMfXOgp3On9KhY0kLLqQr9rV2N
# nutdX+iEz+XMBYiFe3KQG4tOYCd+YmdlbqPjUccmBHfnnLETGBHT+CSe6qgSRKsN
# 3wcMHICZ0DBT+x7tADnSoG8lMJ7N6A0iRdYQnZjcjyupzXFTnIV2sQ==
# SIG # End signature block