AzStackHci.EnvironmentChecker.Utilities.psm1
Import-Module $PSScriptRoot\AzStackHci.EnvironmentChecker.Reporting.psm1 -Force -DisableNameChecking -Global Import-Module $PSScriptRoot\AzStackHci.EnvironmentChecker.PortableUtilities.psm1 -Force -DisableNameChecking -Global Import-LocalizedData -BindingVariable lTxt -FileName AzStackHci.EnvironmentChecker.Strings.psd1 function Test-ModuleUpdate { <# .SYNOPSIS Checks PSGallery for updated module. .DESCRIPTION Checks PSGallery for updated module and gives user 10 seconds to cancel cmdlet and prints update instructions to screen #> param([switch]$PassThru) try { if (-not $PassThru) { $thisVersion = (Get-PSCallStack | Where-Object Command -like 'Invoke-AzstackHci*Validation').InvocationInfo.MyCommand.Version Log-Info ("Looking for module updates for AzStackHci.EnvironmentChecker greater than {0}" -f [system.string]$thisVersion) $ModuleOnline = Find-Module -Name AzStackHci.EnvironmentChecker -Repository PSGallery -ErrorAction SilentlyContinue if ($ModuleOnline -ne $null) { if ([system.version]$($ModuleOnline.Version -replace ('-preview', '')) -gt $thisVersion) { Log-Info ($lTxt.UpdateToVersion -f $ModuleOnline.Version, $ModuleOnline.Name) -ConsoleOut Start-Sleep -Seconds 10 } else { Log-Info ($lTxt.CurrentVersion -f 'AzStackHci.EnvironmentChecker', [system.string]$thisVersion) } } else { Log-Info $lTxt.EnvCheckerVersionNotFound -ConsoleOut -Type Warning } } } catch { Log-Info ($lTxt.Exception -f $MyInvocation.MyCommand.Name, $_.exception.message) -Type Error } } function Test-Count { [CmdletBinding()] param ( [CimInstance[]] $CimData, [int] $minimum, [string] $ValidatorName, [validateset('CRITICAL','WARNING','INFORMATIONAL','Hidden')] [string] $Severity ) try { $className = $CimData.CimSystemProperties.ClassName -split '_' | Select-Object -Last 1 $serverName = $CimData.CimSystemProperties.ServerName | Sort-Object | Get-Unique $instanceId = "Machine: $serverName, Class: $ClassName" if ($CimData.Count -lt $minimum) { $status = 'FAILURE' $detail = $lTxt.MinCount -f $ClassName, $CimData.count, $minimum Log-Info $detail -Type $Severity } else { $detail = $lTxt.MinCount -f $ClassName, $CimData.count, $minimum $status = 'SUCCESS' } $params = @{ Name = 'AzStackHci_{0}_Test_{1}_Minimum_Count' -f $ValidatorName, $className Title = 'Test {0} Minimum Count' -f $className DisplayName = 'Test {0} Minimum Count {1}' -f $className, $serverName Severity = $Severity Description = 'Checking {0} minimum count' -f $className Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = $instanceId TargetResourceName = $instanceId TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = $status AdditionalData = @{ Source = "$ClassName Minimum Count" Resource = $CimData.count Detail = $detail Status = $status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } catch { throw $_ } } function Test-InstanceCountByGroup { <# .SYNOPSIS Test if count matches across groups #> [CmdletBinding()] param ( [CimInstance[]] $CimData, [string[]] $GroupProperty, [string] $ValidatorName, [validateset('CRITICAL','WARNING','INFORMATIONAL','Hidden')] [string] $Severity ) try { $GroupValues = $cimData | Group-Object -Property $groupProperty | Select-Object -ExpandProperty Name $nodeCount = @($cimData.CimSystemProperties.ServerName | Sort-Object | Get-Unique).count foreach ($GroupValue in $GroupValues) { foreach ($group in $GroupProperty) { $gData = $CimData | Where-Object $Group -eq $GroupValue if ($gData.CimSystemProperties.SystemName.Count -eq 1) { $serverName = $gData.CimSystemProperties.SystemName } else { $serverName = 'AllServers' } $className = $gData.CimSystemProperties.ClassName -split '_' | Select-Object -Last 1 $groupData = $gData | Group-Object { $_.CimSystemProperties.ServerName } | Select-Object *, @{label = 'InstanceCount'; e = { $_.count } } $groupDataCount = $groupData.InstanceCount | Sort-Object | Get-Unique # The count of InstanceCounts must equal the number of servers to ensure each server has at least 1 instance # e.g. SVR1 has 6 disks of type A, SVR has 6 disks of type A, but SVR3 could have 5 disks of type A. # There should be only 1 unique InstanceCount from all values to ensure each server has the same instance count # e.g. SVR1 has 6 disks of type A, SVR has 6 disks of type A, SVR3 has 6 disks of type A. $Status = if ($groupData.InstanceCount.Count -ne $nodeCount -or $groupDataCount.Count -gt 1 ) { 'FAILURE' } else { 'SUCCESS' } $groupDataString = ($groupData | Sort-Object InstanceCount | ForEach-Object { "{0}: {1} x {2}" -f $_.Name, $GroupValue, $_.InstanceCount }) -join "`r`n" $dtl = $lTxt.CountByGroup -f $className, $group, $groupDataString if ($status -eq 'SUCCESS') { Log-Info $dtl } else { Log-Info $dtl -Type Warning } $params = @{ Name = 'AzStackHci_{0}_Test_{1}_Instance_Consistency_Count_ByGroup' -f $ValidatorName, $className Title = 'Test {0} Instance Consistency By Group' -f $className DisplayName = 'Test {0} Instance Consistency By Group {1}' -f $className, $ServerName Severity = $Severity Description = 'Checking all servers have same {0} instance count by group' -f $className Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = "Machine: $ServerName, Class: $ClassName, Group: $GroupValue" TargetResourceName = "Machine: $ServerName, Class: $ClassName, Group: $GroupValue" TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = $status AdditionalData = @{ Source = $serverName Resource = $ClassName Detail = $dtl Status = $Status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } } } catch { throw $_ } } function Test-GroupProperty { <# .SYNOPSIS Test if properties match across groups #> [CmdletBinding()] param ( [CimInstance[]] $CimData, [string[]] $GroupProperty, [string[]] $MatchProperty, [string] $ValidatorName, [validateset('CRITICAL','WARNING','INFORMATIONAL','Hidden')] [string] $Severity ) try { # Group by name and compare properties within each group $className = $CimData.CimSystemProperties.ClassName -split '_' | Select-Object -Last 1 $ServerName = $CimData.CimSystemProperties.ServerName | Sort-Object | Get-Unique $groupedData = @($CimData | Group-Object -Property $groupProperty) $returnResult = @() if ($serverName.Count -gt 1) { $serverName = 'AllServers' } $returnResult += foreach ($group in $groupedData) { $instanceId = "Machine: {0}, Class: {1} Group: {2}" -f $ServerName, $className, $group.Name $groupName = $group.Name $detail = $null if ($group.Count -gt 1) { foreach ($propertyName in $matchProperty) { # Using Select-Object -Unique to get unique values because Get-Unique doesn't work with null and empty values if (($group.Group.$propertyName | Select-Object -Unique).Count -gt 1) { $status = 'FAILURE' $detail = $lTxt.MismatchProp -f $className, $propertyName, ("'{0}'" -f ($group.Group.$propertyName -join "', '")) Log-Info -Message $detail -Type Warning } else { $detail = $lTxt.MatchProp -f $className, $propertyName, ($group.Group.$propertyName -join ', ') $status = 'SUCCESS' } $params = @{ Name = 'AzStackHci_{0}_Test_{1}_Group_Consistency' -f $ValidatorName, $className Title = 'Test {0} Grouped by {1} has consistent {2} property values' -f $className, $groupName, $propertyName DisplayName = 'Test {0} Grouped by {1} has consistent {2} property values {3}' -f $className, $groupName, $propertyName, $ServerName Severity = $Severity Description = 'Checking {0} Grouped by {1} for consistent {2} property' -f $className, $groupName, $propertyName Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = "Machine: $ServerName, Class: $ClassName, Group: $GroupValue, Property: $propertyName" TargetResourceName = "Machine: $ServerName, Class: $ClassName, Group: $GroupValue, Property: $propertyName" TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = $status AdditionalData = @{ Source = "$serverName, $ClassName, $groupName, $propertName" Resource = ($group.Group.$propertyName -join "', '") Detail = $detail Status = $Status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } } } $returnResult } catch { throw $_ } } function Test-InstanceCount { <# .SYNOPSIS Test if instance count matches across instances #> [CmdletBinding()] param ( [Parameter()] [CimInstance[]] $CimData, [Parameter()] [string] $ValidatorName, [validateset('CRITICAL','WARNING','INFORMATIONAL','Hidden')] [string] $Severity, [Parameter()] [string] $NamePostFix ) if ($CimData.CimSystemProperties.SystemName.Count -eq 1) { $serverName = $CimData.CimSystemProperties.SystemName } else { $serverName = 'AllServers' } $className = $CimData.CimSystemProperties.ClassName -split '_' | Select-Object -Last 1 $InstanceId = "Machine: $ServerName, Class: $ClassName" $groupData = $cimData | Group-Object { $_.CimSystemProperties.ServerName } | Select-Object *, @{label = 'InstanceCount'; e = { $_.count } } $groupDataCount = $groupData.InstanceCount | Sort-Object | Get-Unique $status = if ($groupDataCount.Count -gt 1) { 'FAILURE' } else { 'SUCCESS' } $groupDataString = ($groupData | Sort-Object InstanceCount | ForEach-Object { "{0} x {1}" -f $_.Name, $_.InstanceCount }) -join "`r`n" if ($NamePostFix) { $Name = 'AzStackHci_{0}_Test_{1}_{2}_Instance_Consistency_Count' -f $ValidatorName, $className, $NamePostFix $Title = 'Test {0} {1} Instance Count Consistency' -f $className, $NamePostFix $DisplayName = 'Test {0} {1} Instance Count Consistency {2}' -f $className, $NamePostFix, $serverName $Description = 'Checking all servers have same {0} {1} instance count' -f $className, $NamePostFix $dtl = $lTxt.InstanceCount -f $ClassName, "($NamePostFix) ", $groupDataString } else { $Name = 'AzStackHci_{0}_Test_{1}_Instance_Consistency_Count' -f $ValidatorName, $className $Title = 'Test {0} Instance Count Consistency' -f $className $DisplayName = 'Test {0} Instance Count Consistency {1}' -f $className, $serverName $Description = 'Checking all servers have same {0} instance count' -f $className $dtl = $lTxt.InstanceCount -f $ClassName, $NamePostFix, $groupDataString } if ($Status -eq 'SUCCESS') { Log-Info $dtl } else { Log-Info $dtl -Type Warning } $params = @{ Name = $Name Title = $Title DisplayName = $DisplayName Severity = $Severity Description = $Description Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = $InstanceId TargetResourceName = $InstanceId TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = $status AdditionalData = @{ Source = $serverName Resource = $ClassName Detail = $dtl Status = $status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } function Test-PropertySync { <# .SYNOPSIS Test if properties match across instances #> [CmdletBinding()] param ( [Parameter()] [CimInstance[]] $CimData, [Parameter()] [string[]] $MatchProperty, [string] $ValidatorName, [validateset('CRITICAL','WARNING','INFORMATIONAL','Hidden')] [string] $Severity ) try { $returnResult = @() $className = $CimData.CimSystemProperties.ClassName -split '_' | Select-Object -Last 1 $serverName = $CimData.CimSystemProperties.ServerName | Sort-Object | Get-Unique if ($serverName.Count -gt 1) { $serverName = 'AllServers' $returnResult += Test-InstanceCount -CimData $CimData -Severity $Severity -ValidatorName $ValidatorName } $instanceId = "Machine: $ServerName, Class: $ClassName, Instance: All" $returnResult += if ($CimData.Count -gt 1) { foreach ($propertyName in $matchProperty) { # Using Select-Object -Unique to get unique values because Get-Unique doesn't work with null and empty values if (($CimData.$propertyName | Select-Object -Unique).Count -gt 1) { $status = 'FAILURE' $detail = $lTxt.MismatchProp -f $className, $propertyName, ("'{0}'" -f ($CimData.$propertyName -join "', '")) Log-Info -Message $detail -Type Warning } else { $detail = $lTxt.MatchProp -f $className, $propertyName, ($CimData.$propertyName -join ',') $status = 'SUCCESS' } $params = @{ Name = 'AzStackHci_{0}_Test_{1}_Property_{2}_Consistency' -f $ValidatorName, $className, $propertyName Title = 'Test {0} Property {1}' -f $className, $propertyName DisplayName = 'Test {0} Property {1} {2}' -f $className, $propertyName, $ServerName Severity = $Severity Description = 'Checking all {0} for consistent {1} property' -f $className, $propertyName Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = $InstanceId TargetResourceName = $InstanceId TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = $status AdditionalData = @{ Source = "$className`: $propertyName" Resource = $CimData.$propertyName -join ',' Detail = $detail Status = $status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } } return $returnResult } catch { throw $_ } } function Test-DesiredProperty { <# .SYNOPSIS Test if properties have required value #> [cmdletbinding()] param ( [CimInstance[]] $cimData, [hashtable] $desiredPropertyValue, [string] $InstanceIdStr, [string] $ValidatorName, [validateset('CRITICAL','WARNING','INFORMATIONAL','Hidden')] [string] $Severity ) try { # Test properties $returnResult = @() $returnResult += foreach ($instance in $cimData) { $serverName = $instance.CimSystemProperties.ServerName | Sort-Object | Get-Unique $className = $instance.CimSystemProperties.ClassName -split '_' | Select-Object -Last 1 $sb = ([scriptblock]::Create($InstanceIdStr)) $instanceId = Invoke-Command -ScriptBlock $sb Log-Info -Message ($lTxt.Test -f $className, $instanceId) foreach ($propertyName in $desiredPropertyValue.Keys) { $detail = $null $passed = $false $hint = $null $diagProp = $null $desiredPropertyValueCheck = $null $desiredPropertyValueCheck = if ($desiredPropertyValue.$propertyName -is [hashtable]) { $desiredPropertyValue.$propertyName.Value } else { $desiredPropertyValue.$propertyName } $instancePropertyValue = $instance.$propertyName | Select-Object -First 1 if ($instancePropertyValue -notin $desiredPropertyValueCheck) { # Try to add additional diagnostic property if ($desiredPropertyValue.$propertyName.DiagnosticProperty) { $diagProp = ' ({0}: {1})' -f $desiredPropertyValue.$propertyName.DiagnosticProperty, ($instance.$($desiredPropertyValue.$propertyName.DiagnosticProperty) | Select-Object -First 1) } $status = 'FAILURE' $hint = if ($desiredPropertyValue.$propertyName.hint) { ' ({0})' -f $desiredPropertyValue.$propertyName.hint } $detail = $lTxt.UnexProp -f $className, $propertyName, $instancePropertyValue, ($desiredPropertyValueCheck -join ','), $hint, $diagProp Log-Info -Message $detail -Type Warning } else { $status = 'SUCCESS' $detail = $lTxt.Prop -f $className, $propertyName, $instancePropertyValue, ($desiredPropertyValueCheck -join ','), $hint } $params = @{ Name = 'AzStackHci_{0}_Test_{1}_Instance_Property_{2}' -f $ValidatorName, $className, $propertyName Title = 'Test {0} Property {1}' -f $className, $propertyName DisplayName = 'Test {0} Property {1} {2}' -f $className, $propertyName, $ServerName Severity = $Severity Description = 'Checking {0} for property {1} has desired value' -f $className, $propertyName Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = $InstanceId TargetResourceName = $InstanceId TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = $status AdditionalData = @{ Source = "$className`: $propertyName" Resource = if ($hint) { "$($instancePropertyValue)$hint" } else { $instancePropertyValue } Detail = $detail Status = $status TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } } return $returnResult } catch { throw $_ } } function Get-TestCount { param ( [Parameter()] [string] $ModuleName, [Parameter()] [string] $CommandPrefix ) try { $command = Get-Command -Name $CommandPrefix* -Module $ModuleName if ($command) { return $command.Count } else { return 1 } } catch { return 1 } } function Test-CimData { param ( $Data, $ClassName, $Detail ) $systemNames = $Data.ComputerName | Sort-Object | Get-Unique $testResult = foreach ($systemName in $systemNames) { $sData = $Data.CimData | Where-Object { $_.CimSystemProperties.ServerName -eq $systemName } if ($sData.count -eq 0) { $params = @{ Name = 'AzStackHci_Hardware_Test_{0}' -f $className Title = "Test $ClassName API" DisplayName = "Test $ClassName API $systemName" Severity = 'CRITICAL' Description = "Checking $ClassName has CIM data" Tags = @{} Remediation = 'https://aka.ms/hci-envch' TargetResourceID = "Machine: $systemName, Class: $ClassName" TargetResourceName = "Machine: $systemName, Class: $ClassName" TargetResourceType = $className Timestamp = [datetime]::UtcNow Status = 'FAILURE' AdditionalData = @{ Source = $systemName Resource = 'Null' Detail = if ([string]::IsNullOrEmpty($detail)) { "Unable to retrieve data for $ClassName on $systemName" } else { $Detail } Status = 'FAILURE' TimeStamp = [datetime]::UtcNow } HealthCheckSource = $ENV:EnvChkrId } New-AzStackHciResultObject @params } } return $testResult } function Get-DeploymentData { [cmdletbinding()] param ($Path) try { $Json = Get-Content -Path $Path | ConvertFrom-Json $DeploymentData = $json.ScaleUnits[0].DeploymentData if ([string]::IsNullOrEmpty($DeploymentData)) { Log-Info $lTxt.InvalidDeploymentData -Type Warning return $null } return $DeploymentData } catch { throw $_ } } function Get-TestListByFunction { <# .SYNOPSIS Retrieve list of tests for a given validator .DESCRIPTION Tests should be prefixed with Test- and reside in a "helpers" module #> [CmdletBinding()] param ( [Parameter()] [string] $prefix = 'Test-*', [Parameter()] [string] $ModuleName ) try { $script:envchktestList = Get-Command -Name $prefix -Module $ModuleName | Select-Object -ExpandProperty Name Write-Debug -Message "Retrieving list of tests for $($validator.Command): $($script:envchktestList -join ',')" -verbose return $script:envchktestList } catch { Write-Debug -Message "Failed to retrieve test list. Error $($_.exception)" -Verbose } } function Select-TestList { <# .SYNOPSIS Filter Testlist by Include, Exclude and File based exclusions .DESCRIPTION Include replaces complete list, exclude is applied and file based exclusions are removed by regex. #> [CmdletBinding()] param ( [Parameter()] [string[]] $TestList, [Parameter()] [string[]] $Include, [Parameter()] [string[]] $Exclude, [Parameter()] [string] $FilePath = "$PsScriptRoot\ExcludeTests.txt" ) try { $returnList = @($TestList) if ($include) { $returnList = $Include Log-Info "Setting tests to $($include -join ',')" } if ($exclude) { Log-Info "Removing tests $($exclude -join ',')" $returnList = $returnList | Select-String -Pattern $exclude -NotMatch } if ($returnList.count -eq 0) { throw "No tests to perform after filtering" } if (Test-Path -Path $FilePath) { $fileExclusion = Get-Content -Path $FilePath Log-Info "Reading exclusion file $FilePath" -ConsoleOut Log-Info "Applying file exclusions: $($fileExclusion -join ',')" -ConsoleOut $returnList = $returnList | Select-String -Pattern $fileExclusion -NotMatch } Log-Info "Test list: $($returnList -join ',')" if ($returnList.Count -eq 0) { Log-Info -Message "No tests to run." -ConsoleOut -Type Warning break noTestsBreak } return $returnList } catch { Log-Info "Failed to filter test list. Error: $($_.exception)" -Type Warning } } function Set-TrustedHosts { [CmdletBinding()] param ( [Parameter()] [string[]] $Nodes ) $trustedHosts = (Get-Item -Path WSMan:\localhost\Client\TrustedHosts).Value foreach ($node in $nodes) { if ('*' -notin $TrustedHosts -and ($node -notin $TrustedHosts.Split(','))) { Log-Info "Adding $node to TrustedHosts" Set-Item WSMan:\localhost\Client\TrustedHosts -Value $node -Concatenate -Force } else { Log-Info "TrustedHosts already matches $node. Continuing." } } } function Get-IsProxyEnabled { $line1, $line2, $line3, $JsonLines = netsh winhttp show advproxy $proxy = $JsonLines | ConvertFrom-Json -ErrorAction SilentlyContinue Log-Info "Proxy Enabled: $([bool]$proxy.Proxy)" Log-Info "Proxy Output:" Log-Info "$($proxy | Format-Table | Out-String)" [bool]$proxy.Proxy } Export-ModuleMember -Function Get-DeploymentData Export-ModuleMember -Function Get-IsProxyEnabled Export-ModuleMember -Function Get-TestCount Export-ModuleMember -Function Get-TestListByFunction Export-ModuleMember -Function Select-TestList Export-ModuleMember -Function Set-TrustedHosts Export-ModuleMember -Function Test-Count Export-ModuleMember -Function Test-DesiredProperty Export-ModuleMember -Function Test-GroupProperty Export-ModuleMember -Function Test-InstanceCount Export-ModuleMember -Function Test-InstanceCountByGroup Export-ModuleMember -Function Test-ModuleUpdate Export-ModuleMember -Function Test-PropertySync Export-ModuleMember -Function Test-CimData # SIG # Begin signature block # MIIoRgYJKoZIhvcNAQcCoIIoNzCCKDMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCADTn9js6tx9R0r # 5MyWti/jnmOu6xKCnPqlUma3qb6nhaCCDXYwggX0MIID3KADAgECAhMzAAAEhV6Z # 7A5ZL83XAAAAAASFMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjUwNjE5MTgyMTM3WhcNMjYwNjE3MTgyMTM3WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDASkh1cpvuUqfbqxele7LCSHEamVNBfFE4uY1FkGsAdUF/vnjpE1dnAD9vMOqy # 5ZO49ILhP4jiP/P2Pn9ao+5TDtKmcQ+pZdzbG7t43yRXJC3nXvTGQroodPi9USQi # 9rI+0gwuXRKBII7L+k3kMkKLmFrsWUjzgXVCLYa6ZH7BCALAcJWZTwWPoiT4HpqQ # hJcYLB7pfetAVCeBEVZD8itKQ6QA5/LQR+9X6dlSj4Vxta4JnpxvgSrkjXCz+tlJ # 67ABZ551lw23RWU1uyfgCfEFhBfiyPR2WSjskPl9ap6qrf8fNQ1sGYun2p4JdXxe # UAKf1hVa/3TQXjvPTiRXCnJPAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUuCZyGiCuLYE0aU7j5TFqY05kko0w # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwNTM1OTAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBACjmqAp2Ci4sTHZci+qk # tEAKsFk5HNVGKyWR2rFGXsd7cggZ04H5U4SV0fAL6fOE9dLvt4I7HBHLhpGdE5Uj # Ly4NxLTG2bDAkeAVmxmd2uKWVGKym1aarDxXfv3GCN4mRX+Pn4c+py3S/6Kkt5eS # DAIIsrzKw3Kh2SW1hCwXX/k1v4b+NH1Fjl+i/xPJspXCFuZB4aC5FLT5fgbRKqns # WeAdn8DsrYQhT3QXLt6Nv3/dMzv7G/Cdpbdcoul8FYl+t3dmXM+SIClC3l2ae0wO # lNrQ42yQEycuPU5OoqLT85jsZ7+4CaScfFINlO7l7Y7r/xauqHbSPQ1r3oIC+e71 # 5s2G3ClZa3y99aYx2lnXYe1srcrIx8NAXTViiypXVn9ZGmEkfNcfDiqGQwkml5z9 # nm3pWiBZ69adaBBbAFEjyJG4y0a76bel/4sDCVvaZzLM3TFbxVO9BQrjZRtbJZbk # C3XArpLqZSfx53SuYdddxPX8pvcqFuEu8wcUeD05t9xNbJ4TtdAECJlEi0vvBxlm # M5tzFXy2qZeqPMXHSQYqPgZ9jvScZ6NwznFD0+33kbzyhOSz/WuGbAu4cHZG8gKn # lQVT4uA2Diex9DMs2WHiokNknYlLoUeWXW1QrJLpqO82TLyKTbBM/oZHAdIc0kzo # STro9b3+vjn2809D0+SOOCVZMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr # /Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAASFXpnsDlkvzdcAAAAABIUwDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINcGgsFdfu/FlQPqwjXraP2n # FAWD/5QVEooG6J3A3EUrMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAJOpetQbv2zk3S7JRHJ04iOe386VN3rGxLBA2CwyDJ8aSeqFEzyg+3f08 # jdNzMCXWbpCH0CSk8a38izoY19I/e9K7hNguSCuiVixc3c4j1WF8X5eRko+vgMdQ # HggaD9tD8Bm/PqWJB7KepiTw8AvBlBH0DO514XM4HiGGpjC4OS+HLdzqJ0AvOeft # Vy+Bj4qRH2BNj3u4OZ8OPOVXuA4s8s58emPe9eSx+TtdaGu/NRCZR9AzusrL1idU # 8h1pZTY7gr2u5WvgHO3R3+uHioKWjeDctJ1kWl0bVm2ahHBxv0R+HgpUQSRm/N9M # z8RaioNW2td0Hw4cicACq4wsvOYFvqGCF7AwghesBgorBgEEAYI3AwMBMYIXnDCC # F5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq # hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCBR9NJW0Qxq8IG5K7r0RFKO/OPg56ogd7TmrxSkA9fnqgIGaK4AZHkO # GBMyMDI1MDkwOTE5MjIxMy43ODVaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT # TjozNjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB91ggdQTK+8L0AAEAAAH3MA0G # CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0 # MDcyNTE4MzEwNloXDTI1MTAyMjE4MzEwNlowgdMxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w # ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjM2MDUt # MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl # MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA0OdHTBNom6/uXKaEKP9r # PITkT6QxF11tjzB0Nk1byDpPrFTHha3hxwSdTcr8Y0a3k6EQlwqy6ROz42e0R5eD # W+dCoQapipDIFUOYp3oNuqwX/xepATEkY17MyXFx6rQW2NcWUJW3Qo2AuJ0HOtbl # SpItQZPGmHnGqkt/DB45Fwxk6VoSvxNcQKhKETkuzrt8U6DRccQm1FdhmPKgDzgc # fDPM5o+GnzbiMu6y069A4EHmLMmkecSkVvBmcZ8VnzFHTDkGLdpnDV5FXjVObAgb # SM0cnqYSGfRp7VGHBRqyoscvR4bcQ+CV9pDjbJ6S5rZn1uA8hRhj09Hs33HRevt4 # oWAVYGItgEsG+BrCYbpgWMDEIVnAgPZEiPAaI8wBGemE4feEkuz7TAwgkRBcUzLg # Q4uvPqRD1A+Jkt26+pDqWYSn0MA8j0zacQk9q/AvciPXD9It2ez+mqEzgFRRsJGL # tcf9HksvK8Jsd6I5zFShlqi5bpzf1Y4NOiNOh5QwW1pIvA5irlal7qFhkAeeeZqm # op8+uNxZXxFCQG3R3s5pXW89FiCh9rmXrVqOCwgcXFIJQAQkllKsI+UJqGq9rmRA # BJz5lHKTFYmFwcM52KWWjNx3z6odwz2h+sxaxewToe9GqtDx3/aU+yqNRcB8w0tS # XUf+ylN4uk5xHEpLpx+ZNNsCAwEAAaOCAUkwggFFMB0GA1UdDgQWBBTfRqQzP3m9 # PZWuLf1p8/meFfkmmDAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf # BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww # bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m # dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El # MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF # BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAN0ajafILeL6S # QIMIMAXM1Qd6xaoci2mOrpR8vKWyyTsL3b83A7XGLiAbQxTrqnXvVWWeNst5YQD8 # saO+UTgOLJdTdfUADhLXoK+RlwjfndimIJT9MH9tUYXLzJXKhZM09ouPwNsrn8YO # LIpdAi5TPyN8Cl11OGZSlP9r8JnvomW00AoJ4Pl9rlg0G5lcQknAXqHa9nQdWp1Z # xXqNd+0JsKmlR8tcANX33ClM9NnaClJExLQHiKeHUUWtqyLMl65TW6wRM7XlF7Y+ # PTnC8duNWn4uLng+ON/Z39GO6qBj7IEZxoq4o3avEh9ba43UU6TgzVZaBm8VaA0w # SwUe/pqpTOYFWN62XL3gl/JC2pzfIPxP66XfRLIxafjBVXm8KVDn2cML9IvRK02s # 941Y5+RR4gSAOhLiQQ6A03VNRup+spMa0k+XTPAi+2aMH5xa1Zjb/K8u9f9M05U0 # /bUMJXJDP++ysWpJbVRDiHG7szaca+r3HiUPjQJyQl2NiOcYTGV/DcLrLCBK2zG5 # 03FGb04N5Kf10XgAwFaXlod5B9eKh95PnXKx2LNBgLwG85anlhhGxxBQ5mFsJGkB # n0PZPtAzZyfr96qxzpp2pH9DJJcjKCDrMmZziXazpa5VVN36CO1kDU4ABkSYTXOM # 8RmJXuQm7mUF3bWmj+hjAJb4pz6hT5UwggdxMIIFWaADAgECAhMzAAAAFcXna54C # m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp # Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy # MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B # AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51 # yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY # 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9 # cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN # 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua # Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74 # kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2 # K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5 # TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk # i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q # BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri # Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC # BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl # pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y # eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA # YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw # MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w # Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp # b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm # ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM # 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW # OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4 # FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw # xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX # fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX # VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC # onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU # 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG # ahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT # TjozNjA1LTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAb28KDG/xXbNBjmM7/nqw3bgrEOaggYMw # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF # AAIFAOxq8pcwIhgPMjAyNTA5MDkxODM4MTVaGA8yMDI1MDkxMDE4MzgxNVowdzA9 # BgorBgEEAYRZCgQBMS8wLTAKAgUA7GrylwIBADAKAgEAAgINHwIB/zAHAgEAAgIS # bTAKAgUA7GxEFwIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAow # CAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQCci/U8+1q6 # fcU7WFBoNUIo+2hatCWHaQ4tU2U4J+IKP29VQcsCVisbBwEgK2iP8uo25iJcEmE2 # ZVesSvXILY1V1jl9aIF2NHeUrLCYVxKeZeJD2DSH2hGN8bAr8RhYYBtkBaJTXhg7 # c26HFOx/2hni7hW558CrWN0FLsiWwADg+vCETkazCOtr2qlYeviS1RzPk8GO8Azm # 7pIHCNm+Ikw+R0cl35488IJ1z6tTTp3rB40hPzJpoHQwxHtMZwbDuuLEUqfDLyD9 # H0GoiN4JyxfGUFb8TwndHCT042+UMZ+moiKDlYsVlczZWQF+gUj5r1tZePB4iTqI # +Qgrdmc7K0wrMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTACEzMAAAH3WCB1BMr7wvQAAQAAAfcwDQYJYIZIAWUDBAIBBQCgggFKMBoG # CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg5VA/cR0x # 2E6es3ucQi4gqB34SEAA8aq2Ro+jG5V5YAYwgfoGCyqGSIb3DQEJEAIvMYHqMIHn # MIHkMIG9BCAh2pjaa3ca0ecYuhu60uYHP/IKnPbedbVQJ5SoIH5Z4jCBmDCBgKR+ # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB91ggdQTK+8L0AAEA # AAH3MCIEIL+6hbbv23au5YgRuXSXMgngfLinSQ+d36lqwsYVtvLCMA0GCSqGSIb3 # DQEBCwUABIICAL3GdMUOuiJTZ0NOD19IE9s3O19KpPJDNHQnl76SssLpsWVftBKS # Yk8q3OUzDuZtUzgMSv+c/75+5WuwDj0RlLmPafRvY7mtoQxopIrqxtooGa+MZIsU # u7UT641y2gNPhlxXHWhgI2CItzZwXKfmWZfS4lbKkdYDSJm/ZWR789yWbm5pHkud # QFfRWIGnpgSAUDviTynsB90fVowh4CteGCcyrYThh5kUO/xACKLCBbYbizRC8H2s # cna6ntmqcegibmG9zSB6YOgqjU6/Rf5u6N88iG/0t24yo8Arm4jw2vrvQa45nOeT # fK99H9PBOhejfurdNAWvm4eboboNG/F9dGv6H4UvoZo1b1STnKMh2FpB0wn32IIK # 6s9cgn7yeiAHsGr8BVjzX+cwK+aHjMMcmr77ZSPmxQzf52sLxs311gbMPeXG0MNo # IxUh3pklf6RKiYC5Xqi++qs9VX49Dyi59/Z1OyiEf7YveQEYKtFbWzL8eiHnAVJl # RfJDH+fewR7RzZsbUAwzwPfwcGFlpvkQrGlnH7HhSERafwpWRxEuVb/t49jAL9DE # iLs/LFZ6IMT0+42LgXghmEkIjWSRiFXS8IuNjFq2tc08XCT9gSG/waaU+svRaavi # Wk7R8vdikLcUE/WfQ3G3C9hpsXWGS9hxqbY0OBu4ckGSTP3D43w+Qv1h # SIG # End signature block |