| Server IP : 121.121.20.254 / Your IP : 216.73.216.142 Web Server : Microsoft-IIS/10.0 System : Windows NT WEB-SERVER 10.0 build 20348 (Windows Server 2022) AMD64 User : IUSR ( 0) PHP Version : 8.3.28 Disable Function : NONE MySQL : ON | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Program Files/WindowsPowerShell/Modules/Pester/3.4.0/ |
Upload File : |
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$manifestPath = "$here\Pester.psd1"
$changeLogPath = "$here\CHANGELOG.md"
# DO NOT CHANGE THIS TAG NAME; IT AFFECTS THE CI BUILD.
Describe -Tags 'VersionChecks' "Pester manifest and changelog" {
$script:manifest = $null
It "has a valid manifest" {
{
$script:manifest = Test-ModuleManifest -Path $manifestPath -ErrorAction Stop -WarningAction SilentlyContinue
} | Should Not Throw
}
It "has a valid name in the manifest" {
$script:manifest.Name | Should Be Pester
}
It "has a valid guid in the manifest" {
$script:manifest.Guid | Should Be 'a699dea5-2c73-4616-a270-1f7abb777e71'
}
It "has a valid version in the manifest" {
$script:manifest.Version -as [Version] | Should Not BeNullOrEmpty
}
$script:changelogVersion = $null
It "has a valid version in the changelog" {
foreach ($line in (Get-Content $changeLogPath))
{
if ($line -match "^\D*(?<Version>(\d+\.){1,3}\d+)")
{
$script:changelogVersion = $matches.Version
break
}
}
$script:changelogVersion | Should Not BeNullOrEmpty
$script:changelogVersion -as [Version] | Should Not BeNullOrEmpty
}
It "changelog and manifest versions are the same" {
$script:changelogVersion -as [Version] | Should be ( $script:manifest.Version -as [Version] )
}
if (Get-Command git.exe -ErrorAction SilentlyContinue) {
$script:tagVersion = $null
It "is tagged with a valid version" {
$thisCommit = git.exe log --decorate --oneline HEAD~1..HEAD
if ($thisCommit -match 'tag:\s*(\d+(?:\.\d+)*)')
{
$script:tagVersion = $matches[1]
}
$script:tagVersion | Should Not BeNullOrEmpty
$script:tagVersion -as [Version] | Should Not BeNullOrEmpty
}
It "all versions are the same" {
$script:changelogVersion -as [Version] | Should be ( $script:manifest.Version -as [Version] )
$script:manifest.Version -as [Version] | Should be ( $script:tagVersion -as [Version] )
}
}
}
if ($PSVersionTable.PSVersion.Major -ge 3)
{
$error.Clear()
Describe 'Clean treatment of the $error variable' {
Context 'A Context' {
It 'Performs a successful test' {
$true | Should Be $true
}
}
It 'Did not add anything to the $error variable' {
$error.Count | Should Be 0
}
}
InModuleScope Pester {
Describe 'SafeCommands table' {
$path = $ExecutionContext.SessionState.Module.ModuleBase
$filesToCheck = Get-ChildItem -Path $path -Recurse -Include *.ps1,*.psm1 -Exclude *.Tests.ps1
$callsToSafeCommands = @(
foreach ($file in $files)
{
$tokens = $parseErrors = $null
$ast = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref] $tokens, [ref] $parseErrors)
$filter = {
$args[0] -is [System.Management.Automation.Language.CommandAst] -and
$args[0].InvocationOperator -eq [System.Management.Automation.Language.TokenKind]::Ampersand -and
$args[0].CommandElements[0] -is [System.Management.Automation.Language.IndexExpressionAst] -and
$args[0].CommandElements[0].Target -is [System.Management.Automation.Language.VariableExpressionAst] -and
$args[0].CommandElements[0].Target.VariablePath.UserPath -match '^(?:script:)?SafeCommands$'
}
$ast.FindAll($filter, $true)
}
)
$uniqueSafeCommands = $callsToSafeCommands | ForEach-Object { $_.CommandElements[0].Index.Value } | Select-Object -Unique
$missingSafeCommands = $uniqueSafeCommands | Where-Object { -not $script:SafeCommands.ContainsKey($_) }
It 'The SafeCommands table contains all commands that are called from the module' {
$missingSafeCommands | Should Be $null
}
}
}
}
Describe 'Style rules' {
$pesterRoot = (Get-Module Pester).ModuleBase
$files = @(
Get-ChildItem $pesterRoot -Include *.ps1,*.psm1
Get-ChildItem $pesterRoot\Functions -Include *.ps1,*.psm1 -Recurse
)
It 'Pester source files contain no trailing whitespace' {
$badLines = @(
foreach ($file in $files)
{
$lines = [System.IO.File]::ReadAllLines($file.FullName)
$lineCount = $lines.Count
for ($i = 0; $i -lt $lineCount; $i++)
{
if ($lines[$i] -match '\s+$')
{
'File: {0}, Line: {1}' -f $file.FullName, ($i + 1)
}
}
}
)
if ($badLines.Count -gt 0)
{
throw "The following $($badLines.Count) lines contain trailing whitespace: `r`n`r`n$($badLines -join "`r`n")"
}
}
It 'Pester Source Files all end with a newline' {
$badFiles = @(
foreach ($file in $files)
{
$string = [System.IO.File]::ReadAllText($file.FullName)
if ($string.Length -gt 0 -and $string[-1] -ne "`n")
{
$file.FullName
}
}
)
if ($badFiles.Count -gt 0)
{
throw "The following files do not end with a newline: `r`n`r`n$($badFiles -join "`r`n")"
}
}
}
InModuleScope Pester {
Describe 'ResolveTestScripts' {
Setup -File SomeFile.ps1
Setup -File SomeFile.Tests.ps1
Setup -File SomeOtherFile.ps1
Setup -File SomeOtherFile.Tests.ps1
It 'Resolves non-wildcarded file paths regardless of whether the file ends with Tests.ps1' {
$result = @(ResolveTestScripts $TestDrive\SomeOtherFile.ps1)
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeOtherFile.ps1"
}
It 'Finds only *.Tests.ps1 files when the path contains wildcards' {
$result = @(ResolveTestScripts $TestDrive\*.ps1)
$result.Count | Should Be 2
$paths = $result | Select-Object -ExpandProperty Path
($paths -contains "$TestDrive\SomeFile.Tests.ps1") | Should Be $true
($paths -contains "$TestDrive\SomeOtherFile.Tests.ps1") | Should Be $true
}
It 'Finds only *.Tests.ps1 files when the path refers to a directory and does not contain wildcards' {
$result = @(ResolveTestScripts $TestDrive)
$result.Count | Should Be 2
$paths = $result | Select-Object -ExpandProperty Path
($paths -contains "$TestDrive\SomeFile.Tests.ps1") | Should Be $true
($paths -contains "$TestDrive\SomeOtherFile.Tests.ps1") | Should Be $true
}
It 'Assigns empty array and hashtable to the Arguments and Parameters properties when none are specified by the caller' {
$result = @(ResolveTestScripts "$TestDrive\SomeFile.ps1")
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
,$result[0].Arguments | Should Not Be $null
,$result[0].Parameters | Should Not Be $null
$result[0].Arguments.GetType() | Should Be ([object[]])
$result[0].Arguments.Count | Should Be 0
$result[0].Parameters.GetType() | Should Be ([hashtable])
$result[0].Parameters.PSBase.Count | Should Be 0
}
Context 'Passing in Dictionaries instead of Strings' {
It 'Allows the use of a "P" key instead of "Path"' {
$result = @(ResolveTestScripts @{ P = "$TestDrive\SomeFile.ps1" })
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
}
$testArgs = @('I am a string')
It 'Allows the use of an "Arguments" key in the dictionary' {
$result = @(ResolveTestScripts @{ Path = "$TestDrive\SomeFile.ps1"; Arguments = $testArgs })
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
$result[0].Arguments.Count | Should Be 1
$result[0].Arguments[0] | Should Be 'I am a string'
}
It 'Allows the use of an "Args" key in the dictionary' {
$result = @(ResolveTestScripts @{ Path = "$TestDrive\SomeFile.ps1"; Args = $testArgs })
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
$result[0].Arguments.Count | Should Be 1
$result[0].Arguments[0] | Should Be 'I am a string'
}
It 'Allows the use of an "A" key in the dictionary' {
$result = @(ResolveTestScripts @{ Path = "$TestDrive\SomeFile.ps1"; A = $testArgs })
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
$result[0].Arguments.Count | Should Be 1
$result[0].Arguments[0] | Should Be 'I am a string'
}
$testParams = @{ MyKey = 'MyValue' }
It 'Allows the use of a "Parameters" key in the dictionary' {
$result = @(ResolveTestScripts @{ Path = "$TestDrive\SomeFile.ps1"; Parameters = $testParams })
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
$result[0].Parameters.PSBase.Count | Should Be 1
$result[0].Parameters['MyKey'] | Should Be 'MyValue'
}
It 'Allows the use of a "Params" key in the dictionary' {
$result = @(ResolveTestScripts @{ Path = "$TestDrive\SomeFile.ps1"; Params = $testParams })
$result.Count | Should Be 1
$result[0].Path | Should Be "$TestDrive\SomeFile.ps1"
$result[0].Parameters.PSBase.Count | Should Be 1
$result[0].Parameters['MyKey'] | Should Be 'MyValue'
}
It 'Throws an error if no Path is specified' {
{ ResolveTestScripts @{} } | Should Throw
}
It 'Throws an error if a Parameters key is used, but does not contain an IDictionary object' {
{ ResolveTestScripts @{ P='P'; Params = 'A string' } } | Should Throw
}
}
}
}
# SIG # Begin signature block
# MIInZwYJKoZIhvcNAQcCoIInWDCCJ1QCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBfE/e7u3jI6yz7
# QBumibsiH2jWUPju+4aTP+s3pHx6C6CCC7QwggXLMIIEs6ADAgECAhMzAAABQGf2
# mGsxCLhyAAAAAAFAMA0GCSqGSIb3DQEBCwUAMIGOMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMTgwNgYDVQQDEy9NaWNyb3NvZnQgV2luZG93cyBU
# aGlyZCBQYXJ0eSBDb21wb25lbnQgQ0EgMjAxMjAeFw0yNTExMTMxOTU5NDNaFw0y
# NjExMTAxOTU5NDNaMIGEMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMS4wLAYDVQQDEyVNaWNyb3NvZnQgV2luZG93cyAzcmQgcGFydHkgQ29tcG9u
# ZW50MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEArGt4Hrjs3D7+IIab
# GkPGtg4XeWQFi8nKsdeF+N6nkYF9wsmw0qPk4OovEiJnCSRiEtLfYy3Icn4iOp7L
# 24oCa0zlgYCND3OnNfYOuVpMsq3CSkXYg3H+VMiB11hOLcctTu4RWy4ZRKsL5NVI
# AduJFgd/1Qs2mQpUuOyFfLKhu/+Z+T2c9YALxsfnPvqn8Tn8Tt8wdZuFwz7kK3jl
# e2T3YBofybAR2aH678TnOxhLe2/hEpTdKaVfcqyrIX0Mw/LwqEJnj4G8amBbQ7OG
# RnKm1VNd4nMpRt1SflNlVo1Q3Qqnj9K6mSPw99YGMCTaVr6jKPylsWyW4nsvu8m0
# MbBJJiLOi0sOTHtwQEVcBH6WM7xbODqwPaklS1wDbED1wfzImIUR8WsXJVjDm7Fg
# x4JDo8oLIjKFrEvzBfrYWsvlDg8p9XgR7EB/IJwXGuJbFzo/S+r3D5DkUZXX/72k
# XA4FeRJAgLePAuGChPvyQiLtKJeJm9ftJeukrIcs7JpJVHObAgMBAAGjggGoMIIB
# pDATBgNVHSUEDDAKBggrBgEFBQcDAzAdBgNVHQ4EFgQUB9FDBUZ0W11vsv6qqb9t
# vKspCIowRQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEWMBQGA1UEBRMNMjMwODA5KzUwNjIyOTAfBgNVHSMEGDAWgBRhcaeHr/9p
# 1SF2T1KTKAC+eRKrhDB0BgNVHR8EbTBrMGmgZ6BlhmNodHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBXaW5kb3dzJTIwVGhpcmQl
# MjBQYXJ0eSUyMENvbXBvbmVudCUyMENBJTIwMjAxMi5jcmwwgYEGCCsGAQUFBwEB
# BHUwczBxBggrBgEFBQcwAoZlaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jZXJ0cy9NaWNyb3NvZnQlMjBXaW5kb3dzJTIwVGhpcmQlMjBQYXJ0eSUyMENv
# bXBvbmVudCUyMENBJTIwMjAxMi5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0B
# AQsFAAOCAQEAmFzJPKhkAXPOcfy9S4q1nP3XCvmABVGv/VRzFZ1e+oVtVzOFkbZ6
# osY1OpZqa9CEvtgcrtciv1y9mV1SpxAMwfEqq+Nhw2GdZ3IWqFzWFsEe2S9U196s
# XRIRIxglZMBWyzdy8rQ+P7L2+LciW4qcaw2wtv6YoI0q1isgk0t1OF5kEL0t9hhx
# UrBavTdoqZ3b5JtwDqzmIsxuLtGbE9Pqbz2gx/me+7yduYpIcYlmEmPQkg3gmWkZ
# lnSRePu7/5RXS2TGW1O5JP8aqVcMn0ZkHEhtT368pE/CxQVAkAYHNz6+enP9n+HC
# 2udu395c0fVlRHy/d53f32RukfbjakH8uzCCBeEwggPJoAMCAQICCmELqsEAAAAA
# AAkwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1
# dGhvcml0eSAyMDEwMB4XDTEyMDQxODIzNDgzOFoXDTI3MDQxODIzNTgzOFowgY4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xODA2BgNVBAMTL01p
# Y3Jvc29mdCBXaW5kb3dzIFRoaXJkIFBhcnR5IENvbXBvbmVudCBDQSAyMDEyMIIB
# IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo5wwhAmnYy7PCkfw6iT5ozAg
# D15XMSaBmjEHslDUzmcJCGUKWqVLrtXtEC7npZm1n2gvmItYAqwgtCnEcb0oHKX9
# PJtk5MXr32ElvPDuaL/Rp8t+KgKBTmRcDFOGeVcZN2G3mPkMoE4iWZv5Gy1nPCc8
# VpBm4/1/ZX0Phr01R+iKzPTajulqTqunVeyiiR7VM0VTy/med73NLPkFuH90AR3o
# +xjhQ9EN6arcN2+9/rgP7R1NAUZOCqz8gujsVoMTjjoB7RRkdOpksmYQtmhtyHAA
# fVBILj1D7uAklcbNjsf9uOSVz91++5VeoQHNQ7EH16Qw7puGGipuwQtZonRviwID
# AQABo4IBQzCCAT8wEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFGFxp4ev/2nV
# IXZPUpMoAL55EquEMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQE
# AwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQ
# W9fOmhjEMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNv
# bS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBa
# BggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqG
# SIb3DQEBCwUAA4ICAQBaimfazNX9DSZBd78KRni0s94SaSt3I8JlLwFf0gP0YbpQ
# nS6MOXLzbD5qsR52bey384LczLvFaXAoc2YXP1Tr7gEWSMRG2RuAroE6jQ95bWiw
# nuotPznTyjh+vV58CG4Z3MbC9DgzaGHiUkeD4QABVtK6y4eCBTEKQYtO539fX+1f
# 0zktReuiE7/9HsKYQXFhFl/ICnAlfFlpMSTkcecKuwQX959yHsnSuxq+PQL+CQyy
# Q7RZGplTk5YhX+DWtyYBQpU2rCf9vvSFd2g9GL30vpiIIhGGUhbzRewDlxBwh6Nw
# Q3E828mGAxcM9XNbxn3hXGTt18VI1+0y4tGq08+n9ldOYfl362fyiLPeANoDj9CK
# NDc+HdhiuNKx8+Evi3I7gZZ8b/zsZnZyYBsk8qCJbVttAC7vKN2GhwXCtLnlvmTC
# KvJKFVyY4sQnhf9S42J+D7ICC9dmxwqy0z0gBBRQMlmDCn2b7Vo4EgFSui9eIHKO
# SvH953ECjDvhB77Jc/TdR9i077SkszC5iT52yrkAmFZ+q+qKuKXQOKtpdxMLFC/p
# qkEf97q9Ois0iu4Kq2PmY/eIJI4gDSs7nePCSVKsnx8OOTtd1G5QauZ9UjqqfDMV
# KQ0mXgFYp06pPXqEb3Q/YJ/kMk82AK9tcdM+pkZlX4F08f7BcdpMoEFagt3xHzGC
# GwkwghsFAgEBMIGmMIGOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMTgwNgYDVQQDEy9NaWNyb3NvZnQgV2luZG93cyBUaGlyZCBQYXJ0eSBDb21w
# b25lbnQgQ0EgMjAxMgITMwAAAUBn9phrMQi4cgAAAAABQDANBglghkgBZQMEAgEF
# AKCCARgwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIPeMbpEhPsuAQOBcxZLF12ho
# 0coz1KZAxOETCWK7sDSyMFAGCisGAQQBgjcKAxwxQgxANURGMzhCRUNDRDZGMzI5
# NzU5QkExMDQzMDc3NkU0NTVCQkM3M0UyQjU0OTA2MjM2NUUwREQyMjJFQ0MxRkMx
# MjBaBgorBgEEAYI3AgEMMUwwSqAkgCIATQBpAGMAcgBvAHMAbwBmAHQAIABXAGkA
# bgBkAG8AdwBzoSKAIGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS93aW5kb3dzMA0G
# CSqGSIb3DQEBAQUABIIBgHSe9jnaTNn3FpTpCGvsSBMCrmjU13lELhrUGuT2e9jJ
# EFS70k1MF0qqQDLw4lVy8dt2qDHScyL7GAqQW3B5tOC15YwzbRjqozJBqIfSKcUi
# Akj4IKDF/iQYU50ys4B6hbYa2crY7xdDkTWSekvItO/IXUxKJ+YVoSO75teEr4/F
# xq9Lt/gZ0b2hgEj7pAWeOfd+ydZrqPOcJd+Bh7qYnNpC408VUpCJfN3PFBh7OQzw
# 75Py9WCtmVzaiAaBcTRnDw0yQXoRCKYDh3JsfnV6kre4BmxJKySBB/nKaIZNWMVk
# ggXogflPSc6xs4DTzGoyCNfyfdm82dsCz/cV+hoAK2IndDZLNI1dXCkYKvnfmOd6
# XWZ1VdaZp1sgJe+x7pHQYSUAFviHR5rgWA7ib+QhyXSMCHzXQ9hnhpBbpsTKE3mC
# CevW1TbIbKU6S93HP90HgaWicU7vTBpyMQrR3oKDF5hnRj22VkiebzQKY6S1zBhG
# I26xM5NrcQLxXoVhnyz1J6GCF5cwgheTBgorBgEEAYI3AwMBMYIXgzCCF38GCSqG
# SIb3DQEHAqCCF3AwghdsAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsqhkiG9w0B
# CRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUA
# BCDSYRKytm+eQ/tVkHimt8N+Sxe/NYB1iskQqKwGC8lETAIGal+V+Ch2GBMyMDI2
# MDgwODE4MzQ0NS41MzlaMASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP
# cGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046RTAwMi0wNUUwLUQ5
# NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghHtMIIH
# IDCCBQigAwIBAgITMwAAAikO1WQqtJfyGgABAAACKTANBgkqhkiG9w0BAQsFADB8
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0yNjAyMTkxOTQwMDdaFw0y
# NzA1MTcxOTQwMDdaMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYD
# VQQLEx5uU2hpZWxkIFRTUyBFU046RTAwMi0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQCeItFq4z1oCYSmUZmpYDsbJWEu++1bbc/Mz7Pa3I0ZX5EON+Wi
# rB0FvnGlyFRUylzO5TJXZfU8QFPOU95P1Y1OZ8J+quA5G+AWSBOr/48scl0s9RBp
# qgTMq/lbyqBz4CMmvVR2QevAgVp4a1hbmOm9G7YWey68N5F5rSDYV0wMlg4Iy8YR
# uFgRN2eBpVXt9IvFaFmBnQLZfo22KZ3L8PWEHUhXU5dLOSZoTfqqQ/B+deW56ACM
# nnHjPxZu+szHhZMLUrMWTgs9J7Cn8DtelcKj9aM+0Zq7tkSDHCrwo6eCSfw3clkt
# XRRrdmsccal8RCDiNFFgZsypwF2aGAF6kg41+Ql+thXpnOMUH4mPCAJZWp0zDWow
# sK/Yo5jHL1pT/AgbL3FoAy4cbhOI4Pb1eQFG+jT7skS2F/b+ZACUA1EDZ830K+Bu
# 0yw+FpSGy8tpd1szk3cUYjIpzIG4z3oFNmiSJN8YdNd4SHsER5Dks5bxiKbpvmfr
# OA39jTb7EW2TT7ySWgJISfvTezuLmQsTVSzNsvapVlHhE2zBqDw409nvOtitCFbn
# hhXNfatzb2+Gf2tX2s6YBa151CC/8+emJvvegXbWNudzYt8cFRom0PZ+fJRhhBfd
# SqCqr8QeOGJ8VYlmxFXqx1SdDSkTCSgpsskGqZwh/6umA1g4L7zeGBNngQIDAQAB
# o4IBSTCCAUUwHQYDVR0OBBYEFCdNRaSL9AW8QvaQ21WjRAXKN4M7MB8GA1UdIwQY
# MBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUt
# U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYB
# BQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj
# cm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB
# /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0G
# CSqGSIb3DQEBCwUAA4ICAQA9wc72lf/czDhp09T3PGAMOQhxl/x04jpE7t39FeqQ
# Sn2Up6DVzhgwnzCqY3NIhLtUaWrd7NxvrhZDca+J4xzvrRQNPHeRQpnJVeHsyTu5
# 3gTBlUB1TRI6OnZt/AVmR9oMJ/NBOqB+d+SOb8Px6zRgRwk62sFkOkB5lig/DMnY
# EeR/amW9Hdo8vXcKmaa/DbSOAHSdfZFt+iqMZfNlkEOn71/RAKTNv4Qpq/2FhcjM
# MmSkIhshBdBVB0VjmkwFfhVUf5TTuLJ9sDR4EyCvOZJ3B6g7Iw6WjQxycjwkfzsV
# MTpfusJ5SwdOHL8yGPWZOePjwa8ISXWs6kiVK/6S0/JVb1LpxpyYKREQjnU/5Oec
# Kt2OXlHdwFWZrwAi98RPZa6EExcb/LGLf10tNHju1eTlohY0jzNZQ0BDgSuMZgMU
# +8EEjtMQMIDnlPGEUON7LHXHH0KL0FA01PEWVZKrr/LUOuuDTNFzw543FPMp4gkC
# IFlKdRuciR1IXOk+Xse6rj9tJFYgVn+44BHou2XQe5RX30ef3AQWa0mxyGDqJzGs
# V3X5+bNQeMV88iWulJPq5sgnGG9O/H1/HH4HsO9ZKGX/WrJpQmFuQrTOR49Xjvea
# C0xaFmGsNg+RhbtD5qTkn+ISDvw0IJ/E/VXNdz/yWgol6r507hT8sAMupnhkF2uw
# 1DCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL
# BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH
# EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV
# BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X
# DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh
# bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM
# 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm
# 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB
# RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb
# fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO
# Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw
# XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW
# /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w
# EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK
# Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2
# BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH
# CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB
# BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v
# BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM
# KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF
# BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW
# BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny
# bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH
# AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF
# AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx
# Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+
# iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2
# pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw
# C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7
# T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO
# Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL
# mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L
# wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5
# m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE
# 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNQMIICOAIB
# ATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x
# EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
# bjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UE
# CxMeblNoaWVsZCBUU1MgRVNOOkUwMDItMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNy
# b3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQC3v9iSO22x
# ob7ZxN5dXCEq+9Iv/6CBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX
# YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg
# Q29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAy
# MDEwMA0GCSqGSIb3DQEBCwUAAgUA7iHM1jAiGA8yMDI2MDgwODE1NDIxNFoYDzIw
# MjYwODA5MTU0MjE0WjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDuIczWAgEAMAoC
# AQACAkG2AgH/MAcCAQACAhImMAoCBQDuIx5WAgEAMDYGCisGAQQBhFkKBAIxKDAm
# MAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcN
# AQELBQADggEBACtKkW5xW6Fr+Z8h0r0ZlJQm0Ti/908PomrGhcn94kKUkF1QqmAx
# 8bczOYdJmLbKnMeBbSiUBWrNIQ3VQf4n0SqPcQH405b7AhaQ4gQuyQmEIGCBOTcg
# tLqyctaItxKht2KlNhgJEzgbTmiZvlLEJrz+fX6r4NnW1DnYEwcYRSRP8JzKMBUD
# +S99nW0+ncJOtwU2YaURsf6JsAU7NNs997XQ2tZNRAtd+VlHRuzsXlxCrCCYDSst
# 6tkzM+0+jPQSdboPz4JD4v2X48aXLKUqHMssBbEno4fuaIma0IkS6W3z8qKdJppV
# eg8E/+i9+FJj4iLKMXJbEMqYtcxwteEVp5IxggQNMIIECQIBATCBkzB8MQswCQYD
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAikO1WQqtJfyGgABAAACKTANBglg
# hkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqG
# SIb3DQEJBDEiBCBVtzGn4fgKgwdazFOjfuh5idABogUjMon0BFtdFRv76DCB+gYL
# KoZIhvcNAQkQAi8xgeowgecwgeQwgb0EILfKPfEitvD/lSvEumxqPkkeOEtgkmKF
# EVMuel9oOrqSMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAC
# EzMAAAIpDtVkKrSX8hoAAQAAAikwIgQg/NLIFvE06rzJasI8svnSIdSibJ/fYqlQ
# AUcX8h92JKAwDQYJKoZIhvcNAQELBQAEggIAb/rNhX1hJVyZPxJ2BxtA3SGFZkRx
# 9ptXlnKBcP/8k4ctCR/gn6iuyDgqCy7LNymHzRIqMxMIWwfR6TR6EchVfGUzSp5f
# fOTMfDCdZ19LzSsMXQStvtyNzxa5p6Mbuwnaz0GhBDpimkgGRUPKdrMXrnKRYKEe
# nZ7g87wGuF3zOb9BUkXCFFEC92ISZ+d+BBeNHdMJ1uGelQnccnixUTnp1drzvD1H
# FdEs001wsdokrZXtPYmnpUg+V42a5rprC07gpaI91ZMTQXjNjhOi1a7cplxZuoW6
# 1SzlC2zgC1Ts5q4xozrv55jRwRWGLoc8g09vMKIR0bEIJCs8fq0+mJH7961+teQY
# BM9joj/QVFYbjze3xiIHsaAfSt8Ymdq2966LthcZ65m5cQpH6EWTN6227BmfvD/k
# /f2EXBo2wceWNky8h7oJVwJ6ID3AfZGx24vBdk3Am98zV9UCnEA7060pGlMjUUiM
# 86m22D+Zmo7OI2lN32BmERXVbUC3q0S4HfyfkOqKmwLtubvFFDEdaLiZNIm5M51A
# N6WnyPz7eLF2RgklJE048mi8V+z+WZBeFSEDOUq2xFDmoGo3H4tlEKz/Cvl/3h+K
# kB+SESqz1XzPMjZV/MHt5QJNITSIStK9BudwMqHttWM6PJSRvxZJPOsGgliOn6oK
# azpqcJitWhrblyU=
# SIG # End signature block