AzStackHci.EnvironmentChecker.Helpers.psm1
|
<#
.SYNOPSIS Validation Helper functions for AzStackHci Environment Checker .DESCRIPTION This module contains validation helper functions for AzStackHci Environment Checker that can be used across multiple validators. .NOTES See individual function documentation for details and usage. #> function Assert-ServiceState { <# .SYNOPSIS Asserts and corrects the state of one or more services on local or remote computers. .DESCRIPTION This function validates the running state and startup type of specified Windows services. It supports both local and remote execution via PSSession, can attempt automatic remediation, and returns standardized AzStackHciResultObject(s) for integration with environment validation workflows. When remediation is enabled, the function will: 1. Check current service state 2. Attempt to correct any mismatches (startup type first, then running state) 3. Wait for the specified duration to allow service stabilization 4. Re-verify the service state 5. Report success or failure with detailed error information Results can be returned per-service or grouped (one result per computer covering all services). Two modes are supported: - Simple mode: All services use the same DesiredState, DesiredStartupType, and WaitTimeSeconds - Advanced mode: Each service can have individual configuration via ServiceConfiguration hashtable .PARAMETER ServiceName One or more service names to validate. Use the service name (not display name). Example: 'WinRM', 'W32Time', 'WinHttpAutoProxySvc' Used in simple mode where all services share the same configuration. .PARAMETER ServiceConfiguration Hashtable where keys are service names and values are hashtables containing: - DesiredState: 'Running' or 'Stopped' (optional) - DesiredStartupType: 'Automatic', 'Manual', 'Disabled', or 'AutomaticDelayedStart' (optional) - WaitTimeSeconds: Integer 1-300 (optional, defaults to global WaitTimeSeconds) Example: @{ 'WinRM' = @{ DesiredState = 'Running'; DesiredStartupType = 'Automatic'; WaitTimeSeconds = 60 } 'Spooler' = @{ DesiredState = 'Stopped'; DesiredStartupType = 'Disabled'; WaitTimeSeconds = 15 } } .PARAMETER DesiredState The expected running state of the service(s). Valid values: 'Running', 'Stopped' If not specified, only startup type is validated. Applies to all services when using ServiceName parameter. .PARAMETER DesiredStartupType The expected startup type of the service(s). Valid values: 'Automatic', 'Manual', 'Disabled', 'AutomaticDelayedStart' If not specified, only running state is validated. Applies to all services when using ServiceName parameter. .PARAMETER PsSession Existing PSSession(s) to use for remote service validation. If not specified, validates services on the local computer. .PARAMETER Remediate When specified, attempts to correct service state if it doesn't match desired configuration. - Sets startup type to DesiredStartupType if specified and mismatched - Starts/stops service to match DesiredState if specified and mismatched - Waits for WaitTimeSeconds after changes - Re-validates state before returning results .PARAMETER WaitTimeSeconds Number of seconds to wait after remediation attempts before re-checking service state. Default: 30 seconds This allows time for services to fully initialize or stop. Can be overridden per-service when using ServiceConfiguration parameter. .PARAMETER MaxRetries Maximum number of remediation attempts before giving up. Default: 1 (single attempt) Range: 1-5 Each retry includes the full cycle: attempt fix → wait → verify. .PARAMETER Severity Severity level for the result object. Valid values: 'CRITICAL', 'WARNING', 'INFORMATIONAL', 'Hidden' .PARAMETER ValidatorName Name of the parent validator calling this function. Used for result object naming and categorization. .PARAMETER TestName Custom name for the test result object. Overrides the default naming pattern. Use placeholders: {ValidatorName}, {ServiceName}, {ComputerName} Example: 'AzStackHci_{ValidatorName}_Custom_{ServiceName}' .PARAMETER TestTitle Custom title for the test result object. Overrides the default title. Use placeholders: {ServiceName}, {ComputerName} Example: 'Validate {ServiceName} Configuration' .PARAMETER TestDisplayName Custom display name for the test result object. Overrides the default display name. Use placeholders: {ServiceName}, {ComputerName} Example: '{ServiceName} on {ComputerName}' .PARAMETER GroupResults When specified, returns one result object per computer covering all services. When omitted (default), returns one result object per service per computer. Useful for reducing result object count when validating multiple services. .OUTPUTS Returns one or more AzStackHciResultObject instances. .EXAMPLE Assert-ServiceState -ServiceName 'WinRM' -DesiredState 'Running' -DesiredStartupType 'Automatic' -Severity 'CRITICAL' -ValidatorName 'Network' Validates that WinRM service is running with automatic startup on the local computer. .EXAMPLE $sessions = New-PSSession -ComputerName 'Server01', 'Server02' Assert-ServiceState -ServiceName @('WinRM', 'WinHttpAutoProxySvc') -DesiredState 'Running' -PsSession $sessions -Remediate -WaitTimeSeconds 60 -Severity 'WARNING' -ValidatorName 'Prerequisites' Remove-PSSession $sessions Checks two services on two remote servers via PSSession, attempts to start them if stopped, waits 60 seconds, then verifies. .EXAMPLE $sessions = New-PSSession -ComputerName 'Node01', 'Node02', 'Node03' Assert-ServiceState -ServiceName 'ClusSvc' -DesiredState 'Running' -DesiredStartupType 'Automatic' -PsSession $sessions -GroupResults -Severity 'CRITICAL' -ValidatorName 'Cluster' Uses existing PSSessions to validate cluster service on multiple nodes, returning one result per node. .EXAMPLE $serviceConfig = @{ 'WinRM' = @{ DesiredState = 'Running'; DesiredStartupType = 'Automatic'; WaitTimeSeconds = 60 } 'Spooler' = @{ DesiredState = 'Stopped'; DesiredStartupType = 'Disabled'; WaitTimeSeconds = 15 } 'W32Time' = @{ DesiredState = 'Running'; DesiredStartupType = 'Automatic' } } Assert-ServiceState -ServiceConfiguration $serviceConfig -Remediate -Severity 'WARNING' -ValidatorName 'Services' Validates multiple services on the local computer with individual configurations and wait times. .EXAMPLE Assert-ServiceState -ServiceName 'BITS' -DesiredStartupType 'Manual' -Severity 'INFORMATIONAL' -ValidatorName 'Services' -TestName 'AzStackHci_MyValidator_BITS_Check' -TestTitle 'BITS Configuration Check' Validates startup type with custom result object naming. .NOTES - Requires appropriate permissions on target computers - When using PSSession, WinRM must be enabled on target computers - Remediation requires administrative privileges - Callers are responsible for creating and managing PSSessions for remote execution - Error details are captured in the AdditionalData.Detail property of failed results #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, ParameterSetName = 'SimpleMode')] [string[]] $ServiceName, [Parameter(Mandatory = $true, ParameterSetName = 'AdvancedMode')] [hashtable] $ServiceConfiguration, [Parameter(ParameterSetName = 'SimpleMode')] [ValidateSet('Running', 'Stopped')] [string] $DesiredState, [Parameter(ParameterSetName = 'SimpleMode')] [ValidateSet('Automatic', 'Manual', 'Disabled', 'AutomaticDelayedStart')] [string] $DesiredStartupType, [Parameter()] [System.Management.Automation.Runspaces.PSSession[]] $PsSession, [Parameter()] [switch] $Remediate, [Parameter()] [ValidateRange(1, 300)] [int] $WaitTimeSeconds = 30, [Parameter()] [ValidateRange(1, 5)] [int] $MaxRetries = 1, [Parameter(Mandatory = $true)] [ValidateSet('CRITICAL', 'WARNING', 'INFORMATIONAL', 'Hidden')] [string] $Severity, [Parameter(Mandatory = $true)] [string] $ValidatorName, [Parameter()] [string] $TestName, [Parameter()] [string] $TestTitle, [Parameter()] [string] $TestDisplayName, [Parameter()] [switch] $GroupResults ) try { # Build service configuration list $serviceConfigList = @{} if ($PSCmdlet.ParameterSetName -eq 'SimpleMode') { # Validate that at least one desired property is specified if (-not $DesiredState -and -not $DesiredStartupType) { throw "At least one of DesiredState or DesiredStartupType must be specified." } # All services use same configuration foreach ($svcName in $ServiceName) { $serviceConfigList[$svcName] = @{ DesiredState = $DesiredState DesiredStartupType = $DesiredStartupType WaitTimeSeconds = $WaitTimeSeconds } } } else { # Advanced mode - validate and normalize configuration foreach ($svcName in $ServiceConfiguration.Keys) { $config = $ServiceConfiguration[$svcName] # Validate that at least one desired property is specified if (-not $config.DesiredState -and -not $config.DesiredStartupType) { throw "Service '$svcName': At least one of DesiredState or DesiredStartupType must be specified." } $serviceConfigList[$svcName] = @{ DesiredState = $config.DesiredState DesiredStartupType = $config.DesiredStartupType WaitTimeSeconds = if ($config.WaitTimeSeconds) { $config.WaitTimeSeconds } else { $WaitTimeSeconds } } } } # Determine execution mode if ($PsSession) { Log-Info "Testing services on computers via PSSession: $($PsSession.ComputerName -join ', ')" } else { Log-Info "Testing services on local computer" } # Script block to execute on each computer $scriptBlock = { param($ServiceConfigs, $Remediate, $MaxRetries) $results = @() $computerName = $env:COMPUTERNAME foreach ($svcName in $ServiceConfigs.Keys) { $config = $ServiceConfigs[$svcName] $result = @{ ServiceName = $svcName ComputerName = $computerName Status = 'SUCCESS' CurrentState = $null CurrentStartupType = $null ErrorMessage = $null Details = @() } try { # Get service $service = Get-Service -Name $svcName -ErrorAction Stop $result.CurrentState = $service.Status.ToString() # Get startup type $wmiService = Get-CimInstance -ClassName Win32_Service -Filter "Name='$svcName'" -ErrorAction Stop $startMode = $wmiService.StartMode if ($startMode -eq 'Auto' -and (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$svcName" -Name 'DelayedAutostart' -ErrorAction SilentlyContinue).DelayedAutostart -eq 1) { $startMode = 'AutomaticDelayedStart' } elseif ($startMode -eq 'Auto') { $startMode = 'Automatic' } $result.CurrentStartupType = $startMode # Check startup type if ($config.DesiredStartupType -and $result.CurrentStartupType -ne $config.DesiredStartupType) { $result.Status = 'FAILURE' $result.Details += "Startup type is '$($result.CurrentStartupType)', expected '$($config.DesiredStartupType)'" if ($Remediate) { try { $setParams = @{ Name = $svcName StartupType = $config.DesiredStartupType ErrorAction = 'Stop' } Set-Service @setParams $result.Details += "Attempted to set startup type to '$($config.DesiredStartupType)'" } catch { $result.ErrorMessage = "Failed to set startup type: $($_.Exception.Message)" $result.Details += $result.ErrorMessage } } } elseif ($config.DesiredStartupType) { $result.Details += "Startup type is '$($result.CurrentStartupType)' as expected" } # Check running state if ($config.DesiredState) { if ($result.CurrentState -ne $config.DesiredState) { $result.Status = 'FAILURE' $result.Details += "Service state is '$($result.CurrentState)', expected '$($config.DesiredState)'" if ($Remediate) { try { if ($config.DesiredState -eq 'Running') { Start-Service -Name $svcName -ErrorAction Stop $result.Details += "Attempted to start service" } else { Stop-Service -Name $svcName -Force -ErrorAction Stop $result.Details += "Attempted to stop service" } } catch { $result.ErrorMessage = "Failed to change service state: $($_.Exception.Message)" $result.Details += $result.ErrorMessage } } } else { $result.Details += "Service state is '$($result.CurrentState)' as expected" } } # If remediation was attempted, wait and re-check (with retries) if ($Remediate -and $result.Status -eq 'FAILURE' -and -not $result.ErrorMessage) { $attemptNumber = 1 $remediationSuccessful = $false while ($attemptNumber -le $MaxRetries -and -not $remediationSuccessful) { $waitTime = $config.WaitTimeSeconds Start-Sleep -Seconds $waitTime $result.Details += "Waited $waitTime seconds for service stabilization (Attempt $attemptNumber of $MaxRetries)" # Re-check service $service = Get-Service -Name $svcName -ErrorAction Stop $result.CurrentState = $service.Status.ToString() $wmiService = Get-CimInstance -ClassName Win32_Service -Filter "Name='$svcName'" -ErrorAction Stop $startMode = $wmiService.StartMode if ($startMode -eq 'Auto' -and (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$svcName" -Name 'DelayedAutostart' -ErrorAction SilentlyContinue).DelayedAutostart -eq 1) { $startMode = 'AutomaticDelayedStart' } elseif ($startMode -eq 'Auto') { $startMode = 'Automatic' } $result.CurrentStartupType = $startMode # Validate current state $finalStatus = 'SUCCESS' if ($config.DesiredStartupType -and $result.CurrentStartupType -ne $config.DesiredStartupType) { $finalStatus = 'FAILURE' } if ($config.DesiredState -and $result.CurrentState -ne $config.DesiredState) { $finalStatus = 'FAILURE' } if ($finalStatus -eq 'SUCCESS') { $result.Status = 'SUCCESS' $result.Details += "Remediation successful on attempt $attemptNumber of ${MaxRetries}: Service is now in desired state" $remediationSuccessful = $true } else { # Still not in correct state if ($attemptNumber -lt $MaxRetries) { # Try remediation again $result.Details += "Attempt $attemptNumber verification: Service still not in desired state, retrying..." # Retry startup type change if needed if ($config.DesiredStartupType -and $result.CurrentStartupType -ne $config.DesiredStartupType) { try { $setParams = @{ Name = $svcName StartupType = $config.DesiredStartupType ErrorAction = 'Stop' } Set-Service @setParams $result.Details += "Retry attempt $($attemptNumber + 1): Attempted to set startup type to '$($config.DesiredStartupType)'" } catch { $result.ErrorMessage = "Failed to set startup type on retry: $($_.Exception.Message)" $result.Details += $result.ErrorMessage break } } # Retry service state change if needed if ($config.DesiredState -and $result.CurrentState -ne $config.DesiredState) { try { if ($config.DesiredState -eq 'Running') { Start-Service -Name $svcName -ErrorAction Stop $result.Details += "Retry attempt $($attemptNumber + 1): Attempted to start service" } else { Stop-Service -Name $svcName -Force -ErrorAction Stop $result.Details += "Retry attempt $($attemptNumber + 1): Attempted to stop service" } } catch { $result.ErrorMessage = "Failed to change service state on retry: $($_.Exception.Message)" $result.Details += $result.ErrorMessage break } } } else { # Final attempt failed if ($config.DesiredStartupType -and $result.CurrentStartupType -ne $config.DesiredStartupType) { $result.Details += "After ${MaxRetries} attempt(s): Startup type is still '$($result.CurrentStartupType)', expected '$($config.DesiredStartupType)'" } if ($config.DesiredState -and $result.CurrentState -ne $config.DesiredState) { $result.Details += "After ${MaxRetries} attempt(s): Service state is still '$($result.CurrentState)', expected '$($config.DesiredState)'" } } $attemptNumber++ } } } } catch { $result.Status = 'FAILURE' $result.ErrorMessage = $_.Exception.Message $result.Details += "Error: $($_.Exception.Message)" } $results += [PSCustomObject]$result } return $results } # Execute script block $allResults = @() if ($PsSession) { # Remote execution via PSSession - execute in parallel across all sessions Log-Info "Checking services on computers via PSSession: $($PsSession.ComputerName -join ', ')" try { # Invoke-Command with multiple sessions executes in parallel $serviceResults = Invoke-Command -Session $PsSession -ScriptBlock $scriptBlock -ArgumentList @($serviceConfigList, $Remediate.IsPresent, $MaxRetries) -ErrorAction SilentlyContinue -ErrorVariable remoteErrors $allResults += $serviceResults # Handle any computers that failed if ($remoteErrors) { # Determine which computers succeeded $succeededComputers = $serviceResults | Select-Object -ExpandProperty ComputerName -Unique $allComputers = $PsSession | Select-Object -ExpandProperty ComputerName $failedComputers = $allComputers | Where-Object { $_ -notin $succeededComputers } # Create failure results for computers that didn't respond foreach ($computer in $failedComputers) { # Find the error for this computer $errorForComputer = $remoteErrors | Where-Object { $_.OriginInfo.PSComputerName -eq $computer -or $_.TargetObject -eq $computer } | Select-Object -First 1 $errorMsg = if ($errorForComputer) { $errorForComputer.Exception.Message } else { "Failed to execute on $computer" } Log-Info "Failed to check services on $computer`: $errorMsg" -Type Error foreach ($svcName in $serviceConfigList.Keys) { $failureResult = [PSCustomObject]@{ ServiceName = $svcName ComputerName = $computer Status = 'FAILURE' CurrentState = $null CurrentStartupType = $null ErrorMessage = "Failed to connect or execute: $errorMsg" Details = @("Failed to connect or execute: $errorMsg") } $allResults += $failureResult } } } } catch { # Complete failure across all sessions (rare) $errorMsg = $_.Exception.Message Log-Info "Failed to execute Invoke-Command: $errorMsg" -Type Error # Create failure results for all computers and services foreach ($session in $PsSession) { $computer = $session.ComputerName foreach ($svcName in $serviceConfigList.Keys) { $failureResult = [PSCustomObject]@{ ServiceName = $svcName ComputerName = $computer Status = 'FAILURE' CurrentState = $null CurrentStartupType = $null ErrorMessage = "Failed to connect or execute: $errorMsg" Details = @("Failed to connect or execute: $errorMsg") } $allResults += $failureResult } } } } else { # Local execution try { Log-Info "Checking services on local computer" $serviceResults = & $scriptBlock -ServiceConfigs $serviceConfigList -Remediate $Remediate.IsPresent -MaxRetries $MaxRetries $allResults += $serviceResults } catch { # Create failure result for all services $errorMsg = $_.Exception.Message Log-Info "Failed to check services locally: $errorMsg" -Type Error foreach ($svcName in $serviceConfigList.Keys) { $failureResult = [PSCustomObject]@{ ServiceName = $svcName ComputerName = $env:COMPUTERNAME Status = 'FAILURE' CurrentState = $null CurrentStartupType = $null ErrorMessage = "Failed to execute: $errorMsg" Details = @("Failed to execute: $errorMsg") } $allResults += $failureResult } } } # Generate result objects $resultObjects = @() $allServiceNames = $serviceConfigList.Keys if ($GroupResults) { # One result per computer $groupedByComputer = $allResults | Group-Object -Property ComputerName foreach ($group in $groupedByComputer) { $computer = $group.Name $services = $group.Group $overallStatus = if ($services.Status -contains 'FAILURE') { 'FAILURE' } else { 'SUCCESS' } $detailLines = @() $detailLines += "Services checked: $($allServiceNames -join ', ')" foreach ($svc in $services) { $detailLines += "[$($svc.ServiceName)]" $detailLines += $svc.Details } $detail = $detailLines -join "`r`n" if ($overallStatus -eq 'FAILURE') { Log-Info "Service validation failed on $computer" -Type Warning Log-Info $detail -Type Warning } else { Log-Info "Service validation passed on $computer" Log-Info $detail } # Apply custom naming or use defaults $resultName = if ($TestName) { $TestName -replace '\{ValidatorName\}', $ValidatorName -replace '\{ComputerName\}', $computer } else { 'AzStackHci_{0}_Test_Services_State' -f $ValidatorName } $resultTitle = if ($TestTitle) { $TestTitle -replace '\{ComputerName\}', $computer } else { 'Test Services State' } $resultDisplayName = if ($TestDisplayName) { $TestDisplayName -replace '\{ComputerName\}', $computer } else { 'Test Services State' } $params = @{ Name = $resultName Title = $resultTitle DisplayName = $resultDisplayName Severity = $Severity Description = 'Validating service state: {0}' -f ($allServiceNames -join ', ') Tags = @{} Remediation = Get-DeviceRequirementsUrl TargetResourceID = "Machine: $computer, Services: $($allServiceNames -join ', ')" TargetResourceName = "Machine: $computer, Services: $($allServiceNames -join ', ')" TargetResourceType = 'Service' Timestamp = [datetime]::UtcNow Status = $overallStatus AdditionalData = @{ Source = $computer Resource = $allServiceNames -join ', ' Detail = $detail Status = $overallStatus TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } $resultObjects += New-AzStackHciResultObject @params } } else { # One result per service per computer foreach ($svcResult in $allResults) { $computer = $svcResult.ComputerName $svcName = $svcResult.ServiceName $detail = $svcResult.Details -join "`r`n" if ($svcResult.Status -eq 'FAILURE') { Log-Info "Service $svcName validation failed on $computer" -Type Warning Log-Info $detail -Type Warning } else { Log-Info "Service $svcName validation passed on $computer" Log-Info $detail } $resourceValue = "State: $($svcResult.CurrentState), StartupType: $($svcResult.CurrentStartupType)" # Apply custom naming or use defaults $resultName = if ($TestName) { $TestName -replace '\{ValidatorName\}', $ValidatorName -replace '\{ServiceName\}', $svcName -replace '\{ComputerName\}', $computer } else { 'AzStackHci_{0}_Test_Service_{1}_State' -f $ValidatorName, $svcName } $resultTitle = if ($TestTitle) { $TestTitle -replace '\{ServiceName\}', $svcName -replace '\{ComputerName\}', $computer } else { 'Test Service {0} State' -f $svcName } $resultDisplayName = if ($TestDisplayName) { $TestDisplayName -replace '\{ServiceName\}', $svcName -replace '\{ComputerName\}', $computer } else { 'Test Service {0} State' -f $svcName } $params = @{ Name = $resultName Title = $resultTitle DisplayName = $resultDisplayName Severity = $Severity Description = 'Validating service {0} state' -f $svcName Tags = @{} Remediation = Get-DeviceRequirementsUrl TargetResourceID = "Machine: $computer, Service: $svcName" TargetResourceName = "Machine: $computer, Service: $svcName" TargetResourceType = 'Service' Timestamp = [datetime]::UtcNow Status = $svcResult.Status AdditionalData = @{ Source = $computer Resource = $resourceValue Detail = $detail Status = $svcResult.Status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } $resultObjects += New-AzStackHciResultObject @params } } return $resultObjects } catch { Log-Info "Error in Assert-ServiceState: $($_.Exception.Message)" -Type Error throw $_ } } function Get-DeviceRequirementsUrl { if ($ENV:EnvChkrId -like '*Small*') { return 'https://aka.ms/azurelocallowcapacityrequirements' } else { return 'https://aka.ms/hci-envch' } } Export-ModuleMember -Function Assert-ServiceState Export-ModuleMember -Function Get-DeviceRequirementsUrl # SIG # Begin signature block # MIIncQYJKoZIhvcNAQcCoIInYjCCJ14CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB7NGTFoRtASY7N # fNnMhWTz48ww54agXnyKTJxZwUtWFKCCDMkwggYEMIID7KADAgECAhMzAAACHPrN # xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1 # OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP # oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC # /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf # rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j # qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT # xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT # DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw # YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w # cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl # MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC # AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN # rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK # 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK # Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY # BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu # uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE # msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz # 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6 # U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO # 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD # 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC # EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX # DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ # Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq # lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo # 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv # QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a # 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1 # FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO # GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7 # ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ # uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS # CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm # VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3 # SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E # BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX # LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB # Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP # oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw # TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC # AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D # 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY # nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI # vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6 # aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w # PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7 # RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK # /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK # YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw # YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT # Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghn+MIIZ+gIBATBu # MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc # +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwG # CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZI # hvcNAQkEMSIEIHwEgB4xwZJTlXyo3Umi0elyjEdqJVwMe2xpW1rKmCpMMEIGCisG # AQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEAstZEiw+2kpQpylVVDitm # F9UGOUWW2nuOApbWA4X3WoIROM9xo2iD1gJiuVYXYr17DWgLsRElawbk5gby3ay+ # qKMy0VGfACq0tN4ednUXOs6TArT+Za/JBdQ1kVyxLxZo57sTnEQaAQCGpNCw7Acg # YinKdRBJJ2Vub+tDMYHiSMakqVFFcC0e5X8rXtad+2qEnWIrZHWNkLDxmkOGgAvP # emS/ZAu+rMlNjbdrA3im85oE49w3M1CUiO5MLEgveUAA92fGGzttZWCyeiBlLxDM # H0J2gOtrmnVBKy1hU7rFE22+/AVfQVHNxvaK+kA8vvfR9cM4c5dj97cDV+4eBCsf # d6GCF7AwghesBgorBgEEAYI3AwMBMYIXnDCCF5gGCSqGSIb3DQEHAqCCF4kwgheF # AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFFMIIB # QQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCDguUdeH7rjfbyRBFtU # r65tx1VQao2Vgvvg/xij5t+miwIGaexvE19PGBMyMDI2MDUwMzE0MzExMS40MDZa # MASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0 # ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo2NTFBLTA1RTAtRDk0NzElMCMG # A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEf4wggcoMIIFEKAD # AgECAhMzAAACFRgD04EHJnxTAAEAAAIVMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m # dCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDgxNDE4NDgyMFoXDTI2MTExMzE4 # NDgyMFowgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTAr # BgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUG # A1UECxMeblNoaWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxN # aWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEFAAOC # Ag8AMIICCgKCAgEAw3HV3hVxL0lEYPV03XeNKZ517VIbgexhlDPdpXwDS0BYtxPw # i4XYpZR1ld0u6cr2Xjuugdg50DUx5WHL0QhY2d9vkJSk02rE/75hcKt91m2Ih287 # QRxRMmFu3BF6466k8qp5uXtfe6uciq49YaS8p+dzv3uTarD4hQ8UT7La95pOJiRq # xxd0qOGLECvHLEXPXioNSx9pyhzhm6lt7ezLxJeFVYtxShkavPoZN0dOCiYeh4Kg # oKoyagzMuSiLCiMUW4Ue4Qsm658FJNGTNh7V5qXYVA6k5xjw5WeWdKOz0i9A5jBc # bY9fVOo/cA8i1bytzcDTxb3nctcly8/OYeNstkab/Isq3Cxe1vq96fIHE1+ZGmJj # ka1sodwqPycVp/2tb+BjulPL5D6rgUXTPF84U82RLKHV57bB8fHRpgnjcWBQuXPg # VeSXpERWimt0NF2lCOLzqgrvS/vYqde5Ln9YlKKhAZ/xDE0TLIIr6+I/2JTtXP34 # nfjTENVqMBISWcakIxAwGb3RB5yHCxynIFNVLcfKAsEdC5U2em0fAvmVv0sonqnv # 17cuaYi2eCLWhoK1Ic85Dw7s/lhcXrBpY4n/Rl5l3wHzs4vOIhu87DIy5QUaEupE # syY0NWqgI4BWl6v1wgse+l8DWFeUXofhUuCgVTuTHN3K8idoMbn8Q3edUIECAwEA # AaOCAUkwggFFMB0GA1UdDgQWBBSJIXfxcqAwFqGj9jdwQtdSqadj1zAfBgNVHSME # GDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5odHRw # Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBUaW1l # LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwGCCsG # AQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p # Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNVHRMB # Af8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDAN # BgkqhkiG9w0BAQsFAAOCAgEAd42HtV+kGbvxzLBTC5O7vkCIBPy/BwpjCzeL53hA # iEOebp+VdNnwm9GVCfYq3KMfrj4UvKQTUAaS5Zkwe1gvZ3ljSSnCOyS5OwNu9dpg # 3ww+QW2eOcSLkyVAWFrLn6Iig3TC/zWMvVhqXtdFhG2KJ1lSbN222csY3E3/BrGl # uAlvET9gmxVyyxNy59/7JF5zIGcJibydxs94JL1BtPgXJOfZzQ+/3iTc6eDtmaWT # 6DKdnJocp8wkXKWPIsBEfkD6k1Qitwvt0mHrORah75SjecOKt4oWayVLkPTho12e # 0ongEg1cje5fxSZGthrMrWKvI4R7HEC7k8maH9ePA3ViH0CVSSOefaPTGMzIhHCo # 5p3jG5SMcyO3eA9uEaYQJITJlLG3BwwGmypY7C/8/nj1SOhgx1HgJ0ywOJL9xfP4 # AOcWmCfbsqgGbCaC7WH5sINdzfMar8V7YNFqkbCGUKhc8GpIyE+MKnyVn33jsuaG # AlNRg7dVRUSoYLJxvUsw9GOwyBpBwbE9sqOLm+HsO00oF23PMio7WFXcFTZAjp3u # jihBAfLrXICgGOHPdkZ042u1LZqOcnlr3XzvgMe+mPPyasW8f0rtzJj3V5E/EKiy # QlPxj9Mfq2x9himnlXWGZCVPeEBROrNbDYBfazTyLNCOTsRtksOSV3FBtPnpQtLN # 754wggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3DQEB # CwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD # VQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAe # Fw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA5OGm # TOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/XE/H # ZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1hlDc # wUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7M62A # W36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3KNi1w # jjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy1cCG # MFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF803RKJ # 1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQcNIIP # 8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahhaYQFz # ymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkLiWHz # NgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV2xo3 # xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIGCSsG # AQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUpzxD/ # LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBTMFEG # DCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29m # dC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYIKwYB # BQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8G # A1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQw # VgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9j # cmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUF # BwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3Br # aS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQEL # BQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1OdfC # cTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYAA7AF # vonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbzaN9l # 9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6LGYnn # 8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3mSj5m # O0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0SCyx # TkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxkoJLo4 # S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFmPWn9 # y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC4822rpM # +Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7vzhw # RNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDWTCCAkEC # AQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0 # ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo2NTFBLTA1RTAtRDk0NzElMCMG # A1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIa # AxUAj6eTejbuYE1Ifjbfrt6tXevCUSCggYMwgYCkfjB8MQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T # dGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAO2heQUwIhgPMjAyNjA1MDMw # NzM0MjlaGA8yMDI2MDUwNDA3MzQyOVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA # 7aF5BQIBADAKAgEAAgIJowIB/zAHAgEAAgISdDAKAgUA7aLKhQIBADA2BgorBgEE # AYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYag # MA0GCSqGSIb3DQEBCwUAA4IBAQCrOcIVaAkw/PrB8wJN9p73l7REfyz7iPnOfU9C # 8PEXMkvj+YPwV0roGlbTSNv0bidbON1MUk8WgjEFBBwSp/0k65COmh/ppW11Gl2S # rfhOpprUrJmzOl1auKqxVTdbRE+CED52BnszfZrqmk4Mj238iP0VO6oxW9t4pfB/ # hVeTaf2igpMoTHdOoFV+wKOeDDk1XRR2+3GLmthZzSVSfvEqo+fD9Kpd8tmHsuW8 # ADnqYRlGxCwhDhsR5ElK105kpOGIj9VDNbwrvT9I6RLNj4Q/Dnhg8zRB5VtI807q # MWC8EKhsvMP1XhuFuV78ZuFyXeV+XfS4jx/WoAJhJMAFiUNkMYIEDTCCBAkCAQEw # gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAIVGAPTgQcmfFMA # AQAAAhUwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B # CRABBDAvBgkqhkiG9w0BCQQxIgQgipGl8Kd6OdmF5sCgakJ3BTZ+XJVmmeB7vGXF # H57sIHQwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBwEPR2PDrTFLcrtQsK # rUi7oz5JNRCF/KRHMihSNe7sijCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w # IFBDQSAyMDEwAhMzAAACFRgD04EHJnxTAAEAAAIVMCIEIBqc8pIbgkUBl+m5tNCz # IFlR5RUBapAjgKe/JVm88ntNMA0GCSqGSIb3DQEBCwUABIICAH/PpVrFQkhF4hIw # Onpk00pZ8+J9PgoKeGx6DKapRsu4IlYq3YnoOfed5eW3Qt//v/onnCRL9lmq3ror # 00Vigoy+IDivPdmRhBK97ZiIiOYxEURC9RUOp2LY0MKgM8IrLkn4HGu/NxTinbuu # vqn9NGLGOu9HSBgmRL9q9RH7y99/IEKVvqYXMt2lttzNpxherbUUpws58TcBdlvR # KFyTfN+iHXsWg1Ix/1h5nplLqAHL+hwbz7H1OXXOv3gEgjx91Afi5niiS2vQiMrR # Oi/4vBPoJBpvPqNsc8qWZWNNExHRBHRxTU8qf6O6XlTIT/vN783ZBZW9u8mxLIK7 # 0mTBRI/pBCHfY2Hp4pfluKPWTWp4nOVsTBgnaVlOXgSXy0S4FfqkevFlxzGsWjJy # ea6OMjURym34cWLgTUYSSIZgHeneomF9T7+hIdOTOiYxn/nXhUkZsi4M7NFr0IYn # 3lel/7cf6WQBRBWSlU17OUrIPoVa8Akc0STGjvknxEIt8TcRBhICIG6WeX9saB9W # Ng38QK80176Xt49oWMukUF60CGJP/J6L2quk8Hoq/0yjI0cTKAQd+l8DMj2BAWCv # spssQCXlY4m7/gj+NXLyM4KjX5HCehBM8XUtzzoVwYnMVx/9lKhMhE3VXE0lewH/ # 3Jcveck9ZqYQ+eKWZ32WV+jS2q1Q # SIG # End signature block |