modules/AzStack.Buddy/AzStack.Buddy.EventViewer.psm1

Import-LocalizedData -BindingVariable 'msg' -BaseDirectory "$PSScriptRoot\locale" -UICulture "en-US" -WarningAction SilentlyContinue
Import-Module $PSScriptRoot\..\AzStack.Utilities\AzStack.Utilities.psm1 -WarningAction SilentlyContinue

function New-FilterTable() {
    param(
        [string]$LogName,
        [string]$ProviderName,
        [string]$Path,
        [DateTime]$Time = (Get-Date),
        [array]$ID,
        [string]$Duration = "1",
        [bool]$Backwards = $true
    )
    $EndTime = $Time
    $StartTime = $Time

    $history = if($Backwards -eq $true) {"-"} else {""}

    if($Duration -like "*:*:*") {
        # go into detail mode.
        $durationArr = $Duration.split(":")
        $StartTime = $StartTime.AddHours($history + $durationArr[0])
        $StartTime = $StartTime.AddMinutes($history + $durationArr[1])
        $StartTime = $StartTime.AddSeconds($history + $durationArr[2])
    } else {
        $StartTime = $StartTime.AddHours($history + $Duration)
    }

    if($Backwards -eq $false) {
        $TempTime = $EndTime
        $EndTime = $StartTime
        $StartTime = $TempTime
    }

    $table = @{
        StartTime = $StartTime
        Endtime = $EndTime
        LogName = $LogName
    }

    if($null -ne $ProviderName -and $ProviderName -ne "") {$table.ProviderName = $ProviderName}

    if($null -ne $Path -and $Path -ne "") {$table.Path = $Path}

    if($null -ne $ID) {$table.ID = $ID}

    return $table
}

<#
.SYNOPSIS
Get eventlog entries from a cluster or its node in filtered format
 
.DESCRIPTION
Get-AzsSupportWinEvents read various windows eventlogs (which can be read with get-winevent) from a cluster or remote computers
 
.PARAMETER Logname
Name of the log, wildcards can be used ("*")
 
.PARAMETER Cluster
Name of the cluster
 
.PARAMETER clusterNodes
Name of the clusterNodes. Use "," as separator
 
.PARAMETER Message
Filter for event message, wildcards can be used ("*")
 
.PARAMETER EventId
EventID filtering. Use "," as separator
 
.PARAMETER FilterInformation
Filter out informational events, disabled by default. (1 or 0)
 
.PARAMETER ProviderName
Event provider name filter.
 
.PARAMETER Backwards
Go back in time.
 
.PARAMETER Date
Date of start.
 
.PARAMETER Duration
Time window of the events, can be hours (single digit) or specified time (hh:mm:ss)
 
.PARAMETER Detailed
Output will be in format-list format, disabled by default
 
.EXAMPLE
Checking 2 clusterNodes's logs contains the word "smbclient" on 01/10/2024 between 17:00 and 20:00
Get-AzsSupportWinEvents -clusterNodes strhci03,strhci02 -Logname *smbclient* -FilterInformation 0 -Date 01/10/2024 -time 17:00:00 -Duration 3
 
.NOTES
General notes
#>

function Get-AzsSupportWinEvents {
    param (
        [Parameter(Mandatory=$true)]
            [string]$Logname = (Read-Host "Logname (* for wildcard)"),
        [Parameter(Mandatory=$false)]
            $Cluster = (Get-Cluster),
            $clusterNodes = $null,
            [string]$Message = $null,
            [array]$EventId = $null,
            [bool]$FilterInformation = $false,
            [array]$ProviderName = $null,
            [bool]$Backwards = $true,
            [string]$Date = (Get-Date),
            [string]$Duration  = "1",
            [bool]$Detailed = $false

    )

    #create filter table
    $filter = New-FilterTable `
        -LogName $Logname `
        -Time $Date `
        -Duration $Duration `
        -ID $EventId `
        -ProviderName $ProviderName `
        -Backwards $Backwards

    # Default event level: Informational included
    # Information level filter
    $maxlevel = 4

    if ($Filterinformation -eq $true) {
        [int]$maxlevel = 3
        Trace-Output -Level:Information -Message $msg.eventViewerExcludeInfo
    } else {
        Trace-Output -Level:Information -Message $msg.eventViewerAllEventsIncluded
    }

    Trace-Output -Level:Information -Message $msg.eventViewerFilerList
    $filter

    if ($null -eq $clusterNodes) {
        $clusterNodes = Get-ClusterNode -Cluster $cluster
    }

    foreach ($ClusterNode in $clusterNodes) {
        Trace-Output -Level:Information -Message ($msg.eventViewerClusterNodeLogName -f $ClusterNode.Name, $Logname)

        $output =  Get-winevent -ComputerName $ClusterNode -FilterHashtable $Filter -ErrorAction SilentlyContinue | Where-Object {$_.Level -gt 0 -and $_.Level -le $maxlevel}

        $output = $output | Where-Object message -like "*$message*"

        if ($detailed -ne $false) {
            $output | Sort-Object TimeCreated | Format-List Timecreated,Providername,Id,Leveldisplayname,Message
        } else {
            $output | Sort-Object TimeCreated | Format-Table Timecreated,Providername,Id,Leveldisplayname,Message -Wrap
        }
    }
}
# SIG # Begin signature block
# MIIoKAYJKoZIhvcNAQcCoIIoGTCCKBUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAzzq53j1Wuh/3U
# hcW/CdelaGRXA687GyqdM7umbg4e+6CCDXYwggX0MIID3KADAgECAhMzAAAEBGx0
# Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz
# NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo
# DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3
# a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF
# HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy
# 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w
# RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW
# MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci
# tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG
# CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0
# MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC
# Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj
# L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp
# h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3
# cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X
# dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL
# E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi
# u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1
# sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq
# 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb
# DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/
# V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq
# 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
# /Xmfwb1tbWrJUnMTDXpQzTGCGggwghoEAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp
# Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB
# BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO
# MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIPOOoRQ4N2Sk3bDSRoqduRwU
# DkoBr5xaiEgfxrS9rBvfMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A
# cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB
# BQAEggEAjNE4EtRhxBLRDwFxIs57ZzztZIVGEGKIq+ET9UQMupwrRsnOjMledKLm
# 9X9sCvEshNVGZqPkgjW5QqfHfUeimOjzI0nisIRhm3ciBCj4Sse2501EtkXaADVJ
# tQfiBwu8dZxG8ZcwcYmD9TkIUc752vglbxfq7EklrIs0ruaBT3nKDrC2X/iUqU2M
# OwRvzVqvgvcngBpofU2nwm+5FeDJ7/3irVeYESxoKZ1S3iEOnc7mEKzR9h6R5sQz
# ykDhCXkULePpslpmEi35xf9oeX1mcG0v4EUxBKqEF6HBeE6Ha2BHaT3PTbaYaux8
# TTka+uuuRbgf52qY7NQsaXDskaYKIKGCF5IwgheOBgorBgEEAYI3AwMBMYIXfjCC
# F3oGCSqGSIb3DQEHAqCCF2swghdnAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFQBgsq
# hkiG9w0BCRABBKCCAT8EggE7MIIBNwIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl
# AwQCAQUABCDMzy3VgM5xnfUoVYKmyXXI0Sm8wuV+W7Q4lLaOQYlNfAIGZ7eiaqpF
# GBEyMDI1MDMxMTE2MTUzMS42WjAEgAIB9KCB0aSBzjCByzELMAkGA1UEBhMCVVMx
# EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT
# FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJp
# Y2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOkE0MDAtMDVF
# MC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR
# 6jCCByAwggUIoAMCAQICEzMAAAICeVB0IRR9uKEAAQAAAgIwDQYJKoZIhvcNAQEL
# BQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
# B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
# AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjUwMTMwMTk0MjQ0
# WhcNMjYwNDIyMTk0MjQ0WjCByzELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
# b3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEn
# MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOkE0MDAtMDVFMC1EOTQ3MSUwIwYDVQQD
# ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEF
# AAOCAg8AMIICCgKCAgEAt3kqenLnFBjpHD4OLyliiXxEHrIStmQbGFNbQ1r0Lui/
# ZafnZ6q2oyHTXh9Rzd6M94ohqCVrjdh1TWZHDrd/GlhnmzNIFFDrT47i4bjuXeu2
# KULBwSQFoXL3vzFXaED49Z44gI0ojqy/MRWqxSyOOkR/DXg4QD13CaVp+wCMwsiI
# 2Tmidg1gPukMDc8KowYCKX9YVhcKh7zxHnctJ6LV27Vn0/bwki/bHQyuivxx/R7G
# mOcC5lFAe0n7ixqNTlhJujCchto4saovTckaMqXRfHUco1sSkZdiccL23rZQ04qO
# ul5YkznJKtkYDPmaHGRG+hKDnbXdFyody88dvQIR8ZZPuniMGr5R2Lji2QyqHTzl
# Teo9SCfW66JWOpmW6EOdTqnuZxDOYf1iV9vBi2YqBJCTfKjnuT+T9mMfR6Dqi7oF
# 9NKgs8auAQ5vMR/ORysbygjuSopKKWkRhrUJV4w8rrDFpax3Mkreeg4S+HXFZ5+3
# Rby+dM70JRWTIVaHoVkkJJFrlJQgqiDq03u0W5p23SaLB/u5Qvp+d4JysuDqGc7l
# Hqswp0gdSTVzypyaIz9w3uccLKYubVL0BTX5Xxk7I2YEAIAwXYPwztExoC0Qyr2U
# AmeaiLl6UEcoN+8nOdXvec/FNpsrFNF50qVnooB6pMjgLQ33CKauRr+x1fnWtkcC
# AwEAAaOCAUkwggFFMB0GA1UdDgQWBBTaBrm1D4z9n/In5CCr8Mta5Uh02TAfBgNV
# HSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5o
# dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBU
# aW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwG
# CCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRz
# L01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNV
# HRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIH
# gDANBgkqhkiG9w0BAQsFAAOCAgEAg/N2hUFMTd+x5DqCQzNZmhxWVVBnKk0HD5zg
# +lKGETJgyr9Bmmx5RPNgGICz7lZbpJ+x7STxds9I504AH0TJ9uiRSzxuzv12yitu
# YawTyd9JQbsIwE1befFANQVqO5bJp8q7q/+ofABc618q17Zb80GKmkWGPZNFBWOR
# jPp/WGhBCtg9uvHvmvhw5lnvrWC9h/vTuENTEC2oPnIjcC5I//kJcaV4lqLvSrwD
# 9LSJPnx/Bd8MOVTk4vWmffqj47M8N9R+J3bYrwWWh+bOW6CZh9iW7TLn9su4UnSX
# RNFFtgdBRGTyyJnppSobJSTVahDu0T4Je3PNULlUjufH36Zm8LUsYWKxEt1bD4JV
# 5/Tgxew6pjzBvxsrAeKP0JKTVKvsEu2zkUzc6hzLR/qK3dmEpmvtW8lga/4syCoI
# DgnRM2mQ38ptdhjOmuEviMugFCKe/yiKQJn1n163DCu1exAc8aHs5C0RBFiOF7T8
# KRAZ7TmtaAx92f/nUcbMS9L4Mmu4zX6zu6Is0wJZ/9mQWAfYqFHqG4+QBi+OZtpn
# CkpOxxOc1EXlZCC6WCgUOfl//IxTtf6Wcqs0HiNf6Cf0S6InNUoni13xE/RFmSAY
# 2TGfOOpg26dcpyvVGzYgo0sJkxedPWJ/TOO1ULMbL9aJULuda1VR5EjZvq06y8Ct
# bb4b9JkwggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3
# DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
# A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIw
# MAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAx
# MDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVT
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1l
# LVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA
# 5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/
# XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1
# hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7
# M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3K
# Ni1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy
# 1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF80
# 3RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQc
# NIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahha
# YQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkL
# iWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV
# 2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIG
# CSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUp
# zxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBT
# MFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYI
# KwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGG
# MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186a
# GMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br
# aS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsG
# AQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29t
# L3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcN
# AQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1
# OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYA
# A7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbz
# aN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6L
# GYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3m
# Sj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0
# SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxko
# JLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFm
# PWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC482
# 2rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7
# vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDTTCC
# AjUCAQEwgfmhgdGkgc4wgcsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5n
# dG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAl
# BgNVBAsTHm5TaGllbGQgVFNTIEVTTjpBNDAwLTA1RTAtRDk0NzElMCMGA1UEAxMc
# TWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUASYlI
# aQlgP91/42ciMtMnukScC86ggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UE
# CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
# b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ
# Q0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAOt6g1swIhgPMjAyNTAzMTEwOTM5Mzla
# GA8yMDI1MDMxMjA5MzkzOVowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA63qDWwIB
# ADAHAgEAAgIXADAHAgEAAgIVIDAKAgUA63vU2wIBADA2BgorBgEEAYRZCgQCMSgw
# JjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3
# DQEBCwUAA4IBAQAi+/C2hHHg1zxxmlx+arPDZ0a4PAIXzmSwgCJi1EPLr4CUUQUH
# Q8hWtDjQcmmwERH8HOnx6PwgddbEKjNwYPxdbZsw+ZK1pi6M7OYGkFfNs2LP8skg
# RfNc0R9cnLSfhgUkODHRGx3OfcZuuWOr05RTf9ot7LyUY7kLKOnE7n7dx/Pc9sIr
# cXswjy5Qn8P5YPUNr/KSSYW8GmRzl97aoBH6f+XEwmro4lsHLkykZ9Y0M9Naq4Kh
# PdoL+xsY0UwWS99szvqIU2gqSeT7hqiHaGp0RYSxSJg2TZUWb39br5o6QcstUndG
# khzM7tKP850GSRUFuaBxA41LJUifjLXonSwHMYIEDTCCBAkCAQEwgZMwfDELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z
# b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAICeVB0IRR9uKEAAQAAAgIwDQYJ
# YIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkq
# hkiG9w0BCQQxIgQg21aaf5VniqlnjJQLqch54zeCXHDmvkxyKBeDpQb16IkwgfoG
# CyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCDzjeoBGAeWy81y1rlJi/GXfMVwLKl5
# LHnRcqJXzJRf7DCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
# aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
# cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
# AhMzAAACAnlQdCEUfbihAAEAAAICMCIEIGgPNfy2x6JpcNfI1WzlJ21EoAmgsHcw
# hCaO3jEfNzBvMA0GCSqGSIb3DQEBCwUABIICAB3V2YPm3jTGNXsr1N3piuVGrVf8
# ZOj/JVX6Famoe25lFVEqcjievvqktDPn8VaqqLb6hGgEwb4+KSk+F8unpbd5b4ef
# WAtD6OeKaFCF+ay7p0rN9tB4cE5VmAr2z2wcpAcWx4nwgZ8jgf+5mFX21C9YR95Q
# ICwYw6RCLaSq49iZBOsA6bHIB2ctwACPq8RbmL2TXb/C0yMD3NHDRb2seNd+/L8U
# 0osepQllnbAPgE+vanmzTdNaX3HN18QD58NXq9/HYcSgtYe70gg4Q9DZ8c0CWuzI
# z2mlVHUpu12W68LsT/w6Sz231j+T4Dlqn/VxWoZrrTqVdGfVpcea7hgmcZRLrVar
# a9fIwHIDKY/DaOyx2ZitEqb5nd60Mm+tGBbSM1eg9clR9EkA8n2Pbxa6OZaD6Vr8
# xvmZfePg6yqDalPgnAHVy6otR8ecLAp5GMSafWdQiSZKLGyfVejVsPWp0Poy1Vh7
# 3PCkToolsC50zBG4Tt7qoVRWLPRJyDsKhflnO12XcHKi2LqGv144I5ZXSonjVNX1
# fxKrBuGgOo/Z1uY56Kd34EHqkRnRn34QhIMupU+mpMiXlE+6qEY5jwH1wr+hagdd
# OJzDaKa3XPpyOrL8vig29dB/PFyeV+V9Nzp3efvR1pcueU9oy2HfSaJWw7Zwa4Ze
# hNn7bFvpbXhXr6EG
# SIG # End signature block