functions/Install-IntuneResourcetriggers.ps1

function Install-IntuneResourceTriggers {
    [CmdletBinding()]
    param (
        [Parameter(ValueFromPipelineByPropertyName)]
        [Byte[]]
        $Key,

        [Parameter(ValueFromPipelineByPropertyName)]
        [String]
        $ProfilePath,
        
        [Parameter(ValueFromPipelineByPropertyName)]
        [String]
        $CentralDataPath = "$([System.Environment]::GetFolderPath('CommonApplicationData'))/IntuneResourceLocalization",
        
        [Parameter(ValueFromPipelineByPropertyName)]
        [String]
        $LogPath = "$([System.Environment]::GetFolderPath('CommonApplicationData'))/IntuneResourceLocalization/Logs"
    )
    begin {
        # if (!$Script:Configuration) {
        # throw 'The configuration has not been set yet. Please use the cmdlet "Get-IntuneResourceEnvironment" to initialize'
        # }
        try {
            $ScheduledTaskConfiguration = (Get-IntuneCustomConfiguration).taskSchedulerTasks
        }
        catch {
            throw 'Cannot access the configuration file detailing Scheduled Task information'
        }
    }
    
    process {

        function createScheduledTaskEventTrigger {
            [CmdletBinding()]
            param(
                [PSCustomObject] $TriggerConfig
            )
            
            #$Trigger = New-ScheduledTaskTrigger -AtLogOn
            $CIMTriggerClass = Get-CimClass -ClassName MSFT_TaskEventTrigger -Namespace Root/Microsoft/Windows/TaskScheduler:MSFT_TaskEventTrigger
            $Trigger = New-CimInstance -CimClass $CIMTriggerClass -ClientOnly

            if ($TriggerConfig | Get-Member -MemberType Properties | Where-Object { $_.Name -eq "sourceDataName" }) {
                $Trigger.Subscription = @"
<QueryList>
<Query Id="0" Path="$($TriggerConfig.sourceLog)">
<Select Path="$($TriggerConfig.sourceLog)">
*[System[Provider[@Name='$(($TriggerConfig.sourceLog -split '/')[0])'] and EventID=$($TriggerConfig.sourceEventID)]]
and
*[EventData[Data[@Name='$($TriggerConfig.sourceDataName)'] and (Data='$($TriggerConfig.sourceDataValue)')]]
and
*[EventData[Data[@Name='$($TriggerConfig.sourceHostName)'] and (Data='$($TriggerConfig.sourceHostValue)')]]
</Select>
</Query>
</QueryList>
"@

            }
            else {
                $Trigger.Subscription = @"
<QueryList>
<Query Id="0" Path="$($TriggerConfig.sourceLog)">
<Select Path="$($TriggerConfig.sourceLog)">
*[System[Provider[@Name='$(($TriggerConfig.sourceLog -split '/')[0])'] and EventID=$($TriggerConfig.sourceEventID)]]
</Select>
</Query>
</QueryList>
"@

            }
            $Trigger.Enabled = $True
            return $Trigger
        }

        function createScheduledTaskAtLogonTrigger {
            [CmdletBinding()]
            param(
                [PSCustomObject] $TriggerConfig
            )
            
            $Trigger = New-ScheduledTaskTrigger -AtLogOn # -User ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
            # $Trigger.Delay = 'PT10S' # No longer wanted.
            $Trigger.Enabled = $True
            return $Trigger
        }

        function createScheduledTaskAtWorkstationUnlockTrigger {
            [CmdletBinding()]
            param(
                [PSCustomObject] $TriggerConfig
            )

            $CIMTriggerClass = Get-CimClass -ClassName MSFT_TaskSessionStateChangeTrigger -Namespace Root/Microsoft/Windows/TaskScheduler
            $Trigger = New-CimInstance -CimClass $CIMTriggerClass -ClientOnly
            $Trigger.StateChange = 8  # TASK_SESSION_STATE_CHANGE_TYPE.TASK_SESSION_UNLOCK (taskschd.h)
            $Trigger.Enabled = $True
            return $Trigger
        }
        function createScheduledTaskTrigger {
            [CmdletBinding()]
            param(
                [PSCustomObject] $TriggerConfig
            )
            if ($TriggerConfig.triggerType -eq "Event") {

                return createScheduledTaskEventTrigger -TriggerConfig $TriggerConfig
            }
            elseif ($TriggerConfig.triggerType -eq "AtLogon") {

                return createScheduledTaskAtLogonTrigger -TriggerConfig $TriggerConfig
            }
            elseif ($TriggerConfig.triggerType -eq "AtWorkstationUnlock") {

                return createScheduledTaskAtWorkstationUnlockTrigger -TriggerConfig $TriggerConfig
            }
        }

        function createScheduledTaskEncodedCommandFromTemplateAction {
            [CmdletBinding()]
            param(
                [PSCustomObject] $ActionConfig
            )
            
            $ScriptContents = (Get-IntuneScriptTemplates)[$ActionConfig.templateScript]
            If ($ProfilePath) {
                $ScriptContents = $ScriptContents.Replace("`$ProfilePath = ([System.Environment]::GetFolderPath('UserProfile'))", "`$ProfilePath = '$($ProfilePath)'")
            }
            if ($CentralDataPath) {
                $ScriptContents = $ScriptContents.Replace("`$CentralDataPath = (Join-Path -Path ([System.Environment]::GetFolderPath('CommonApplicationData')) -ChildPath 'IntuneResourceLocalization')", "`$CentralDataPath = '$($CentralDataPath)'")
            }
            if ($LogPath) {
                $ScriptContents = $ScriptContents.Replace("`$LogPath = Join-Path -Path ([System.Environment]::GetFolderPath('UserProfile')) -ChildPath `"Documents\WindowsPowerShell\Transcripts`"", "`$LogPath = '$($LogPath)'")
            }
            if ($key) {
                $ScriptContents = $ScriptContents.Replace('$Key = $null', "`$Key = @($($Key -join ','))")
            }
            $scriptBlockString = $ScriptContents.ToString()
            $bytes = [System.Text.Encoding]::Unicode.GetBytes($scriptBlockString)
            $encodedCommand = [Convert]::ToBase64String($bytes)

            # $Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NonInteractive -WindowStyle Hidden -EncodedCommand $($encodedCommand)"
            
            # 2023-10-25: changing to .cmd /c start /min "" powershell... to minimize pop-ups
            $encoding = if ($PSVersionTable.PSEdition -eq 'Core') {
                [System.Text.Encoding]::UTF8
            }
            else {
                'UTF8'
            }
            $ScriptContents | Out-File -FilePath (Join-Path -Path $($CentralDataPath) -ChildPath "$($ActionConfig.templateScript).ps1") -Encoding $encoding
            $Action = New-ScheduledTaskAction -Execute "cmd" -Argument "/c start /min """" powershell -WindowStyle Hidden -File ""$(Join-Path -Path $($CentralDataPath) -ChildPath "$($ActionConfig.templateScript).ps1")"""

            # 2023-09: Separate Start-Process to try and hide the window
            # $Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-WindowStyle Hidden -Command `"& {Start-Process -FilePath 'powershell.Exe' -Wait -NoNewWindow -ArgumentList '-WindowStyle Hidden -EncodedCommand $($encodedCommand)'} `""

            # powershell.exe -Command '& {Start-Process -FilePath ''C:\windows\system32\WindowsPowerShell\v1.0\powershell.Exe'' -ArgumentList ''-EncodedCommand <snip>'' -Wait -WindowStyle Minimized }'


            return $Action
        }
        function createScheduledTaskAction {
            [CmdletBinding()]
            param(
                [PSCustomObject] $ActionConfig
            )
            if ($ActionConfig.actionType -eq "EncodedCommand") {

                return createScheduledTaskEncodedCommandFromTemplateAction -ActionConfig $ActionConfig
            }
        }

        function getUserToRunUnder {
            [CmdletBinding(DefaultParameterSetName = 'User')]
            param(
                [Parameter(Mandatory, ParameterSetName = 'User')]
                [String]$User,

                [Parameter(Mandatory, ParameterSetName = 'Group')]
                [String]
                $Group
            )
            $TaskPrincipalOptions = switch ($PSCmdlet.ParameterSetName) {
                'User' {
                    switch ($User) {
                        'CurrentUser' {
                            @{
                                UserId    = [System.Security.Principal.WindowsIdentity]::GetCurrent().Name
                                LogonType = 'Interactive'
                                RunLevel  = 'Limited'
                            }
                        }
                        
                        'LocalSystem' {
                            @{
                                UserId    = 'NT AUTHORITY\SYSTEM'
                                LogonType = 'ServiceAccount'
                                RunLevel  = 'Highest'
                            }
                        }

                        'LastLoggedOn' {
                            $lastLogonEvent = Get-WinEvent -LogName Security -FilterXPath "*[System[EventID=4624]]" | Sort-Object TimeCreated -Descending | Select-Object -First 1
                            $loggedInUser = $lastLogonEvent.Properties[5].Value            
                            @{
                                UserId    = $loggedInUser
                                LogonType = 'Interactive'
                                RunLevel  = 'Limited'
                            }
                        }
                    }
                }
                'Group' {
                    @{
                        GroupId  = $Group
                        RunLevel = 'Limited'
                    }
                }
            }
            New-ScheduledTaskPrincipal @TaskPrincipalOptions
        }
        

        foreach ($ScheduledTask in ($ScheduledTaskConfiguration)) {
            Write-Information "Creating Scheduled Task '$($ScheduledTask.Name)'"

            $Actions = @() + ( $ScheduledTask.actions | ForEach-Object {
                    return createScheduledTaskAction -ActionConfig $_
                })

            $Triggers = @() + ( $ScheduledTask.triggers | ForEach-Object {
                    return createScheduledTaskTrigger -TriggerConfig $_
                })

            $Principal = if ($ScheduledTask.user) {
                getUserToRunUnder -User $ScheduledTask.user
            }
            else {
                getUSerToRunUnder -Group $ScheduledTask.group
            }
            $TaskSettings = @{
                AllowStartIfOnBatteries         = $true
                Compatibility                   = 'Win8'
                DisallowDemandStart             = $false
                DisallowHardTerminate           = $false
                DisallowStartOnRemoteAppSession = $true
                DontStopIfGoingOnBatteries      = $true 
                DontStopOnIdleEnd               = $true
                MultipleInstances               = 'IgnoreNew' # 'Queue' # 'Parallel' # 'IgnoreNew'
                RunOnlyIfIdle                   = $false
            }
            $ScheduledTaskSettings = (New-ScheduledTaskSettingsSet @TaskSettings )
            Register-ScheduledTask -TaskName $ScheduledTask.Name -Action $Actions -Trigger $Triggers -Principal $Principal -Settings $ScheduledTaskSettings -Force

            if ($ScheduledTask.startAfterInstallation) {
                Start-ScheduledTask -TaskName $ScheduledTask.Name
            }

        }
    }
    
    end {
    }
}

# SIG # Begin signature block
# MIIuxQYJKoZIhvcNAQcCoIIutjCCLrICAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCRXxEkdvyEQwLd
# hfORfHQAbP/re1zhQDS5/30vY+Z806CCFD4wggVyMIIDWqADAgECAhB2U/6sdUZI
# k/Xl10pIOk74MA0GCSqGSIb3DQEBDAUAMFMxCzAJBgNVBAYTAkJFMRkwFwYDVQQK
# ExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENvZGUgU2ln
# bmluZyBSb290IFI0NTAeFw0yMDAzMTgwMDAwMDBaFw00NTAzMTgwMDAwMDBaMFMx
# CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQD
# EyBHbG9iYWxTaWduIENvZGUgU2lnbmluZyBSb290IFI0NTCCAiIwDQYJKoZIhvcN
# AQEBBQADggIPADCCAgoCggIBALYtxTDdeuirkD0DcrA6S5kWYbLl/6VnHTcc5X7s
# k4OqhPWjQ5uYRYq4Y1ddmwCIBCXp+GiSS4LYS8lKA/Oof2qPimEnvaFE0P31PyLC
# o0+RjbMFsiiCkV37WYgFC5cGwpj4LKczJO5QOkHM8KCwex1N0qhYOJbp3/kbkbuL
# ECzSx0Mdogl0oYCve+YzCgxZa4689Ktal3t/rlX7hPCA/oRM1+K6vcR1oW+9YRB0
# RLKYB+J0q/9o3GwmPukf5eAEh60w0wyNA3xVuBZwXCR4ICXrZ2eIq7pONJhrcBHe
# OMrUvqHAnOHfHgIB2DvhZ0OEts/8dLcvhKO/ugk3PWdssUVcGWGrQYP1rB3rdw1G
# R3POv72Vle2dK4gQ/vpY6KdX4bPPqFrpByWbEsSegHI9k9yMlN87ROYmgPzSwwPw
# jAzSRdYu54+YnuYE7kJuZ35CFnFi5wT5YMZkobacgSFOK8ZtaJSGxpl0c2cxepHy
# 1Ix5bnymu35Gb03FhRIrz5oiRAiohTfOB2FXBhcSJMDEMXOhmDVXR34QOkXZLaRR
# kJipoAc3xGUaqhxrFnf3p5fsPxkwmW8x++pAsufSxPrJ0PBQdnRZ+o1tFzK++Ol+
# A/Tnh3Wa1EqRLIUDEwIrQoDyiWo2z8hMoM6e+MuNrRan097VmxinxpI68YJj8S4O
# JGTfAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G
# A1UdDgQWBBQfAL9GgAr8eDm3pbRD2VZQu86WOzANBgkqhkiG9w0BAQwFAAOCAgEA
# Xiu6dJc0RF92SChAhJPuAW7pobPWgCXme+S8CZE9D/x2rdfUMCC7j2DQkdYc8pzv
# eBorlDICwSSWUlIC0PPR/PKbOW6Z4R+OQ0F9mh5byV2ahPwm5ofzdHImraQb2T07
# alKgPAkeLx57szO0Rcf3rLGvk2Ctdq64shV464Nq6//bRqsk5e4C+pAfWcAvXda3
# XaRcELdyU/hBTsz6eBolSsr+hWJDYcO0N6qB0vTWOg+9jVl+MEfeK2vnIVAzX9Rn
# m9S4Z588J5kD/4VDjnMSyiDN6GHVsWbcF9Y5bQ/bzyM3oYKJThxrP9agzaoHnT5C
# JqrXDO76R78aUn7RdYHTyYpiF21PiKAhoCY+r23ZYjAf6Zgorm6N1Y5McmaTgI0q
# 41XHYGeQQlZcIlEPs9xOOe5N3dkdeBBUO27Ql28DtR6yI3PGErKaZND8lYUkqP/f
# obDckUCu3wkzq7ndkrfxzJF0O2nrZ5cbkL/nx6BvcbtXv7ePWu16QGoWzYCELS/h
# AtQklEOzFfwMKxv9cW/8y7x1Fzpeg9LJsy8b1ZyNf1T+fn7kVqOHp53hWVKUQY9t
# W76GlZr/GnbdQNJRSnC0HzNjI3c/7CceWeQIh+00gkoPP/6gHcH1Z3NFhnj0qinp
# J4fGGdvGExTDOUmHTaCX4GUT9Z13Vunas1jHOvLAzYIwggboMIIE0KADAgECAhB3
# vQ4Ft1kLth1HYVMeP3XtMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAkJFMRkw
# FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENv
# ZGUgU2lnbmluZyBSb290IFI0NTAeFw0yMDA3MjgwMDAwMDBaFw0zMDA3MjgwMDAw
# MDBaMFwxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTIw
# MAYDVQQDEylHbG9iYWxTaWduIEdDQyBSNDUgRVYgQ29kZVNpZ25pbmcgQ0EgMjAy
# MDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMsg75ceuQEyQ6BbqYoj
# /SBerjgSi8os1P9B2BpV1BlTt/2jF+d6OVzA984Ro/ml7QH6tbqT76+T3PjisxlM
# g7BKRFAEeIQQaqTWlpCOgfh8qy+1o1cz0lh7lA5tD6WRJiqzg09ysYp7ZJLQ8LRV
# X5YLEeWatSyyEc8lG31RK5gfSaNf+BOeNbgDAtqkEy+FSu/EL3AOwdTMMxLsvUCV
# 0xHK5s2zBZzIU+tS13hMUQGSgt4T8weOdLqEgJ/SpBUO6K/r94n233Hw0b6nskEz
# IHXMsdXtHQcZxOsmd/KrbReTSam35sOQnMa47MzJe5pexcUkk2NvfhCLYc+YVaMk
# oog28vmfvpMusgafJsAMAVYS4bKKnw4e3JiLLs/a4ok0ph8moKiueG3soYgVPMLq
# 7rfYrWGlr3A2onmO3A1zwPHkLKuU7FgGOTZI1jta6CLOdA6vLPEV2tG0leis1Ult
# 5a/dm2tjIF2OfjuyQ9hiOpTlzbSYszcZJBJyc6sEsAnchebUIgTvQCodLm3HadNu
# twFsDeCXpxbmJouI9wNEhl9iZ0y1pzeoVdwDNoxuz202JvEOj7A9ccDhMqeC5LYy
# AjIwfLWTyCH9PIjmaWP47nXJi8Kr77o6/elev7YR8b7wPcoyPm593g9+m5XEEofn
# GrhO7izB36Fl6CSDySrC/blTAgMBAAGjggGtMIIBqTAOBgNVHQ8BAf8EBAMCAYYw
# EwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E
# FgQUJZ3Q/FkJhmPF7POxEztXHAOSNhEwHwYDVR0jBBgwFoAUHwC/RoAK/Hg5t6W0
# Q9lWULvOljswgZMGCCsGAQUFBwEBBIGGMIGDMDkGCCsGAQUFBzABhi1odHRwOi8v
# b2NzcC5nbG9iYWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUwRgYIKwYBBQUH
# MAKGOmh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2NvZGVzaWdu
# aW5ncm9vdHI0NS5jcnQwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5nbG9i
# YWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUuY3JsMFUGA1UdIAROMEwwQQYJ
# KwYBBAGgMgECMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24u
# Y29tL3JlcG9zaXRvcnkvMAcGBWeBDAEDMA0GCSqGSIb3DQEBCwUAA4ICAQAldaAJ
# yTm6t6E5iS8Yn6vW6x1L6JR8DQdomxyd73G2F2prAk+zP4ZFh8xlm0zjWAYCImbV
# YQLFY4/UovG2XiULd5bpzXFAM4gp7O7zom28TbU+BkvJczPKCBQtPUzosLp1pnQt
# pFg6bBNJ+KUVChSWhbFqaDQlQq+WVvQQ+iR98StywRbha+vmqZjHPlr00Bid/XSX
# hndGKj0jfShziq7vKxuav2xTpxSePIdxwF6OyPvTKpIz6ldNXgdeysEYrIEtGiH6
# bs+XYXvfcXo6ymP31TBENzL+u0OF3Lr8psozGSt3bdvLBfB+X3Uuora/Nao2Y8nO
# ZNm9/Lws80lWAMgSK8YnuzevV+/Ezx4pxPTiLc4qYc9X7fUKQOL1GNYe6ZAvytOH
# X5OKSBoRHeU3hZ8uZmKaXoFOlaxVV0PcU4slfjxhD4oLuvU/pteO9wRWXiG7n9dq
# cYC/lt5yA9jYIivzJxZPOOhRQAyuku++PX33gMZMNleElaeEFUgwDlInCI2Oor0i
# xxnJpsoOqHo222q6YV8RJJWk4o5o7hmpSZle0LQ0vdb5QMcQlzFSOTUpEYck08T7
# qWPLd0jV+mL8JOAEek7Q5G7ezp44UCb0IXFl1wkl1MkHAHq4x/N36MXU4lXQ0x72
# f1LiSY25EXIMiEQmM2YBRN/kMw4h3mKJSAfa9TCCB9gwggXAoAMCAQICDBWogW6/
# LwshkhlS8zANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQ
# R2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVW
# IENvZGVTaWduaW5nIENBIDIwMjAwHhcNMjQxMjEzMTIwMTMwWhcNMjUxMjE0MTIw
# MTMwWjCCAQwxHTAbBgNVBA8MFFByaXZhdGUgT3JnYW5pemF0aW9uMRUwEwYDVQQF
# EwwwNDI5LjAzNy4yMzUxEzARBgsrBgEEAYI3PAIBAxMCQkUxCzAJBgNVBAYTAkJF
# MRcwFQYDVQQIEw5WbGFhbXMtQnJhYmFudDEQMA4GA1UEBxMHQmVlcnNlbDEbMBkG
# A1UECRMSQS4gVmF1Y2FtcHNsYWFuIDQyMRowGAYDVQQKExFJbmV0dW0gQmVsZ2l1
# bSBOVjEaMBgGA1UEAxMRSW5ldHVtIEJlbGdpdW0gTlYxMjAwBgkqhkiG9w0BCQEW
# I3N0aWpuLnNvZW5zQGluZXR1bS1yZWFsZG9sbWVuLndvcmxkMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAv4j0mMO8/KNDdm0dp624UDqAcIy901BIXPcB
# MaVLkl9IL/g9OBVVTLeTIvMYm425wHf+62r3I8QYf/2xXEEu4KoIPc+lzOAMQzWQ
# vCxQjITxHBn5K8EJsu0ZguL3u+pEolWtDEt0BDj7jMmzDpPHiiAe2JhNZMmKW2DM
# Yp8Ine0y4zjb21xfonkX8dUhOWDJ/fFlBio0Qgc1HfnonYmgUu6h/iHTlGypIa6X
# MMgjDIxXgJIIK1Mrk/lxQ2G0uxdL+xHr1P0AlknrVMJFV2uQ0wC95GsMw5/5XRln
# xXF3EcHZixZQTz/sIgk/uSc1fhuAw8lza1MB9+2dDDrloZnDKzvnVPzis0oXMW5Q
# CaO1tarBr46dPNQ0WDWXh3Dsl+xEMy5sTnhUEBBng8+HBuLY1BuXwhO62KE+SYI9
# XWYMR+VFsvHDoQWSzt77m8dDn6IYn+loOhsoOb4etN5sHji+S2hBDB9BqGsDybCS
# Pucwh6pe39cWS6GQb68kZNxs43MQVv5nJ/6LBfTFhzWFxCPjEmWs7hoK2rL4GLSL
# cwr2nLtf0HQLtCfMJLt82zOMYkXZk2Kn7eFLD3OhS/GGUGo2T/V/0z8tc4QW92Rh
# Uo6Rrfdx3TTP0F2LCr/HAWd7wfbxyIQFFQaAEMSALnqRsxqNe42BCi1aZPeyVjoz
# FSLeiVUCAwEAAaOCAeYwggHiMA4GA1UdDwEB/wQEAwIHgDCBnwYIKwYBBQUHAQEE
# gZIwgY8wTAYIKwYBBQUHMAKGQGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20v
# Y2FjZXJ0L2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMC5jcnQwPwYIKwYBBQUHMAGG
# M2h0dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNh
# MjAyMDBVBgNVHSAETjBMMEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUFBwIBFiZodHRw
# czovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBAzAJBgNV
# HRMEAjAAMEcGA1UdHwRAMD4wPKA6oDiGNmh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5j
# b20vZ3NnY2NyNDVldmNvZGVzaWduY2EyMDIwLmNybDAuBgNVHREEJzAlgSNzdGlq
# bi5zb2Vuc0BpbmV0dW0tcmVhbGRvbG1lbi53b3JsZDATBgNVHSUEDDAKBggrBgEF
# BQcDAzAfBgNVHSMEGDAWgBQlndD8WQmGY8Xs87ETO1ccA5I2ETAdBgNVHQ4EFgQU
# f0jm5utH8OLv1QEC0Wk4aX/23aEwDQYJKoZIhvcNAQELBQADggIBALEDyyzBbsaf
# sKEtVuqOC7qle41dIA7uid58TkqaT6XnUggf/pI4RYPKrk3ZfZ3zDWUwkFtXiSB8
# 4T9JIDTM4gF58Lg3dbwf8jUzPPUp4HLdNSME45IVDpEla+A20p5DmDjYqW73xx1z
# 64AnUQgRxPJvjDITc1q2FIRPvaKOF18s95HqO0aMO5//RQKCQO8XG60QU2iEKPDx
# QXzrTbFQc9nNH/zw44/2H0C+BRlyUTsQ/2j57LmT0W5nT99qk25oanaJC1C/Xji5
# uLtSL3n8iPOlQfct3XfphHBCBpS/+01WaVCVThjeonqRk3OlSjQeWTt+KXunXWVi
# vForgxkzrS9YAsxEuv/O1aZNAAxlamKKUpC0KnbTu/XHxKacAHWnC6v4TG+tA6S+
# exjazpK6g29cIy46eLH1Uai0EvL7+kKXe5j5FdYJTcm4N58QWeikTrVWXZg9ZCW/
# 7VTRMjKtxTMn0uQ/K/u7a41ZIZG8TUQKPO0aA/TpCwcAKYkz/YGqeJiJWjEvTb3w
# Q8jH8g5P3Cx8w/OcJec3F5d6FrS4WVh4kcl48p+u9PvtS1+zRA0/6OlPkHnFX6Or
# dvAFBBaD1tqQD4cELodfU3Xh1NNxC+LuSE3wD1/bjTlFtZbyIH9xBF06mxQh9CGV
# POZj8ZmsBndoJWPccWFyseMf3nBBHXzoMYIZ3TCCGdkCAQEwbDBcMQswCQYDVQQG
# EwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFs
# U2lnbiBHQ0MgUjQ1IEVWIENvZGVTaWduaW5nIENBIDIwMjACDBWogW6/LwshkhlS
# 8zANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkG
# CSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEE
# AYI3AgEVMC8GCSqGSIb3DQEJBDEiBCCBwmiF71kith34yWdb6KoKpthz4U38o/ay
# VgGSnYezyTANBgkqhkiG9w0BAQEFAASCAgC4le9dICwqPz0vkZHMybm+XWpejshD
# Y/HYfTTZFlJ+/cOe0e4UU2ZJMOYLSTpMGfkqqlqYLwXn4lL4MbgPnwbHjHo8hCIQ
# NsO5v8wEz3/xbfo0yxVtlwR21lruufJ4bZOPmPUg3/CO/SwRx/hWxq46eKgA5pQZ
# O7uJmdUwZup2H7rDJh044KGjb1tuX5eNu0lcYn6oohp8NpyOwHWUbC1SUIuJEoiF
# 7L8Aro19Xq4eO4W92XGeQ6swHYUwU4sNvAeJ2W25+xG9zc/H1FQ4aooDfsyu1R3I
# lXdBykXtLdizWZmHjvxFm8+aQU7uyK4zzR1Qfze74v8sDEdG2HbCzUtvGKom4+b/
# R0PJC/t6caxRQDzECERNJAhbrVC5Kb10QNe30HR40+vMNuUlqJ4J/Fzs4/PJf3zK
# FUc8Lx4/YMnBTMyIgKUWsD5tzUtgaaJ5vzYAzIjXnE3GlRunBuA4VofJpTUZF2kh
# TEH3Ii2iaBAqSruu7O33z7AVJzNvrFu1Vo8Y+DYwpovfY6AJZU2HQgNyXjJ8DMA8
# RNZLsnsePuYJOz5GOipvwOmRmoB03jWIr6vcdnzwFS6wQunAXsxDLmCTv7RcloaY
# Z0/Vpb/URs4WH9QXmLoivdjzCQATh2gbp4hvkOxByUfMOdOVaCRj5Qe5I3ekkoy4
# 4VB3NwoCfOJPyaGCFrswgha3BgorBgEEAYI3AwMBMYIWpzCCFqMGCSqGSIb3DQEH
# AqCCFpQwghaQAgEDMQ0wCwYJYIZIAWUDBAIBMIHfBgsqhkiG9w0BCRABBKCBzwSB
# zDCByQIBAQYLKwYBBAGgMgIDAQIwMTANBglghkgBZQMEAgEFAAQgCweT16+8bqvC
# tk36QJCLveWtINZyUGKqlyua3BxqmVwCFGhQRxQDCwKr5d8Hv+mMT7n+K4/DGA8y
# MDI1MDcwMTEwNTk0M1owAwIBAaBYpFYwVDELMAkGA1UEBhMCQkUxGTAXBgNVBAoM
# EEdsb2JhbFNpZ24gbnYtc2ExKjAoBgNVBAMMIUdsb2JhbHNpZ24gVFNBIGZvciBD
# b2RlU2lnbjEgLSBSNqCCEkswggZjMIIES6ADAgECAhABAAsgBbOUB2LbPjZ5lJup
# MA0GCSqGSIb3DQEBDAUAMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxT
# aWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAt
# IFNIQTM4NCAtIEc0MB4XDTI1MDQxMTE0NDczOVoXDTM0MTIxMDAwMDAwMFowVDEL
# MAkGA1UEBhMCQkUxGTAXBgNVBAoMEEdsb2JhbFNpZ24gbnYtc2ExKjAoBgNVBAMM
# IUdsb2JhbHNpZ24gVFNBIGZvciBDb2RlU2lnbjEgLSBSNjCCAaIwDQYJKoZIhvcN
# AQEBBQADggGPADCCAYoCggGBAKJbxKpNSeUjeD7ghevmqgo+1fKsqKdEYfeKy5mN
# +wp/Hq/NEpHys3SRyZN06mvUGOFMFeoXnV30m+YJNF8nctzDRI9ahPmaJjxHIwu7
# kbRnXwfz7Z4nlic47T1VJZhD61DLKBVO8KCUnEVdVuv+nn4tgckh17IWd9FdRA2d
# pSkNAyt6t2yOLCRP+Z/3UMvIi+IY02kvb9GEMuUSWPqNTVocT/x7Dbpuuzq+KxQ7
# BiBPOYYOa+INwlxboqlr5TZj2wgVoHcafzwqmNC4ntOA7imw8EXep65uQB+aCESc
# hVIy7xuBztC9VF2DLieidSczuN/EQNJiUb1NmcGyOsohR2ktMd0oBWpL4RCy5+LZ
# sJ4GD4/hQ19y2lh554vzBiV0cZzdKUHWCahGISlJazB/ftipZ3XM//cl2BhMsE7f
# PHd8vk1Bb2ZQANATDmDDK2BUBKbZUYNg2K8ebFrV9arws5OrBAS0VTxGxNIvidNS
# C5Qc0aXCbrGVEMhitkVUjhX1zwIDAQABo4IBqDCCAaQwDgYDVR0PAQH/BAQDAgeA
# MBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMB0GA1UdDgQWBBSAQ0z8um0dE9J1EogJ
# d2/bxk+VVDBWBgNVHSAETzBNMAgGBmeBDAEEAjBBBgkrBgEEAaAyAR4wNDAyBggr
# BgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2lnbi5jb20vcmVwb3NpdG9yeS8w
# DAYDVR0TAQH/BAIwADCBkAYIKwYBBQUHAQEEgYMwgYAwOQYIKwYBBQUHMAGGLWh0
# dHA6Ly9vY3NwLmdsb2JhbHNpZ24uY29tL2NhL2dzdHNhY2FzaGEzODRnNDBDBggr
# BgEFBQcwAoY3aHR0cDovL3NlY3VyZS5nbG9iYWxzaWduLmNvbS9jYWNlcnQvZ3N0
# c2FjYXNoYTM4NGc0LmNydDAfBgNVHSMEGDAWgBTqFsZp5+PLV0U5M6TwQL7Qw71l
# ljBBBgNVHR8EOjA4MDagNKAyhjBodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2Nh
# L2dzdHNhY2FzaGEzODRnNC5jcmwwDQYJKoZIhvcNAQEMBQADggIBALemx0qZdnT9
# IGInvYl8Nwc+V88LL5omIrBI26MkWYp/o6h9uiBau30DCKzeVXV/ChpeaRHttW/L
# JD31HLYq6KOkEuaFhEpeJM2aMNoif6iZ++k5Ly/r9n+Jh6JRiwcMg5u+H16+vFut
# 8bomEqZ23+zWD8gWhyO8yfxK0k+GwNNEwvn7T7bUvhvzITVGioN+MmifGegBDZz3
# QgfFSK7f7KnekdZPPTo8dYy9+kARD1K9nbSCJUtyou+AlNeWE7xvl8bfXMBPtBsf
# 6kUL/GGxflHLHYGFOIzUWQdJE1dwbHd5ciFprfA0+EUI/S0NSCzqahvws8HfavRi
# S+o0iXkqtQAuGaHFTLqnGHfw/SaSDC/QUP8JOZYCZIFxHNYEYD7A7FPc89+icpjd
# fmIb8dFa+u469EH6pN1dM+v8VZhACSmn03iHw/YUHIY4hpMsNxCjYsh8jN+63Svw
# bE0sdKwdzB3ahPf3R0F+TVDkAllL4ZFstdLu9csxilp2wFkOjTbqvX7XMGBU5nMq
# OWGxcM35MkvmO/PjvbraoIulaBNjc1SW7nKhi2bSRScxiQ+8Xv66lC8GB3kNxz0p
# zQmoG+o6gXhUp108dBm7mLpN4wOdXUDbbKIFQBlwqh7IetkFQJf4GnU33EWjKSFg
# HNwj7qd8dfXQwKbKZkcjlc1wVLbIglrCMIIGWTCCBEGgAwIBAgINAewckkDe/S5A
# XXxHdDANBgkqhkiG9w0BAQwFADBMMSAwHgYDVQQLExdHbG9iYWxTaWduIFJvb3Qg
# Q0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UEAxMKR2xvYmFsU2ln
# bjAeFw0xODA2MjAwMDAwMDBaFw0zNDEyMTAwMDAwMDBaMFsxCzAJBgNVBAYTAkJF
# MRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWdu
# IFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0MIICIjANBgkqhkiG9w0BAQEF
# AAOCAg8AMIICCgKCAgEA8ALiMCP64BvhmnSzr3WDX6lHUsdhOmN8OSN5bXT8MeR0
# EhmW+s4nYluuB4on7lejxDXtszTHrMMM64BmbdEoSsEsu7lw8nKujPeZWl12rr9E
# qHxBJI6PusVP/zZBq6ct/XhOQ4j+kxkX2e4xz7yKO25qxIjw7pf23PMYoEuZHA6H
# pybhiMmg5ZninvScTD9dW+y279Jlz0ULVD2xVFMHi5luuFSZiqgxkjvyen38Dljf
# gWrhsGweZYIq1CHHlP5CljvxC7F/f0aYDoc9emXr0VapLr37WD21hfpTmU1bdO1y
# S6INgjcZDNCr6lrB7w/Vmbk/9E818ZwP0zcTUtklNO2W7/hn6gi+j0l6/5Cx1Pcp
# Fdf5DV3Wh0MedMRwKLSAe70qm7uE4Q6sbw25tfZtVv6KHQk+JA5nJsf8sg2glLCy
# lMx75mf+pliy1NhBEsFV/W6RxbuxTAhLntRCBm8bGNU26mSuzv31BebiZtAOBSGs
# sREGIxnk+wU0ROoIrp1JZxGLguWtWoanZv0zAwHemSX5cW7pnF0CTGA8zwKPAf1y
# 7pLxpxLeQhJN7Kkm5XcCrA5XDAnRYZ4miPzIsk3bZPBFn7rBP1Sj2HYClWxqjcoi
# XPYMBOMp+kuwHNM3dITZHWarNHOPHn18XpbWPRmwl+qMUJFtr1eGfhA3HWsaFN8C
# AwEAAaOCASkwggElMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEA
# MB0GA1UdDgQWBBTqFsZp5+PLV0U5M6TwQL7Qw71lljAfBgNVHSMEGDAWgBSubAWj
# kxPioufi1xzWx/B/yGdToDA+BggrBgEFBQcBAQQyMDAwLgYIKwYBBQUHMAGGImh0
# dHA6Ly9vY3NwMi5nbG9iYWxzaWduLmNvbS9yb290cjYwNgYDVR0fBC8wLTAroCmg
# J4YlaHR0cDovL2NybC5nbG9iYWxzaWduLmNvbS9yb290LXI2LmNybDBHBgNVHSAE
# QDA+MDwGBFUdIAAwNDAyBggrBgEFBQcCARYmaHR0cHM6Ly93d3cuZ2xvYmFsc2ln
# bi5jb20vcmVwb3NpdG9yeS8wDQYJKoZIhvcNAQEMBQADggIBAH/iiNlXZytCX4Gn
# CQu6xLsoGFbWTL/bGwdwxvsLCa0AOmAzHznGFmsZQEklCB7km/fWpA2PHpbyhqIX
# 3kG/T+G8q83uwCOMxoX+SxUk+RhE7B/CpKzQss/swlZlHb1/9t6CyLefYdO1RkiY
# lwJnehaVSttixtCzAsw0SEVV3ezpSp9eFO1yEHF2cNIPlvPqN1eUkRiv3I2ZOBlY
# wqmhfqJuFSbqtPl/KufnSGRpL9KaoXL29yRLdFp9coY1swJXH4uc/LusTN763lNM
# g/0SsbZJVU91naxvSsguarnKiMMSME6yCHOfXqHWmc7pfUuWLMwWaxjN5Fk3hgks
# 4kXWss1ugnWl2o0et1sviC49ffHykTAFnM57fKDFrK9RBvARxx0wxVFWYOh8lT0i
# 49UKJFMnl4D6SIknLHniPOWbHuOqhIKJPsBK9SH+YhDtHTD89szqSCd8i3VCf2vL
# 86VrlR8EWDQKie2CUOTRe6jJ5r5IqitV2Y23JSAOG1Gg1GOqg+pscmFKyfpDxMZX
# xZ22PLCLsLkcMe+97xTYFEBsIB3CLegLxo1tjLZx7VIh/j72n585Gq6s0i96ILH0
# rKod4i0UnfqWah3GPMrz2Ry/U02kR1l8lcRDQfkl4iwQfoH5DZSnffK1CfXYYHJA
# UJUg1ENEvvqglecgWbZ4xqRqqiKbMIIFgzCCA2ugAwIBAgIORea7A4Mzw4VlSOb/
# RVEwDQYJKoZIhvcNAQEMBQAwTDEgMB4GA1UECxMXR2xvYmFsU2lnbiBSb290IENB
# IC0gUjYxEzARBgNVBAoTCkdsb2JhbFNpZ24xEzARBgNVBAMTCkdsb2JhbFNpZ24w
# HhcNMTQxMjEwMDAwMDAwWhcNMzQxMjEwMDAwMDAwWjBMMSAwHgYDVQQLExdHbG9i
# YWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2lnbjETMBEGA1UE
# AxMKR2xvYmFsU2lnbjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJUH
# 6HPKZvnsFMp7PPcNCPG0RQssgrRIxutbPK6DuEGSMxSkb3/pKszGsIhrxbaJ0cay
# /xTOURQh7ErdG1rG1ofuTToVBu1kZguSgMpE3nOUTvOniX9PeGMIyBJQbUJmL025
# eShNUhqKGoC3GYEOfsSKvGRMIRxDaNc9PIrFsmbVkJq3MQbFvuJtMgamHvm566qj
# uL++gmNQ0PAYid/kD3n16qIfKtJwLnvnvJO7bVPiSHyMEAc4/2ayd2F+4OqMPKq0
# pPbzlUoSB239jLKJz9CgYXfIWHSw1CM69106yqLbnQneXUQtkPGBzVeS+n68UARj
# NN9rkxi+azayOeSsJDa38O+2HBNXk7besvjihbdzorg1qkXy4J02oW9UivFyVm4u
# iMVRQkQVlO6jxTiWm05OWgtH8wY2SXcwvHE35absIQh1/OZhFj931dmRl4QKbNQC
# TXTAFO39OfuD8l4UoQSwC+n+7o/hbguyCLNhZglqsQY6ZZZZwPA1/cnaKI0aEYdw
# gQqomnUdnjqGBQCe24DWJfncBZ4nWUx2OVvq+aWh2IMP0f/fMBH5hc8zSPXKbWQU
# LHpYT9NLCEnFlWQaYw55PfWzjMpYrZxCRXluDocZXFSxZba/jJvcE+kNb7gu3Gdu
# yYsRtYQUigAZcIN5kZeR1BonvzceMgfYFGM8KEyvAgMBAAGjYzBhMA4GA1UdDwEB
# /wQEAwIBBjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBSubAWjkxPioufi1xzW
# x/B/yGdToDAfBgNVHSMEGDAWgBSubAWjkxPioufi1xzWx/B/yGdToDANBgkqhkiG
# 9w0BAQwFAAOCAgEAgyXt6NH9lVLNnsAEoJFp5lzQhN7craJP6Ed41mWYqVuoPId8
# AorRbrcWc+ZfwFSY1XS+wc3iEZGtIxg93eFyRJa0lV7Ae46ZeBZDE1ZXs6KzO7V3
# 3EByrKPrmzU+sQghoefEQzd5Mr6155wsTLxDKZmOMNOsIeDjHfrYBzN2VAAiKrlN
# IC5waNrlU/yDXNOd8v9EDERm8tLjvUYAGm0CuiVdjaExUd1URhxN25mW7xocBFym
# Fe944Hn+Xds+qkxV/ZoVqW/hpvvfcDDpw+5CRu3CkwWJ+n1jez/QcYF8AOiYrg54
# NMMl+68KnyBr3TsTjxKM4kEaSHpzoHdpx7Zcf4LIHv5YGygrqGytXm3ABdJ7t+uA
# /iU3/gKbaKxCXcPu9czc8FB10jZpnOZ7BN9uBmm23goJSFmH63sUYHpkqmlD75HH
# TOwY3WzvUy2MmeFe8nI+z1TIvWfspA9MRf/TuTAjB0yPEL+GltmZWrSZVxykzLsV
# iVO6LAUP5MSeGbEYNNVMnbrt9x+vJJUEeKgDu+6B5dpffItKoZB0JaezPkvILFa9
# x8jvOOJckvB595yEunQtYQEgfn7R8k8HWV+LLUNS60YMlOH1Zkd5d9VUWx+tJDfL
# RVpOoERIyNiwmcUVhAn21klJwGW45hpxbqCo8YLoRT5s1gLXCmeDBVrJpBAxggNJ
# MIIDRQIBATBvMFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52
# LXNhMTEwLwYDVQQDEyhHbG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4
# NCAtIEc0AhABAAsgBbOUB2LbPjZ5lJupMAsGCWCGSAFlAwQCAaCCAS0wGgYJKoZI
# hvcNAQkDMQ0GCyqGSIb3DQEJEAEEMCsGCSqGSIb3DQEJNDEeMBwwCwYJYIZIAWUD
# BAIBoQ0GCSqGSIb3DQEBCwUAMC8GCSqGSIb3DQEJBDEiBCCjQoSLHASMTOkN144g
# TSvCEWALo1ZQJeyGsx3qIHbE9DCBsAYLKoZIhvcNAQkQAi8xgaAwgZ0wgZowgZcE
# IHJe8n9I4W5puWPYQmiMW8oHqIxpFwZCyP9aK3evYFz9MHMwX6RdMFsxCzAJBgNV
# BAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYDVQQDEyhHbG9i
# YWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0AhABAAsgBbOUB2Lb
# PjZ5lJupMA0GCSqGSIb3DQEBCwUABIIBgBEPgyf9LQ+pCzuPrspA1ZAYvRoR+Iiy
# boyo5PDyCSrbKNQ38y0UGM3qp2A0/cU+Makrw8kJR6auo4+zJH5KHY2wjtySCEFM
# dc2U3N0ZgbVFZTdu6u20ozDXIelFvYWIy6yQ7k+kRNsna/ysUpq6tVCtNaTNKZJ7
# xnWbzAkQ7uBeZElYFIuSnbdNGQRt8LrIDfqXAj8wpbdiCCyjtfB97cgewFyLXUCB
# iunnwW2HBhzOJzLE3JbAl791YiWJdexJomwbXPe7yhkwwaHIgpZzbyW58hyeHprt
# yVODb2oN18dWhKThJs4Cni3yLVmag1lyLoXPybc2jRKrcup3L9ZLR6Sybf88XJy3
# LcqZLXmuyqxk7ASfTScK37ZldCMFXFp61DQWf2z/muV5IKd6ZzzzuhEJlygxkInH
# pkALvLjBE+zlYMd/IQDV2w6VjDUof56yMpY4RWWekRG23lKU06UkUhIQN7s1YRK0
# JK/BYbIJAg+oCefWB+0CWcykzjnzsrhoZg==
# SIG # End signature block