﻿    <#
      .SYNOPSIS
       Video and audio playback quality assessment.

      .DESCRIPTION
       The MediaQuality assessment supports local and streaming scenarios with the Movies & TV app and Netflix.
       Options are available to control light or verbose tracing and playback duration.

      .PARAMETER PlaybackDuration
       The workload duration in minutes.

      .PARAMETER CustomPlaybackSource
       An optional path to a media file that is to be played for this Assessment.

      .PARAMETER PlaybackSource
       A PlaybackSourceEnum value, such as -3, or a video resolution, such as 1080.

      .PARAMETER ExtendedLogs
       A flag to signal writing out a set of extra commands lines, such as dxdiag /t, pertenant to evaluating media playback quality.

      .PARAMETER TraceOption
       Integer, 1 to enable the light WPR profile, any other integer to enable the verbose WPR profile.

      .EXAMPLE
       MediaQuality -PlaybackSource 1080 -Minutes 2 -FiniteDuration

    #>

Param( 
    [parameter(Mandatory=$true)][int32]$PlaybackDuration, # specified workload duration in minutes
    [parameter(Mandatory=$false)][string]$CustomPlaybackSource,

    <#
        >0: local video specific resolution
        0: local video autoselect
        -1: custom local video
        -2: custom streaming video
        -3: default streaming video
        -4: netflix
        -5: default streaming audio
        -6: custom streaming audio
    #>

    [parameter(Mandatory=$true)][int32]$PlaybackSource, 
    [parameter(Mandatory=$false)][switch]$ExtendedLogs, 
    [parameter(Mandatory=$false)][int32]$TraceOption
)

$ErrorActionPreference = 'Stop'

try {

    # Set to true if you need to hang the script at the end to check console output
    $Global:debugFlag = $false

    # Need to know where our script is so we can use full path to all our dependent files.
    $Global:InvocationPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent
    $AxeUniversalPath = Convert-Path((Get-Item env:\AssessmentAxeUniversalPath).value)

    # Import the modules and functions    
    try {
        Import-Module "$AxeUniversalPath\UniversalAssessment.psm1" -ErrorAction Stop
    }
    catch {
        throw "Failed to import $AxeUniversalPath\UniversalAssessment.psm1"
    }
    
    try {
        Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MediaAssessment.psm1') -ErrorAction Stop
    }
    catch {
        throw "Failed to import module MediaAssessment.psm1"
    }
    
    try {
        Import-Module (Join-Path -Path $PSScriptRoot -ChildPath 'MediaPlayerUIA.psm1') -ErrorAction Stop
    }
    catch {
        throw "Failed to import module MediaPlayerUIA.psm1."
    }

    #Initialize universal execution framework
    Initialize-UniversalFramework -InvocationPath $InvocationPath -AxeUniversalPath $AxeUniversalPath

    "Init done..." | Log-Info


    #*****************************************************************
    #
    #                Definitions and imports
    #
    #*****************************************************************

    # Recover the INI configuration file contents.  
    try {

        $INIFilePath = (Join-Path -Path $PSScriptRoot -ChildPath (Join-Path -Path resources -ChildPath 'MediaAssessment.ini'))
        Get-INI -INIFilePath $INIFilePath -ErrorAction Stop
    }
    catch {throw ("Error reading INI config file: {0}" -f $_)}

    # Tools and resources
    $arch                  = Get-ProcessorArchitecture
    
    $screenCapturePathBase = "screenshot"

    # logs folder
    $LogsPath = "$AXEResultsPath\logs"
    if (-not (test-path $LogsPath)) {
        New-Item $LogsPath -type directory
    }

    # Analysis profiles

    ## WPAPROFILE_FILE
    $WPAPROFILE_FILE = Get-ConfigValue -Section 'PROFILES' -Key 'WPAPROFILE_FILE' -Default 'resources\MediaProfile.wpaProfile'
    if (-not(Test-ValidFileName -FileName $WPAPROFILE_FILE -Extension '.wpaprofile')) {
        throw ("Invalid WPAPROFILE_FILE name '{0}'. Must be avlid file name with .wpaProfile extension. Please check config file PROFILES section, WPAPROFILE_FILE key." -f $WPAPROFILE_FILE)
    }
    $WPAPROFILE_FILE = Get-RootName -FileName $WPAPROFILE_FILE

    ## Regions file
    $MediaRegionsFile = Get-ConfigValue -Section 'PROFILES' -Key 'MEDIA_REGIONS_FILE' -Default 'resources\Media.regions.xml'
    if (-not(Test-ValidFileName -FileName $MediaRegionsFile -Extension '.xml')) {
        throw ("Invalid MEDIA_REGIONS_FILE name '{0}'. Must be valid file name with .xml extension. Please check config file PROFILES section, MEDIA_REGIONS_FILE key." -f $MediaRegionsFile)
    }
    $MediaRegionsFile = Get-RootName -FileName $MediaRegionsFile

    # AXE termination signal handling loop
    $Global:TerminationLoop = $true

    # results files
    $ETWLogfile = Get-ConfigValue -Section 'OUTPUT' -Key 'ETWLogfile' -Default 'Timing_MediaQuality.etl'
    if (-not(Test-ValidFileName -FileName $ETWLogfile -Extension '.etl')) {
        throw ("Invalid ETWLogfile name '{0}'. Must be a valid file name with .etl extension. Please check config file OUTPUT section, ETWLogfile key." -f $ETWLogfile)
    }

    # Add an extra Analysis_MediaQuality.etl for verbose option
    $ETWLogfileVerbose = Get-ConfigValue -Section 'OUTPUT' -Key 'ETWLogfileVerbose' -Default 'Analysis_MediaQuality.etl'
    if (-not(Test-ValidFileName -FileName $ETWLogfileVerbose -Extension '.etl')) {
        throw ("Invalid ETWLogfileVerbose name '{0}'. Must be a valid file name with .etl extension. Please check config file OUTPUT section, ETWLogfileVerbose key." -f $ETWLogfileVerbose)
    }

    # Precondition to starting the workload is that the test results file name is valid.
    $TestResultsFile = Get-ConfigValue -Section 'OUTPUT' -Key 'TestResultsFile' -Default 'results.txt'
    if (-not(Test-ValidFileName -FileName $TestResultsFile)) {
        throw ("Invalid TestResultsFile '{0}'. Must be a valid file name. Please check config file OUTPUT section, TestResultsFile key." -f $TestResultsFile)
    }

    # Allowance for the wpr tracing to stabilize before starting the workload.
        $traceSeconds = 5
        $traceString = (Get-ConfigValue -Section QUALITY_CONSTANT -Key TRACE_STABILIZATION_SECONDS -Default '5')
        if (-not ([int]::TryParse($traceString, [ref]$traceSeconds))) {
            throw ("Error converting config [QUALITY_CONSTANT][TRACE_STABILIZATION_SECONDS] value '{0}' to [int]." -f $traceString)
        }
    Set-Variable -Name TraceStabilizationSeconds -Value $traceSeconds -Option Constant
    
    # Allowance for the application to stabilize before checking on status.
        $playbackSeconds = 10
        $playbackString = ((Get-ConfigValue -Section QUALITY_CONSTANT -Key 'PLAYBACK_STABILIZATION_SECONDS' -Default '10'))
        if (-not ([int]::TryParse($playbackString, [ref]$playbackSeconds))) {
            throw ("Error converting config [QUALITY_CONSTANT][PLAYBACK_STABILIZATION_SECONDS] value '{0}' to [int]." -f $playbackString)
        }
    Set-Variable -Name PlaybackStabilizationSeconds -Value $playbackSeconds -Option Constant

    # Allowance for the media playback to stop earlier than the user expected.
    $toleranceSeconds  = 10
        $tolerenceString = (Get-ConfigValue -Section QUALITY_CONSTANT -Key PLAYBACK_TIME_TOLERANCE_SECONDS -Default '10')
        if (-not ([int]::TryParse($tolerenceString, [ref]$toleranceSeconds))) {
            throw ("Error converting config [QUALITY_CONSTANT][PLAYBACK_TIME_TOLERANCE_SECONDS] value '{0}' to [int]." -f $tolerenceString)
        }
    Set-Variable -Name PlaybackTimeToleranceSeconds -Value $toleranceSeconds -Option Constant

    # Netflix pre-load stabilization time in seconds before playing the video
    $stabilizationSeconds = 10
        $stabilizationString = (Get-ConfigValue -Section SCENARIO_AUTOMATION -Key NETFLIX_STABILIZATION_SECONDS -Default '10')
        if (-not ([int]::TryParse($stabilizationString, [ref]$stabilizationSeconds))) {
            throw ("Error converting config [SCENARIO_AUTOMATION][NETFLIX_STABILIZATION_SECONDS] value '{0}' to [int]." -f $stabilizationString)
        }
    Set-Variable -Name NetflixStabilizationSeconds -Value $stabilizationSeconds -Option Constant

    $ETWLogPath            = "$AXEResultsPath\$ETWLogfile"
    $ETWLogVerbosePath     = "$AXEResultsPath\$ETWLogfileVerbose"

    #*****************************************************************
    #
    #                Playback source selection
    #
    #*****************************************************************
    
    $Playback = Select-PlaybackSource  -PlaybackSource         $PlaybackSource `
                                       -CustomPlaybackSource   $CustomPlaybackSource `
                                       -Architecture           $arch

    # check system resolution and log it
    if ( $PlaybackSource -eq ([int]([PlaybackSourceEnum]::DEFAULT_LOCAL_AUTOSELECT)) ) {
        "SYSRES=$(Get-ScreenResolution)" | Out-File "$LogsPath\resolution.log" -ErrorAction SilentlyContinue -Force
    }

    # select which WPR profile to use, and which synchronization protocol, if any, to use
    $profile = "VideoQuality"

    if      ($PlaybackSource -eq [PlaybackSourceEnum]::NETFLIX) {

    }
     elseif (($PlaybackSource -eq [PlaybackSourceEnum]::CUSTOM_STREAMING_VIDEO) `
        -or  ($PlaybackSource -eq [PlaybackSourceEnum]::DEFAULT_STREAMING_VIDEO)) {

    }

    # Add $profileVerbose with verbose option for Analysis_MediaQuality.etl
    $profileVerbose = "$($profile)_Analysis"

    # select a light or verbose WPR profile based supplied switch.
    try {
        switch ([TraceOption]$TraceOption)
        {
            ([TraceOption]::LIGHT)   {$profile = "$($profile)_Timing"  ;break}
            ([TraceOption]::VERBOSE) {$profile = "$($profile)_Analysis";break}
        }
    }
    catch {
        throw ("Invalid trace option '{0}'." -f $TraceOption)
    }

    #*****************************************************************
    #
    #                Workload preparation
    #
    #*****************************************************************

    $Global:axeSupport.ReportProgress([Microsoft.Assessments.AxeProgressType]::Percent, 0, "Workload preparation and logs gathering")
    
    "Check UWP Video Player Policy..." | Log-Info
    DisableWow64FsRedirection
    Set-UwpVideoPlayerPolicy
    RevertWow64FsRedirection

    if ($ExtendedLogs) {
        "Capture log files..." | Log-Info
        DisableWow64FsRedirection
        Write-AuxQualityLogs -LogsPath $LogsPath
        RevertWow64FsRedirection
    }

    "Cancel tracing, just in case some sessions are already running..." | Log-Info
    Cancel-ETWTracing

    "Install applicable playback packages..." | Log-Info
    Install-PlaybackPackage $Playback.Workload $arch

    "Launch applicable streaming media to allow time for library sync..." | Log-Info
    Start-StreamingWorkload -PlaybackSource $PlaybackSource

    "Stop playback processes..." | Log-Info
    Stop-Workload

    "Check battery..." | Log-Info
    Test-IsOnBattery -LogsPath $LogsPath -Keyword "BEFORE"

    #*****************************************************************
    #
    #                Tracing and termination timers
    #
    #*****************************************************************

    "Set timer for playback duration ($PlaybackDuration minutes)..." | Log-Info
    # set timer to stop workload after X minutes
    $Timer_FiniteDuration = New-Object Timers.Timer
    $Timer_FiniteDuration.Interval = $PlaybackDuration*60*1000
    $Timer_FiniteDuration.AutoReset = $false

    $Timer_FiniteDuration_Analysis = New-Object Timers.Timer
    $Timer_FiniteDuration_Analysis.Interval = $PlaybackDuration*60*1000 / 2
    $Timer_FiniteDuration_Analysis.AutoReset = $false


    # define trigger action to gracefully exit AXE signal processing loop
    $Action_FiniteDuration = { $Global:TerminationLoop = $false } 

    # register event/action and start timer
     "Register timer object..." | Log-Info
    Register-ObjectEvent -InputObject $Timer_FiniteDuration -EventName elapsed -SourceIdentifier Timer_FiniteDuration -Action $Action_FiniteDuration
    Register-ObjectEvent -InputObject $Timer_FiniteDuration_Analysis -EventName elapsed -SourceIdentifier Timer_FiniteDuration_Analysis -Action $Action_FiniteDuration


    #*****************************************************************
    #
    #                Actual workload!
    #
    #*****************************************************************
    
    $Global:axeSupport.ReportProgress([Microsoft.Assessments.AxeProgressType]::Percent, 10, "Executing workload for timing iteration")
    
    # minimize all windows before starting workload
    if ($Playback.ArgumentList -eq $null)
    {
        $shell = New-Object -ComObject "Shell.Application"
        $shell.MinimizeAll()
    }

    # prepare to play Netflix
    if ($Playback.Workload -eq 'NETFLIX') {
        Start-Executable $Playback.ExePath '-appuid "4DF9E0F8.Netflix_mcm4njqhnhss8!Netflix.App"'
        Start-Sleep -Seconds $NetflixStabilizationSeconds
    }

    if ($PlaybackSource -eq [PlaybackSourceEnum]::DEFAULT_STREAMING_VIDEO)
    {
        ### Buy in Windows Store the default content to be streamed that is free
        "Adding the default video to be streamed to user's library" | Log-Info
        $SearchString = Get-ConfigValue -Section 'STREAMING' -Key 'DEFAULT_SEARCH_VIDEO' -Default 'Remaking the Legend'
        Add-StreamingContent -VideoSearchString $SearchString -Playback $Playback
    }

    #start tracing and stabilize
    "Start tracing with profile: `"$profile`"..." | Log-Info
    Start-ETWTracingFromManifest -Profile $profile -Description "Timing ETL"

    Start-Sleep -Seconds $TraceStabilizationSeconds

    # start playing the video
    Log-StartOperation -Id 100 -Payload "SAT"
    
    Log-DiscreteOperation -Id 200 -Payload $Playback.Workload
    
    if ( @(([WorkloadEnum]'MOVIESTV'),([WorkloadEnum]'MEDIAPLAYER'),([WorkloadEnum]'NETFLIX')) -contains ($Playback.Workload) )
    {
        $playerInfo = Get-PlayerInfo -Workload $Playback.Workload
        Log-DiscreteOperation -Id 201 -Payload $playerInfo
    }
    
    Log-DiscreteOperation -Id 202 -Payload $PlaybackDuration

    if ($Playback.ArgumentList -eq $null)
    {
        if($Playback.Workload -eq 'MEDIAPLAYER')
        {
            $returnValue = Start-MediaPlayer -PlaybackSourceName $Playback.ExePath
            if(-not($returnValue))
            {
                throw ("Error start media player.")
            }
        }
        else
        {
            ("Launch playback source: ExePath={0}..." -f $Playback.ExePath ) | Log-Info
            $OutPut = Start-Process $Playback.ExePath
        }
    }
    else
    {
        ("Launch playback source: ExePath={0} ArgumentList={1}..." -f $Playback.ExePath, $Playback.ArgumentList[0] ) | Log-Info
        $OutPut = Start-Executable $Playback.ExePath $Playback.ArgumentList
    }

    "ScenarioAutomationTool results..." | Log-Info
    $OutPut | Log-Info
    
    # move mouse to avoid "pause" overlay on UI
    MoveMouseToScreenCenter

    # let app stabilize
    Start-Sleep -Seconds $PlaybackStabilizationSeconds
    Get-ScreenCapture $AXEResultsPath $screenCapturePathBase

    # done with setup
    Log-StopOperation -Id 100 -Payload "SAT"

    "Start playback duration timer..." | Log-Info
    $Timer_FiniteDuration.start()


    #*****************************************************************
    #
    #                AXE termination signal handling
    #
    #*****************************************************************

    "Wait for playback end or user triggered cancellation..." | Log-Info

    # check if AXE tried to cancel the assessment as the job end condition is met
    while(($Global:TerminationLoop) -and (-not ($Global:axeSupport.CancelEvent.WaitOne( 5 * 1000 )) )) {}

    "Playback completed..." | Log-Info
    Get-ScreenCapture $AXEResultsPath $screenCapturePathBase

    # stop playback handling process
    "Stop playback processes..." | Log-Info
    Stop-Workload

    "Stop tracing and saving file `"$ETWLogPath`"..." | Log-Info
    Stop-ETWTracingFromManifest -TraceFullName $ETWLogPath

    #double check if the ETL is on disk
    if(-not(test-path $ETWLogPath))
    {
        throw ("Error saving ETW `"$ETWLogPath`" ")
    }


    #*****************************************************************
    #
    #                Actual workload!
    #                (for Analysis_MediaQuality.etl)
    #
    #*****************************************************************

    $Global:axeSupport.ReportProgress([Microsoft.Assessments.AxeProgressType]::Percent, 40, "Executing workload for analysis iteration")

    if ( -not ($Global:axeSupport.Canceled) ) {

        # stop timer and reset AXE termination signal
        $Timer_FiniteDuration.Stop()
        $Global:TerminationLoop = $true

        # prepare to play Netflix
        if ($Playback.Workload -eq 'NETFLIX') {
            Start-Executable $Playback.ExePath '-appuid "4DF9E0F8.Netflix_mcm4njqhnhss8!Netflix.App"'
            Start-Sleep -Seconds $NetflixStabilizationSeconds
        }

        # start tracing and stabilize
        "Start tracing with profile for verbose option: `"$profileVerbose`"..." | Log-Info
        Start-ETWTracingFromManifest -Profile $profileVerbose -Description "Analysis ETL"
        Start-Sleep -Seconds $TraceStabilizationSeconds

        # start playing the video
        if ($Playback.ArgumentList -eq $null)
        {
            if($Playback.Workload -eq 'MEDIAPLAYER')
            {
                $returnValue = Start-MediaPlayer -PlaybackSourceName $Playback.ExePath
                if(-not($returnValue))
                {
                    throw ("Error start media player.")
                }
            }
            else
            {
                ("Launch playback source: ExePath={0}..." -f $Playback.ExePath ) | Log-Info
                $OutPut = Start-Process $Playback.ExePath
            }
        }
        else
        {
            ("Launch playback source: ExePath={0} ArgumentList={1}..." -f $Playback.ExePath, $Playback.ArgumentList[0] ) | Log-Info
            $OutPut = Start-Executable $Playback.ExePath $Playback.ArgumentList
        }

        "ScenarioAutomationTool results..." | Log-Info
        $OutPut | Log-Info
        
        MoveMouseToScreenCenter

        "Start playback duration timer..." | Log-Info
        $Timer_FiniteDuration_Analysis.Start()

        # let app stabilize
        Start-Sleep -Seconds $PlaybackStabilizationSeconds
        Get-ScreenCapture $AXEResultsPath $screenCapturePathBase

    #*****************************************************************
    #
    #                AXE termination signal handling
    #                (for Analysis_MediaQuality.etl)
    #
    #*****************************************************************

        "Wait for playback end or user triggered cancellation..." | Log-Info
        # check if AXE tried to cancel the assessment as the job end condition is met
        while(($Global:TerminationLoop) -and (-not ($Global:axeSupport.CancelEvent.WaitOne( 5 * 1000 )) )) {}

        "Playback completed..." | Log-Info
        Get-ScreenCapture $AXEResultsPath $screenCapturePathBase

        # stop playback handling process
        "Stop playback processes..." | Log-Info
        Stop-Workload

        "Stop tracing and saving file `"$ETWLogVerbosePath`"..." | Log-Info
        Stop-ETWTracingFromManifest -TraceFullName $ETWLogVerbosePath

        #double check if the ETL is on disk
        if(-not(test-path $ETWLogVerbosePath))
        {
            throw ("Error saving ETW `"$ETWLogVerbosePath`" ")
        }
    }

    #*****************************************************************
    #
    #                Results processing
    #
    #*****************************************************************

    $Global:axeSupport.ReportProgress([Microsoft.Assessments.AxeProgressType]::Percent, 90, "Processing results and trace files")

    #
    # MediaDiagnostics XDM
    #

    "Generate MediaDiagnosticsLog.xml ..." | Log-Info
    $MediaDiagnosticsPath = "C:\temp\mediadiagnostics"
    Try {
        Remove-Item -Path $MediaDiagnosticsPath -Recurse -Force -ErrorAction Stop
    }
    Catch {
        "Remove old mediadiagnostics files failed" | Log-Error
    }
    
    if (-not(Test-Path $MediaDiagnosticsPath))
    {
        New-Item -ItemType directory -Path $MediaDiagnosticsPath
    }

    if (Test-Path $MediaDiagnosticsPath)
    {
        Start-Executable autoxa.exe -I "$ETWLogVerbosePath" -p MediaDiagnostics | out-file "$AXEResultsPath\autoxa.log"
        Copy-Item $MediaDiagnosticsPath -Destination $LogsPath -Recurse
    }

    # Copy the WPA Profile file and regions file for use by results
    $jsonInfoFile = $InvocationPath + "\MediaDiagnosticsInfo.json"
    Copy-Item -Path $WPAPROFILE_FILE -Destination $AXEResultsPath -Force -ErrorAction Ignore
    Copy-Item -Path $MediaRegionsFile -Destination $AXEResultsPath -Force -ErrorAction Ignore
    Copy-Item -Path $INIFilePath -Destination $AXEResultsPath -Force -ErrorAction Ignore
    Copy-Item -Path $jsonInfoFile -Destination $AXEResultsPath -Force -ErrorAction Ignore
}
catch
{    
    Handle-UniversalFrameworkException -Exception $_
}
finally 
{
    #*****************************************************************
    #
    #                Workload cleanup
    #
    #*****************************************************************

    Test-IsOnBattery -LogsPath $LogsPath -Keyword "AFTER"

    # cancel all timer events
    #
    Unregister-Event Timer_FiniteDuration -ErrorAction SilentlyContinue
    Unregister-Event Timer_FiniteDuration_Analysis -ErrorAction SilentlyContinue

    # Cancel any ETL tracing that might be going on
    #   
    Cancel-ETWTracing

    # stop playback handling process
    Stop-Workload

    # We should always properly dispose of this guy.
    #
    "Cleanup..." | Log-Info
    Cleanup-UniversalFramework
}

# SIG # Begin signature block
# MIInzgYJKoZIhvcNAQcCoIInvzCCJ7sCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCMhKnxlLLMavip
# y6Q3+Imz9hB9zs31Ar1YopwxmHB9uqCCDYUwggYDMIID66ADAgECAhMzAAADTU6R
# phoosHiPAAAAAANNMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
# bmcgUENBIDIwMTEwHhcNMjMwMzE2MTg0MzI4WhcNMjQwMzE0MTg0MzI4WjB0MQsw
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
# AQDUKPcKGVa6cboGQU03ONbUKyl4WpH6Q2Xo9cP3RhXTOa6C6THltd2RfnjlUQG+
# Mwoy93iGmGKEMF/jyO2XdiwMP427j90C/PMY/d5vY31sx+udtbif7GCJ7jJ1vLzd
# j28zV4r0FGG6yEv+tUNelTIsFmmSb0FUiJtU4r5sfCThvg8dI/F9Hh6xMZoVti+k
# bVla+hlG8bf4s00VTw4uAZhjGTFCYFRytKJ3/mteg2qnwvHDOgV7QSdV5dWdd0+x
# zcuG0qgd3oCCAjH8ZmjmowkHUe4dUmbcZfXsgWlOfc6DG7JS+DeJak1DvabamYqH
# g1AUeZ0+skpkwrKwXTFwBRltAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUId2Img2Sp05U6XI04jli2KohL+8w
# VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
# dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMDUxNzAfBgNVHSMEGDAW
# gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
# MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
# XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
# ACMET8WuzLrDwexuTUZe9v2xrW8WGUPRQVmyJ1b/BzKYBZ5aU4Qvh5LzZe9jOExD
# YUlKb/Y73lqIIfUcEO/6W3b+7t1P9m9M1xPrZv5cfnSCguooPDq4rQe/iCdNDwHT
# 6XYW6yetxTJMOo4tUDbSS0YiZr7Mab2wkjgNFa0jRFheS9daTS1oJ/z5bNlGinxq
# 2v8azSP/GcH/t8eTrHQfcax3WbPELoGHIbryrSUaOCphsnCNUqUN5FbEMlat5MuY
# 94rGMJnq1IEd6S8ngK6C8E9SWpGEO3NDa0NlAViorpGfI0NYIbdynyOB846aWAjN
# fgThIcdzdWFvAl/6ktWXLETn8u/lYQyWGmul3yz+w06puIPD9p4KPiWBkCesKDHv
# XLrT3BbLZ8dKqSOV8DtzLFAfc9qAsNiG8EoathluJBsbyFbpebadKlErFidAX8KE
# usk8htHqiSkNxydamL/tKfx3V/vDAoQE59ysv4r3pE+zdyfMairvkFNNw7cPn1kH
# Gcww9dFSY2QwAxhMzmoM0G+M+YvBnBu5wjfxNrMRilRbxM6Cj9hKFh0YTwba6M7z
# ntHHpX3d+nabjFm/TnMRROOgIXJzYbzKKaO2g1kWeyG2QtvIR147zlrbQD4X10Ab
# rRg9CpwW7xYxywezj+iNAc+QmFzR94dzJkEPUSCJPsTFMIIHejCCBWKgAwIBAgIK
# YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
# OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
# BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
# VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
# 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
# UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
# 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
# dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
# lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
# kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
# A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
# X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
# 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
# sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
# T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
# 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
# bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
# BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
# uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
# c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
# MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
# cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
# YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
# 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
# v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
# pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
# KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
# CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
# mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
# hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
# BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
# oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
# gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
# cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGZ8wghmbAgEBMIGVMH4x
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
# Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAANNTpGmGiiweI8AAAAA
# A00wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
# HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINeu
# rpKO0hGQSbg2ksb9rxyMcq7cZ/Q1+MR0zwtV0eGsMEIGCisGAQQBgjcCAQwxNDAy
# oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20wDQYJKoZIhvcNAQEBBQAEggEAu4S8czntqBLtxsM42r1xHparmzVVlzW6FwWV
# JkKNr53E5XCXmZ1B6pr7yYB2qYiqd9D9dXKmjpL2PKUVfkVpB5m3G3lAhVAo5lH6
# nhgdldT5UZGQe9CD8DFdmDheszF8+BdzIlvugQdxxNb8jDQADAAOJQ+rwc0A5u1Q
# ROBRjpbDghjoI1oaQEdUoeloPmAHpRZDsL6fCduLLh/Ube1g3kAGmmQ/QPe+Xtan
# vRS8MO7I/W0eYAJH5vnOtitNWwbd+JPem6lRYzCQ2XZrRa58WSbXzo5CRI3fJhbe
# xoFSdRHTuiw28cqTT9TiwtEP1MzP8m2Xg2WGxRrqItjG5YDJLKGCFykwghclBgor
# BgEEAYI3AwMBMYIXFTCCFxEGCSqGSIb3DQEHAqCCFwIwghb+AgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIBQAIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCCnHcGjJhDI0GyJ5Musov6XmTJcGN9B3ixq
# ELehjNS1IQIGZN+EFCS4GBMyMDIzMDgyMzAxMjk1MS42MDRaMASAAgH0oIHYpIHV
# MIHSMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJjAkBgNVBAsT
# HVRoYWxlcyBUU1MgRVNOOjg2REYtNEJCQy05MzM1MSUwIwYDVQQDExxNaWNyb3Nv
# ZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIReDCCBycwggUPoAMCAQICEzMAAAG3ISca
# B6IqhkYAAQAAAbcwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAg
# UENBIDIwMTAwHhcNMjIwOTIwMjAyMjE0WhcNMjMxMjE0MjAyMjE0WjCB0jELMAkG
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z
# b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMg
# VFNTIEVTTjo4NkRGLTRCQkMtOTMzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
# U3RhbXAgU2VydmljZTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMf9
# z1dQNBNkTBq3HJclypjQcJIlDAgpvsw4vHJe06n532RKGkcn0V7p65OeA1wOoO+8
# NsopnjPpVZ8+4s/RhdMCMNPQJXoWdkWOp/3puIEs1fzPBgTJrdmzdyUYzrAloICY
# x722gmdpbNf3P0y5Z2gRO48sWIYyYeNJYch+ZfJzXqqvuvq7G8Nm8IMQi8Zayvx+
# 5dSGBM5VYHBxCEjXF9EN6Qw7A60SaXjKjojSpUmpaM4FmVec985PNdSh8hOeP2tL
# 781SBan92DT19tfNHv9H0FAmE2HGRwizHkJ//mAZdS0s6bi/UwPMksAia5bpnIDB
# OoaYdWkV0lVG5rN0+ltRz9zjlaH9uhdGTJ+WiNKOr7mRnlzYQA53ftSSJBqsEpTz
# Cv7c673fdvltx3y48Per6vc6UR5e4kSZsH141IhxhmRR2SmEabuYKOTdO7Q/vlvA
# fQxuEnJ93NL4LYV1IWw8O+xNO6gljrBpCOfOOTQgWJF+M6/IPyuYrcv79Lu7lc67
# S+U9MEu2dog0MuJIoYCMiuVaXS5+FmOJiyfiCZm0VJsJ570y9k/tEQe6aQR9MxDW
# 1p2F3HWebolXj9su7zrrElNlHAEvpFhcgoMniylNTiTZzLwUj7TH83gnugw1FCEV
# Vh5U9lwNMPL1IGuz/3U+RT9wZCBJYIrFJPd6k8UtAgMBAAGjggFJMIIBRTAdBgNV
# HQ4EFgQUs/I5Pgw0JAVhDdYB2yPII8l4tOwwHwYDVR0jBBgwFoAUn6cVXQBeYl2D
# 9OXSZacbUzUZ6XIwXwYDVR0fBFgwVjBUoFKgUIZOaHR0cDovL3d3dy5taWNyb3Nv
# ZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy
# MDIwMTAoMSkuY3JsMGwGCCsGAQUFBwEBBGAwXjBcBggrBgEFBQcwAoZQaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBUaW1l
# LVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUB
# Af8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwDQYJKoZIhvcNAQELBQAD
# ggIBAA2dZMybhVxSXTbJzFgvNiMCV5/Ayn5UuzJU495YDtcefold0ehR9QBGBhHm
# AMt10WYCHz2WQUyM3mQD4IsHfEL1JEwgG9tGq71ucn9dknLBHD30JvbQRhIKcvFS
# nvRCCpVpilM8F/YaWXC9VibSef/PU2GWA+1zs64VFxJqHeuy8KqrQyfF20SCnd8z
# RZl4YYBcjh9G0GjhJHUPAYEx0r8jSWjyi2o2WAHD6CppBtkwnZSf7A68DL4OwwBp
# mFB3+vubjgNwaICS+fkGVvRnP2ZgmlfnaAas8Mx7igJqciqq0Q6An+0rHj1kxisN
# dIiTzFlu5Gw2ehXpLrl59kvsmONVAJHhndpx3n/0r76TH+3WNS9UT9jbxQkE+t2t
# hif6MK5krFMnkBICCR/DVcV1qw9sg6sMEo0wWSXlQYXvcQWA65eVzSkosylhIlIZ
# ZLL3GHZD1LQtAjp2A5F7C3Iw4Nt7C7aDCfpFxom3ZulRnFJollPHb3unj9hA9xvR
# iKnWMAMpS4MZAoiV4O29zWKZdUzygp7gD4WjKK115KCJ0ovEcf92AnwMAXMnNs1o
# 0LCszg+uDmiQZs5eR7jzdKzVfF1z7bfDYNPAJvm5pSQdby3wIOsN/stYjM+EkaPt
# Uzr8OyMwrG+jpFMbsB4cfN6tvIeGtrtklMJFtnF68CcZZ5IAMIIHcTCCBVmgAwIB
# AgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UE
# BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEwOTMwMTgyMjI1
# WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCC
# AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIhC3miy9ckeb0O
# 1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNxWuJ+Slr+uDZn
# hUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFcUTE3oAo4bo3t
# 1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAcnVL+tuhiJdxq
# D89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUoveO0hyTD4MmP
# frVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyziYrLNueKNiOSW
# rAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9fvzZnkXftnIv
# 231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdHGO2n6Jl8P0zb
# r17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7XKHYC4jMYcten
# IPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiER9vcG9H9stQc
# xWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/eKtFtvUeh17a
# j54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3FQEEBQIDAQAB
# MCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAdBgNVHQ4EFgQU
# n6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEEAYI3TIN9AQEw
# QTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9E
# b2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsGAQQB
# gjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/
# MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJ
# oEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01p
# Y1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYB
# BQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9v
# Q2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCdVX38Kq3h
# LB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pkbHzQdTltuw8x
# 5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gngugnue99qb74p
# y27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3lbYoVSfQJL1A
# oL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHCgRlCGVJ1ijbC
# HcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6MhrZlvSP9pEB
# 9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEUBHG/ZPkkvnNt
# yo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvshVGtqRRFHqfG3
# rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+fpO+y/g75LcV
# v7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrpNPgkNWcr4A24
# 5oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHIqzqKOghif9lw
# Y1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAtQwggI9AgEBMIIBAKGB2KSB1TCB
# 0jELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMk
# TWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1U
# aGFsZXMgVFNTIEVTTjo4NkRGLTRCQkMtOTMzNTElMCMGA1UEAxMcTWljcm9zb2Z0
# IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAyGdBGMObODlsGBZm
# SUX2oWgfqcaggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
# Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
# cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN
# BgkqhkiG9w0BAQUFAAIFAOiPSGEwIhgPMjAyMzA4MjIyMjQ0NDlaGA8yMDIzMDgy
# MzIyNDQ0OVowdDA6BgorBgEEAYRZCgQBMSwwKjAKAgUA6I9IYQIBADAHAgEAAgIB
# VDAHAgEAAgIRTjAKAgUA6JCZ4QIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEE
# AYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUAA4GB
# AOFKah5KNNI1ruvcTvG8t3O2vxpfbdJM8flQXJNxtVh9VxItA2ajAvDJsX8jtxdF
# 4LnD2K0aqiDY4WjUopg1wDXYdb03736cfxZPrgy2DGzabL6dpFhaMIztf14yTtbJ
# FAQ05jvsWjxPqM/c8vUEswB7h46ITTYyy5ldsp6hDJ8uMYIEDTCCBAkCAQEwgZMw
# fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
# TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAG3IScaB6IqhkYAAQAA
# AbcwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0BCRAB
# BDAvBgkqhkiG9w0BCQQxIgQgdz2pHohMbBUh0xTA+gNK0Ch1vR2SILiQa1gG6BlF
# nuwwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBsJ3jTsh7aL8hNeiYGL5/8
# IBn8zUfr7/Q7rkM8ic1wQTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
# EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
# ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
# QSAyMDEwAhMzAAABtyEnGgeiKoZGAAEAAAG3MCIEIOGe0dcJ21gqs+T1TlE0nuNb
# wevlEqOVfAxnI/fBYJe6MA0GCSqGSIb3DQEBCwUABIICAFn0JMx8HVdddhLiYl4D
# cIeEqGMnVud6CKnIMM1C0jiL90nzfAUHLTuU5kdASVwbFbM06NC44MICUofa6ClX
# eljIALHIHdNwjLwIrpzUX5FwPl/hggXijCvsWvDVMz8TEv2U+REWumkrpRIc4BG3
# n0qdO0FbKHGJjW92JSYqWlqOWVCkU8gBcy3GVyd0rYyJIEGVfTLratcFFfeFBkl1
# jD0LMjRvUTXOoww8LOnHZ41fMcYPmJpU4K2+iXBQ+7E8lVJPLSS9Wp01h8nKJPeU
# yUFgbpa0T7IDQKxPTBX/P4H6wAIbxwvVvI68NfWfjqP1Uczhv7jXNBHJcfnoZn/H
# mFnkuPRv5HxX/3Kf5cvIbGWV2PufatlmO0JQsi5ubXgDDU3Wc860Qn5363i3/xH4
# AfvDCwD0pwXnVobXwj/vbMAhRhns8rYNpZoBsIbjNMVcewhjPnGChbelkiT91T2K
# 8TiCoMGxlM0xFX+p1f4s2WrSSmH8QHSMUlV6IrqlBo5ViElE94EJ8a5BkOyNpa6V
# PMAcdLnozeYqCqPfi3hvF0PLOBiEQP8/uTk3KG3Xb9Hy+vhPuSsmWX67Q03WCrHq
# 0LBZLRip7185ghNWJlxmhJakGJEEIeNJ7BLl8VAuMkBNioOshscWEEN89ehA5K0T
# Qy0jV1njXlHw1veucPWi5uqR
# SIG # End signature block
