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)')]]
</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
# MIIufAYJKoZIhvcNAQcCoIIubTCCLmkCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD/0Pu4ccOsPd/w
# LB43UTsWldcdH8OGZl0x5d6D70lLG6CCE/8wggVyMIIDWqADAgECAhB2U/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/kMw4h3mKJSAfa9TCCB5kwggWBoAMCAQICDH+jGUtp
# n7qIskPg4DANBgkqhkiG9w0BAQsFADBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQ
# R2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVW
# IENvZGVTaWduaW5nIENBIDIwMjAwHhcNMjMwODIzMDg0MjIzWhcNMjQwODIzMDg0
# MjIzWjCB/jEdMBsGA1UEDwwUUHJpdmF0ZSBPcmdhbml6YXRpb24xFTATBgNVBAUT
# DDA0MjkuMDM3LjIzNTETMBEGCysGAQQBgjc8AgEDEwJCRTELMAkGA1UEBhMCQkUx
# FzAVBgNVBAgTDlZsYWFtcy1CcmFiYW50MRAwDgYDVQQHEwdCZWVyc2VsMRswGQYD
# VQQJExJBLiBWYXVjYW1wc2xhYW4gNDIxJTAjBgNVBAoTHEluZXR1bSBSZWFsZG9s
# bWVuIEJlbGdpdW0gTlYxDjAMBgNVBAsTBVdQQUFTMSUwIwYDVQQDExxJbmV0dW0g
# UmVhbGRvbG1lbiBCZWxnaXVtIE5WMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAz9zO2ny9NoHSdEnF2zFfkTHtLB/oDq80CHB7+7FKCK5aOGYO0Nv/Bg9k
# Qc6tHyf/03nK4y4vwxWPIaGcqWe1k1MwvSru5bPbXjS6CnPLnm0OKpHjXCryvvdt
# fcyFSZrRPF8wSG6UmYewSEOP8xOUXx2kFcsjrWxHkjvwfrPIKBaCLn/Gldl9MlUc
# K8PmPlz0jKMkN6/16Q3R3MqnCfKPIEBkHbEJ3f8F9lRnHq9o2exmfE2GhN7UtBDZ
# uN/jzMkPBW7h1AEOZXpzJlUTSMvGJqYGkHX8JxCWwgJWvtZF03dnKWEaJt+3wAOg
# DZUj0Yxzz7vsk2Auc+EMwkdlfCSoMDjCv6UmKF7CsLtr6UgDuRR8KK+K7Is+KVbP
# a3GEAAuKnXAEdOyGfNmsdyewELrMAlh4fvxcVcLzM9cGgoHo8RU6dczImANeqzm9
# /+LwX3rqem95gkRe8JuJUkBniQVFiQ+6ZvyXzm0L3qCtp0JAsd+n6hCGTR8VzeRY
# UDxzmVbnpjBctIEPNT8PqZlFv9zoJxS22X9aZOhBpsuAVtwM5cVt7qR0eCXXPZJk
# 9LFUcDCYn/nqi1Qc/IptSjE1ETo9h0GD97Ri4fm2D4ahjsngricSl5oMYbC2PHcn
# jOjdd7Ab+UturGdjUvQR/7Z4qjymHJqFA41DPadfBJ6BU+b0IMkCAwEAAaOCAbYw
# ggGyMA4GA1UdDwEB/wQEAwIHgDCBnwYIKwYBBQUHAQEEgZIwgY8wTAYIKwYBBQUH
# MAKGQGh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2dzZ2NjcjQ1
# ZXZjb2Rlc2lnbmNhMjAyMC5jcnQwPwYIKwYBBQUHMAGGM2h0dHA6Ly9vY3NwLmds
# b2JhbHNpZ24uY29tL2dzZ2NjcjQ1ZXZjb2Rlc2lnbmNhMjAyMDBVBgNVHSAETjBM
# MEEGCSsGAQQBoDIBAjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxz
# aWduLmNvbS9yZXBvc2l0b3J5LzAHBgVngQwBAzAJBgNVHRMEAjAAMEcGA1UdHwRA
# MD4wPKA6oDiGNmh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vZ3NnY2NyNDVldmNv
# ZGVzaWduY2EyMDIwLmNybDATBgNVHSUEDDAKBggrBgEFBQcDAzAfBgNVHSMEGDAW
# gBQlndD8WQmGY8Xs87ETO1ccA5I2ETAdBgNVHQ4EFgQUL5AOgixh/ZL7PiP/4x2P
# 10jJK7cwDQYJKoZIhvcNAQELBQADggIBAL41K2LQmY2+hWstzMugRhfgZwX+V1PN
# jMNef/pd8fyAobNpwnK3kQz8E7QBSPA1c3oWqTSoC5o+vODkxpelyi+whicBKxEn
# hY97+T1JOZ5nEJbo2QsHPtFEpKsbW3uPcB29iLcBomNjrEQoomcgsyTiHj+6z2OU
# 79uDqJfkUUg7w73fg756VLIpGUo1rWRF6bZh/I6Zjrk+pbL8Su11U1a8H40Xlg8H
# cThHQenIGN7AvmbEkZihQQn2jkdDlkk17f+vNw0GpdvNl6Ufu+RiY/ojEljmr6Vg
# QmQ6B7FNodDCE6u3xj3iYFV9hyHIkST17QMQj2mV3KQ0tAl4QZZHkjvO1AGvjd3b
# VicdJ1EmYMmrP7ovUrujwLZqz3Iux+dWJNShggXzm2NBkD5bgrZPKDvTi9Dd3b0U
# IMO88vOo5eMtuolhgozu6Q9EHsuXV+lt/VWO+I0Qgwx/HkFAM99HgVdpXiTkJmZg
# vx5C958jaHWk83ybattp7BVrbrzf3FugZhqe0z78n9kACxHW5FhZhDh1vXPUW1yL
# HIayt+i0xT7F7lUbuooxyeiOIQYNNXyfbONsDwZDZLbgr2YAxn7y0ZE/9mQ969qE
# GDu6XBehyy6p/SKIwVE5ue92rnWhxtQLIezQVGjMOXBIZv/sy+u5HOFQsy5jGjHM
# pwzCqJ/r3IiYMYIZ0zCCGc8CAQEwbDBcMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQ
# R2xvYmFsU2lnbiBudi1zYTEyMDAGA1UEAxMpR2xvYmFsU2lnbiBHQ0MgUjQ1IEVW
# IENvZGVTaWduaW5nIENBIDIwMjACDH+jGUtpn7qIskPg4DANBglghkgBZQMEAgEF
# AKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJAzEMBgor
# BgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3
# DQEJBDEiBCBrmt7JqSsYUJGtAbf1iXKo8mVYw2s5oMQiXl7T/rCaiDANBgkqhkiG
# 9w0BAQEFAASCAgBboisi5kwpomoxr4mO0rA4/T9oISGDjj5DvjE+Iv7bKzWpAEyi
# tuwEe4oS5zDoZeQfAejZFoC+CxnV90z68fl89LWUyQsgU9UMuQ6B7c9U45jk5fLx
# R3QH/303LRHxAREqEfkhLuIvo+GwF0qfbTsJGQN+T5kX+fL+r2d/i2TvY/nWe7HG
# uBQos7AJqpEWa6Vs62raoLRm2eejO0n1EtRy9vlGfdzdW3MMqUipqgJqVMJbDoki
# YIHNABbfaQSTd1zyurxlzdIkGqwy2NNDPTtsXelYfnvRdYvMZudQgMslmNrsyWTq
# 2tX1goal0vVDRRtC8OJ9lIz6ljzr53SuhVA2AhrLOETp5z7iOxihdZc72hSV0YhL
# skqwmw3Imrb8S0D6BDjkT6ANy8p7Fp1DSliAtOmdaQqbh4oHUAWy150Tqqd3J2LD
# 1ddGwmkrs1ZCM13sLmNOW7tH9NinTMyVj0WZ82SWP8mXQmWJnwKIKasFE820Ivi5
# wMNkFW38qxeRz1EyRErUIl0EUPdD3PlE0yFdIu3OeGsM0gObd9en0dc4G8Jsb7sy
# 2KDuNHVsx+FatU9wzYK3YwZ53D1gqKYVf4q/bFStMOljEQ+BGJiEaUievt6iE015
# ngNVb76GBsbBqg1ioBL2kG02cLD8dyVO/gIHj66WNDHCEjew8cjRC85kPKGCFrEw
# ghatBgorBgEEAYI3AwMBMYIWnTCCFpkGCSqGSIb3DQEHAqCCFoowghaGAgEDMQ0w
# CwYJYIZIAWUDBAIBMIHfBgsqhkiG9w0BCRABBKCBzwSBzDCByQIBAQYLKwYBBAGg
# MgIDAQIwMTANBglghkgBZQMEAgEFAAQgm7Xgsd6uwuh3FcAJnrn7HPYIEzCc3c5W
# jZA0UBlmUzsCFAXbnoUAnk8oyiHIOOJZ39nUH/tHGA8yMDI0MDIyMjE0MDgzMVow
# AwIBAaBYpFYwVDELMAkGA1UEBhMCQkUxGTAXBgNVBAoMEEdsb2JhbFNpZ24gbnYt
# c2ExKjAoBgNVBAMMIUdsb2JhbHNpZ24gVFNBIGZvciBDb2RlU2lnbjEgLSBSNqCC
# EkEwggZZMIIEQaADAgECAhABsovUz+7uDb7Qsw2b+ENqMA0GCSqGSIb3DQEBCwUA
# MFsxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMTEwLwYD
# VQQDEyhHbG9iYWxTaWduIFRpbWVzdGFtcGluZyBDQSAtIFNIQTM4NCAtIEc0MB4X
# DTIyMDQwNjA3NDUzOFoXDTMzMDUwODA3NDUzOFowVDELMAkGA1UEBhMCQkUxGTAX
# BgNVBAoMEEdsb2JhbFNpZ24gbnYtc2ExKjAoBgNVBAMMIUdsb2JhbHNpZ24gVFNB
# IGZvciBDb2RlU2lnbjEgLSBSNjCCAaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoC
# ggGBALCtSOBZ5WkREjOOtF+7B4VC4MlJpWTwBpj9zPDI+oqcGX1mqjMg17p+aaNf
# 4n9KlFHPxcvXqjekgQEK+teQ6hl2HVrc1iJCvKk/3g8bSKt4ZlqxofRAj8ekoV+h
# wvzifI97V6WBepAri+ukKNw+LXJlKzC0aDzkCpidKx22cVGbgLegeqDdiU5dmhYp
# Exh9LodrS/r0ZJRC6z2UwqsEm2XYTHHPNiP4Lpkg2V93peqNF8VPIJdsMyRInDOM
# TJ0IjuUotsJaKIyh1b4Kk2FiluF1cfqQHAldYK0dCPLowrLDACKS+9zQuRlBQr2K
# y71sxu0oakqPNLRpmhtah144OLxSLDoOvLoQT9IAsxy60oEVPq+vXLDl2F+gan6M
# /INDuXdhikdzP6My0TqrJ1Wb8htRXYTjJNJWOJ7cSm+ZX1EhMsS9WPDxIWgZ7xg1
# Mj+MdA0tbPIi+bghAZ+asCk39DpJ2uhqV53ZAqHwHLldthn9AZV6Q4cL/cVL42q2
# BeeF8wIDAQABo4IBnjCCAZowDgYDVR0PAQH/BAQDAgeAMBYGA1UdJQEB/wQMMAoG
# CCsGAQUFBwMIMB0GA1UdDgQWBBTu8IPK1rEJy7AOJh3Gnhue9WV9+TBMBgNVHSAE
# RTBDMEEGCSsGAQQBoDIBHjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9i
# YWxzaWduLmNvbS9yZXBvc2l0b3J5LzAMBgNVHRMBAf8EAjAAMIGQBggrBgEFBQcB
# AQSBgzCBgDA5BggrBgEFBQcwAYYtaHR0cDovL29jc3AuZ2xvYmFsc2lnbi5jb20v
# Y2EvZ3N0c2FjYXNoYTM4NGc0MEMGCCsGAQUFBzAChjdodHRwOi8vc2VjdXJlLmds
# b2JhbHNpZ24uY29tL2NhY2VydC9nc3RzYWNhc2hhMzg0ZzQuY3J0MB8GA1UdIwQY
# MBaAFOoWxmnn48tXRTkzpPBAvtDDvWWWMEEGA1UdHwQ6MDgwNqA0oDKGMGh0dHA6
# Ly9jcmwuZ2xvYmFsc2lnbi5jb20vY2EvZ3N0c2FjYXNoYTM4NGc0LmNybDANBgkq
# hkiG9w0BAQsFAAOCAgEAO/RcO/81JP4+qrLnGseAbEpWuLlkdXbczotvwB5svK0Z
# iydsam4NsLEvU53ZV+HxWWfCItXBkY5JLEUwGHlOagiO0BlYXYJo+7wmuYxM5TfN
# tsYWOsIp9efMskqAgkAhHfaExm6wvt8K3NjAu+gmcpe3x81QSmkDr43vt4oN/Xcc
# tr6mr9oXnA6xk5wFHkVzs87os7P+xZewyXLs7ssJsMsfva/dlzimLvE1mT70Y6oT
# nhmvMD9Sp3xt//cM8DUJLxGxfdGDiDxiZti5b8hJmLhvwmwSqFi52YmIvBKz78/y
# smkZUJN4H88CTgDWWKspfgk033jsBsStwgyQ4JZE6BDoYiRhcPtVTjDbOP1BABil
# aAeDd3r3MI+zu94c8Szc15WP4iAndi9pHyl+HGcWvQFlcEAxt477FIzTT/LdKwIZ
# eti8X4x5uufs6hprbHT40mQCxOYp+Jg52a3l1DJOg64tBJCDavk/fOupABeV2Sqy
# YMASM0Ijkemyax5zZ0OjCRMveGqzs40JO9M7iMyUS2NAsnMTEOpsNF4+25FYV1Rb
# lhPKmd+EZlBNqAzKYmrRi8OR7+oN3ZX06iowkopkrErfV5xPxFO99CYGv4c0JK1x
# qkyitbthvkl76fIODG4JghkxQgSVQV5OCJkQccQfzlqEckjbsvsSeCIXR9ZCNUow
# ggZZMIIEQaADAgECAg0B7BySQN79LkBdfEd0MA0GCSqGSIb3DQEBDAUAMEwxIDAe
# BgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFI2MRMwEQYDVQQKEwpHbG9iYWxT
# aWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMB4XDTE4MDYyMDAwMDAwMFoXDTM0MTIx
# MDAwMDAwMFowWzELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYt
# c2ExMTAvBgNVBAMTKEdsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gU0hBMzg0
# IC0gRzQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDwAuIwI/rgG+Ga
# dLOvdYNfqUdSx2E6Y3w5I3ltdPwx5HQSGZb6zidiW64HiifuV6PENe2zNMeswwzr
# gGZt0ShKwSy7uXDycq6M95laXXauv0SofEEkjo+6xU//NkGrpy39eE5DiP6TGRfZ
# 7jHPvIo7bmrEiPDul/bc8xigS5kcDoenJuGIyaDlmeKe9JxMP11b7Lbv0mXPRQtU
# PbFUUweLmW64VJmKqDGSO/J6ffwOWN+BauGwbB5lgirUIceU/kKWO/ELsX9/RpgO
# hz16ZevRVqkuvftYPbWF+lOZTVt07XJLog2CNxkM0KvqWsHvD9WZuT/0TzXxnA/T
# NxNS2SU07Zbv+GfqCL6PSXr/kLHU9ykV1/kNXdaHQx50xHAotIB7vSqbu4ThDqxv
# Dbm19m1W/oodCT4kDmcmx/yyDaCUsLKUzHvmZ/6mWLLU2EESwVX9bpHFu7FMCEue
# 1EIGbxsY1TbqZK7O/fUF5uJm0A4FIayxEQYjGeT7BTRE6giunUlnEYuC5a1ahqdm
# /TMDAd6ZJflxbumcXQJMYDzPAo8B/XLukvGnEt5CEk3sqSbldwKsDlcMCdFhniaI
# /MiyTdtk8EWfusE/VKPYdgKVbGqNyiJc9gwE4yn6S7Ac0zd0hNkdZqs0c48efXxe
# ltY9GbCX6oxQkW2vV4Z+EDcdaxoU3wIDAQABo4IBKTCCASUwDgYDVR0PAQH/BAQD
# AgGGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFOoWxmnn48tXRTkzpPBA
# vtDDvWWWMB8GA1UdIwQYMBaAFK5sBaOTE+Ki5+LXHNbH8H/IZ1OgMD4GCCsGAQUF
# BwEBBDIwMDAuBggrBgEFBQcwAYYiaHR0cDovL29jc3AyLmdsb2JhbHNpZ24uY29t
# L3Jvb3RyNjA2BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLmdsb2JhbHNpZ24u
# Y29tL3Jvb3QtcjYuY3JsMEcGA1UdIARAMD4wPAYEVR0gADA0MDIGCCsGAQUFBwIB
# FiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzANBgkqhkiG
# 9w0BAQwFAAOCAgEAf+KI2VdnK0JfgacJC7rEuygYVtZMv9sbB3DG+wsJrQA6YDMf
# OcYWaxlASSUIHuSb99akDY8elvKGohfeQb9P4byrze7AI4zGhf5LFST5GETsH8Kk
# rNCyz+zCVmUdvX/23oLIt59h07VGSJiXAmd6FpVK22LG0LMCzDRIRVXd7OlKn14U
# 7XIQcXZw0g+W8+o3V5SRGK/cjZk4GVjCqaF+om4VJuq0+X8q5+dIZGkv0pqhcvb3
# JEt0Wn1yhjWzAlcfi5z8u6xM3vreU0yD/RKxtklVT3WdrG9KyC5qucqIwxIwTrII
# c59eodaZzul9S5YszBZrGM3kWTeGCSziRdayzW6CdaXajR63Wy+ILj198fKRMAWc
# znt8oMWsr1EG8BHHHTDFUVZg6HyVPSLj1QokUyeXgPpIiScseeI85Zse46qEgok+
# wEr1If5iEO0dMPz2zOpIJ3yLdUJ/a8vzpWuVHwRYNAqJ7YJQ5NF7qMnmvkiqK1XZ
# jbclIA4bUaDUY6qD6mxyYUrJ+kPExlfFnbY8sIuwuRwx773vFNgUQGwgHcIt6AvG
# jW2MtnHtUiH+PvafnzkarqzSL3ogsfSsqh3iLRSd+pZqHcY8yvPZHL9TTaRHWXyV
# xENB+SXiLBB+gfkNlKd98rUJ9dhgckBQlSDUQ0S++qCV5yBZtnjGpGqqIpswggWD
# MIIDa6ADAgECAg5F5rsDgzPDhWVI5v9FUTANBgkqhkiG9w0BAQwFADBMMSAwHgYD
# VQQLExdHbG9iYWxTaWduIFJvb3QgQ0EgLSBSNjETMBEGA1UEChMKR2xvYmFsU2ln
# bjETMBEGA1UEAxMKR2xvYmFsU2lnbjAeFw0xNDEyMTAwMDAwMDBaFw0zNDEyMTAw
# MDAwMDBaMEwxIDAeBgNVBAsTF0dsb2JhbFNpZ24gUm9vdCBDQSAtIFI2MRMwEQYD
# VQQKEwpHbG9iYWxTaWduMRMwEQYDVQQDEwpHbG9iYWxTaWduMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAlQfoc8pm+ewUyns89w0I8bRFCyyCtEjG61s8
# roO4QZIzFKRvf+kqzMawiGvFtonRxrL/FM5RFCHsSt0bWsbWh+5NOhUG7WRmC5KA
# ykTec5RO86eJf094YwjIElBtQmYvTbl5KE1SGooagLcZgQ5+xIq8ZEwhHENo1z08
# isWyZtWQmrcxBsW+4m0yBqYe+bnrqqO4v76CY1DQ8BiJ3+QPefXqoh8q0nAue+e8
# k7ttU+JIfIwQBzj/ZrJ3YX7g6ow8qrSk9vOVShIHbf2MsonP0KBhd8hYdLDUIzr3
# XTrKotudCd5dRC2Q8YHNV5L6frxQBGM032uTGL5rNrI55KwkNrfw77YcE1eTtt6y
# +OKFt3OiuDWqRfLgnTahb1SK8XJWbi6IxVFCRBWU7qPFOJabTk5aC0fzBjZJdzC8
# cTflpuwhCHX85mEWP3fV2ZGXhAps1AJNdMAU7f05+4PyXhShBLAL6f7uj+FuC7II
# s2FmCWqxBjplllnA8DX9ydoojRoRh3CBCqiadR2eOoYFAJ7bgNYl+dwFnidZTHY5
# W+r5paHYgw/R/98wEfmFzzNI9cptZBQselhP00sIScWVZBpjDnk99bOMylitnEJF
# eW4OhxlcVLFltr+Mm9wT6Q1vuC7cZ27JixG1hBSKABlwg3mRl5HUGie/Nx4yB9gU
# YzwoTK8CAwEAAaNjMGEwDgYDVR0PAQH/BAQDAgEGMA8GA1UdEwEB/wQFMAMBAf8w
# HQYDVR0OBBYEFK5sBaOTE+Ki5+LXHNbH8H/IZ1OgMB8GA1UdIwQYMBaAFK5sBaOT
# E+Ki5+LXHNbH8H/IZ1OgMA0GCSqGSIb3DQEBDAUAA4ICAQCDJe3o0f2VUs2ewASg
# kWnmXNCE3tytok/oR3jWZZipW6g8h3wCitFutxZz5l/AVJjVdL7BzeIRka0jGD3d
# 4XJElrSVXsB7jpl4FkMTVlezorM7tXfcQHKso+ubNT6xCCGh58RDN3kyvrXnnCxM
# vEMpmY4w06wh4OMd+tgHM3ZUACIquU0gLnBo2uVT/INc053y/0QMRGby0uO9RgAa
# bQK6JV2NoTFR3VRGHE3bmZbvGhwEXKYV73jgef5d2z6qTFX9mhWpb+Gm+99wMOnD
# 7kJG7cKTBYn6fWN7P9BxgXwA6JiuDng0wyX7rwqfIGvdOxOPEoziQRpIenOgd2nH
# tlx/gsge/lgbKCuobK1ebcAF0nu364D+JTf+AptorEJdw+71zNzwUHXSNmmc5nsE
# 324GabbeCglIWYfrexRgemSqaUPvkcdM7BjdbO9TLYyZ4V7ycj7PVMi9Z+ykD0xF
# /9O5MCMHTI8Qv4aW2ZlatJlXHKTMuxWJU7osBQ/kxJ4ZsRg01Uyduu33H68klQR4
# qAO77oHl2l98i0qhkHQlp7M+S8gsVr3HyO844lyS8Hn3nIS6dC1hASB+ftHyTwdZ
# X4stQ1LrRgyU4fVmR3l31VRbH60kN8tFWk6gREjI2LCZxRWECfbWSUnAZbjmGnFu
# oKjxguhFPmzWAtcKZ4MFWsmkEDGCA0kwggNFAgEBMG8wWzELMAkGA1UEBhMCQkUx
# GTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExMTAvBgNVBAMTKEdsb2JhbFNpZ24g
# VGltZXN0YW1waW5nIENBIC0gU0hBMzg0IC0gRzQCEAGyi9TP7u4NvtCzDZv4Q2ow
# CwYJYIZIAWUDBAIBoIIBLTAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwKwYJ
# KoZIhvcNAQk0MR4wHDALBglghkgBZQMEAgGhDQYJKoZIhvcNAQELBQAwLwYJKoZI
# hvcNAQkEMSIEIFdqDwk9sAQGlCLKXwc2uLIEfhMNZtybWQVF7mvJRWJFMIGwBgsq
# hkiG9w0BCRACLzGBoDCBnTCBmjCBlwQg/yAZoKRz6OmSh2W71GYBxlhZjaoTGAhp
# NgOafPAhypkwczBfpF0wWzELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNp
# Z24gbnYtc2ExMTAvBgNVBAMTKEdsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0g
# U0hBMzg0IC0gRzQCEAGyi9TP7u4NvtCzDZv4Q2owDQYJKoZIhvcNAQELBQAEggGA
# WVBKsgvxUkZyE2y5hZxnivZJuR/DdY+SAeu6arPEoed2wEQQXA8l+t4Asr7hrCs6
# qww4i6F0/eK8Sb+0FSvlAwLMXa+wwAqPcUxmmvx4vSu+MBXnY5pz9yZGRVU1n6ZQ
# UuUPE4hZhKSFkVDVKYR32oMPUgz+352IBLbSgaimUZTR9f1lEIowG6I4EURdr6xB
# rUJTDpmhDC+AYi9vmnpzHPcP/khzaZQa4u1Bk/784n+NI+iHlz3HBhbxPJRWh/NF
# Km6N1qamMjgMZIdSZDtoXZ3weKmygt8FH9WDriEXJIiS/22awk/PzHzrnlOxBLsj
# Yyjyf4hJ3rdYKQasyEbHzqs1HevtJqEeTaP6qwdGjxdnEzt05sSk7sXs+bUbZP+i
# l/qJdRvoiyDLP+EWioN9Hte4/CcUQkcpo2h+i1gN9AwZJq5rj43JlMEVxG9iZkLF
# fVbF7elIS0ET/n3coAETrMynn5339HEFylZPmmYt0ay1Wt9eTlyhg16mbagBJTiO
# SIG # End signature block