| Server IP : 209.209.40.120 / Your IP : 216.73.217.112 Web Server : Microsoft-IIS/10.0 System : Windows NT NEWWWW 10.0 build 17763 (Windows Server 2019) i586 User : NEWWWW$ ( 0) PHP Version : 8.3.30 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : OFF | Perl : OFF | Python : OFF | Sudo : OFF | Pkexec : OFF Directory : C:/Windows/SecureBoot/ExampleRolloutScripts/ |
Upload File : |
<#
.SYNOPSIS
Shows the current status of the Secure Boot rollout orchestrator.
.DESCRIPTION
Provides real-time visibility into the rollout progress:
- Current wave number and devices targeted
- Devices updated vs pending
- Blocked buckets requiring attention
- Recent activity log
- Dashboard link
Run this anytime to see how the rollout is progressing.
.PARAMETER ReportBasePath
Path to the report/state directory used by the orchestrator
.PARAMETER ShowLog
Display recent log entries (last 50 lines)
.PARAMETER ShowBlocked
Show details of blocked buckets
.PARAMETER ShowWaves
Show wave history with device counts
.PARAMETER Watch
Continuously refresh status every N seconds
.PARAMETER OpenDashboard
Open the latest HTML dashboard in browser
.EXAMPLE
.\Get-SecureBootRolloutStatus.ps1 -ReportBasePath "C:\SecureBootReports"
.EXAMPLE
.\Get-SecureBootRolloutStatus.ps1 -ReportBasePath "C:\SecureBootReports" -Watch 30
.EXAMPLE
.\Get-SecureBootRolloutStatus.ps1 -ReportBasePath "C:\SecureBootReports" -OpenDashboard
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ReportBasePath,
[Parameter(Mandatory = $false)]
[switch]$ShowLog,
[Parameter(Mandatory = $false)]
[switch]$ShowBlocked,
[Parameter(Mandatory = $false)]
[switch]$ShowWaves,
[Parameter(Mandatory = $false)]
[int]$Watch = 0,
[Parameter(Mandatory = $false)]
[switch]$OpenDashboard
)
$ErrorActionPreference = "Stop"
$DownloadUrl = "https://aka.ms/getsecureboot"
$DownloadSubPage = "Deployment and Monitoring Samples"
# Note: This script has no dependencies on other scripts.
# For the complete toolset, download from: $DownloadUrl -> $DownloadSubPage
# ============================================================================
# HELPER FUNCTIONS
# ============================================================================
function ConvertTo-Hashtable {
param([Parameter(ValueFromPipeline = $true)]$InputObject)
process {
if ($null -eq $InputObject) { return @{} }
if ($InputObject -is [System.Collections.IDictionary]) { return $InputObject }
if ($InputObject -is [PSCustomObject]) {
$hash = @{}
foreach ($prop in $InputObject.PSObject.Properties) {
$hash[$prop.Name] = ConvertTo-Hashtable $prop.Value
}
return $hash
}
if ($InputObject -is [System.Collections.IEnumerable] -and $InputObject -isnot [string]) {
return @($InputObject | ForEach-Object { ConvertTo-Hashtable $_ })
}
return $InputObject
}
}
function Show-Status {
$stateDir = Join-Path $ReportBasePath "RolloutState"
$rolloutStatePath = Join-Path $stateDir "RolloutState.json"
$blockedBucketsPath = Join-Path $stateDir "BlockedBuckets.json"
Clear-Host
Write-Host ""
Write-Host ("=" * 80) -ForegroundColor Cyan
Write-Host " SECURE BOOT ROLLOUT STATUS" -ForegroundColor Cyan
Write-Host " $(Get-Date -Format 'yyyy-MM-dd HH:mm:ss')" -ForegroundColor Gray
Write-Host ("=" * 80) -ForegroundColor Cyan
Write-Host ""
# Check if orchestrator task is running
$task = Get-ScheduledTask -TaskName "SecureBoot-Rollout-Orchestrator" -ErrorAction SilentlyContinue
if ($task) {
$taskState = $task.State
$color = if ($taskState -eq "Running") { "Green" } elseif ($taskState -eq "Ready") { "Yellow" } else { "Red" }
Write-Host "Scheduled Task: " -NoNewline
Write-Host $taskState -ForegroundColor $color
} else {
Write-Host "Scheduled Task: " -NoNewline
Write-Host "Not Installed" -ForegroundColor Gray
}
# Load rollout state
if (-not (Test-Path $rolloutStatePath)) {
Write-Host ""
Write-Host "No rollout state found. Orchestrator may not have started yet." -ForegroundColor Yellow
Write-Host "State path: $rolloutStatePath" -ForegroundColor Gray
return
}
$state = Get-Content $rolloutStatePath -Raw | ConvertFrom-Json | ConvertTo-Hashtable
Write-Host ""
Write-Host "ROLLOUT PROGRESS" -ForegroundColor Yellow
Write-Host ("-" * 40)
$status = $state.Status
$statusColor = switch ($status) {
"Completed" { "Green" }
"InProgress" { "Cyan" }
"NotStarted" { "Gray" }
default { "White" }
}
Write-Host "Status: " -NoNewline
Write-Host $status -ForegroundColor $statusColor
Write-Host "Current Wave: $($state.CurrentWave)"
Write-Host "Total Devices: $($state.TotalDevicesTargeted)"
Write-Host "Total Updated: $($state.TotalDevicesUpdated)"
$notUpdated = $state.TotalDevicesTargeted - $state.TotalDevicesUpdated
if ($notUpdated -gt 0) {
Write-Host "Not Updated: " -NoNewline
Write-Host "$notUpdated" -ForegroundColor Yellow
}
if ($state.StartedAt) {
Write-Host "Started: $($state.StartedAt)"
}
if ($state.LastAggregation) {
Write-Host "Last Check: $($state.LastAggregation)"
}
if ($state.CompletedAt) {
Write-Host "Completed: $($state.CompletedAt)" -ForegroundColor Green
}
# Show progress bar
if ($state.TotalDevicesTargeted -gt 0) {
$pct = if ($state.TotalDevicesUpdated -and $state.TotalDevicesTargeted) {
[math]::Round(($state.TotalDevicesUpdated / $state.TotalDevicesTargeted) * 100, 1)
} else { 0 }
Write-Host ""
Write-Host "Progress: " -NoNewline
$barWidth = 40
$filled = [math]::Floor($barWidth * $pct / 100)
$empty = $barWidth - $filled
$pctColor = if ($pct -ge 90) { "Green" } elseif ($pct -ge 50) { "Cyan" } elseif ($pct -ge 25) { "Yellow" } else { "Red" }
Write-Host "[" -NoNewline
if ($filled -gt 0) {
Write-Host ("=" * ($filled - 1) + ">") -ForegroundColor $pctColor -BackgroundColor DarkGreen -NoNewline
}
if ($empty -gt 0) {
Write-Host (" " * $empty) -BackgroundColor DarkGray -NoNewline
}
Write-Host "] " -NoNewline
Write-Host "$pct%" -ForegroundColor $pctColor
Write-Host " $($state.TotalDevicesUpdated) / $($state.TotalDevicesTargeted) devices" -ForegroundColor Gray
}
# Blocked buckets summary
if (Test-Path $blockedBucketsPath) {
$blocked = Get-Content $blockedBucketsPath -Raw | ConvertFrom-Json | ConvertTo-Hashtable
if ($blocked.Count -gt 0) {
Write-Host ""
Write-Host "BLOCKED BUCKETS: " -NoNewline -ForegroundColor Red
Write-Host "$($blocked.Count) buckets need attention" -ForegroundColor Red
if ($ShowBlocked) {
Write-Host ""
foreach ($key in $blocked.Keys) {
$info = $blocked[$key]
Write-Host " ► $key" -ForegroundColor Red
Write-Host " Reason: $($info.Reason)" -ForegroundColor Gray
$devices = if ($info.FailedDevices) { $info.FailedDevices } else { "(unknown)" }
Write-Host " Devices: " -NoNewline -ForegroundColor Gray
Write-Host "$devices" -ForegroundColor Yellow
Write-Host " Since: $($info.BlockedAt)" -ForegroundColor Gray
Write-Host " Unblock: " -NoNewline -ForegroundColor Gray
Write-Host ".\Start-SecureBootRolloutOrchestrator.ps1 -ReportBasePath '$ReportBasePath' -UnblockBucket '$key'" -ForegroundColor Cyan
Write-Host ""
}
Write-Host " To unblock ALL buckets:" -ForegroundColor Gray
Write-Host " .\Start-SecureBootRolloutOrchestrator.ps1 -ReportBasePath '$ReportBasePath' -UnblockAll" -ForegroundColor Cyan
} else {
Write-Host " Run with -ShowBlocked for details" -ForegroundColor Gray
}
}
}
# Wave history
if ($ShowWaves -and $state.WaveHistory -and $state.WaveHistory.Count -gt 0) {
Write-Host ""
Write-Host "WAVE HISTORY" -ForegroundColor Yellow
Write-Host ("-" * 40)
foreach ($wave in $state.WaveHistory) {
Write-Host "Wave $($wave.WaveNumber): " -NoNewline -ForegroundColor Cyan
Write-Host "$($wave.DeviceCount) devices" -NoNewline
Write-Host " - $($wave.StartedAt)" -ForegroundColor Gray
}
}
# Latest dashboard
$latestAggregation = Get-ChildItem -Path $ReportBasePath -Directory -Filter "Aggregation_*" -ErrorAction SilentlyContinue |
Sort-Object Name -Descending |
Select-Object -First 1
if ($latestAggregation) {
# Prefer the stable Latest.html link (always current, never deleted by retention)
$latestDashboard = Join-Path $latestAggregation.FullName "SecureBoot_Dashboard_Latest.html"
$timestampedDashboard = Get-ChildItem -Path $latestAggregation.FullName -Filter "SecureBoot_Dashboard_2*.html" -ErrorAction SilentlyContinue |
Sort-Object LastWriteTime -Descending | Select-Object -First 1
if ((Test-Path $latestDashboard) -or $timestampedDashboard) {
Write-Host ""
Write-Host "DASHBOARD" -ForegroundColor Yellow
if (Test-Path $latestDashboard) {
Write-Host " Latest: $latestDashboard" -ForegroundColor White
}
if ($timestampedDashboard) {
Write-Host " Timestamped: $($timestampedDashboard.FullName)" -ForegroundColor Gray
}
if ($OpenDashboard) {
$openPath = if (Test-Path $latestDashboard) { $latestDashboard } else { $timestampedDashboard.FullName }
Start-Process $openPath
}
}
}
# Recent log
if ($ShowLog) {
$logFile = Get-ChildItem -Path $stateDir -Filter "Orchestrator_*.log" -ErrorAction SilentlyContinue |
Sort-Object Name -Descending |
Select-Object -First 1
if ($logFile) {
Write-Host ""
Write-Host "RECENT LOG" -ForegroundColor Yellow
Write-Host ("-" * 40)
Get-Content $logFile.FullName -Tail 20 | ForEach-Object {
if ($_ -match '\[ERROR\]') {
Write-Host $_ -ForegroundColor Red
} elseif ($_ -match '\[WARN\]') {
Write-Host $_ -ForegroundColor Yellow
} elseif ($_ -match '\[OK\]') {
Write-Host $_ -ForegroundColor Green
} elseif ($_ -match '\[WAVE\]') {
Write-Host $_ -ForegroundColor Cyan
} else {
Write-Host $_ -ForegroundColor Gray
}
}
}
}
Write-Host ""
Write-Host ("-" * 80) -ForegroundColor DarkGray
if (-not $ShowLog -or -not $ShowWaves -or -not $ShowBlocked) {
Write-Host "Options: -ShowLog | -ShowWaves | -ShowBlocked | -OpenDashboard | -Watch 30" -ForegroundColor DarkGray
}
}
# ============================================================================
# MAIN
# ============================================================================
if (-not (Test-Path $ReportBasePath)) {
Write-Host "Report path not found: $ReportBasePath" -ForegroundColor Red
exit 1
}
if ($Watch -gt 0) {
Write-Host "Watching status every $Watch seconds. Press Ctrl+C to stop." -ForegroundColor Cyan
while ($true) {
Show-Status
Start-Sleep -Seconds $Watch
}
} else {
Show-Status
}
# SIG # Begin signature block
# MIIpxQYJKoZIhvcNAQcCoIIptjCCKbICAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDbsPrPR3i7syzC
# oFo3mYB0caMelipWAp1XVHjLH1ZDraCCDeUwgga9MIIEpaADAgECAhMzAAAAHEif
# gd+hsLd3AAAAAAAcMA0GCSqGSIb3DQEBDAUAMIGIMQswCQYDVQQGEwJVUzETMBEG
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
# cm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0
# aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yNDA4MDgyMTM2MjNaFw0zNTA2MjMy
# MjA0MDFaMF8xCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xMDAuBgNVBAMTJ01pY3Jvc29mdCBXaW5kb3dzIENvZGUgU2lnbmluZyBQ
# Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJp9a30nwXYq
# Lq7j1TT/zCtt7vxU+CCj+7BkifS/B2gXKGU7OV9SXRJGP1yFs5p6jpsYi4cYzF56
# AV0AEmmEjV8wT2lvPU5BhN3wV30HqYPIYEj5P3WXf0kXD9fvjUf1GAtXEriJ8w7A
# LNaVEm9Rs4ePA0ZsYHaCbU5kBUJQDXv76hafOcQgdFCA3I3zYtfzX2vOwx87uDOa
# CuyKORZih9c3zTf+TLC5QYLyhVMBnDXEHDOrvaw92DSyIqpdgRWpufzqDFy1egVj
# koXZhb+9pZ9heUzNXTXhOoXzexh6YzAL4flBWm+Bc1hQyESenEvBJznV+25u3h77
# jjgMUY44+WXQ4u9qddDe/U5SeAaKRvvibmi4z7QRpLvZsla0CPiOUGz00Do5sfkC
# 0EwlsSzfM3+8A9rsyFVOgWDVPzt98OJP2EoaEOq8GE9GCoN2i7/4C2FCwff1BSCT
# JWZO1Wcr2MteJE6UxGV+ihA8nN51YPKD2dYGoewrXvRzC/1HoUeSvlZf0mf9GHEt
# vvkbJVRRo6PBf0md5t87Vb1mM/fIp1eypyaxmXkgpcBwuylsOq2kSVOJ5wBPoaEs
# sJkeMcKnEuuu++UKdDHlS0DtsYjN0QnOucvTdSsdvhzKOSjJF3XVqr9f2C945LXT
# 5rxKIHUIEDBcNYU6BKDDH6rfpKOOCSilAgMBAAGjggFGMIIBQjAOBgNVHQ8BAf8E
# BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFB6C3w7XjLPXAjSDDtqr
# rWW5r7jsMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB
# Af8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBL
# oEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv
# TWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggr
# BgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNS
# b29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcNAQEMBQADggIBAENf+N8/
# u+mUjDtc9btoA52RBc0XVDSBMQBMqxu56hXHBwuctUWs1XBqDDMIFCHu9c6Y/UF+
# TN8EIgjnujApKYmHP4f4EM3ARSmlzrpF5ozOJx0BA5FUv1jmpdf/2ZbqpvCxlxv/
# G1R4KjrSmmqPHzs6igw3b7RTbj7BxIS8fOIkwYWQhB2fLjlg+3HSrDGPFIhpIJWV
# amMIR7a72OGonjdf45rspwqIHuynZU4avy9ruB/Rhhbwm+fMb8BMecIaTmkohx/E
# ZZ5GNWcN6oTYW3G2BM3B3YznWkl9t4shP60fMue+2ksdHGWSE8EVTdSmGUdj0jrU
# c46lGVFJISF3/MxcxnlNeP1Khyr+ZzT4Ets/I7mufpaLnLalzMR2zIuhGOAWWswe
# sbjtFzkVUFgDR2SW903I0XKlbPEA6q8epHGJ9roxh85nsEKcBNUw4Scp68KCqSpF
# BaKiyV1skd+l8U50WNePMb9Bzz0OfASal8v5sQG+DW01kN+I+RKUIbM5I50wJjiH
# ymQFNDsbobFx9I95mCEEPU7fUZ3VT/HOUVbkmX7ltIC/eQAu5GO8fu+ceETMybvb
# oxUM4dYNC+PzooUxfmC0DuKRwB21bX9+acuIBkxIm4Ed3O19w1VLoA7UNOUuJ7z6
# NQ2W/+q7cnfOPl2QVL4qlgCblUT2vmQpllV3MIIHIDCCBQigAwIBAgITMwAAASJs
# BjOj0VK23QAAAAABIjANBgkqhkiG9w0BAQwFADBfMQswCQYDVQQGEwJVUzEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTAwLgYDVQQDEydNaWNyb3NvZnQg
# V2luZG93cyBDb2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwMzA1MTk1ODI0WhcN
# MjcwMzAzMTk1ODI0WjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMR4wHAYDVQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggIiMA0GCSqGSIb3
# DQEBAQUAA4ICDwAwggIKAoICAQCeFlu3IJtMm0DcCUF5EKHUKh/L06a1JyvxX2aV
# aapyABxwDINwxmSS0MR5ObqvX4TKhYX2Ic7+HNhNjxZg7UJUTMamRDcmnS3QHYOe
# oqsgveL1mGQsvBqWROEi2tBe8PrwJrYd4tefld81kaQ1cnbzuUuou3fuAHNudJnA
# CW5SqPmZHF565Ij7jwMeJPxU5JHsPAs/Y11aWPxI85kVEUecjfOMpIx5oTXnNi9U
# nw7BSv/SSrXfkyAyFyqu+PN9ymIWLmOAPaAnJ+QxGRZ9D7jJy4fZK0RxO1GlPTaj
# h9xgbz7SDSeC70z8Ro8mgO3ImrCDv4KdJztT5dnCieVXLMSxCqWikfKznmoCaAqG
# 5skdylL5CFi8TQVKASb2QR0MjS1fqX0FpOkgibu7+m2EPzjp36SkgZ1TXVfAO3j5
# BjRZT/VXaWS0Zk+eNn8/SQf8U/LRRpnuJXhkOWVBNIGq5ew6EsKIQm5Dter5NTSK
# J8gUlqiwDKZ1HuaTEWn1PmgN0YYF9av8fDTeVbEPQe04yv47o8lYpldFM0B9kWOc
# kIc0U+hXNC/+pnDVUh2fjN+JtMaLKTTOciXM2F0tt3CbdKO+cCmlCzSuhN9aeQ2m
# GEnQY3v3V3W15uaUpYELTYOTeTwDVkYJXCZK/zNRXxU38rQ+LwxLOeRVNvEYh2Js
# 0nuX0QIDAQABo4IBvjCCAbowDgYDVR0PAQH/BAQDAgeAMB8GA1UdJQQYMBYGCisG
# AQQBgjc9BgEGCCsGAQUFBwMDMAwGA1UdEwEB/wQCMAAwHQYDVR0OBBYEFJ8ytbdA
# tti7ifaKbKxtPwbvlJiSMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQLEyRNaWNyb3Nv
# ZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUTDTIzMDg2NSs1
# MDY5NjUwHwYDVR0jBBgwFoAUHoLfDteMs9cCNIMO2qutZbmvuOwwagYDVR0fBGMw
# YTBfoF2gW4ZZaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWlj
# cm9zb2Z0JTIwV2luZG93cyUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIwMjAyNC5j
# cmwwdwYIKwYBBQUHAQEEazBpMGcGCCsGAQUFBzAChltodHRwOi8vd3d3Lm1pY3Jv
# c29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFdpbmRvd3MlMjBDb2Rl
# JTIwU2lnbmluZyUyMFBDQSUyMDIwMjQuY3J0MA0GCSqGSIb3DQEBDAUAA4ICAQCY
# WFIyjTfk5OvOrxA8oAS2jbS6/P0DDLLiqZsyy6dY9vfid+P2uawuygeoVwkvGqMO
# 0UDWuupsy8VQ/5Fw+GXfx7n9AfvoVg30rHm883siWQ9/GaayCh219lbearlRziyq
# TZoz7ShvA23fRoKs3I9LlXWWOH1d5CeFtuyX0D4oRBU1pQS+ijDSv848ZiLwqjig
# Q7XBaYiPNVQI8xMkkVeIc6B575rVsxqLF5rQFMuXZhwU+BXEbVa4tmVAzY9geP3X
# dOP+L/OwWQV83Z6poT/RW6QMqkNpgf7Pc3oSGKGTpr32AwHIutwmWaEaj8asyDUj
# FABzJBG6AH8pugTf440r61uNlw6mDXppfOZVyuHuH93uNzaINvuW/Y/yEYSDdTvy
# 6Sn5GwWrHKNA23UR18Abu7B2uOeDhiTq69oePmKEAPjjHMTQBrZUX+VBwv+v7MJB
# r8A0s4zg/AY+A/LmN5veQpcAjTj9H+2mKEQobRTUHKBDW1T1fXYQb1JdWQXDK9In
# 6Lx8EaWOExYktAceGfzxC9NoCjxBUb8ba6QOQXNaqrzQlDzGwqxLsiClN+H6h58p
# BfFF2OoSaLlgpih0WRfp7sTGddsp6ajbAAX7VSI/W32o2G7KaDIc1jiok64BnBRo
# ewtKnNm3Ny0ulmJ6IgIZA5DOAxT9tPtEtNhwHmhshzGCGzYwghsyAgEBMHYwXzEL
# MAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEwMC4G
# A1UEAxMnTWljcm9zb2Z0IFdpbmRvd3MgQ29kZSBTaWduaW5nIFBDQSAyMDI0AhMz
# AAABImwGM6PRUrbdAAAAAAEiMA0GCWCGSAFlAwQCAQUAoIH6MBkGCSqGSIb3DQEJ
# AzEMBgorBgEEAYI3AgEEMC8GCSqGSIb3DQEJBDEiBCAQh5xeZe4ZmThy/cbKD9h/
# yYraaYMAkwk+etSXkOjB8zBQBgorBgEEAYI3CgMcMUIMQDc2MzcyNkQyRDNCMjY2
# QUU0NjNEMEY5MDczRURFRTczNTQxNzUxMTVGNkNCNkIwOTJEQTU3MzRBRTNBOTk2
# QzIwWgYKKwYBBAGCNwIBDDFMMEqgJIAiAE0AaQBjAHIAbwBzAG8AZgB0ACAAVwBp
# AG4AZABvAHcAc6EigCBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vd2luZG93czAN
# BgkqhkiG9w0BAQEFAASCAgBFdA/5Tc/sTzf44oItoWQdmLE7+z8ek1EMkk0yeldT
# Eg2F17mqrHeotiXonxzqWnjFKiPRGxruNUAvb++G7QZEsN3r1CGl/Nq1/Rgu40jX
# t5Vd42mzvFsZts9JfpXacERHF4ZgcMuirZaz09lsWwbgtc/Jcg0CFS40O0H1UhNi
# /704lF0kAQ290QP/1K6YOkLoy5y/jjBv8wYa03ec0pBHl+BpBKeY+Zg/LtGDLUE/
# gHnjyuhUp6xvd85sgMDnagCA9KUKLdlCgCtHfCsVFo+WMaRotBj8vh3+VdZS9SNB
# ANeN5IX1ARkhluTb1yP9xf77uE7B0vLcdq/8DvP9d2jofRMiJ7p/1hco0T1H4dxV
# sl+eS83doTCiXTHOq69ZUhwEHjnwhtfWlIwE+EwUv3fWs55QJupsuC9G/wMjM9Wx
# Fcd7gnPMe/JxCsTLCXY60qruf19oQsszzov+TOP9bedAPz9InlwzaMuEHCYkUMK2
# lMXozCiPq5kkWhSvnw9kfMTii8bUTNAbGofqy5vfdTlUcsWQiitBw3esbxVP46an
# hlce0gxiEGB2k00skSh1gIjNZJi4bYzSlJGN5b+EwmYCol2pB5etU7lnIj6CNFoI
# wbZYVDRgW1uad5KvZy6H9orokMoHomvMrsMZ0zIcAlp7gf4Kfiw+UsP+O9E5fZgx
# OKGCF5QwgheQBgorBgEEAYI3AwMBMYIXgDCCF3wGCSqGSIb3DQEHAqCCF20wghdp
# AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFSBgsqhkiG9w0BCRABBKCCAUEEggE9MIIB
# OQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCCSsW5eUxPiBbe8EktB
# ozwYDmQVym76KbtdZy0r9GENAAIGahdR35ccGBMyMDI2MDYwNjA4MzU1NS4wNzla
# MASAAgH0oIHRpIHOMIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYD
# VQQLEx5uU2hpZWxkIFRTUyBFU046OTYwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1p
# Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WgghHqMIIHIDCCBQigAwIBAgITMwAA
# AiY1tD5nQ5P2HwABAAACJjANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzET
# MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1T
# dGFtcCBQQ0EgMjAxMDAeFw0yNjAyMTkxOTQwMDJaFw0yNzA1MTcxOTQwMDJaMIHL
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxN
# aWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRT
# UyBFU046OTYwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0
# YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC//w+Z
# ZIL5RFFpVI8D3ZyuNu8IzcAEOD30OLYjh337rXjcrIlOSzpJc4ZeUxEyli6x6F6z
# m4NR8dbPb9diDp/hOUzHWGxiA1Z3RXKBb/4F/ojyvN43SEGWqSfVc3I3BlsYT35e
# cVAJ9kVf90YOv29tFjJBBZkYvrT/DwwyRLscOyP4p+9/lyJjD+ULs3YXBhVrfZ+M
# bQB+BYKLqRvBKbj/wR9akNrMxQINoGaD5jZO/N/nSsmG2P1zv/cv4gSoMBnWeQIB
# kjd2I5w1DeXupp2vSiNmR5sA2ZkBK3yiQWaJvRxODlkfiyHk9Mkk/TrYTjmjPCbh
# e+uqhHNRy8UlbOvWsCq0tRtUykHv39DgqAfJNrE8OSt835rBzDprrcAhwmgfhoVi
# 4AKeqwikY0nUa48K0Qy80XT4fiEA3ExEZNaRFo9Nq/GwbfgqKqGmc9xhKuRFcjtu
# a4KHZvnAvpWgEFSOCkovXs/BcLnkEHM9xZ8iUag5CyhNqXYYE/z0pcXdYaNIkQ68
# EWmuvLm7g9oofV2vOm5GVNoghnkWG6nGPo/JwEgmA9oSS0EfvFRMWPA/gpSvF3sh
# ArKHnaEpVSSi3DNbyiuYiEs9Ko0IkZc8xKFeQRaqGRxrB+2r/7B3X81Tps99KhFw
# g+wD87od22F2MUg1x7twt3gaVnFk0IZIwUPCGwIDAQABo4IBSTCCAUUwHQYDVR0O
# BBYEFF3hn9fYJN2Y/Z9LVbBPIxAzXHsQMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl
# 0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0
# LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAy
# MDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93
# d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1T
# dGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/
# BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4IC
# AQA2Ux0tr9sYCjsq0FRyiVpx15OurNXv6Qk7iX+ArVPlz3w4tqjcTNm1dt3tTua2
# wJMpJhPH8n7UXhmT98d5Du44Ll4adnse4SQfVg3QL6aRkXHnJUn8y9iftB/Py22n
# 9xnwPFfj3QlDOSgLuHleu97U0iH2ZaluYabWXJihdiYpK8cPHFlqZOAiot0+GD8d
# P+RMuvpxt/F2LmYelpoZwriiFOUmlxEUV7xJHyZZlDquskeyuq01DTv91N4qM8cf
# PPhl/2pc4HeMf/nd2HouifJbDQFNd4WPhLzn0Sy3u1Zh3+S3tjQdqN+dyw60RaV+
# RXCoOLgFZ3MAg/GoDl+fvb5hy/1a71ctX8wEad1Pf6def2pqfl3wFc++hkF8DXXT
# ZofJN4YVaN3InwbAGQDDkNK4lqecCixxmSKwidPynGeE5OtvNoK1pkLsm/i8F1Rj
# GczZ/kSF2VDkqG866iQ+jVbGOQ6Du3eyyFcFKZoDJ4B5mEAS9aT2SKqllLeybObo
# H6r67siR5B/2Hnu7+KYuYZy0BEadtA6ngG4cnSR9JsrkhhsKmb11ujqwgJyNx92M
# soGGwNgN1aI0QID8CsjCFwpfmMzlA44xHKYv3hmjxeqBS4uU5rQeiAnVgpJeaVGK
# m/lzPDtnppGV+7XhRp5b1ZxT/Z7Xxc+I7H7/jCtQDZoaZTCCB3EwggVZoAMCAQIC
# EzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYT
# AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS
# b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoX
# DTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIi
# MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC
# 0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VG
# Iwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP
# 2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/P
# XfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361
# VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwB
# Sru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9
# X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269e
# wvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDw
# wvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr
# 9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+e
# FnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAj
# BgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+n
# FV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEw
# PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j
# cy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3
# FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAf
# BgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBH
# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNS
# b29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl
# ckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4Swf
# ZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTC
# j/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu
# 2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/
# GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3D
# YXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbO
# xnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqO
# Cb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I
# 6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0
# zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaM
# mdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNT
# TY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNNMIICNQIBATCB+aGB0aSBzjCByzEL
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWlj
# cm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1Mg
# RVNOOjk2MDAtMDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
# cCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoDFQCi/fMxFtkqr7XMXdsRyWU0lSKHZ6CB
# gzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD
# VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAk
# BgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEB
# CwUAAgUA7c5VNjAiGA8yMDI2MDYwNjA4MTM0MloYDzIwMjYwNjA3MDgxMzQyWjB0
# MDoGCisGAQQBhFkKBAExLDAqMAoCBQDtzlU2AgEAMAcCAQACAhHJMAcCAQACAhL6
# MAoCBQDtz6a2AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAI
# AgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEBAFn40C/PM6uT
# VsdtrH0Mjpy1LnvoWCoHC50dPP5JWir9NwxQugCpCmUUpcb6ksbfRMwWFiOw/DdX
# 5feBoiL5ziPQgBoM551wj+g1+UFr0R4iHup/VPg0iwu45lZZXINlggWZhGj4YTBI
# /J1CHOUA0+FLHKCGev73Mw18KtctpxaZXMrdd+AANRP0QweCDb77JbhgxoXjMH+n
# FZhA9i+ziW2GSb0mAIAYRiBCmBAF9YuvlUr61l8S2fb4omVtQ+TSh0qybav8+vZx
# zkNDWG66pOhJkksrfTHjJmAqFSFsvKDaZf7uw0Kc2f1+0+pJjW/jzuBonaFhcEaD
# E6cKcCTlzwYxggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0Eg
# MjAxMAITMwAAAiY1tD5nQ5P2HwABAAACJjANBglghkgBZQMEAgEFAKCCAUowGgYJ
# KoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCBiAfqFlQEH
# wcJkqc5Sr8kTJegJtiFIr1f8u9oBTOIVTTCB+gYLKoZIhvcNAQkQAi8xgeowgecw
# geQwgb0EIMwyXGFnTNsZRBrs6GN/BbV0okaNP3VBYqLFjUsFnbgqMIGYMIGApH4w
# fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
# ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd
# TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAImNbQ+Z0OT9h8AAQAA
# AiYwIgQgLGP50t6qZ+61dN1PHFbHd03GkC3NuZCQ9ZJ4vtyxUCgwDQYJKoZIhvcN
# AQELBQAEggIArIhH93SNFkwPmXuYnAE1In02ruwWGa/vOIB/fiOx2lExKA/q/4gL
# hK0/xs0HJd6aDR9HCmowe3ZDdRjENvIikVx7RA0KNDABzAGg+yIQRMNW2lK4MX/1
# DyTRo4cNumtDQ027wddbjBIvaSG6Aa/v1qjnNNsC9eA0LmoxoYRB+WmX5rseJie2
# nkA8sIzT0RGeAwVm78m3UCbCaRHIHUv+GBYawTqnq8hT2KY3wI6ynk6p9Idy4tkW
# /7qbN8rVg52mDEaevlFSWIbJQvLEWp2bnT23OpYlXKzaU09FyhBqrFSD+l9VFXMj
# DLt3ArqBCuYJOCCArBpcxtz1NrhQA2175b1kkk8GNkO76wClBOyViXcdGj7u3OOG
# j1Crr1a0inQA43CrJw3hyp0G4UWRIQRCXgjAzPGqf3jb+QY1QN4FbdYRAkhFZxw2
# 3vS/eto75y3rxBwYbbNsx2hYhKZFetC9G+m9zsHaWBMH3iSaP2OfcgBjzOmfQdio
# 4fbw9cbHGgHRH/olWt9qoESeCn01JU8x9NpFDKIBCqF4YDPvdXCa3hFUoehfT52h
# yasl5hC17uya/3pA7xY8uNQdk1RnDcuy+CrzRVG1ad4h5wQ3E9AOu8q4o9WwiPKN
# 59W8k0ufItZlquNo4waqK1Iy1FP+vCicp92qwsfTrIDZhXgKRhBpdqY=
# SIG # End signature block