function Get-HumanTime($Seconds) { if($Seconds -gt 0.99) { $time = [math]::Round($Seconds, 2) $unit = 's' } else { $time = [math]::Floor($Seconds * 1000) $unit = 'ms' } return "$time$unit" } function GetFullPath ([string]$Path) { if (-not [System.IO.Path]::IsPathRooted($Path)) { $Path = & $SafeCommands['Join-Path'] $ExecutionContext.SessionState.Path.CurrentFileSystemLocation $Path } return $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($Path) } function Export-PesterResults { param ( $PesterState, [string] $Path, [string] $Format ) switch ($Format) { 'LegacyNUnitXml' { Export-NUnitReport -PesterState $PesterState -Path $Path -LegacyFormat } 'NUnitXml' { Export-NUnitReport -PesterState $PesterState -Path $Path } default { throw "'$Format' is not a valid Pester export format." } } } function Export-NUnitReport { param ( [parameter(Mandatory=$true,ValueFromPipeline=$true)] $PesterState, [parameter(Mandatory=$true)] [String]$Path, [switch] $LegacyFormat ) #the xmlwriter create method can resolve relatives paths by itself. but its current directory might #be different from what PowerShell sees as the current directory so I have to resolve the path beforehand #working around the limitations of Resolve-Path $Path = GetFullPath -Path $Path $settings = & $SafeCommands['New-Object'] -TypeName Xml.XmlWriterSettings -Property @{ Indent = $true NewLineOnAttributes = $false } $xmlFile = $null $xmlWriter = $null try { $xmlFile = [IO.File]::Create($Path) $xmlWriter = [Xml.XmlWriter]::Create($xmlFile, $settings) Write-NUnitReport -XmlWriter $xmlWriter -PesterState $PesterState -LegacyFormat:$LegacyFormat $xmlWriter.Flush() $xmlFile.Flush() } finally { if ($null -ne $xmlWriter) { try { $xmlWriter.Close() } catch {} } if ($null -ne $xmlFile) { try { $xmlFile.Close() } catch {} } } } function Write-NUnitReport($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { # Write the XML Declaration $XmlWriter.WriteStartDocument($false) # Write Root Element $xmlWriter.WriteStartElement('test-results') Write-NUnitTestResultAttributes @PSBoundParameters Write-NUnitTestResultChildNodes @PSBoundParameters $XmlWriter.WriteEndElement() } function Write-NUnitTestResultAttributes($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { $XmlWriter.WriteAttributeString('xmlns','xsi', $null, 'http://www.w3.org/2001/XMLSchema-instance') $XmlWriter.WriteAttributeString('xsi','noNamespaceSchemaLocation', [Xml.Schema.XmlSchema]::InstanceNamespace , 'nunit_schema_2.5.xsd') $XmlWriter.WriteAttributeString('name','Pester') $XmlWriter.WriteAttributeString('total', ($PesterState.TotalCount - $PesterState.SkippedCount)) $XmlWriter.WriteAttributeString('errors', '0') $XmlWriter.WriteAttributeString('failures', $PesterState.FailedCount) $XmlWriter.WriteAttributeString('not-run', '0') $XmlWriter.WriteAttributeString('inconclusive', $PesterState.PendingCount + $PesterState.InconclusiveCount) $XmlWriter.WriteAttributeString('ignored', $PesterState.SkippedCount) $XmlWriter.WriteAttributeString('skipped', '0') $XmlWriter.WriteAttributeString('invalid', '0') $date = & $SafeCommands['Get-Date'] $XmlWriter.WriteAttributeString('date', (& $SafeCommands['Get-Date'] -Date $date -Format 'yyyy-MM-dd')) $XmlWriter.WriteAttributeString('time', (& $SafeCommands['Get-Date'] -Date $date -Format 'HH:mm:ss')) } function Write-NUnitTestResultChildNodes($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { Write-NUnitEnvironmentInformation @PSBoundParameters Write-NUnitCultureInformation @PSBoundParameters $XmlWriter.WriteStartElement('test-suite') Write-NUnitGlobalTestSuiteAttributes @PSBoundParameters $XmlWriter.WriteStartElement('results') Write-NUnitDescribeElements @PSBoundParameters $XmlWriter.WriteEndElement() $XmlWriter.WriteEndElement() } function Write-NUnitEnvironmentInformation($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { $XmlWriter.WriteStartElement('environment') $environment = Get-RunTimeEnvironment foreach ($keyValuePair in $environment.GetEnumerator()) { $XmlWriter.WriteAttributeString($keyValuePair.Name, $keyValuePair.Value) } $XmlWriter.WriteEndElement() } function Write-NUnitCultureInformation($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { $XmlWriter.WriteStartElement('culture-info') $XmlWriter.WriteAttributeString('current-culture', ([System.Threading.Thread]::CurrentThread.CurrentCulture).Name) $XmlWriter.WriteAttributeString('current-uiculture', ([System.Threading.Thread]::CurrentThread.CurrentUiCulture).Name) $XmlWriter.WriteEndElement() } function Write-NUnitGlobalTestSuiteAttributes($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { $XmlWriter.WriteAttributeString('type', 'Powershell') # TODO: This used to be writing $PesterState.Path, back when that was a single string (and existed.) # Better would be to produce a test suite for each resolved file, rather than for the value # of the path that was passed to Invoke-Pester. $XmlWriter.WriteAttributeString('name', 'Pester') $XmlWriter.WriteAttributeString('executed', 'True') $isSuccess = $PesterState.FailedCount -eq 0 $result = Get-ParentResult $PesterState $XmlWriter.WriteAttributeString('result', $result) $XmlWriter.WriteAttributeString('success',[string]$isSuccess) $XmlWriter.WriteAttributeString('time',(Convert-TimeSpan $PesterState.Time)) $XmlWriter.WriteAttributeString('asserts','0') } function Write-NUnitDescribeElements($PesterState, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat) { $Describes = $PesterState.TestResult | & $SafeCommands['Group-Object'] -Property Describe if ($null -ne $Describes) { foreach ($currentDescribe in $Describes) { $DescribeInfo = Get-TestSuiteInfo $currentDescribe #Write test suites $XmlWriter.WriteStartElement('test-suite') if ($LegacyFormat) { $suiteType = 'PowerShell' } else { $suiteType = 'TestFixture' } Write-NUnitTestSuiteAttributes -TestSuiteInfo $DescribeInfo -TestSuiteType $suiteType -XmlWriter $XmlWriter -LegacyFormat:$LegacyFormat $XmlWriter.WriteStartElement('results') Write-NUnitDescribeChildElements -TestResults $currentDescribe.Group -XmlWriter $XmlWriter -LegacyFormat:$LegacyFormat -DescribeName $DescribeInfo.Name $XmlWriter.WriteEndElement() $XmlWriter.WriteEndElement() } } } function Get-TestSuiteInfo ([Microsoft.PowerShell.Commands.GroupInfo]$TestSuiteGroup) { $suite = @{ resultMessage = 'Failure' success = 'False' totalTime = '0.0' name = $TestSuiteGroup.Name description = $TestSuiteGroup.Name } #calculate the time first, I am converting the time into string in the TestCases $suite.totalTime = (Get-TestTime $TestSuiteGroup.Group) $suite.success = (Get-TestSuccess $TestSuiteGroup.Group) $suite.resultMessage = Get-GroupResult $TestSuiteGroup.Group $suite } function Get-TestTime($tests) { [TimeSpan]$totalTime = 0; if ($tests) { foreach ($test in $tests) { $totalTime += $test.time } } Convert-TimeSpan -TimeSpan $totalTime } function Convert-TimeSpan { param ( [Parameter(ValueFromPipeline=$true)] $TimeSpan ) process { if ($TimeSpan) { [string][math]::round(([TimeSpan]$TimeSpan).totalseconds,4) } else { '0' } } } function Get-TestSuccess($tests) { $result = $true if ($tests) { foreach ($test in $tests) { if (-not $test.Passed) { $result = $false break } } } [String]$result } function Write-NUnitTestSuiteAttributes($TestSuiteInfo, [System.Xml.XmlWriter] $XmlWriter, [string] $TestSuiteType, [switch] $LegacyFormat) { $XmlWriter.WriteAttributeString('type', $TestSuiteType) $XmlWriter.WriteAttributeString('name', $TestSuiteInfo.name) $XmlWriter.WriteAttributeString('executed', 'True') $XmlWriter.WriteAttributeString('result', $TestSuiteInfo.resultMessage) $XmlWriter.WriteAttributeString('success', $TestSuiteInfo.success) $XmlWriter.WriteAttributeString('time',$TestSuiteInfo.totalTime) $XmlWriter.WriteAttributeString('asserts','0') if (-not $LegacyFormat) { $XmlWriter.WriteAttributeString('description', $TestSuiteInfo.Description) } } function Write-NUnitDescribeChildElements([object[]] $TestResults, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat, [string] $DescribeName) { $suites = $TestResults | & $SafeCommands['Group-Object'] -Property ParameterizedSuiteName foreach ($suite in $suites) { if ($suite.Name) { $suiteInfo = Get-TestSuiteInfo -TestSuiteGroup $suite $XmlWriter.WriteStartElement('test-suite') if (-not $LegacyFormat) { $suiteInfo.Name = "$DescribeName.$($suiteInfo.Name)" } Write-NUnitTestSuiteAttributes -TestSuiteInfo $suiteInfo -TestSuiteType 'ParameterizedTest' -XmlWriter $XmlWriter -LegacyFormat:$LegacyFormat $XmlWriter.WriteStartElement('results') } Write-NUnitTestCaseElements -TestResults $suite.Group -XmlWriter $XmlWriter -LegacyFormat:$LegacyFormat -DescribeName $DescribeName -ParameterizedSuiteName $suite.Name if ($suite.Name) { $XmlWriter.WriteEndElement() $XmlWriter.WriteEndElement() } } } function Write-NUnitTestCaseElements([object[]] $TestResults, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat, [string] $DescribeName, [string] $ParameterizedSuiteName) { foreach ($testResult in $TestResults) { $XmlWriter.WriteStartElement('test-case') Write-NUnitTestCaseAttributes -TestResult $testResult -XmlWriter $XmlWriter -LegacyFormat:$LegacyFormat -DescribeName $DescribeName -ParameterizedSuiteName $ParameterizedSuiteName $XmlWriter.WriteEndElement() } } function Write-NUnitTestCaseAttributes($TestResult, [System.Xml.XmlWriter] $XmlWriter, [switch] $LegacyFormat, [string] $DescribeName, [string] $ParameterizedSuiteName) { $testName = $TestResult.Name if (-not $LegacyFormat) { if ($testName -eq $ParameterizedSuiteName) { $paramString = '' if ($null -ne $TestResult.Parameters) { $params = @( foreach ($value in $TestResult.Parameters.Values) { if ($null -eq $value) { 'null' } elseif ($value -is [string]) { '"{0}"' -f $value } else { #do not use .ToString() it uses the current culture settings #and we need to use en-US culture, which [string] or .ToString([Globalization.CultureInfo]'en-us') uses [string]$value } } ) $paramString = $params -join ',' } $testName = "$testName($paramString)" } $testName = "$DescribeName.$testName" $XmlWriter.WriteAttributeString('description', $TestResult.Name) } $XmlWriter.WriteAttributeString('name', $testName) $XmlWriter.WriteAttributeString('time', (Convert-TimeSpan $TestResult.Time)) $XmlWriter.WriteAttributeString('asserts', '0') $XmlWriter.WriteAttributeString('success', $TestResult.Passed) switch ($TestResult.Result) { Passed { $XmlWriter.WriteAttributeString('result', 'Success') $XmlWriter.WriteAttributeString('executed', 'True') break } Skipped { $XmlWriter.WriteAttributeString('result', 'Ignored') $XmlWriter.WriteAttributeString('executed', 'False') break } Pending { $XmlWriter.WriteAttributeString('result', 'Inconclusive') $XmlWriter.WriteAttributeString('executed', 'True') break } Inconclusive { $XmlWriter.WriteAttributeString('result', 'Inconclusive') $XmlWriter.WriteAttributeString('executed', 'True') if ($TestResult.FailureMessage) { $XmlWriter.WriteStartElement('reason') $xmlWriter.WriteElementString('message', $TestResult.FailureMessage) $XmlWriter.WriteEndElement() # Close reason tag } break } Failed { $XmlWriter.WriteAttributeString('result', 'Failure') $XmlWriter.WriteAttributeString('executed', 'True') $XmlWriter.WriteStartElement('failure') $xmlWriter.WriteElementString('message', $TestResult.FailureMessage) $XmlWriter.WriteElementString('stack-trace', $TestResult.StackTrace) $XmlWriter.WriteEndElement() # Close failure tag break } } } function Get-RunTimeEnvironment() { # based on what we found during startup, use the appropriate cmdlet if ( $SafeCommands['Get-CimInstance'] -ne $null ) { $osSystemInformation = (& $SafeCommands['Get-CimInstance'] Win32_OperatingSystem) } elseif ( $SafeCommands['Get-WmiObject'] -ne $null ) { $osSystemInformation = (& $SafeCommands['Get-WmiObject'] Win32_OperatingSystem) } else { $osSystemInformation = @{ Name = "Unknown" Version = "0.0.0.0" } } @{ 'nunit-version' = '2.5.8.0' 'os-version' = $osSystemInformation.Version platform = $osSystemInformation.Name cwd = (& $SafeCommands['Get-Location']).Path #run path 'machine-name' = $env:ComputerName user = $env:Username 'user-domain' = $env:userDomain 'clr-version' = [string]$PSVersionTable.ClrVersion } } function Exit-WithCode ($FailedCount) { $host.SetShouldExit($FailedCount) } function Get-ParentResult ($InputObject) { #I am not sure about the result precedence, and can't find any good source #TODO: Confirm this is the correct order of precedence if ($inputObject.FailedCount -gt 0) { return 'Failure' } if ($InputObject.SkippedCount -gt 0) { return 'Ignored' } if ($InputObject.PendingCount -gt 0) { return 'Inconclusive' } return 'Success' } function Get-GroupResult ($InputObject) { #I am not sure about the result precedence, and can't find any good source #TODO: Confirm this is the correct order of precedence if ($InputObject | & $SafeCommands['Where-Object'] {$_.Result -eq 'Failed'}) { return 'Failure' } if ($InputObject | & $SafeCommands['Where-Object'] {$_.Result -eq 'Skipped'}) { return 'Ignored' } if ($InputObject | & $SafeCommands['Where-Object'] {$_.Result -eq 'Pending' -or $_.Result -eq 'Inconclusive'}) { return 'Inconclusive' } return 'Success' } # SIG # Begin signature block # MIInYQYJKoZIhvcNAQcCoIInUjCCJ04CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAuHDKWsUEKLtTX # JcChkzSHEWRBgB95P6ikKjBN9SHVLKCCC7QwggXLMIIEs6ADAgECAhMzAAABQGf2 # 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 # GwMwghr/AgEBMIGmMIGOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMTgwNgYDVQQDEy9NaWNyb3NvZnQgV2luZG93cyBUaGlyZCBQYXJ0eSBDb21w # b25lbnQgQ0EgMjAxMgITMwAAAUBn9phrMQi4cgAAAAABQDANBglghkgBZQMEAgEF # AKCB+jAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAvBgkqhkiG9w0BCQQxIgQg # 2c2EkjPE+faxA1/TPgA2uTT+GiIAxJhkJgVEWkOZ4VUwUAYKKwYBBAGCNwoDHDFC # DEBFRTA4RkI3NkY4RDhCNkZBNUQ4OTFEMzk3Nzg0OTY3ODg2RDRCOUQ1NjhFRDE1 # Q0Y4QjQwRDc3QjM0NjVENjdEMFoGCisGAQQBgjcCAQwxTDBKoCSAIgBNAGkAYwBy # AG8AcwBvAGYAdAAgAFcAaQBuAGQAbwB3AHOhIoAgaHR0cDovL3d3dy5taWNyb3Nv # ZnQuY29tL3dpbmRvd3MwDQYJKoZIhvcNAQEBBQAEggGAefrs5VhHw+cEx3MWF4yt # HS5s50i+PDdIxIPH+TTrDITsLzY4xHW3mxtLy5QFq75vFS/tTLbTfuH6gFXCT12W # 3NuV+HV4EDa6yyoeGQL2c8NEFsU6IVj4OJvsDKj8i6IczK88i4Shv4Lrt/T3i+sb # vlqAM/KMEvUV/zC0eJzmfEU5kM6RbC5eyV1wACzT86G/cBax0Fcy2mbapVZdqcyW # Sf4f+arsrstu+6yoBROLMXYi/aWc9Zw9pHUNSbFuCdh2wJA4V4lHXe1xnblNvOWa # UVl6v49D5tpTo2SMcJC8QDDE4MHKONi0VkSvMespUdq72TCVMbW9MB9nEl57PhOq # NynqbkbCJ/CSjMnREaU0znmDtY/TEG20BxZRynEZh/QyGgiMXCm3RLXtNxkYMYd+ # ZRb1JecyV09GTBRieb6FGhs1f49Xhx39jjRnr7TV6b/GaIQCYhcvP8A9IKZWDQA+ # WyOWhkHk8KMIDTYQ9/al3rggBtp7HN309U7NthtC06u+oYIXsDCCF6wGCisGAQQB # gjcDAwExghecMIIXmAYJKoZIhvcNAQcCoIIXiTCCF4UCAQMxDzANBglghkgBZQME # AgEFADCCAVoGCyqGSIb3DQEJEAEEoIIBSQSCAUUwggFBAgEBBgorBgEEAYRZCgMB # MDEwDQYJYIZIAWUDBAIBBQAEIJJp+DNdz9zlH0ScJDLGeHp85AoWucrpPK0mPMq4 # 8QJ6AgZp7G9Lu2UYEzIwMjYwNTA2MTU0MDUyLjI3OVowBIACAfSggdmkgdYwgdMx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1p # Y3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNo # aWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQg # VGltZS1TdGFtcCBTZXJ2aWNloIIR/jCCBygwggUQoAMCAQICEzMAAAIVGAPTgQcm # fFMAAQAAAhUwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTAwHhcNMjUwODE0MTg0ODIwWhcNMjYxMTEzMTg0ODIwWjCB0zELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0 # IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxkIFRT # UyBFU046NjUxQS0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDDcdXe # FXEvSURg9XTdd40pnnXtUhuB7GGUM92lfANLQFi3E/CLhdillHWV3S7pyvZeO66B # 2DnQNTHlYcvRCFjZ32+QlKTTasT/vmFwq33WbYiHbztBHFEyYW7cEXrjrqTyqnm5 # e197q5yKrj1hpLyn53O/e5NqsPiFDxRPstr3mk4mJGrHF3So4YsQK8csRc9eKg1L # H2nKHOGbqW3t7MvEl4VVi3FKGRq8+hk3R04KJh6HgqCgqjJqDMy5KIsKIxRbhR7h # CybrnwUk0ZM2HtXmpdhUDqTnGPDlZ5Z0o7PSL0DmMFxtj19U6j9wDyLVvK3NwNPF # vedy1yXLz85h42y2Rpv8iyrcLF7W+r3p8gcTX5kaYmORrWyh3Co/JxWn/a1v4GO6 # U8vkPquBRdM8XzhTzZEsodXntsHx8dGmCeNxYFC5c+BV5JekRFaKa3Q0XaUI4vOq # Cu9L+9ip17kuf1iUoqEBn/EMTRMsgivr4j/YlO1c/fid+NMQ1WowEhJZxqQjEDAZ # vdEHnIcLHKcgU1Utx8oCwR0LlTZ6bR8C+ZW/Syieqe/Xty5piLZ4ItaGgrUhzzkP # Duz+WFxesGljif9GXmXfAfOzi84iG7zsMjLlBRoS6kSzJjQ1aqAjgFaXq/XCCx76 # XwNYV5Reh+FS4KBVO5Mc3cryJ2gxufxDd51QgQIDAQABo4IBSTCCAUUwHQYDVR0O # BBYEFIkhd/FyoDAWoaP2N3BC11Kpp2PXMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl # 0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy # MDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1T # dGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/ # BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IC # AQB3jYe1X6QZu/HMsFMLk7u+QIgE/L8HCmMLN4vneECIQ55un5V02fCb0ZUJ9irc # ox+uPhS8pBNQBpLlmTB7WC9neWNJKcI7JLk7A2712mDfDD5BbZ45xIuTJUBYWsuf # oiKDdML/NYy9WGpe10WEbYonWVJs3bbZyxjcTf8GsaW4CW8RP2CbFXLLE3Ln3/sk # XnMgZwmJvJ3Gz3gkvUG0+Bck59nND7/eJNzp4O2ZpZPoMp2cmhynzCRcpY8iwER+ # QPqTVCK3C+3SYes5FqHvlKN5w4q3ihZrJUuQ9OGjXZ7SieASDVyN7l/FJka2Gsyt # Yq8jhHscQLuTyZof148DdWIfQJVJI559o9MYzMiEcKjmneMblIxzI7d4D24RphAk # hMmUsbcHDAabKljsL/z+ePVI6GDHUeAnTLA4kv3F8/gA5xaYJ9uyqAZsJoLtYfmw # g13N8xqvxXtg0WqRsIZQqFzwakjIT4wqfJWffeOy5oYCU1GDt1VFRKhgsnG9SzD0 # Y7DIGkHBsT2yo4ub4ew7TSgXbc8yKjtYVdwVNkCOne6OKEEB8utcgKAY4c92RnTj # a7Utmo5yeWvdfO+Ax76Y8/Jqxbx/Su3MmPdXkT8QqLJCU/GP0x+rbH2GKaeVdYZk # JU94QFE6s1sNgF9rNPIs0I5OxG2Sw5JXcUG0+elC0s3vnjCCB3EwggVZoAMCAQIC # EzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoX # DTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0 # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC # 0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VG # Iwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP # 2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/P # XfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361 # VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwB # Sru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9 # X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269e # wvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDw # wvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr # 9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+e # FnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAj # BgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+n # FV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEw # PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j # cy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3 # FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAf # BgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBH # hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNS # b29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF # BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl # ckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4Swf # ZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTC # j/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu # 2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/ # GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3D # YXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbO # xnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqO # Cb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I # 6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0 # zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaM # mdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNT # TY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNZMIICQQIBATCCAQGhgdmkgdYwgdMx # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1p # Y3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNo # aWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQg # VGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQCPp5N6Nu5gTUh+Nt+u # 3q1d68JRIKCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n # dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y # YXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0G # CSqGSIb3DQEBCwUAAgUA7aVthTAiGA8yMDI2MDUwNjA3MzQyOVoYDzIwMjYwNTA3 # MDczNDI5WjB3MD0GCisGAQQBhFkKBAExLzAtMAoCBQDtpW2FAgEAMAoCAQACAg1G # AgH/MAcCAQACAhJ5MAoCBQDtpr8FAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisG # AQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQAD # ggEBADUbRdXAfixNN+laHPZQ/lv/tAx5JuVOT59VpCjzw4a0itp/0vEETJAL+hFm # /Q35rQgov1xEvDoIYFVsCER5ryj/z9+KUDhXAmwYrKs2bXZJHZR2yZNt4eqqydSB # 0tf6VQFqzKR/c9YA9Ws1zNWquWS7zl1eRQO/j33zQjqGhakN3dErAxVD5dsboyVl # wiyLtp4EUG06IiTU9dSfS9JQBU0X6khQSX5gqu5QgZP0UBMco34Hel9MWGkoMQ6T # EKW5mqZaGSbLSVmOBliF+11Hj8nQhHSg72meaml2lucwRj9A6B1hIa76jwBG3RfW # JZb5Ol0nuX9zerpmjgMuipRnev4xggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt # ZS1TdGFtcCBQQ0EgMjAxMAITMwAAAhUYA9OBByZ8UwABAAACFTANBglghkgBZQME # AgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJ # BDEiBCA5aBxxN142lyRIrL+uwHhRsnZN3GlCTgtrFq2OLKKOQjCB+gYLKoZIhvcN # AQkQAi8xgeowgecwgeQwgb0EIHAQ9HY8OtMUtyu1CwqtSLujPkk1EIX8pEcyKFI1 # 7uyKMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAIV # GAPTgQcmfFMAAQAAAhUwIgQgUmruv32Vlpw3YTI0vgH1PcUaSUxNS7tHUjRU4wYi # rkAwDQYJKoZIhvcNAQELBQAEggIAkJ8Gi9Zv2orpZjAe7fJk9f8BfvSVhnm9Gyrd # Aq+y2wZxWquse8BTeLGO6fr7PokwCWZVtlTGT600VEWtj45l3n83VBJ+i+w5loyF # 5zpQaM3CEvRzIt/0sYfEIoeM0KmSSR8jSpi2blrlbSzmjCBGXx1kQzFLTrrVpsrL # Pk0jaaWdvmWLiHczglkEv1NlEkfR+fq4cOaAugrG8VlOGDPzpLVhYGfTbfiUBKU8 # lOJHr7vlRWDN85TUJzMWbLxyv30aAswkH13vWqfJA1mrgo17Q6nuJnx36foTjKjw # cK6U3CpuofA4o+qyoLZsPj2sfLDoE9snM/GveMPvVw27giH2unHQvsgCJCvOjE0m # stnqiikAmHijel+BBJxYjFYoqinPbdTSkWy8LMK13ptZHEeYdan6MW4wQykjt6Ii # VqblHndMK6kIztqYXkQngoqGWD/RplyXPgNIP7f7s86wcq0/D4VudemgprTXHSdJ # DiKgDo22BNLRQ295fPSdEOd5l25J7f06VMxG9HozodqCOKGfaTzSVrgl+iJzLoBL # f2cYp38dlar+DyNd0crMQhCIm7rmSu08gM5oNtUga6RsTANC9fu331zRioFqGH6n # /c71ywaAI95qMAEMvVdnMvf0PNa0Khwe+rrAlaV/0vH2/9ShjoJfH9hfL3FHaTIn # duycwrI= # SIG # End signature block x

Windows NT KPTV 6.2 build 9200 (Windows Server 2012 Datacenter Edition) i586