TheDashboard.psm1
function Format-AddSpaceToSentence { <# .SYNOPSIS Short description .DESCRIPTION Long description .PARAMETER Text Parameter description .EXAMPLE $test = @( 'OnceUponATime', 'OnceUponATime1', 'Money@Risk', 'OnceUponATime123', 'AHappyMan2014' 'OnceUponATime_123' ) Format-AddSpaceToSentence -Text $Test $Test | Format-AddSpaceToSentence -ToLowerCase .NOTES General notes #> [CmdletBinding()] param( [Parameter(Mandatory = $false, ValueFromPipeline = $true, Position = 0)][string[]] $Text, [switch] $ToLowerCase ) Begin { } Process { $Value = foreach ($T in $Text) { ($T -creplace '([A-Z\W_]|\d+)(?<![a-z])', ' $&').trim() } if ($ToLowerCase) { $Value.ToLower() } else { $Value } } End { } } function Get-GitHubLatestRelease { <# .SYNOPSIS Gets one or more releases from GitHub repository .DESCRIPTION Gets one or more releases from GitHub repository .PARAMETER Url Url to github repository .EXAMPLE Get-GitHubLatestRelease -Url "https://api.github.com/repos/evotecit/Testimo/releases" | Format-Table .NOTES General notes #> [CmdLetBinding()] param( [parameter(Mandatory)][alias('ReleasesUrl')][uri] $Url ) $ProgressPreference = 'SilentlyContinue' $Responds = Test-Connection -ComputerName $URl.Host -Quiet -Count 1 if ($Responds) { Try { [Array] $JsonOutput = (Invoke-WebRequest -Uri $Url -ErrorAction Stop | ConvertFrom-Json) foreach ($JsonContent in $JsonOutput) { [PSCustomObject] @{ PublishDate = [DateTime] $JsonContent.published_at CreatedDate = [DateTime] $JsonContent.created_at PreRelease = [bool] $JsonContent.prerelease Version = [version] ($JsonContent.name -replace 'v', '') Tag = $JsonContent.tag_name Branch = $JsonContent.target_commitish Errors = '' } } } catch { [PSCustomObject] @{ PublishDate = $null CreatedDate = $null PreRelease = $null Version = $null Tag = $null Branch = $null Errors = $_.Exception.Message } } } else { [PSCustomObject] @{ PublishDate = $null CreatedDate = $null PreRelease = $null Version = $null Tag = $null Branch = $null Errors = "No connection (ping) to $($Url.Host)" } } $ProgressPreference = 'Continue' } function Remove-EmptyValue { [alias('Remove-EmptyValues')] [CmdletBinding()] param( [alias('Splat', 'IDictionary')][Parameter(Mandatory)][System.Collections.IDictionary] $Hashtable, [string[]] $ExcludeParameter, [switch] $Recursive, [int] $Rerun, [switch] $DoNotRemoveNull, [switch] $DoNotRemoveEmpty, [switch] $DoNotRemoveEmptyArray, [switch] $DoNotRemoveEmptyDictionary ) foreach ($Key in [string[]] $Hashtable.Keys) { if ($Key -notin $ExcludeParameter) { if ($Recursive) { if ($Hashtable[$Key] -is [System.Collections.IDictionary]) { if ($Hashtable[$Key].Count -eq 0) { if (-not $DoNotRemoveEmptyDictionary) { $Hashtable.Remove($Key) } } else { Remove-EmptyValue -Hashtable $Hashtable[$Key] -Recursive:$Recursive } } else { if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { $Hashtable.Remove($Key) } } } else { if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') { $Hashtable.Remove($Key) } elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) { $Hashtable.Remove($Key) } } } } if ($Rerun) { for ($i = 0; $i -lt $Rerun; $i++) { Remove-EmptyValue -Hashtable $Hashtable -Recursive:$Recursive } } } function Start-TimeLog { [CmdletBinding()] param() [System.Diagnostics.Stopwatch]::StartNew() } function Stop-TimeLog { [CmdletBinding()] param ( [Parameter(ValueFromPipeline = $true)][System.Diagnostics.Stopwatch] $Time, [ValidateSet('OneLiner', 'Array')][string] $Option = 'OneLiner', [switch] $Continue ) Begin { } Process { if ($Option -eq 'Array') { $TimeToExecute = "$($Time.Elapsed.Days) days", "$($Time.Elapsed.Hours) hours", "$($Time.Elapsed.Minutes) minutes", "$($Time.Elapsed.Seconds) seconds", "$($Time.Elapsed.Milliseconds) milliseconds" } else { $TimeToExecute = "$($Time.Elapsed.Days) days, $($Time.Elapsed.Hours) hours, $($Time.Elapsed.Minutes) minutes, $($Time.Elapsed.Seconds) seconds, $($Time.Elapsed.Milliseconds) milliseconds" } } End { if (-not $Continue) { $Time.Stop() } return $TimeToExecute } } function Write-Color { <# .SYNOPSIS Write-Color is a wrapper around Write-Host delivering a lot of additional features for easier color options. .DESCRIPTION Write-Color is a wrapper around Write-Host delivering a lot of additional features for easier color options. It provides: - Easy manipulation of colors, - Logging output to file (log) - Nice formatting options out of the box. - Ability to use aliases for parameters .PARAMETER Text Text to display on screen and write to log file if specified. Accepts an array of strings. .PARAMETER Color Color of the text. Accepts an array of colors. If more than one color is specified it will loop through colors for each string. If there are more strings than colors it will start from the beginning. Available colors are: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White .PARAMETER BackGroundColor Color of the background. Accepts an array of colors. If more than one color is specified it will loop through colors for each string. If there are more strings than colors it will start from the beginning. Available colors are: Black, DarkBlue, DarkGreen, DarkCyan, DarkRed, DarkMagenta, DarkYellow, Gray, DarkGray, Blue, Green, Cyan, Red, Magenta, Yellow, White .PARAMETER StartTab Number of tabs to add before text. Default is 0. .PARAMETER LinesBefore Number of empty lines before text. Default is 0. .PARAMETER LinesAfter Number of empty lines after text. Default is 0. .PARAMETER StartSpaces Number of spaces to add before text. Default is 0. .PARAMETER LogFile Path to log file. If not specified no log file will be created. .PARAMETER DateTimeFormat Custom date and time format string. Default is yyyy-MM-dd HH:mm:ss .PARAMETER LogTime If set to $true it will add time to log file. Default is $true. .PARAMETER LogRetry Number of retries to write to log file, in case it can't write to it for some reason, before skipping. Default is 2. .PARAMETER Encoding Encoding of the log file. Default is Unicode. .PARAMETER ShowTime Switch to add time to console output. Default is not set. .PARAMETER NoNewLine Switch to not add new line at the end of the output. Default is not set. .PARAMETER NoConsoleOutput Switch to not output to console. Default all output goes to console. .EXAMPLE Write-Color -Text "Red ", "Green ", "Yellow " -Color Red,Green,Yellow .EXAMPLE Write-Color -Text "This is text in Green ", "followed by red ", "and then we have Magenta... ", "isn't it fun? ", "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan .EXAMPLE Write-Color -Text "This is text in Green ", "followed by red ", "and then we have Magenta... ", "isn't it fun? ", "Here goes DarkCyan" -Color Green,Red,Magenta,White,DarkCyan -StartTab 3 -LinesBefore 1 -LinesAfter 1 .EXAMPLE Write-Color "1. ", "Option 1" -Color Yellow, Green Write-Color "2. ", "Option 2" -Color Yellow, Green Write-Color "3. ", "Option 3" -Color Yellow, Green Write-Color "4. ", "Option 4" -Color Yellow, Green Write-Color "9. ", "Press 9 to exit" -Color Yellow, Gray -LinesBefore 1 .EXAMPLE Write-Color -LinesBefore 2 -Text "This little ","message is ", "written to log ", "file as well." ` -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" -TimeFormat "yyyy-MM-dd HH:mm:ss" Write-Color -Text "This can get ","handy if ", "want to display things, and log actions to file ", "at the same time." ` -Color Yellow, White, Green, Red, Red -LogFile "C:\testing.txt" .EXAMPLE Write-Color -T "My text", " is ", "all colorful" -C Yellow, Red, Green -B Green, Green, Yellow Write-Color -t "my text" -c yellow -b green Write-Color -text "my text" -c red .EXAMPLE Write-Color -Text "Testuję czy się ładnie zapisze, czy będą problemy" -Encoding unicode -LogFile 'C:\temp\testinggg.txt' -Color Red -NoConsoleOutput .NOTES Understanding Custom date and time format strings: https://learn.microsoft.com/en-us/dotnet/standard/base-types/custom-date-and-time-format-strings Project support: https://github.com/EvotecIT/PSWriteColor Original idea: Josh (https://stackoverflow.com/users/81769/josh) #> [alias('Write-Colour')] [CmdletBinding()] param ( [alias ('T')] [String[]]$Text, [alias ('C', 'ForegroundColor', 'FGC')] [ConsoleColor[]]$Color = [ConsoleColor]::White, [alias ('B', 'BGC')] [ConsoleColor[]]$BackGroundColor = $null, [alias ('Indent')][int] $StartTab = 0, [int] $LinesBefore = 0, [int] $LinesAfter = 0, [int] $StartSpaces = 0, [alias ('L')] [string] $LogFile = '', [Alias('DateFormat', 'TimeFormat')][string] $DateTimeFormat = 'yyyy-MM-dd HH:mm:ss', [alias ('LogTimeStamp')][bool] $LogTime = $true, [int] $LogRetry = 2, [ValidateSet('unknown', 'string', 'unicode', 'bigendianunicode', 'utf8', 'utf7', 'utf32', 'ascii', 'default', 'oem')][string]$Encoding = 'Unicode', [switch] $ShowTime, [switch] $NoNewLine, [alias('HideConsole')][switch] $NoConsoleOutput ) if (-not $NoConsoleOutput) { $DefaultColor = $Color[0] if ($null -ne $BackGroundColor -and $BackGroundColor.Count -ne $Color.Count) { Write-Error "Colors, BackGroundColors parameters count doesn't match. Terminated." return } if ($LinesBefore -ne 0) { for ($i = 0; $i -lt $LinesBefore; $i++) { Write-Host -Object "`n" -NoNewline } } if ($StartTab -ne 0) { for ($i = 0; $i -lt $StartTab; $i++) { Write-Host -Object "`t" -NoNewline } } if ($StartSpaces -ne 0) { for ($i = 0; $i -lt $StartSpaces; $i++) { Write-Host -Object ' ' -NoNewline } } if ($ShowTime) { Write-Host -Object "[$([datetime]::Now.ToString($DateTimeFormat))] " -NoNewline } if ($Text.Count -ne 0) { if ($Color.Count -ge $Text.Count) { if ($null -eq $BackGroundColor) { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewline } } else { for ($i = 0; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewline } } } else { if ($null -eq $BackGroundColor) { for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -NoNewline } for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -NoNewline } } else { for ($i = 0; $i -lt $Color.Length ; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $Color[$i] -BackgroundColor $BackGroundColor[$i] -NoNewline } for ($i = $Color.Length; $i -lt $Text.Length; $i++) { Write-Host -Object $Text[$i] -ForegroundColor $DefaultColor -BackgroundColor $BackGroundColor[0] -NoNewline } } } } if ($NoNewLine -eq $true) { Write-Host -NoNewline } else { Write-Host } if ($LinesAfter -ne 0) { for ($i = 0; $i -lt $LinesAfter; $i++) { Write-Host -Object "`n" -NoNewline } } } if ($Text.Count -and $LogFile) { $TextToFile = "" for ($i = 0; $i -lt $Text.Length; $i++) { $TextToFile += $Text[$i] } $Saved = $false $Retry = 0 Do { $Retry++ try { if ($LogTime) { "[$([datetime]::Now.ToString($DateTimeFormat))] $TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append -ErrorAction Stop -WhatIf:$false } else { "$TextToFile" | Out-File -FilePath $LogFile -Encoding $Encoding -Append -ErrorAction Stop -WhatIf:$false } $Saved = $true } catch { if ($Saved -eq $false -and $Retry -eq $LogRetry) { Write-Warning "Write-Color - Couldn't write to log file $($_.Exception.Message). Tried ($Retry/$LogRetry))" } else { Write-Warning "Write-Color - Couldn't write to log file $($_.Exception.Message). Retrying... ($Retry/$LogRetry)" } } } Until ($Saved -eq $true -or $Retry -ge $LogRetry) } } function Convert-FilesToMenu { [CmdletBinding()] param( [System.Collections.IDictionary] $Folders, [Array] $Files ) $MenuBuilder = [ordered] @{} foreach ($Folder in $Folders.Keys) { if (-not $MenuBuilder[$Folder]) { $MenuBuilder[$Folder] = [ordered] @{} } } foreach ($Entry in $Files | Sort-Object { $_.Date } -Descending) { $LimitsConfiguration = $Folders[$Entry.Menu].LimitsConfiguration if ($LimitsConfiguration) { $Limits = $LimitsConfiguration[$Entry.Name] if (-not $Limits) { if ($LimitsConfiguration['*']) { $Limits = $LimitsConfiguration['*'] } else { $Limits = $null } } } else { $Limits = $null } if (-not $MenuBuilder[$Entry.Menu][$Entry.Name]) { $MenuBuilder[$Entry.Menu][$Entry.Name] = @{ Current = $Entry All = [System.Collections.Generic.List[Object]]::new() History = [System.Collections.Generic.List[Object]]::new() } } else { if ($MenuBuilder[$Entry.Menu][$Entry.Name]['Current'].Date -lt $Entry.Date) { $MenuBuilder[$Entry.Menu][$Entry.Name]['Current'] = $Entry } } if ($Limits.LimitItem) { if ($MenuBuilder[$Entry.Menu][$Entry.Name]['All'].Count -ge $Limits.LimitItem) { if ($Limits.IncludeHistory) { $MenuBuilder[$Entry.Menu][$Entry.Name]['History'].Add($Entry) } continue } } elseif ($Limits.LimitDate) { if ($Entry.Date -lt $Limits.LimitDate) { if ($Limits.IncludeHistory) { $MenuBuilder[$Entry.Menu][$Entry.Name]['History'].Add($Entry) } continue } } $MenuBuilder[$Entry.Menu][$Entry.Name]['All'].Add($Entry) } $MenuBuilder } function Convert-FilesToMenuData { [CmdletBinding()] param( [System.Collections.IDictionary] $Folders, [System.Collections.IDictionary] $Replacements, [string] $Extension ) Write-Color -Text '[i]', "[TheDashboard] ", 'Creating Menu from files', ' [Informative] ' -Color Yellow, DarkGray, Yellow, DarkGray, Magenta foreach ($FolderName in $Folders.Keys) { $Folder = $Folders[$FolderName] $FilesInFolder = Get-ChildItem -LiteralPath $Folders[$FolderName].Path -ErrorAction SilentlyContinue -Filter "*$Extension" | Sort-Object -Property Name Write-Color -Text '[i]', "[TheDashboard] ", "Creating Menu from files in folder ", "'$FolderName'", " files in folder ", $($FilesInFolder.Count), ' [Informative] ' -Color Yellow, DarkGray, Yellow, Magenta, Yellow, Magenta, DarkGray foreach ($File in $FilesInFolder) { $Href = "$($Folders[$FolderName].Url)/$($File.Name)" $MenuName = $File.BaseName if ($Folder.ReplacementsGlobal -eq $true) { foreach ($Replace in $Replacements.BeforeSplit.Keys) { $MenuName = $MenuName.Replace($Replace, $Replacements.BeforeSplit[$Replace]) } if ($Replacements.SplitOn) { $Splitted = $MenuName -split $Replacements.SplitOn $Name = $Splitted[0] } else { $Name = $MenuName } if ($Replacements.AddSpaceToName) { $Name = Format-AddSpaceToSentence -Text $Name } foreach ($Replace in $Replacements.AfterSplit.Keys) { $Name = $Name.Replace($Replace, $Replacements.AfterSplit[$Replace]) } $Type = 'global replacements' } elseif ($Folder.Replacements) { foreach ($Replace in $Folder.Replacements.BeforeSplit.Keys) { $MenuName = $MenuName.Replace($Replace, $Folder.Replacements.BeforeSplit[$Replace]) } if ($Folder.Replacements.SplitOn) { $Splitted = $MenuName -split $Folder.Replacements.SplitOn $Name = $Splitted[0] } else { $Name = $MenuName } if ($Folder.Replacements.AddSpaceToName) { $Name = Format-AddSpaceToSentence -Text $Name } foreach ($Replace in $Folder.Replacements.AfterSplit.Keys) { $Name = $Name.Replace($Replace, $Folder.Replacements.AfterSplit[$Replace]) } $Type = 'folder replacements' } else { $Name = $MenuName $Type = 'no replacements applied' } if ($Name) { [ordered] @{ Name = $Name Href = $Href FileName = "$($Folder.Url)_$($File.Name)" Menu = $FolderName MenuLink = $Folder.Url Date = $File.LastWriteTime } } else { Write-Color -Text "[e]", "[TheDashboard] ", "Creating Menu ", "[error] ", "Couldn't create menu item for $($File.FullName). Problem with $Type" -Color Red, DarkGray, Red, DarkGray, Red } } } } function Convert-MultipleReplacements { [CmdletBinding()] param( [System.Collections.IDictionary] $Replacements, [Array] $ReplacementConfiguration ) if (-not $Replacements) { $ReplacementSetting = [ordered] @{ SplitOn = $null BeforeSplit = [ordered] @{} AfterSplit = [ordered] @{} AddSpaceToName = $null } } else { $ReplacementSetting = $Replacements } foreach ($Replacement in $ReplacementConfiguration) { Remove-EmptyValue -Hashtable $Replacement foreach ($R in $Replacement.Keys) { if ($R -eq 'SplitOn') { $ReplacementSetting['SplitOn'] = $Replacement[$R] } elseif ($R -eq 'beforeSplit') { foreach ($Before in $Replacement[$R]) { foreach ($Key in $Before.Keys) { $ReplacementSetting['BeforeSplit'][$Key] = $Before[$Key] } } } elseif ($R -eq 'afterSplit') { foreach ($After in $Replacement[$R]) { foreach ($Key in $After.Keys) { $ReplacementSetting['AfterSplit'][$Key] = $After[$Key] } } } elseif ($R -eq 'addSpaceToName') { $ReplacementSetting['AddSpaceToName'] = $Replacement[$R] } } } $ReplacementSetting } function Copy-HTMLFiles { [cmdletbinding()] param( [System.Collections.IDictionary] $Folders, [string] $Extension ) Write-Color -Text '[i]', "[TheDashboard] ", 'Copying or HTML files', ' [Informative] ' -Color Yellow, DarkGray, Yellow, DarkGray, Magenta foreach ($FolderName in $Folders.Keys) { if ($Folders[$FolderName].CopyFrom) { foreach ($Path in $Folders[$FolderName].CopyFrom) { foreach ($File in Get-ChildItem -LiteralPath $Path -Filter "*$Extension" -Recurse) { $Destination = $File.FullName.Replace($Path, $Folders[$FolderName].Path) $DIrectoryName = [io.path]::GetDirectoryName($Destination) $null = New-Item -Path $DIrectoryName -ItemType Directory -Force Copy-Item -LiteralPath $File.FullName -Destination $Destination -Force -ErrorAction Stop } } } elseif ($Folders[$FolderName].MoveFrom) { foreach ($Path in $Folders[$FolderName].MoveFrom) { foreach ($File in Get-ChildItem -LiteralPath $Path -Filter "*$Extension" -Recurse) { $Destination = $File.FullName.Replace($Path, $Folders[$FolderName].Path) $DIrectoryName = [io.path]::GetDirectoryName($Destination) $null = New-Item -Path $DIrectoryName -ItemType Directory -Force Move-Item -LiteralPath $File.FullName -Destination $Destination -Force -ErrorAction Stop } } } } } function Get-GitHubVersion { [cmdletBinding()] param( [Parameter(Mandatory)][string] $Cmdlet, [Parameter(Mandatory)][string] $RepositoryOwner, [Parameter(Mandatory)][string] $RepositoryName ) $App = Get-Command -Name $Cmdlet -ErrorAction SilentlyContinue if ($App) { [Array] $GitHubReleases = (Get-GitHubLatestRelease -Url "https://api.github.com/repos/$RepositoryOwner/$RepositoryName/releases" -Verbose:$false) $LatestVersion = $GitHubReleases[0] if (-not $LatestVersion.Errors) { if ($App.Version -eq $LatestVersion.Version) { "Current/Latest: $($LatestVersion.Version) at $($LatestVersion.PublishDate)" } elseif ($App.Version -lt $LatestVersion.Version) { "Current: $($App.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Update?" } elseif ($App.Version -gt $LatestVersion.Version) { "Current: $($App.Version), Published: $($LatestVersion.Version) at $($LatestVersion.PublishDate). Lucky you!" } } else { "Current: $($App.Version)" } } } function New-HTMLReport { [cmdletBinding()] param( [Array] $OutputElements, [string] $Logo, [string] $Extension, [System.Collections.IDictionary] $MenuBuilder, [System.Collections.IDictionary] $Configuration, [System.Collections.IDictionary] $TopStats, [Array] $Files, [string] $HTMLPath, [switch] $ShowHTML, [switch] $Online, [switch] $Force ) $TimeLogHTML = Start-TimeLog Write-Color -Text '[i]', '[HTML ] ', "Generating HTML report ($HTMLPath)" -Color Yellow, DarkGray, Yellow $FilePathsGenerated = [System.Collections.Generic.List[string]]::new() $FilePathsGenerated.Add($HTMLPath) New-HTML { New-HTMLNavTop -HomeLinkHome -Logo $Logo { foreach ($Menu in $MenuBuilder.Keys) { $TopMenuSplat = @{ Name = $Menu } if ($Configuration.Folders.$Menu.IconType) { $TopMenuSplat[$Configuration.Folders.$Menu.IconType] = $Configuration.Folders.$Menu.Icon } New-NavTopMenu @TopMenuSplat { foreach ($MenuReport in $MenuBuilder[$Menu].Keys | Sort-Object) { $MenuLink = $MenuBuilder[$Menu][$MenuReport]['Current'].MenuLink $PageName = (( -join ($MenuBuilder[$Menu][$MenuReport]['Current'].Name)).Replace(":", "_").Replace(" ", "_")) New-NavLink -IconRegular calendar-check -Name $MenuBuilder[$Menu][$MenuReport]['Current'].Name -Href "$($MenuLink)_$($PageName)$($Extension)" } } } } -MenuItemsWidth 250px New-HTMLSectionStyle -BorderRadius 0px -HeaderBackGroundColor Grey -RemoveShadow New-HTMLPanelStyle -BorderRadius 0px New-HTMLSection -Invisible { foreach ($E in $OutputElements) { New-HTMLPanel { New-HTMLGage -Label $E.Label -MinValue $E.MinValue -MaxValue $E.MaxValue -Value $E.Value -Counter $TopStats[$E.Date][$($E.Label)] = $E.Value } } } New-HTMLSection -Invisible { New-HTMLPanel { $StatisticsKeys = $TopStats.Keys | Sort-Object | Select-Object -Last 50 [Array] $Dates = foreach ($Day in $StatisticsKeys) { $TopStats[$Day].Date } foreach ($UserInput in $Dates) { $TopStats[$Day].$($UserInput.Label) = $UserInput.Value } New-HTMLChart -Title 'Domain Summary' -TitleAlignment center { New-ChartAxisX -Type datetime -Names $Dates New-ChartAxisY -TitleText 'Numbers' -Show foreach ($UserInput in $OutputElements) { $Values = foreach ($Day in $StatisticsKeys) { $TopStats[$Day].$($UserInput.Label) } New-ChartLine -Name $UserInput.Label -Value $Values } } } New-HTMLPanel { New-HTMLCalendar { foreach ($Menu in $MenuBuilder.Keys) { foreach ($MenuReport in $MenuBuilder[$Menu].Keys) { [Array] $AllReports = $MenuBuilder[$Menu][$MenuReport]['All'] foreach ($CalendarEntry in $AllReports) { if ($($CalendarEntry.Date).Day -eq $($($CalendarEntry.Date).AddMinutes(30)).Day) { New-CalendarEvent -Title $CalendarEntry.Name -StartDate $CalendarEntry.Date -EndDate $($CalendarEntry.Date).AddMinutes(30) -Url $CalendarEntry.FileName } else { New-CalendarEvent -Title $CalendarEntry.Name -StartDate $CalendarEntry.Date.AddMinutes(-30) -EndDate $($CalendarEntry.Date) -Url $CalendarEntry.FileName } } } } } -HeaderRight @('dayGridMonth', 'timeGridWeek', 'timeGridDay', 'listMonth', 'listYear') } } foreach ($Menu in $MenuBuilder.Keys) { Write-Color -Text '[i]', '[HTML ] ', "Building Menu for ", $Menu -Color Yellow, DarkGray, Yellow, DarkCyan $TopMenuSplat = @{ Name = $Menu } if ($Configuration.Folders.$Menu.IconType) { $TopMenuSplat[$Configuration.Folders.$Menu.IconType] = $Configuration.Folders.$Menu.Icon } foreach ($MenuReport in $MenuBuilder[$Menu].Keys | Sort-Object) { $MenuLink = $MenuBuilder[$Menu][$MenuReport]['Current'].MenuLink $PathToSubReports = [io.path]::GetDirectoryName($HTMLPath) $PageName = ($MenuBuilder[$Menu][$MenuReport]['Current'].Name).Replace(":", "_").Replace(" ", "_") $FullPath = [io.path]::Combine($PathToSubReports, "$($MenuLink)_$PageName$($Extension)") $CurrentReport = $MenuBuilder[$Menu][$MenuReport]['Current'] $AllReports = $MenuBuilder[$Menu][$MenuReport]['All'] [Array] $HistoryReports = $MenuBuilder[$Menu][$MenuReport]['History'] $Name = $CurrentReport.Name New-HTMLReportPage -Report $CurrentReport -AllReports $AllReports -HistoryReports $HistoryReports -FilePath $FullPath -PathToSubReports $PathToSubReports -Name $Name $FilePathsGenerated.Add($FullPath) foreach ($Report in $AllReports) { $FullPathOther = [io.path]::Combine($PathToSubReports, $Report.FileName) $Name = $Report.Name + ' - ' + $Report.Date $FilePathsGenerated.Add($FullPathOther) New-HTMLReportPage -SubReport -Report $Report -AllReports $AllReports -FilePath $FullPathOther -PathToSubReports $PathToSubReports -Name $Name -HistoryReports $HistoryReports } } Write-Color -Text '[i]', '[HTML ] ', "Ending Menu for ", $Menu -Color Yellow, DarkGray, Yellow, DarkCyan } Write-Color -Text '[i]', '[HTML ] ', "Saving HTML reports (this may take a while...)" -Color Yellow, DarkGray, Yellow } -FilePath $HTMLPath -ShowHTML:$ShowHTML.IsPresent -TitleText 'The Dashboard' -Online:$Online.IsPresent $TimeLogEndHTML = Stop-TimeLog -Time $TimeLogHTML -Option OneLiner Write-Color -Text '[i]', '[HTML ] ', 'Generating HTML report', " [Time to execute: $TimeLogEndHTML]" -Color Yellow, DarkGray, Yellow, DarkGray $FilePathsGenerated } function New-HTMLReportPage { [cmdletBinding()] param( [System.Collections.IDictionary] $Report, [Array] $AllReports, [Array] $HistoryReports, [string] $FilePath, [string] $PathToSubReports, [string] $Name, [switch] $SubReport ) if ($SubReport) { Write-Color -Text '[i]', '[HTML ] ', "Generating HTML page ($MenuReport) sub report ($FilePath)" -Color Yellow, DarkGray, Yellow } else { Write-Color -Text '[i]', '[HTML ] ', "Generating HTML page ($MenuReport) report ($FilePath)" -Color Yellow, DarkGray, Yellow } New-HTMLPage -Name $Name { New-HTMLSection -HeaderText "Summary for $($Report.Name)" -HeaderBackGroundColor Black { New-HTMLSection -Invisible { New-HTMLPanel { New-HTMLText -Text "Report name: ", $CurrentReport.Name -FontSize 12px New-HTMLText -Text "Report date: ", $CurrentReport.Date -FontSize 12px New-HTMLText -Text "All reports in this catagory: ", $AllReports.Count -FontSize 12px New-HTMLList { if ($AllReports.Count -eq 1) { New-HTMLListItem -Text "Date in report: ", $AllReports[0].Date -FontSize 12px -FontWeight normal, bold -TextDecoration none, underline } else { New-HTMLListItem -Text "Date ranges from: ", $AllReports[$AllReports.Count - 1].Date, " to ", $AllReports[0].Date -FontSize 12px -FontWeight normal, bold, normal, bold -TextDecoration none, underline, none, underline } } if ($HistoryReports.Count) { New-HTMLText -Text "History reports in this catagory: ", $HistoryReports.Count -FontSize 12px New-HTMLList { if ($HistoryReports.Count -gt 1) { New-HTMLListItem -Text "Date ranges from: ", $HistoryReports[$AllReports.Count - 1].Date, " to ", $HistoryReports[0].Date -FontSize 12px -FontWeight normal, bold, normal, bold -TextDecoration none, underline, none, underline } else { New-HTMLListItem -Text "Date in report: ", $HistoryReports[0].Date -FontSize 12px -FontWeight normal, bold -TextDecoration none, underline } } } } -Invisible } New-HTMLSection -Invisible { New-HTMLCalendar { foreach ($CalendarEntry in $AllReports) { if ($($CalendarEntry.Date).Day -eq $($($CalendarEntry.Date).AddMinutes(30)).Day) { New-CalendarEvent -Title $CalendarEntry.Name -StartDate $CalendarEntry.Date -EndDate $($CalendarEntry.Date).AddMinutes(30) -Url $CalendarEntry.FileName } else { New-CalendarEvent -Title $CalendarEntry.Name -StartDate $CalendarEntry.Date.AddMinutes(-30) -EndDate $($CalendarEntry.Date) -Url $CalendarEntry.FileName } } foreach ($CalendarEntry in $HistoryReports) { if ($($CalendarEntry.Date).Day -eq $($($CalendarEntry.Date).AddMinutes(30)).Day) { New-CalendarEvent -Title $CalendarEntry.Name -StartDate $CalendarEntry.Date -EndDate $($CalendarEntry.Date).AddMinutes(30) -Url $CalendarEntry.Href -TargetName 'iFrameWithContent' } else { New-CalendarEvent -Title $CalendarEntry.Name -StartDate $CalendarEntry.Date.AddMinutes(-30) -EndDate $($CalendarEntry.Date) -Url $CalendarEntry.Href -TargetName 'iFrameWithContent' } } } -HeaderRight @('dayGridMonth', 'timeGridWeek', 'timeGridDay', 'listMonth', 'listYear') } } -Height 300px New-HTMLSection -Invisible { } -Height 15px New-HTMLFrame -SourcePath $Report.Href -Scrolling Auto -Height 2000px -Name 'iFrameWithContent' } -FilePath $FilePath } $Global:HTMLIcons = [ordered] @{ FontAwesomeBrands = [ordered] @{ '500px' = 'f26e' 'accessible-icon' = 'f368' 'accusoft' = 'f369' 'acquisitions-incorporated' = 'f6af' 'adn' = 'f170' 'adversal' = 'f36a' 'affiliatetheme' = 'f36b' 'airbnb' = 'f834' 'algolia' = 'f36c' 'alipay' = 'f642' 'amazon' = 'f270' 'amazon-pay' = 'f42c' 'amilia' = 'f36d' 'android' = 'f17b' 'angellist' = 'f209' 'angrycreative' = 'f36e' 'angular' = 'f420' 'app-store' = 'f36f' 'app-store-ios' = 'f370' 'apper' = 'f371' 'apple' = 'f179' 'apple-pay' = 'f415' 'artstation' = 'f77a' 'asymmetrik' = 'f372' 'atlassian' = 'f77b' 'audible' = 'f373' 'autoprefixer' = 'f41c' 'avianex' = 'f374' 'aviato' = 'f421' 'aws' = 'f375' 'bandcamp' = 'f2d5' 'battle-net' = 'f835' 'behance' = 'f1b4' 'behance-square' = 'f1b5' 'bimobject' = 'f378' 'bitbucket' = 'f171' 'bitcoin' = 'f379' 'bity' = 'f37a' 'black-tie' = 'f27e' 'blackberry' = 'f37b' 'blogger' = 'f37c' 'blogger-b' = 'f37d' 'bluetooth' = 'f293' 'bluetooth-b' = 'f294' 'bootstrap' = 'f836' 'btc' = 'f15a' 'buffer' = 'f837' 'buromobelexperte' = 'f37f' 'buy-n-large' = 'f8a6' 'canadian-maple-leaf' = 'f785' 'cc-amazon-pay' = 'f42d' 'cc-amex' = 'f1f3' 'cc-apple-pay' = 'f416' 'cc-diners-club' = 'f24c' 'cc-discover' = 'f1f2' 'cc-jcb' = 'f24b' 'cc-mastercard' = 'f1f1' 'cc-paypal' = 'f1f4' 'cc-stripe' = 'f1f5' 'cc-visa' = 'f1f0' 'centercode' = 'f380' 'centos' = 'f789' 'chrome' = 'f268' 'chromecast' = 'f838' 'cloudflare' = 'e07d' 'cloudscale' = 'f383' 'cloudsmith' = 'f384' 'cloudversify' = 'f385' 'codepen' = 'f1cb' 'codiepie' = 'f284' 'confluence' = 'f78d' 'connectdevelop' = 'f20e' 'contao' = 'f26d' 'cotton-bureau' = 'f89e' 'cpanel' = 'f388' 'creative-commons' = 'f25e' 'creative-commons-by' = 'f4e7' 'creative-commons-nc' = 'f4e8' 'creative-commons-nc-eu' = 'f4e9' 'creative-commons-nc-jp' = 'f4ea' 'creative-commons-nd' = 'f4eb' 'creative-commons-pd' = 'f4ec' 'creative-commons-pd-alt' = 'f4ed' 'creative-commons-remix' = 'f4ee' 'creative-commons-sa' = 'f4ef' 'creative-commons-sampling' = 'f4f0' 'creative-commons-sampling-plus' = 'f4f1' 'creative-commons-share' = 'f4f2' 'creative-commons-zero' = 'f4f3' 'critical-role' = 'f6c9' 'css3' = 'f13c' 'css3-alt' = 'f38b' 'cuttlefish' = 'f38c' 'd-and-d' = 'f38d' 'd-and-d-beyond' = 'f6ca' 'dailymotion' = 'e052' 'dashcube' = 'f210' 'deezer' = 'e077' 'delicious' = 'f1a5' 'deploydog' = 'f38e' 'deskpro' = 'f38f' 'dev' = 'f6cc' 'deviantart' = 'f1bd' 'dhl' = 'f790' 'diaspora' = 'f791' 'digg' = 'f1a6' 'digital-ocean' = 'f391' 'discord' = 'f392' 'discourse' = 'f393' 'dochub' = 'f394' 'docker' = 'f395' 'draft2digital' = 'f396' 'dribbble' = 'f17d' 'dribbble-square' = 'f397' 'dropbox' = 'f16b' 'drupal' = 'f1a9' 'dyalog' = 'f399' 'earlybirds' = 'f39a' 'ebay' = 'f4f4' 'edge' = 'f282' 'edge-legacy' = 'e078' 'elementor' = 'f430' 'ello' = 'f5f1' 'ember' = 'f423' 'empire' = 'f1d1' 'envira' = 'f299' 'erlang' = 'f39d' 'ethereum' = 'f42e' 'etsy' = 'f2d7' 'evernote' = 'f839' 'expeditedssl' = 'f23e' 'facebook' = 'f09a' 'facebook-f' = 'f39e' 'facebook-messenger' = 'f39f' 'facebook-square' = 'f082' 'fantasy-flight-games' = 'f6dc' 'fedex' = 'f797' 'fedora' = 'f798' 'figma' = 'f799' 'firefox' = 'f269' 'firefox-browser' = 'e007' 'first-order' = 'f2b0' 'first-order-alt' = 'f50a' 'firstdraft' = 'f3a1' 'flickr' = 'f16e' 'flipboard' = 'f44d' 'fly' = 'f417' 'font-awesome' = 'f2b4' 'font-awesome-alt' = 'f35c' 'font-awesome-flag' = 'f425' 'fonticons' = 'f280' 'fonticons-fi' = 'f3a2' 'fort-awesome' = 'f286' 'fort-awesome-alt' = 'f3a3' 'forumbee' = 'f211' 'foursquare' = 'f180' 'free-code-camp' = 'f2c5' 'freebsd' = 'f3a4' 'fulcrum' = 'f50b' 'galactic-republic' = 'f50c' 'galactic-senate' = 'f50d' 'get-pocket' = 'f265' 'gg' = 'f260' 'gg-circle' = 'f261' 'git' = 'f1d3' 'git-alt' = 'f841' 'git-square' = 'f1d2' 'github' = 'f09b' 'github-alt' = 'f113' 'github-square' = 'f092' 'gitkraken' = 'f3a6' 'gitlab' = 'f296' 'gitter' = 'f426' 'glide' = 'f2a5' 'glide-g' = 'f2a6' 'gofore' = 'f3a7' 'goodreads' = 'f3a8' 'goodreads-g' = 'f3a9' 'google' = 'f1a0' 'google-drive' = 'f3aa' 'google-pay' = 'e079' 'google-play' = 'f3ab' 'google-plus' = 'f2b3' 'google-plus-g' = 'f0d5' 'google-plus-square' = 'f0d4' 'google-wallet' = 'f1ee' 'gratipay' = 'f184' 'grav' = 'f2d6' 'gripfire' = 'f3ac' 'grunt' = 'f3ad' 'guilded' = 'e07e' 'gulp' = 'f3ae' 'hacker-news' = 'f1d4' 'hacker-news-square' = 'f3af' 'hackerrank' = 'f5f7' 'hips' = 'f452' 'hire-a-helper' = 'f3b0' 'hive' = 'e07f' 'hooli' = 'f427' 'hornbill' = 'f592' 'hotjar' = 'f3b1' 'houzz' = 'f27c' 'html5' = 'f13b' 'hubspot' = 'f3b2' 'ideal' = 'e013' 'imdb' = 'f2d8' 'innosoft' = 'e080' 'instagram' = 'f16d' 'instagram-square' = 'e055' 'instalod' = 'e081' 'intercom' = 'f7af' 'internet-explorer' = 'f26b' 'invision' = 'f7b0' 'ioxhost' = 'f208' 'itch-io' = 'f83a' 'itunes' = 'f3b4' 'itunes-note' = 'f3b5' 'java' = 'f4e4' 'jedi-order' = 'f50e' 'jenkins' = 'f3b6' 'jira' = 'f7b1' 'joget' = 'f3b7' 'joomla' = 'f1aa' 'js' = 'f3b8' 'js-square' = 'f3b9' 'jsfiddle' = 'f1cc' 'kaggle' = 'f5fa' 'keybase' = 'f4f5' 'keycdn' = 'f3ba' 'kickstarter' = 'f3bb' 'kickstarter-k' = 'f3bc' 'korvue' = 'f42f' 'laravel' = 'f3bd' 'lastfm' = 'f202' 'lastfm-square' = 'f203' 'leanpub' = 'f212' 'less' = 'f41d' 'line' = 'f3c0' 'linkedin' = 'f08c' 'linkedin-in' = 'f0e1' 'linode' = 'f2b8' 'linux' = 'f17c' 'lyft' = 'f3c3' 'magento' = 'f3c4' 'mailchimp' = 'f59e' 'mandalorian' = 'f50f' 'markdown' = 'f60f' 'mastodon' = 'f4f6' 'maxcdn' = 'f136' 'mdb' = 'f8ca' 'medapps' = 'f3c6' 'medium' = 'f23a' 'medium-m' = 'f3c7' 'medrt' = 'f3c8' 'meetup' = 'f2e0' 'megaport' = 'f5a3' 'mendeley' = 'f7b3' 'microblog' = 'e01a' 'microsoft' = 'f3ca' 'mix' = 'f3cb' 'mixcloud' = 'f289' 'mixer' = 'e056' 'mizuni' = 'f3cc' 'modx' = 'f285' 'monero' = 'f3d0' 'napster' = 'f3d2' 'neos' = 'f612' 'nimblr' = 'f5a8' 'node' = 'f419' 'node-js' = 'f3d3' 'npm' = 'f3d4' 'ns8' = 'f3d5' 'nutritionix' = 'f3d6' 'octopus-deploy' = 'e082' 'odnoklassniki' = 'f263' 'odnoklassniki-square' = 'f264' 'old-republic' = 'f510' 'opencart' = 'f23d' 'openid' = 'f19b' 'opera' = 'f26a' 'optin-monster' = 'f23c' 'orcid' = 'f8d2' 'osi' = 'f41a' 'page4' = 'f3d7' 'pagelines' = 'f18c' 'palfed' = 'f3d8' 'patreon' = 'f3d9' 'paypal' = 'f1ed' 'penny-arcade' = 'f704' 'perbyte' = 'e083' 'periscope' = 'f3da' 'phabricator' = 'f3db' 'phoenix-framework' = 'f3dc' 'phoenix-squadron' = 'f511' 'php' = 'f457' 'pied-piper' = 'f2ae' 'pied-piper-alt' = 'f1a8' 'pied-piper-hat' = 'f4e5' 'pied-piper-pp' = 'f1a7' 'pied-piper-square' = 'e01e' 'pinterest' = 'f0d2' 'pinterest-p' = 'f231' 'pinterest-square' = 'f0d3' 'playstation' = 'f3df' 'product-hunt' = 'f288' 'pushed' = 'f3e1' 'python' = 'f3e2' 'qq' = 'f1d6' 'quinscape' = 'f459' 'quora' = 'f2c4' 'r-project' = 'f4f7' 'raspberry-pi' = 'f7bb' 'ravelry' = 'f2d9' 'react' = 'f41b' 'reacteurope' = 'f75d' 'readme' = 'f4d5' 'rebel' = 'f1d0' 'red-river' = 'f3e3' 'reddit' = 'f1a1' 'reddit-alien' = 'f281' 'reddit-square' = 'f1a2' 'redhat' = 'f7bc' 'renren' = 'f18b' 'replyd' = 'f3e6' 'researchgate' = 'f4f8' 'resolving' = 'f3e7' 'rev' = 'f5b2' 'rocketchat' = 'f3e8' 'rockrms' = 'f3e9' 'rust' = 'e07a' 'safari' = 'f267' 'salesforce' = 'f83b' 'sass' = 'f41e' 'schlix' = 'f3ea' 'scribd' = 'f28a' 'searchengin' = 'f3eb' 'sellcast' = 'f2da' 'sellsy' = 'f213' 'servicestack' = 'f3ec' 'shirtsinbulk' = 'f214' 'shopify' = 'e057' 'shopware' = 'f5b5' 'simplybuilt' = 'f215' 'sistrix' = 'f3ee' 'sith' = 'f512' 'sketch' = 'f7c6' 'skyatlas' = 'f216' 'skype' = 'f17e' 'slack' = 'f198' 'slack-hash' = 'f3ef' 'slideshare' = 'f1e7' 'snapchat' = 'f2ab' 'snapchat-ghost' = 'f2ac' 'snapchat-square' = 'f2ad' 'soundcloud' = 'f1be' 'sourcetree' = 'f7d3' 'speakap' = 'f3f3' 'speaker-deck' = 'f83c' 'spotify' = 'f1bc' 'squarespace' = 'f5be' 'stack-exchange' = 'f18d' 'stack-overflow' = 'f16c' 'stackpath' = 'f842' 'staylinked' = 'f3f5' 'steam' = 'f1b6' 'steam-square' = 'f1b7' 'steam-symbol' = 'f3f6' 'sticker-mule' = 'f3f7' 'strava' = 'f428' 'stripe' = 'f429' 'stripe-s' = 'f42a' 'studiovinari' = 'f3f8' 'stumbleupon' = 'f1a4' 'stumbleupon-circle' = 'f1a3' 'superpowers' = 'f2dd' 'supple' = 'f3f9' 'suse' = 'f7d6' 'swift' = 'f8e1' 'symfony' = 'f83d' 'teamspeak' = 'f4f9' 'telegram' = 'f2c6' 'telegram-plane' = 'f3fe' 'tencent-weibo' = 'f1d5' 'the-red-yeti' = 'f69d' 'themeco' = 'f5c6' 'themeisle' = 'f2b2' 'think-peaks' = 'f731' 'tiktok' = 'e07b' 'trade-federation' = 'f513' 'trello' = 'f181' 'tripadvisor' = 'f262' 'tumblr' = 'f173' 'tumblr-square' = 'f174' 'twitch' = 'f1e8' 'twitter' = 'f099' 'twitter-square' = 'f081' 'typo3' = 'f42b' 'uber' = 'f402' 'ubuntu' = 'f7df' 'uikit' = 'f403' 'umbraco' = 'f8e8' 'uncharted' = 'e084' 'uniregistry' = 'f404' 'unity' = 'e049' 'unsplash' = 'e07c' 'untappd' = 'f405' 'ups' = 'f7e0' 'usb' = 'f287' 'usps' = 'f7e1' 'ussunnah' = 'f407' 'vaadin' = 'f408' 'viacoin' = 'f237' 'viadeo' = 'f2a9' 'viadeo-square' = 'f2aa' 'viber' = 'f409' 'vimeo' = 'f40a' 'vimeo-square' = 'f194' 'vimeo-v' = 'f27d' 'vine' = 'f1ca' 'vk' = 'f189' 'vnv' = 'f40b' 'vuejs' = 'f41f' 'watchman-monitoring' = 'e087' 'waze' = 'f83f' 'weebly' = 'f5cc' 'weibo' = 'f18a' 'weixin' = 'f1d7' 'whatsapp' = 'f232' 'whatsapp-square' = 'f40c' 'whmcs' = 'f40d' 'wikipedia-w' = 'f266' 'windows' = 'f17a' 'wix' = 'f5cf' 'wizards-of-the-coast' = 'f730' 'wodu' = 'e088' 'wolf-pack-battalion' = 'f514' 'wordpress' = 'f19a' 'wordpress-simple' = 'f411' 'wpbeginner' = 'f297' 'wpexplorer' = 'f2de' 'wpforms' = 'f298' 'wpressr' = 'f3e4' 'xbox' = 'f412' 'xing' = 'f168' 'xing-square' = 'f169' 'y-combinator' = 'f23b' 'yahoo' = 'f19e' 'yammer' = 'f840' 'yandex' = 'f413' 'yandex-international' = 'f414' 'yarn' = 'f7e3' 'yelp' = 'f1e9' 'yoast' = 'f2b1' 'youtube' = 'f167' 'youtube-square' = 'f431' 'zhihu' = 'f63f' } FontAwesomeRegular = [ordered] @{ 'address-book' = 'f2b9' 'address-card' = 'f2bb' 'angry' = 'f556' 'arrow-alt-circle-down' = 'f358' 'arrow-alt-circle-left' = 'f359' 'arrow-alt-circle-right' = 'f35a' 'arrow-alt-circle-up' = 'f35b' 'bell' = 'f0f3' 'bell-slash' = 'f1f6' 'bookmark' = 'f02e' 'building' = 'f1ad' 'calendar' = 'f133' 'calendar-alt' = 'f073' 'calendar-check' = 'f274' 'calendar-minus' = 'f272' 'calendar-plus' = 'f271' 'calendar-times' = 'f273' 'caret-square-down' = 'f150' 'caret-square-left' = 'f191' 'caret-square-right' = 'f152' 'caret-square-up' = 'f151' 'chart-bar' = 'f080' 'check-circle' = 'f058' 'check-square' = 'f14a' 'circle' = 'f111' 'clipboard' = 'f328' 'clock' = 'f017' 'clone' = 'f24d' 'closed-captioning' = 'f20a' 'comment' = 'f075' 'comment-alt' = 'f27a' 'comment-dots' = 'f4ad' 'comments' = 'f086' 'compass' = 'f14e' 'copy' = 'f0c5' 'copyright' = 'f1f9' 'credit-card' = 'f09d' 'dizzy' = 'f567' 'dot-circle' = 'f192' 'edit' = 'f044' 'envelope' = 'f0e0' 'envelope-open' = 'f2b6' 'eye' = 'f06e' 'eye-slash' = 'f070' 'file' = 'f15b' 'file-alt' = 'f15c' 'file-archive' = 'f1c6' 'file-audio' = 'f1c7' 'file-code' = 'f1c9' 'file-excel' = 'f1c3' 'file-image' = 'f1c5' 'file-pdf' = 'f1c1' 'file-powerpoint' = 'f1c4' 'file-video' = 'f1c8' 'file-word' = 'f1c2' 'flag' = 'f024' 'flushed' = 'f579' 'folder' = 'f07b' 'folder-open' = 'f07c' 'frown' = 'f119' 'frown-open' = 'f57a' 'futbol' = 'f1e3' 'gem' = 'f3a5' 'grimace' = 'f57f' 'grin' = 'f580' 'grin-alt' = 'f581' 'grin-beam' = 'f582' 'grin-beam-sweat' = 'f583' 'grin-hearts' = 'f584' 'grin-squint' = 'f585' 'grin-squint-tears' = 'f586' 'grin-stars' = 'f587' 'grin-tears' = 'f588' 'grin-tongue' = 'f589' 'grin-tongue-squint' = 'f58a' 'grin-tongue-wink' = 'f58b' 'grin-wink' = 'f58c' 'hand-lizard' = 'f258' 'hand-paper' = 'f256' 'hand-peace' = 'f25b' 'hand-point-down' = 'f0a7' 'hand-point-left' = 'f0a5' 'hand-point-right' = 'f0a4' 'hand-point-up' = 'f0a6' 'hand-pointer' = 'f25a' 'hand-rock' = 'f255' 'hand-scissors' = 'f257' 'hand-spock' = 'f259' 'handshake' = 'f2b5' 'hdd' = 'f0a0' 'heart' = 'f004' 'hospital' = 'f0f8' 'hourglass' = 'f254' 'id-badge' = 'f2c1' 'id-card' = 'f2c2' 'image' = 'f03e' 'images' = 'f302' 'keyboard' = 'f11c' 'kiss' = 'f596' 'kiss-beam' = 'f597' 'kiss-wink-heart' = 'f598' 'laugh' = 'f599' 'laugh-beam' = 'f59a' 'laugh-squint' = 'f59b' 'laugh-wink' = 'f59c' 'lemon' = 'f094' 'life-ring' = 'f1cd' 'lightbulb' = 'f0eb' 'list-alt' = 'f022' 'map' = 'f279' 'meh' = 'f11a' 'meh-blank' = 'f5a4' 'meh-rolling-eyes' = 'f5a5' 'minus-square' = 'f146' 'money-bill-alt' = 'f3d1' 'moon' = 'f186' 'newspaper' = 'f1ea' 'object-group' = 'f247' 'object-ungroup' = 'f248' 'paper-plane' = 'f1d8' 'pause-circle' = 'f28b' 'play-circle' = 'f144' 'plus-square' = 'f0fe' 'question-circle' = 'f059' 'registered' = 'f25d' 'sad-cry' = 'f5b3' 'sad-tear' = 'f5b4' 'save' = 'f0c7' 'share-square' = 'f14d' 'smile' = 'f118' 'smile-beam' = 'f5b8' 'smile-wink' = 'f4da' 'snowflake' = 'f2dc' 'square' = 'f0c8' 'star' = 'f005' 'star-half' = 'f089' 'sticky-note' = 'f249' 'stop-circle' = 'f28d' 'sun' = 'f185' 'surprise' = 'f5c2' 'thumbs-down' = 'f165' 'thumbs-up' = 'f164' 'times-circle' = 'f057' 'tired' = 'f5c8' 'trash-alt' = 'f2ed' 'user' = 'f007' 'user-circle' = 'f2bd' 'window-close' = 'f410' 'window-maximize' = 'f2d0' 'window-minimize' = 'f2d1' 'window-restore' = 'f2d2' } FontAwesomeSolid = [ordered] @{ 'ad' = 'f641' 'address-book' = 'f2b9' 'address-card' = 'f2bb' 'adjust' = 'f042' 'air-freshener' = 'f5d0' 'align-center' = 'f037' 'align-justify' = 'f039' 'align-left' = 'f036' 'align-right' = 'f038' 'allergies' = 'f461' 'ambulance' = 'f0f9' 'american-sign-language-interpreting' = 'f2a3' 'anchor' = 'f13d' 'angle-double-down' = 'f103' 'angle-double-left' = 'f100' 'angle-double-right' = 'f101' 'angle-double-up' = 'f102' 'angle-down' = 'f107' 'angle-left' = 'f104' 'angle-right' = 'f105' 'angle-up' = 'f106' 'angry' = 'f556' 'ankh' = 'f644' 'apple-alt' = 'f5d1' 'archive' = 'f187' 'archway' = 'f557' 'arrow-alt-circle-down' = 'f358' 'arrow-alt-circle-left' = 'f359' 'arrow-alt-circle-right' = 'f35a' 'arrow-alt-circle-up' = 'f35b' 'arrow-circle-down' = 'f0ab' 'arrow-circle-left' = 'f0a8' 'arrow-circle-right' = 'f0a9' 'arrow-circle-up' = 'f0aa' 'arrow-down' = 'f063' 'arrow-left' = 'f060' 'arrow-right' = 'f061' 'arrow-up' = 'f062' 'arrows-alt' = 'f0b2' 'arrows-alt-h' = 'f337' 'arrows-alt-v' = 'f338' 'assistive-listening-systems' = 'f2a2' 'asterisk' = 'f069' 'at' = 'f1fa' 'atlas' = 'f558' 'atom' = 'f5d2' 'audio-description' = 'f29e' 'award' = 'f559' 'baby' = 'f77c' 'baby-carriage' = 'f77d' 'backspace' = 'f55a' 'backward' = 'f04a' 'bacon' = 'f7e5' 'bacteria' = 'e059' 'bacterium' = 'e05a' 'bahai' = 'f666' 'balance-scale' = 'f24e' 'balance-scale-left' = 'f515' 'balance-scale-right' = 'f516' 'ban' = 'f05e' 'band-aid' = 'f462' 'barcode' = 'f02a' 'bars' = 'f0c9' 'baseball-ball' = 'f433' 'basketball-ball' = 'f434' 'bath' = 'f2cd' 'battery-empty' = 'f244' 'battery-full' = 'f240' 'battery-half' = 'f242' 'battery-quarter' = 'f243' 'battery-three-quarters' = 'f241' 'bed' = 'f236' 'beer' = 'f0fc' 'bell' = 'f0f3' 'bell-slash' = 'f1f6' 'bezier-curve' = 'f55b' 'bible' = 'f647' 'bicycle' = 'f206' 'biking' = 'f84a' 'binoculars' = 'f1e5' 'biohazard' = 'f780' 'birthday-cake' = 'f1fd' 'blender' = 'f517' 'blender-phone' = 'f6b6' 'blind' = 'f29d' 'blog' = 'f781' 'bold' = 'f032' 'bolt' = 'f0e7' 'bomb' = 'f1e2' 'bone' = 'f5d7' 'bong' = 'f55c' 'book' = 'f02d' 'book-dead' = 'f6b7' 'book-medical' = 'f7e6' 'book-open' = 'f518' 'book-reader' = 'f5da' 'bookmark' = 'f02e' 'border-all' = 'f84c' 'border-none' = 'f850' 'border-style' = 'f853' 'bowling-ball' = 'f436' 'box' = 'f466' 'box-open' = 'f49e' 'box-tissue' = 'e05b' 'boxes' = 'f468' 'braille' = 'f2a1' 'brain' = 'f5dc' 'bread-slice' = 'f7ec' 'briefcase' = 'f0b1' 'briefcase-medical' = 'f469' 'broadcast-tower' = 'f519' 'broom' = 'f51a' 'brush' = 'f55d' 'bug' = 'f188' 'building' = 'f1ad' 'bullhorn' = 'f0a1' 'bullseye' = 'f140' 'burn' = 'f46a' 'bus' = 'f207' 'bus-alt' = 'f55e' 'business-time' = 'f64a' 'calculator' = 'f1ec' 'calendar' = 'f133' 'calendar-alt' = 'f073' 'calendar-check' = 'f274' 'calendar-day' = 'f783' 'calendar-minus' = 'f272' 'calendar-plus' = 'f271' 'calendar-times' = 'f273' 'calendar-week' = 'f784' 'camera' = 'f030' 'camera-retro' = 'f083' 'campground' = 'f6bb' 'candy-cane' = 'f786' 'cannabis' = 'f55f' 'capsules' = 'f46b' 'car' = 'f1b9' 'car-alt' = 'f5de' 'car-battery' = 'f5df' 'car-crash' = 'f5e1' 'car-side' = 'f5e4' 'caravan' = 'f8ff' 'caret-down' = 'f0d7' 'caret-left' = 'f0d9' 'caret-right' = 'f0da' 'caret-square-down' = 'f150' 'caret-square-left' = 'f191' 'caret-square-right' = 'f152' 'caret-square-up' = 'f151' 'caret-up' = 'f0d8' 'carrot' = 'f787' 'cart-arrow-down' = 'f218' 'cart-plus' = 'f217' 'cash-register' = 'f788' 'cat' = 'f6be' 'certificate' = 'f0a3' 'chair' = 'f6c0' 'chalkboard' = 'f51b' 'chalkboard-teacher' = 'f51c' 'charging-station' = 'f5e7' 'chart-area' = 'f1fe' 'chart-bar' = 'f080' 'chart-line' = 'f201' 'chart-pie' = 'f200' 'check' = 'f00c' 'check-circle' = 'f058' 'check-double' = 'f560' 'check-square' = 'f14a' 'cheese' = 'f7ef' 'chess' = 'f439' 'chess-bishop' = 'f43a' 'chess-board' = 'f43c' 'chess-king' = 'f43f' 'chess-knight' = 'f441' 'chess-pawn' = 'f443' 'chess-queen' = 'f445' 'chess-rook' = 'f447' 'chevron-circle-down' = 'f13a' 'chevron-circle-left' = 'f137' 'chevron-circle-right' = 'f138' 'chevron-circle-up' = 'f139' 'chevron-down' = 'f078' 'chevron-left' = 'f053' 'chevron-right' = 'f054' 'chevron-up' = 'f077' 'child' = 'f1ae' 'church' = 'f51d' 'circle' = 'f111' 'circle-notch' = 'f1ce' 'city' = 'f64f' 'clinic-medical' = 'f7f2' 'clipboard' = 'f328' 'clipboard-check' = 'f46c' 'clipboard-list' = 'f46d' 'clock' = 'f017' 'clone' = 'f24d' 'closed-captioning' = 'f20a' 'cloud' = 'f0c2' 'cloud-download-alt' = 'f381' 'cloud-meatball' = 'f73b' 'cloud-moon' = 'f6c3' 'cloud-moon-rain' = 'f73c' 'cloud-rain' = 'f73d' 'cloud-showers-heavy' = 'f740' 'cloud-sun' = 'f6c4' 'cloud-sun-rain' = 'f743' 'cloud-upload-alt' = 'f382' 'cocktail' = 'f561' 'code' = 'f121' 'code-branch' = 'f126' 'coffee' = 'f0f4' 'cog' = 'f013' 'cogs' = 'f085' 'coins' = 'f51e' 'columns' = 'f0db' 'comment' = 'f075' 'comment-alt' = 'f27a' 'comment-dollar' = 'f651' 'comment-dots' = 'f4ad' 'comment-medical' = 'f7f5' 'comment-slash' = 'f4b3' 'comments' = 'f086' 'comments-dollar' = 'f653' 'compact-disc' = 'f51f' 'compass' = 'f14e' 'compress' = 'f066' 'compress-alt' = 'f422' 'compress-arrows-alt' = 'f78c' 'concierge-bell' = 'f562' 'cookie' = 'f563' 'cookie-bite' = 'f564' 'copy' = 'f0c5' 'copyright' = 'f1f9' 'couch' = 'f4b8' 'credit-card' = 'f09d' 'crop' = 'f125' 'crop-alt' = 'f565' 'cross' = 'f654' 'crosshairs' = 'f05b' 'crow' = 'f520' 'crown' = 'f521' 'crutch' = 'f7f7' 'cube' = 'f1b2' 'cubes' = 'f1b3' 'cut' = 'f0c4' 'database' = 'f1c0' 'deaf' = 'f2a4' 'democrat' = 'f747' 'desktop' = 'f108' 'dharmachakra' = 'f655' 'diagnoses' = 'f470' 'dice' = 'f522' 'dice-d20' = 'f6cf' 'dice-d6' = 'f6d1' 'dice-five' = 'f523' 'dice-four' = 'f524' 'dice-one' = 'f525' 'dice-six' = 'f526' 'dice-three' = 'f527' 'dice-two' = 'f528' 'digital-tachograph' = 'f566' 'directions' = 'f5eb' 'disease' = 'f7fa' 'divide' = 'f529' 'dizzy' = 'f567' 'dna' = 'f471' 'dog' = 'f6d3' 'dollar-sign' = 'f155' 'dolly' = 'f472' 'dolly-flatbed' = 'f474' 'donate' = 'f4b9' 'door-closed' = 'f52a' 'door-open' = 'f52b' 'dot-circle' = 'f192' 'dove' = 'f4ba' 'download' = 'f019' 'drafting-compass' = 'f568' 'dragon' = 'f6d5' 'draw-polygon' = 'f5ee' 'drum' = 'f569' 'drum-steelpan' = 'f56a' 'drumstick-bite' = 'f6d7' 'dumbbell' = 'f44b' 'dumpster' = 'f793' 'dumpster-fire' = 'f794' 'dungeon' = 'f6d9' 'edit' = 'f044' 'egg' = 'f7fb' 'eject' = 'f052' 'ellipsis-h' = 'f141' 'ellipsis-v' = 'f142' 'envelope' = 'f0e0' 'envelope-open' = 'f2b6' 'envelope-open-text' = 'f658' 'envelope-square' = 'f199' 'equals' = 'f52c' 'eraser' = 'f12d' 'ethernet' = 'f796' 'euro-sign' = 'f153' 'exchange-alt' = 'f362' 'exclamation' = 'f12a' 'exclamation-circle' = 'f06a' 'exclamation-triangle' = 'f071' 'expand' = 'f065' 'expand-alt' = 'f424' 'expand-arrows-alt' = 'f31e' 'external-link-alt' = 'f35d' 'external-link-square-alt' = 'f360' 'eye' = 'f06e' 'eye-dropper' = 'f1fb' 'eye-slash' = 'f070' 'fan' = 'f863' 'fast-backward' = 'f049' 'fast-forward' = 'f050' 'faucet' = 'e005' 'fax' = 'f1ac' 'feather' = 'f52d' 'feather-alt' = 'f56b' 'female' = 'f182' 'fighter-jet' = 'f0fb' 'file' = 'f15b' 'file-alt' = 'f15c' 'file-archive' = 'f1c6' 'file-audio' = 'f1c7' 'file-code' = 'f1c9' 'file-contract' = 'f56c' 'file-csv' = 'f6dd' 'file-download' = 'f56d' 'file-excel' = 'f1c3' 'file-export' = 'f56e' 'file-image' = 'f1c5' 'file-import' = 'f56f' 'file-invoice' = 'f570' 'file-invoice-dollar' = 'f571' 'file-medical' = 'f477' 'file-medical-alt' = 'f478' 'file-pdf' = 'f1c1' 'file-powerpoint' = 'f1c4' 'file-prescription' = 'f572' 'file-signature' = 'f573' 'file-upload' = 'f574' 'file-video' = 'f1c8' 'file-word' = 'f1c2' 'fill' = 'f575' 'fill-drip' = 'f576' 'film' = 'f008' 'filter' = 'f0b0' 'fingerprint' = 'f577' 'fire' = 'f06d' 'fire-alt' = 'f7e4' 'fire-extinguisher' = 'f134' 'first-aid' = 'f479' 'fish' = 'f578' 'fist-raised' = 'f6de' 'flag' = 'f024' 'flag-checkered' = 'f11e' 'flag-usa' = 'f74d' 'flask' = 'f0c3' 'flushed' = 'f579' 'folder' = 'f07b' 'folder-minus' = 'f65d' 'folder-open' = 'f07c' 'folder-plus' = 'f65e' 'font' = 'f031' 'football-ball' = 'f44e' 'forward' = 'f04e' 'frog' = 'f52e' 'frown' = 'f119' 'frown-open' = 'f57a' 'funnel-dollar' = 'f662' 'futbol' = 'f1e3' 'gamepad' = 'f11b' 'gas-pump' = 'f52f' 'gavel' = 'f0e3' 'gem' = 'f3a5' 'genderless' = 'f22d' 'ghost' = 'f6e2' 'gift' = 'f06b' 'gifts' = 'f79c' 'glass-cheers' = 'f79f' 'glass-martini' = 'f000' 'glass-martini-alt' = 'f57b' 'glass-whiskey' = 'f7a0' 'glasses' = 'f530' 'globe' = 'f0ac' 'globe-africa' = 'f57c' 'globe-americas' = 'f57d' 'globe-asia' = 'f57e' 'globe-europe' = 'f7a2' 'golf-ball' = 'f450' 'gopuram' = 'f664' 'graduation-cap' = 'f19d' 'greater-than' = 'f531' 'greater-than-equal' = 'f532' 'grimace' = 'f57f' 'grin' = 'f580' 'grin-alt' = 'f581' 'grin-beam' = 'f582' 'grin-beam-sweat' = 'f583' 'grin-hearts' = 'f584' 'grin-squint' = 'f585' 'grin-squint-tears' = 'f586' 'grin-stars' = 'f587' 'grin-tears' = 'f588' 'grin-tongue' = 'f589' 'grin-tongue-squint' = 'f58a' 'grin-tongue-wink' = 'f58b' 'grin-wink' = 'f58c' 'grip-horizontal' = 'f58d' 'grip-lines' = 'f7a4' 'grip-lines-vertical' = 'f7a5' 'grip-vertical' = 'f58e' 'guitar' = 'f7a6' 'h-square' = 'f0fd' 'hamburger' = 'f805' 'hammer' = 'f6e3' 'hamsa' = 'f665' 'hand-holding' = 'f4bd' 'hand-holding-heart' = 'f4be' 'hand-holding-medical' = 'e05c' 'hand-holding-usd' = 'f4c0' 'hand-holding-water' = 'f4c1' 'hand-lizard' = 'f258' 'hand-middle-finger' = 'f806' 'hand-paper' = 'f256' 'hand-peace' = 'f25b' 'hand-point-down' = 'f0a7' 'hand-point-left' = 'f0a5' 'hand-point-right' = 'f0a4' 'hand-point-up' = 'f0a6' 'hand-pointer' = 'f25a' 'hand-rock' = 'f255' 'hand-scissors' = 'f257' 'hand-sparkles' = 'e05d' 'hand-spock' = 'f259' 'hands' = 'f4c2' 'hands-helping' = 'f4c4' 'hands-wash' = 'e05e' 'handshake' = 'f2b5' 'handshake-alt-slash' = 'e05f' 'handshake-slash' = 'e060' 'hanukiah' = 'f6e6' 'hard-hat' = 'f807' 'hashtag' = 'f292' 'hat-cowboy' = 'f8c0' 'hat-cowboy-side' = 'f8c1' 'hat-wizard' = 'f6e8' 'hdd' = 'f0a0' 'head-side-cough' = 'e061' 'head-side-cough-slash' = 'e062' 'head-side-mask' = 'e063' 'head-side-virus' = 'e064' 'heading' = 'f1dc' 'headphones' = 'f025' 'headphones-alt' = 'f58f' 'headset' = 'f590' 'heart' = 'f004' 'heart-broken' = 'f7a9' 'heartbeat' = 'f21e' 'helicopter' = 'f533' 'highlighter' = 'f591' 'hiking' = 'f6ec' 'hippo' = 'f6ed' 'history' = 'f1da' 'hockey-puck' = 'f453' 'holly-berry' = 'f7aa' 'home' = 'f015' 'horse' = 'f6f0' 'horse-head' = 'f7ab' 'hospital' = 'f0f8' 'hospital-alt' = 'f47d' 'hospital-symbol' = 'f47e' 'hospital-user' = 'f80d' 'hot-tub' = 'f593' 'hotdog' = 'f80f' 'hotel' = 'f594' 'hourglass' = 'f254' 'hourglass-end' = 'f253' 'hourglass-half' = 'f252' 'hourglass-start' = 'f251' 'house-damage' = 'f6f1' 'house-user' = 'e065' 'hryvnia' = 'f6f2' 'i-cursor' = 'f246' 'ice-cream' = 'f810' 'icicles' = 'f7ad' 'icons' = 'f86d' 'id-badge' = 'f2c1' 'id-card' = 'f2c2' 'id-card-alt' = 'f47f' 'igloo' = 'f7ae' 'image' = 'f03e' 'images' = 'f302' 'inbox' = 'f01c' 'indent' = 'f03c' 'industry' = 'f275' 'infinity' = 'f534' 'info' = 'f129' 'info-circle' = 'f05a' 'italic' = 'f033' 'jedi' = 'f669' 'joint' = 'f595' 'journal-whills' = 'f66a' 'kaaba' = 'f66b' 'key' = 'f084' 'keyboard' = 'f11c' 'khanda' = 'f66d' 'kiss' = 'f596' 'kiss-beam' = 'f597' 'kiss-wink-heart' = 'f598' 'kiwi-bird' = 'f535' 'landmark' = 'f66f' 'language' = 'f1ab' 'laptop' = 'f109' 'laptop-code' = 'f5fc' 'laptop-house' = 'e066' 'laptop-medical' = 'f812' 'laugh' = 'f599' 'laugh-beam' = 'f59a' 'laugh-squint' = 'f59b' 'laugh-wink' = 'f59c' 'layer-group' = 'f5fd' 'leaf' = 'f06c' 'lemon' = 'f094' 'less-than' = 'f536' 'less-than-equal' = 'f537' 'level-down-alt' = 'f3be' 'level-up-alt' = 'f3bf' 'life-ring' = 'f1cd' 'lightbulb' = 'f0eb' 'link' = 'f0c1' 'lira-sign' = 'f195' 'list' = 'f03a' 'list-alt' = 'f022' 'list-ol' = 'f0cb' 'list-ul' = 'f0ca' 'location-arrow' = 'f124' 'lock' = 'f023' 'lock-open' = 'f3c1' 'long-arrow-alt-down' = 'f309' 'long-arrow-alt-left' = 'f30a' 'long-arrow-alt-right' = 'f30b' 'long-arrow-alt-up' = 'f30c' 'low-vision' = 'f2a8' 'luggage-cart' = 'f59d' 'lungs' = 'f604' 'lungs-virus' = 'e067' 'magic' = 'f0d0' 'magnet' = 'f076' 'mail-bulk' = 'f674' 'male' = 'f183' 'map' = 'f279' 'map-marked' = 'f59f' 'map-marked-alt' = 'f5a0' 'map-marker' = 'f041' 'map-marker-alt' = 'f3c5' 'map-pin' = 'f276' 'map-signs' = 'f277' 'marker' = 'f5a1' 'mars' = 'f222' 'mars-double' = 'f227' 'mars-stroke' = 'f229' 'mars-stroke-h' = 'f22b' 'mars-stroke-v' = 'f22a' 'mask' = 'f6fa' 'medal' = 'f5a2' 'medkit' = 'f0fa' 'meh' = 'f11a' 'meh-blank' = 'f5a4' 'meh-rolling-eyes' = 'f5a5' 'memory' = 'f538' 'menorah' = 'f676' 'mercury' = 'f223' 'meteor' = 'f753' 'microchip' = 'f2db' 'microphone' = 'f130' 'microphone-alt' = 'f3c9' 'microphone-alt-slash' = 'f539' 'microphone-slash' = 'f131' 'microscope' = 'f610' 'minus' = 'f068' 'minus-circle' = 'f056' 'minus-square' = 'f146' 'mitten' = 'f7b5' 'mobile' = 'f10b' 'mobile-alt' = 'f3cd' 'money-bill' = 'f0d6' 'money-bill-alt' = 'f3d1' 'money-bill-wave' = 'f53a' 'money-bill-wave-alt' = 'f53b' 'money-check' = 'f53c' 'money-check-alt' = 'f53d' 'monument' = 'f5a6' 'moon' = 'f186' 'mortar-pestle' = 'f5a7' 'mosque' = 'f678' 'motorcycle' = 'f21c' 'mountain' = 'f6fc' 'mouse' = 'f8cc' 'mouse-pointer' = 'f245' 'mug-hot' = 'f7b6' 'music' = 'f001' 'network-wired' = 'f6ff' 'neuter' = 'f22c' 'newspaper' = 'f1ea' 'not-equal' = 'f53e' 'notes-medical' = 'f481' 'object-group' = 'f247' 'object-ungroup' = 'f248' 'oil-can' = 'f613' 'om' = 'f679' 'otter' = 'f700' 'outdent' = 'f03b' 'pager' = 'f815' 'paint-brush' = 'f1fc' 'paint-roller' = 'f5aa' 'palette' = 'f53f' 'pallet' = 'f482' 'paper-plane' = 'f1d8' 'paperclip' = 'f0c6' 'parachute-box' = 'f4cd' 'paragraph' = 'f1dd' 'parking' = 'f540' 'passport' = 'f5ab' 'pastafarianism' = 'f67b' 'paste' = 'f0ea' 'pause' = 'f04c' 'pause-circle' = 'f28b' 'paw' = 'f1b0' 'peace' = 'f67c' 'pen' = 'f304' 'pen-alt' = 'f305' 'pen-fancy' = 'f5ac' 'pen-nib' = 'f5ad' 'pen-square' = 'f14b' 'pencil-alt' = 'f303' 'pencil-ruler' = 'f5ae' 'people-arrows' = 'e068' 'people-carry' = 'f4ce' 'pepper-hot' = 'f816' 'percent' = 'f295' 'percentage' = 'f541' 'person-booth' = 'f756' 'phone' = 'f095' 'phone-alt' = 'f879' 'phone-slash' = 'f3dd' 'phone-square' = 'f098' 'phone-square-alt' = 'f87b' 'phone-volume' = 'f2a0' 'photo-video' = 'f87c' 'piggy-bank' = 'f4d3' 'pills' = 'f484' 'pizza-slice' = 'f818' 'place-of-worship' = 'f67f' 'plane' = 'f072' 'plane-arrival' = 'f5af' 'plane-departure' = 'f5b0' 'plane-slash' = 'e069' 'play' = 'f04b' 'play-circle' = 'f144' 'plug' = 'f1e6' 'plus' = 'f067' 'plus-circle' = 'f055' 'plus-square' = 'f0fe' 'podcast' = 'f2ce' 'poll' = 'f681' 'poll-h' = 'f682' 'poo' = 'f2fe' 'poo-storm' = 'f75a' 'poop' = 'f619' 'portrait' = 'f3e0' 'pound-sign' = 'f154' 'power-off' = 'f011' 'pray' = 'f683' 'praying-hands' = 'f684' 'prescription' = 'f5b1' 'prescription-bottle' = 'f485' 'prescription-bottle-alt' = 'f486' 'print' = 'f02f' 'procedures' = 'f487' 'project-diagram' = 'f542' 'pump-medical' = 'e06a' 'pump-soap' = 'e06b' 'puzzle-piece' = 'f12e' 'qrcode' = 'f029' 'question' = 'f128' 'question-circle' = 'f059' 'quidditch' = 'f458' 'quote-left' = 'f10d' 'quote-right' = 'f10e' 'quran' = 'f687' 'radiation' = 'f7b9' 'radiation-alt' = 'f7ba' 'rainbow' = 'f75b' 'random' = 'f074' 'receipt' = 'f543' 'record-vinyl' = 'f8d9' 'recycle' = 'f1b8' 'redo' = 'f01e' 'redo-alt' = 'f2f9' 'registered' = 'f25d' 'remove-format' = 'f87d' 'reply' = 'f3e5' 'reply-all' = 'f122' 'republican' = 'f75e' 'restroom' = 'f7bd' 'retweet' = 'f079' 'ribbon' = 'f4d6' 'ring' = 'f70b' 'road' = 'f018' 'robot' = 'f544' 'rocket' = 'f135' 'route' = 'f4d7' 'rss' = 'f09e' 'rss-square' = 'f143' 'ruble-sign' = 'f158' 'ruler' = 'f545' 'ruler-combined' = 'f546' 'ruler-horizontal' = 'f547' 'ruler-vertical' = 'f548' 'running' = 'f70c' 'rupee-sign' = 'f156' 'sad-cry' = 'f5b3' 'sad-tear' = 'f5b4' 'satellite' = 'f7bf' 'satellite-dish' = 'f7c0' 'save' = 'f0c7' 'school' = 'f549' 'screwdriver' = 'f54a' 'scroll' = 'f70e' 'sd-card' = 'f7c2' 'search' = 'f002' 'search-dollar' = 'f688' 'search-location' = 'f689' 'search-minus' = 'f010' 'search-plus' = 'f00e' 'seedling' = 'f4d8' 'server' = 'f233' 'shapes' = 'f61f' 'share' = 'f064' 'share-alt' = 'f1e0' 'share-alt-square' = 'f1e1' 'share-square' = 'f14d' 'shekel-sign' = 'f20b' 'shield-alt' = 'f3ed' 'shield-virus' = 'e06c' 'ship' = 'f21a' 'shipping-fast' = 'f48b' 'shoe-prints' = 'f54b' 'shopping-bag' = 'f290' 'shopping-basket' = 'f291' 'shopping-cart' = 'f07a' 'shower' = 'f2cc' 'shuttle-van' = 'f5b6' 'sign' = 'f4d9' 'sign-in-alt' = 'f2f6' 'sign-language' = 'f2a7' 'sign-out-alt' = 'f2f5' 'signal' = 'f012' 'signature' = 'f5b7' 'sim-card' = 'f7c4' 'sink' = 'e06d' 'sitemap' = 'f0e8' 'skating' = 'f7c5' 'skiing' = 'f7c9' 'skiing-nordic' = 'f7ca' 'skull' = 'f54c' 'skull-crossbones' = 'f714' 'slash' = 'f715' 'sleigh' = 'f7cc' 'sliders-h' = 'f1de' 'smile' = 'f118' 'smile-beam' = 'f5b8' 'smile-wink' = 'f4da' 'smog' = 'f75f' 'smoking' = 'f48d' 'smoking-ban' = 'f54d' 'sms' = 'f7cd' 'snowboarding' = 'f7ce' 'snowflake' = 'f2dc' 'snowman' = 'f7d0' 'snowplow' = 'f7d2' 'soap' = 'e06e' 'socks' = 'f696' 'solar-panel' = 'f5ba' 'sort' = 'f0dc' 'sort-alpha-down' = 'f15d' 'sort-alpha-down-alt' = 'f881' 'sort-alpha-up' = 'f15e' 'sort-alpha-up-alt' = 'f882' 'sort-amount-down' = 'f160' 'sort-amount-down-alt' = 'f884' 'sort-amount-up' = 'f161' 'sort-amount-up-alt' = 'f885' 'sort-down' = 'f0dd' 'sort-numeric-down' = 'f162' 'sort-numeric-down-alt' = 'f886' 'sort-numeric-up' = 'f163' 'sort-numeric-up-alt' = 'f887' 'sort-up' = 'f0de' 'spa' = 'f5bb' 'space-shuttle' = 'f197' 'spell-check' = 'f891' 'spider' = 'f717' 'spinner' = 'f110' 'splotch' = 'f5bc' 'spray-can' = 'f5bd' 'square' = 'f0c8' 'square-full' = 'f45c' 'square-root-alt' = 'f698' 'stamp' = 'f5bf' 'star' = 'f005' 'star-and-crescent' = 'f699' 'star-half' = 'f089' 'star-half-alt' = 'f5c0' 'star-of-david' = 'f69a' 'star-of-life' = 'f621' 'step-backward' = 'f048' 'step-forward' = 'f051' 'stethoscope' = 'f0f1' 'sticky-note' = 'f249' 'stop' = 'f04d' 'stop-circle' = 'f28d' 'stopwatch' = 'f2f2' 'stopwatch-20' = 'e06f' 'store' = 'f54e' 'store-alt' = 'f54f' 'store-alt-slash' = 'e070' 'store-slash' = 'e071' 'stream' = 'f550' 'street-view' = 'f21d' 'strikethrough' = 'f0cc' 'stroopwafel' = 'f551' 'subscript' = 'f12c' 'subway' = 'f239' 'suitcase' = 'f0f2' 'suitcase-rolling' = 'f5c1' 'sun' = 'f185' 'superscript' = 'f12b' 'surprise' = 'f5c2' 'swatchbook' = 'f5c3' 'swimmer' = 'f5c4' 'swimming-pool' = 'f5c5' 'synagogue' = 'f69b' 'sync' = 'f021' 'sync-alt' = 'f2f1' 'syringe' = 'f48e' 'table' = 'f0ce' 'table-tennis' = 'f45d' 'tablet' = 'f10a' 'tablet-alt' = 'f3fa' 'tablets' = 'f490' 'tachometer-alt' = 'f3fd' 'tag' = 'f02b' 'tags' = 'f02c' 'tape' = 'f4db' 'tasks' = 'f0ae' 'taxi' = 'f1ba' 'teeth' = 'f62e' 'teeth-open' = 'f62f' 'temperature-high' = 'f769' 'temperature-low' = 'f76b' 'tenge' = 'f7d7' 'terminal' = 'f120' 'text-height' = 'f034' 'text-width' = 'f035' 'th' = 'f00a' 'th-large' = 'f009' 'th-list' = 'f00b' 'theater-masks' = 'f630' 'thermometer' = 'f491' 'thermometer-empty' = 'f2cb' 'thermometer-full' = 'f2c7' 'thermometer-half' = 'f2c9' 'thermometer-quarter' = 'f2ca' 'thermometer-three-quarters' = 'f2c8' 'thumbs-down' = 'f165' 'thumbs-up' = 'f164' 'thumbtack' = 'f08d' 'ticket-alt' = 'f3ff' 'times' = 'f00d' 'times-circle' = 'f057' 'tint' = 'f043' 'tint-slash' = 'f5c7' 'tired' = 'f5c8' 'toggle-off' = 'f204' 'toggle-on' = 'f205' 'toilet' = 'f7d8' 'toilet-paper' = 'f71e' 'toilet-paper-slash' = 'e072' 'toolbox' = 'f552' 'tools' = 'f7d9' 'tooth' = 'f5c9' 'torah' = 'f6a0' 'torii-gate' = 'f6a1' 'tractor' = 'f722' 'trademark' = 'f25c' 'traffic-light' = 'f637' 'trailer' = 'e041' 'train' = 'f238' 'tram' = 'f7da' 'transgender' = 'f224' 'transgender-alt' = 'f225' 'trash' = 'f1f8' 'trash-alt' = 'f2ed' 'trash-restore' = 'f829' 'trash-restore-alt' = 'f82a' 'tree' = 'f1bb' 'trophy' = 'f091' 'truck' = 'f0d1' 'truck-loading' = 'f4de' 'truck-monster' = 'f63b' 'truck-moving' = 'f4df' 'truck-pickup' = 'f63c' 'tshirt' = 'f553' 'tty' = 'f1e4' 'tv' = 'f26c' 'umbrella' = 'f0e9' 'umbrella-beach' = 'f5ca' 'underline' = 'f0cd' 'undo' = 'f0e2' 'undo-alt' = 'f2ea' 'universal-access' = 'f29a' 'university' = 'f19c' 'unlink' = 'f127' 'unlock' = 'f09c' 'unlock-alt' = 'f13e' 'upload' = 'f093' 'user' = 'f007' 'user-alt' = 'f406' 'user-alt-slash' = 'f4fa' 'user-astronaut' = 'f4fb' 'user-check' = 'f4fc' 'user-circle' = 'f2bd' 'user-clock' = 'f4fd' 'user-cog' = 'f4fe' 'user-edit' = 'f4ff' 'user-friends' = 'f500' 'user-graduate' = 'f501' 'user-injured' = 'f728' 'user-lock' = 'f502' 'user-md' = 'f0f0' 'user-minus' = 'f503' 'user-ninja' = 'f504' 'user-nurse' = 'f82f' 'user-plus' = 'f234' 'user-secret' = 'f21b' 'user-shield' = 'f505' 'user-slash' = 'f506' 'user-tag' = 'f507' 'user-tie' = 'f508' 'user-times' = 'f235' 'users' = 'f0c0' 'users-cog' = 'f509' 'users-slash' = 'e073' 'utensil-spoon' = 'f2e5' 'utensils' = 'f2e7' 'vector-square' = 'f5cb' 'venus' = 'f221' 'venus-double' = 'f226' 'venus-mars' = 'f228' 'vest' = 'e085' 'vest-patches' = 'e086' 'vial' = 'f492' 'vials' = 'f493' 'video' = 'f03d' 'video-slash' = 'f4e2' 'vihara' = 'f6a7' 'virus' = 'e074' 'virus-slash' = 'e075' 'viruses' = 'e076' 'voicemail' = 'f897' 'volleyball-ball' = 'f45f' 'volume-down' = 'f027' 'volume-mute' = 'f6a9' 'volume-off' = 'f026' 'volume-up' = 'f028' 'vote-yea' = 'f772' 'vr-cardboard' = 'f729' 'walking' = 'f554' 'wallet' = 'f555' 'warehouse' = 'f494' 'water' = 'f773' 'wave-square' = 'f83e' 'weight' = 'f496' 'weight-hanging' = 'f5cd' 'wheelchair' = 'f193' 'wifi' = 'f1eb' 'wind' = 'f72e' 'window-close' = 'f410' 'window-maximize' = 'f2d0' 'window-minimize' = 'f2d1' 'window-restore' = 'f2d2' 'wine-bottle' = 'f72f' 'wine-glass' = 'f4e3' 'wine-glass-alt' = 'f5ce' 'won-sign' = 'f159' 'wrench' = 'f0ad' 'x-ray' = 'f497' 'yen-sign' = 'f157' 'yin-yang' = 'f6ad' } FontsMaterialIcon = @( '3d-rotation' '500px' '8tracks' 'account' 'account-add' 'account-box' 'account-box-mail' 'account-box-o' 'account-box-phone' 'account-calendar' 'account-circle' 'account-o' 'accounts' 'accounts-add' 'accounts-alt' 'accounts-list' 'accounts-list-alt' 'accounts-outline' 'airline-seat-flat' 'airline-seat-flat-angled' 'airline-seat-individual-suite' 'airline-seat-legroom-extra' 'airline-seat-legroom-normal' 'airline-seat-legroom-reduced' 'airline-seat-recline-extra' 'airline-seat-recline-normal' 'airplane' 'airplane-off' 'airplay' 'alarm' 'alarm-check' 'alarm-off' 'alarm-plus' 'alarm-snooze' 'album' 'alert-circle' 'alert-circle-o' 'alert-octagon' 'alert-polygon' 'alert-triangle' 'amazon' 'android' 'android-alt' 'apple' 'apps' 'archive' 'arrow-left' 'arrow-left-bottom' 'arrow-merge' 'arrow-missed' 'arrow-right' 'arrow-right-top' 'arrows' 'arrow-split' 'aspect-ratio' 'aspect-ratio-alt' 'assignment' 'assignment-account' 'assignment-alert' 'assignment-check' 'assignment-o' 'assignment-return' 'assignment-returned' 'attachment' 'attachment-alt' 'audio' 'badge-check' 'balance' 'balance-wallet' 'battery' 'battery-alert' 'battery-flash' 'battery-unknown' 'behance' 'bike' 'block' 'block-alt' 'blogger' 'bluetooth' 'bluetooth-connected' 'bluetooth-off' 'bluetooth-search' 'bluetooth-setting' 'blur' 'blur-circular' 'blur-linear' 'blur-off' 'boat' 'book' 'book-image' 'bookmark' 'bookmark-outline' 'border-all' 'border-bottom' 'border-clear' 'border-color' 'border-horizontal' 'border-inner' 'border-left' 'border-outer' 'border-right' 'border-style' 'border-top' 'border-vertical' 'brightness-2' 'brightness-3' 'brightness-4' 'brightness-5' 'brightness-6' 'brightness-7' 'brightness-auto' 'brightness-setting' 'broken-image' 'brush' 'bug' 'bus' 'cake' 'calendar' 'calendar-alt' 'calendar-check' 'calendar-close' 'calendar-note' 'camera' 'camera-add' 'camera-alt' 'camera-bw' 'camera-front' 'camera-mic' 'camera-party-mode' 'camera-rear' 'camera-roll' 'camera-switch' 'car' 'card' 'card-alert' 'card-giftcard' 'card-membership' 'card-off' 'card-sd' 'card-sim' 'card-travel' 'caret-down' 'caret-down-circle' 'caret-left' 'caret-left-circle' 'caret-right' 'caret-right-circle' 'caret-up' 'caret-up-circle' 'car-taxi' 'car-wash' 'case' 'case-check' 'case-download' 'case-play' 'cast' 'cast-connected' 'center-focus-strong' 'center-focus-weak' 'chart' 'chart-donut' 'check' 'check-all' 'check-circle' 'check-circle-u' 'check-square' 'chevron-down' 'chevron-left' 'chevron-right' 'chevron-up' 'circle' 'circle-o' 'city' 'city-alt' 'close' 'close-circle' 'close-circle-o' 'closed-caption' 'cloud' 'cloud-box' 'cloud-circle' 'cloud-done' 'cloud-download' 'cloud-off' 'cloud-outline' 'cloud-outline-alt' 'cloud-upload' 'cocktail' 'code' 'codepen' 'code-setting' 'code-smartphone' 'coffee' 'collection-bookmark' 'collection-case-play' 'collection-folder-image' 'collection-image' 'collection-image-o' 'collection-item' 'collection-item-1' 'collection-item-2' 'collection-item-3' 'collection-item-4' 'collection-item-5' 'collection-item-6' 'collection-item-7' 'collection-item-8' 'collection-item-9' 'collection-item-9-plus' 'collection-music' 'collection-pdf' 'collection-plus' 'collection-speaker' 'collection-text' 'collection-video' 'comment' 'comment-alert' 'comment-alt' 'comment-alt-text' 'comment-edit' 'comment-image' 'comment-list' 'comment-more' 'comment-outline' 'comments' 'comment-text' 'comment-text-alt' 'comment-video' 'compare' 'compass' 'confirmation-number' 'copy' 'crop' 'crop-16-9' 'crop-3-2' 'crop-5-4' 'crop-7-5' 'crop-din' 'crop-free' 'crop-landscape' 'crop-portrait' 'crop-square' 'cutlery' 'delete' 'delicious' 'desktop-mac' 'desktop-windows' 'developer-board' 'device-hub' 'devices' 'devices-off' 'dialpad' 'disc-full' 'disqus' 'dns' 'dock' 'dot-circle' 'dot-circle-alt' 'download' 'dribbble' 'drink' 'dropbox' 'edit' 'eject' 'eject-alt' 'email' 'email-open' 'equalizer' 'evernote' 'explicit' 'exposure' 'exposure-alt' 'eye' 'eyedropper' 'eye-off' 'face' 'facebook' 'facebook-box' 'fast-forward' 'fast-rewind' 'favorite' 'favorite-outline' 'female' 'file' 'file-plus' 'file-text' 'filter-b-and-w' 'filter-center-focus' 'filter-frames' 'filter-list' 'filter-tilt-shift' 'fire' 'flag' 'flare' 'flash' 'flash-auto' 'flash-off' 'flattr' 'flickr' 'flight-land' 'flight-takeoff' 'flip' 'flip-to-back' 'flip-to-front' 'floppy' 'flower' 'flower-alt' 'folder' 'folder-outline' 'folder-person' 'folder-star' 'folder-star-alt' 'font' 'format-align-center' 'format-align-justify' 'format-align-left' 'format-align-right' 'format-bold' 'format-clear' 'format-clear-all' 'format-color-fill' 'format-color-reset' 'format-color-text' 'format-indent-decrease' 'format-indent-increase' 'format-italic' 'format-line-spacing' 'format-list-bulleted' 'format-list-numbered' 'format-ltr' 'format-rtl' 'format-size' 'format-strikethrough' 'format-strikethrough-s' 'format-subject' 'format-underlined' 'format-valign-bottom' 'format-valign-center' 'format-valign-top' 'forward' 'forward-10' 'forward-30' 'forward-5' 'fullscreen' 'fullscreen-alt' 'fullscreen-exit' 'functions' 'gamepad' 'gas-station' 'gesture' 'gif' 'github' 'github-alt' 'github-box' 'globe' 'globe-alt' 'globe-lock' 'google' 'google-drive' 'google-earth' 'google-glass' 'google-maps' 'google-old' 'google-pages' 'google-play' 'google-plus' 'google-plus-box' 'gps' 'gps-dot' 'gps-off' 'gradient' 'graduation-cap' 'grain' 'graphic-eq' 'grid' 'grid-off' 'group' 'group-work' 'hd' 'hdr' 'hdr-off' 'hdr-strong' 'hdr-weak' 'headset' 'headset-mic' 'hearing' 'help' 'help-outline' 'home' 'hospital' 'hospital-alt' 'hotel' 'hourglass' 'hourglass-alt' 'hourglass-outline' 'hq' 'http' 'image' 'image-alt' 'image-o' 'inbox' 'info' 'info-outline' 'input-antenna' 'input-composite' 'input-hdmi' 'input-power' 'input-svideo' 'instagram' 'invert-colors' 'invert-colors-off' 'iridescent' 'key' 'keyboard' 'keyboard-hide' 'label' 'label-alt' 'label-alt-outline' 'label-heart' 'labels' 'lamp' 'landscape' 'language-css3' 'language-html5' 'language-javascript' 'language-python' 'language-python-alt' 'laptop' 'laptop-chromebook' 'laptop-mac' 'lastfm' 'layers' 'layers-off' 'leak' 'leak-off' 'library' 'link' 'linkedin' 'linkedin-box' 'lock' 'lock-open' 'lock-outline' 'long-arrow-down' 'long-arrow-left' 'long-arrow-return' 'long-arrow-right' 'long-arrow-tab' 'long-arrow-up' 'looks' 'loupe' 'mail-reply' 'mail-reply-all' 'mail-send' 'male' 'male-alt' 'male-female' 'mall' 'map' 'markunread-mailbox' 'memory' 'menu' 'mic' 'mic-off' 'mic-outline' 'mic-setting' 'minus' 'minus-circle' 'minus-circle-outline' 'minus-square' 'money' 'money-box' 'money-off' 'mood' 'mood-bad' 'more' 'more-vert' 'mouse' 'movie' 'movie-alt' 'n-1-square' 'n-2-square' 'n-3-square' 'n-4-square' 'n-5-square' 'n-6-square' 'nature' 'nature-people' 'navigation' 'neg-1' 'neg-2' 'network' 'network-alert' 'network-locked' 'network-off' 'network-outline' 'network-setting' 'nfc' 'notifications' 'notifications-active' 'notifications-add' 'notifications-none' 'notifications-off' 'notifications-paused' 'odnoklassniki' 'open-in-browser' 'open-in-new' 'outlook' 'palette' 'panorama-horizontal' 'panorama-vertical' 'panorama-wide-angle' 'parking' 'pause' 'pause-circle' 'pause-circle-outline' 'paypal' 'paypal-alt' 'phone' 'phone-bluetooth' 'phone-end' 'phone-forwarded' 'phone-in-talk' 'phone-locked' 'phone-missed' 'phone-msg' 'phone-paused' 'phone-ring' 'phone-setting' 'phone-sip' 'photo-size-select-large' 'photo-size-select-small' 'picture-in-picture' 'pin' 'pin-account' 'pin-assistant' 'pin-drop' 'pin-help' 'pin-off' 'pinterest' 'pinterest-box' 'pizza' 'plaster' 'play' 'play-circle' 'play-circle-outline' 'play-for-work' 'playlist-audio' 'playlist-plus' 'playstation' 'plus' 'plus-1' 'plus-2' 'plus-circle' 'plus-circle-o' 'plus-circle-o-duplicate' 'plus-square' 'pocket' 'polymer' 'portable-wifi' 'portable-wifi-changes' 'portable-wifi-off' 'power' 'power-input' 'power-setting' 'present-to-all' 'print' 'puzzle-piece' 'quote' 'radio' 'railway' 'reader' 'receipt' 'reddit' 'redo' 'refresh' 'refresh-alt' 'refresh-sync' 'refresh-sync-alert' 'refresh-sync-off' 'remote-control' 'remote-control-alt' 'repeat' 'repeat-one' 'replay' 'replay-10' 'replay-30' 'replay-5' 'roller' 'rotate-ccw' 'rotate-cw' 'rotate-left' 'rotate-right' 'router' 'rss' 'ruler' 'run' 'satellite' 'scanner' 'scissors' 'screen-rotation' 'screen-rotation-lock' 'search' 'search-for' 'search-in-file' 'search-in-page' 'search-replace' 'seat' 'sec-10' 'sec-3' 'select-all' 'settings' 'settings-square' 'shape' 'share' 'shield-check' 'shield-security' 'shopping-basket' 'shopping-cart' 'shopping-cart-plus' 'shuffle' 'sign-in' 'skip-next' 'skip-previous' 'skype' 'slideshare' 'slideshow' 'smartphone' 'smartphone-android' 'smartphone-download' 'smartphone-erase' 'smartphone-info' 'smartphone-iphone' 'smartphone-landscape' 'smartphone-landscape-lock' 'smartphone-lock' 'smartphone-portrait-lock' 'smartphone-ring' 'smartphone-setting' 'smartphone-setup' 'sort-amount-asc' 'sort-amount-desc' 'sort-asc' 'sort-desc' 'soundcloud' 'space-bar' 'speaker' 'spellcheck' 'spinner' 'square-down' 'square-o' 'square-right' 'stackoverflow' 'star' 'star-circle' 'star-half' 'star-outline' 'steam' 'steam-square' 'stop' 'storage' 'store' 'store-24' 'subway' 'sun' 'surround-sound' 'swap' 'swap-alt' 'swap-vertical' 'swap-vertical-circle' 'tab' 'tablet' 'tablet-android' 'tablet-mac' 'tab-unselected' 'tag' 'tag-close' 'tag-more' 'tap-and-play' 'text-format' 'texture' 'thumb-down' 'thumb-up' 'thumb-up-down' 'ticket-star' 'time' 'time-countdown' 'time-interval' 'timer' 'time-restore' 'time-restore-setting' 'timer-off' 'toll' 'tonality' 'toys' 'traffic' 'transform' 'translate' 'trending-down' 'trending-flat' 'trending-up' 'triangle-down' 'triangle-up' 'truck' 'tumblr' 'tune' 'turning-sign' 'tv' 'tv-alt-play' 'tv-list' 'tv-play' 'twitch' 'twitter' 'twitter-box' 'undo' 'unfold-less' 'unfold-more' 'ungroup' 'upload' 'usb' 'vibration' 'videocam' 'videocam-off' 'videocam-switch' 'view-agenda' 'view-array' 'view-carousel' 'view-column' 'view-comfy' 'view-compact' 'view-dashboard' 'view-day' 'view-headline' 'view-list' 'view-list-alt' 'view-module' 'view-quilt' 'view-stream' 'view-subtitles' 'view-toc' 'view-web' 'view-week' 'vignette' 'vimeo' 'vk' 'voicemail' 'volume-down' 'volume-mute' 'volume-off' 'volume-up' 'walk' 'wallpaper' 'washing-machine' 'watch' 'wb-auto' 'whatsapp' 'widgets' 'wifi' 'wifi-alt' 'wifi-alt-2' 'wifi-info' 'wifi-lock' 'wifi-off' 'wifi-outline' 'wikipedia' 'window-maximize' 'window-minimize' 'window-restore' 'windows' 'wrap-text' 'wrench' 'xbox' 'yahoo' 'youtube' 'youtube-play' 'zero' 'zoom-in' 'zoom-out' ) FontsSimple = @( '1001tracklists' '1password' '3m' '42' '4d' '500px' 'a-frame' 'abbrobotstudio' 'abbvie' 'abletonlive' 'about-dot-me' 'abstract' 'academia' 'accenture' 'acclaim' 'accusoft' 'acer' 'acm' 'actigraph' 'activision' 'adafruit' 'adblock' 'adblockplus' 'addthis' 'adguard' 'adobe' 'adobeacrobatreader' 'adobeaftereffects' 'adobeaudition' 'adobecreativecloud' 'adobedreamweaver' 'adobefonts' 'adobeillustrator' 'adobeindesign' 'adobelightroom' 'adobelightroomclassic' 'adobephonegap' 'adobephotoshop' 'adobepremierepro' 'adobexd' 'adonisjs' 'aerlingus' 'aeroflot' 'aeromexico' 'aerospike' 'affinity' 'affinitydesigner' 'affinityphoto' 'affinitypublisher' 'aidungeon' 'aiohttp' 'aiqfome' 'airasia' 'airbnb' 'airbus' 'aircall' 'aircanada' 'airchina' 'airfrance' 'airplayaudio' 'airplayvideo' 'airtable' 'alacritty' 'alfaromeo' 'algolia' 'alibaba-dot-com' 'alibabacloud' 'aliexpress' 'alipay' 'alitalia' 'alliedmodders' 'allocine' 'alltrails' 'alpinedotjs' 'alpinelinux' 'altiumdesigner' 'amazon' 'amazonalexa' 'amazonaws' 'amazondynamodb' 'amazonfiretv' 'amazonlumberyard' 'amazonpay' 'amazonprime' 'amazons3' 'amd' 'americanairlines' 'americanexpress' 'amp' 'amul' 'ana' 'anaconda' 'analogue' 'anchor' 'andela' 'android' 'androidauto' 'androidstudio' 'angellist' 'angular' 'angularjs' 'angularuniversal' 'anilist' 'ansible' 'ansys' 'antdesign' 'antena3' 'anydesk' 'aol' 'apache' 'apacheairflow' 'apacheant' 'apachecassandra' 'apachecloudstack' 'apachecordova' 'apachedruid' 'apacheecharts' 'apacheflink' 'apachegroovy' 'apachehive' 'apachejmeter' 'apachekafka' 'apachekylin' 'apachemaven' 'apachenetbeanside' 'apacheopenoffice' 'apachepulsar' 'apacherocketmq' 'apachesolr' 'apachespark' 'apachetomcat' 'aparat' 'apollographql' 'apostrophe' 'apple' 'applearcade' 'applemusic' 'applepay' 'applepodcasts' 'appletv' 'appsignal' 'appstore' 'appveyor' 'aral' 'arangodb' 'archicad' 'archiveofourown' 'archlinux' 'ardour' 'arduino' 'arkecosystem' 'arlo' 'artixlinux' 'artstation' 'arxiv' 'asana' 'asciidoctor' 'asciinema' 'aseprite' 'askfm' 'askubuntu' 'assemblyscript' 'asus' 'at-and-t' 'atari' 'atlassian' 'atom' 'audacity' 'audi' 'audible' 'audio-technica' 'audioboom' 'audiomack' 'aurelia' 'auth0' 'authy' 'autodesk' 'autohotkey' 'automatic' 'automattic' 'autotask' 'aventrix' 'awesomelists' 'awesomewm' 'awsamplify' 'azureartifacts' 'azuredataexplorer' 'azuredevops' 'azurefunctions' 'azurepipelines' 'b-and-rautomation' 'babel' 'badgr' 'badoo' 'baidu' 'bamboo' 'bancontact' 'bandcamp' 'bandlab' 'bandsintown' 'bankofamerica' 'barclays' 'baremetrics' 'basecamp' 'bata' 'bathasu' 'battle-dot-net' 'bbc' 'bbciplayer' 'beatport' 'beats' 'beatsbydre' 'behance' 'beijingsubway' 'bentley' 'betfair' 'bigbasket' 'bigcartel' 'bigcommerce' 'bilibili' 'bing' 'bit' 'bitbucket' 'bitcoin' 'bitcoincash' 'bitcoinsv' 'bitdefender' 'bitly' 'bitrise' 'bitwarden' 'bitwig' 'blackberry' 'blazemeter' 'blazor' 'blender' 'blockchain-dot-com' 'blogger' 'bloglovin' 'blueprint' 'bluetooth' 'bmcsoftware' 'bmw' 'boeing' 'bookbub' 'bookmeter' 'bookstack' 'boost' 'bootstrap' 'bosch' 'bose' 'bower' 'box' 'brand-dot-ai' 'brandfolder' 'brave' 'breaker' 'britishairways' 'broadcom' 'bt' 'buddy' 'buefy' 'buffer' 'bugatti' 'bugcrowd' 'bugsnag' 'buildkite' 'bulma' 'bunq' 'buymeacoffee' 'buzzfeed' 'byte' 'c' 'cachet' 'cairometro' 'cakephp' 'campaignmonitor' 'canonical' 'canva' 'capacitor' 'carthrottle' 'carto' 'cashapp' 'castbox' 'castorama' 'castro' 'caterpillar' 'cbs' 'cdprojekt' 'celery' 'centos' 'ceph' 'cesium' 'cevo' 'chai' 'chainlink' 'chakraui' 'chart-dot-js' 'chartmogul' 'chase' 'chatbot' 'checkio' 'checkmarx' 'chef' 'chevrolet' 'chinaeasternairlines' 'chinasouthernairlines' 'chocolatey' 'chrysler' 'chupachups' 'cinema4d' 'circle' 'circleci' 'cirrusci' 'cisco' 'citrix' 'citroen' 'civicrm' 'ckeditor4' 'claris' 'clickup' 'clion' 'cliqz' 'clockify' 'clojure' 'cloud66' 'cloudbees' 'cloudcannon' 'cloudera' 'cloudflare' 'cloudsmith' 'cloudways' 'clubhouse' 'clyp' 'cmake' 'cnn' 'co-op' 'cockroachlabs' 'cocoapods' 'cocos' 'coda' 'codacy' 'codeberg' 'codecademy' 'codeceptjs' 'codechef' 'codeclimate' 'codecov' 'codefactor' 'codeforces' 'codeigniter' 'codemagic' 'codemirror' 'codenewbie' 'codepen' 'codeproject' 'codersrank' 'coderwall' 'codesandbox' 'codeship' 'codewars' 'codingame' 'codingninjas' 'codio' 'coffeescript' 'cognizant' 'coinbase' 'commerzbank' 'commonworkflowlanguage' 'composer' 'compropago' 'concourse' 'conda-forge' 'conekta' 'confluence' 'consul' 'contactlesspayment' 'contentful' 'convertio' 'cookiecutter' 'coronaengine' 'coronarenderer' 'corsair' 'couchbase' 'counter-strike' 'countingworkspro' 'coursera' 'coveralls' 'cpanel' 'cplusplus' 'craftcms' 'creativecommons' 'crehana' 'crowdin' 'crowdsource' 'crunchbase' 'crunchyroll' 'cryengine' 'crystal' 'csharp' 'css3' 'csswizardry' 'cucumber' 'curl' 'curseforge' 'cycling74' 'cypress' 'd-wavesystems' 'd3-dot-js' 'dacia' 'daf' 'dailymotion' 'daimler' 'darkreader' 'dart' 'daserste' 'dash' 'dashlane' 'dassaultsystemes' 'databricks' 'datacamp' 'datadog' 'datastax' 'dataversioncontrol' 'datocms' 'datto' 'dazn' 'dblp' 'dcentertainment' 'debian' 'deepin' 'deepnote' 'deezer' 'delicious' 'deliveroo' 'dell' 'delonghi' 'delphi' 'delta' 'deno' 'dependabot' 'derspiegel' 'designernews' 'deutschebahn' 'deutschebank' 'dev-dot-to' 'deviantart' 'devpost' 'devrant' 'dgraph' 'dhl' 'diagrams-dot-net' 'dialogflow' 'diaspora' 'digg' 'digi-keyelectronics' 'digitalocean' 'dior' 'directus' 'discogs' 'discord' 'discourse' 'discover' 'disqus' 'disroot' 'django' 'dlna' 'docker' 'docusign' 'dogecoin' 'dolby' 'doordash' 'dot-net' 'douban' 'draugiem-dot-lv' 'dribbble' 'drone' 'drooble' 'dropbox' 'drupal' 'dsautomobiles' 'dtube' 'duckduckgo' 'dunked' 'duolingo' 'dwm' 'dynamics365' 'dynatrace' 'ea' 'eagle' 'easyjet' 'ebay' 'eclipseche' 'eclipseide' 'eclipsejetty' 'eclipsemosquitto' 'eclipsevert-dot-x' 'editorconfig' 'edx' 'egghead' 'egnyte' 'eightsleep' 'elastic' 'elasticcloud' 'elasticsearch' 'elasticstack' 'electron' 'element' 'elementary' 'eleventy' 'elixir' 'eljueves' 'ello' 'elm' 'elsevier' 'embarcadero' 'ember-dot-js' 'emby' 'emirates' 'emlakjet' 'empirekred' 'enpass' 'envato' 'epel' 'epicgames' 'epson' 'erlang' 'esea' 'eslgaming' 'eslint' 'esphome' 'espressif' 'ethereum' 'ethiopianairlines' 'etihadairways' 'etsy' 'eventbrite' 'eventstore' 'evernote' 'everplaces' 'evry' 'exercism' 'expensify' 'expertsexchange' 'expo' 'express' 'eyeem' 'f-droid' 'f-secure' 'facebook' 'facebookgaming' 'facebooklive' 'faceit' 'facepunch' 'falcon' 'fampay' 'fandango' 'fandom' 'farfetch' 'fastapi' 'fastify' 'fastlane' 'fastly' 'fathom' 'favro' 'feathub' 'fedex' 'fedora' 'fedramp' 'feedly' 'ferrari' 'ferrarin-dot-v-dot' 'ffmpeg' 'fiat' 'fidoalliance' 'fifa' 'figma' 'figshare' 'fila' 'files' 'filezilla' 'fing' 'firebase' 'firefox' 'firefoxbrowser' 'first' 'fitbit' 'fite' 'fiverr' 'flask' 'flathub' 'flattr' 'flickr' 'flipboard' 'flipkart' 'floatplane' 'flood' 'fluentd' 'flutter' 'fmod' 'fnac' 'folium' 'fontawesome' 'fontbase' 'foodpanda' 'ford' 'forestry' 'formstack' 'fortinet' 'fortran' 'fossa' 'fossilscm' 'foursquare' 'foxtel' 'fozzy' 'framer' 'fraunhofer-gesellschaft' 'freebsd' 'freecodecamp' 'freedesktop-dot-org' 'freelancer' 'freenas' 'fujifilm' 'fujitsu' 'furaffinity' 'furrynetwork' 'futurelearn' 'g2a' 'gamejolt' 'garmin' 'gatling' 'gatsby' 'gauges' 'geeksforgeeks' 'generalelectric' 'generalmotors' 'genius' 'gentoo' 'geocaching' 'gerrit' 'ghost' 'ghostery' 'gimp' 'giphy' 'git' 'gitbook' 'gitea' 'gitee' 'gitextensions' 'github' 'githubactions' 'githubsponsors' 'gitkraken' 'gitlab' 'gitlfs' 'gitpod' 'gitter' 'glassdoor' 'glitch' 'gmail' 'gnome' 'gnu' 'gnubash' 'gnuemacs' 'gnuicecat' 'gnuprivacyguard' 'gnusocial' 'go' 'godotengine' 'gofundme' 'gog-dot-com' 'goldenline' 'goodreads' 'google' 'googleads' 'googleadsense' 'googleanalytics' 'googleassistant' 'googlecalendar' 'googlecardboard' 'googlecast' 'googlechat' 'googlechrome' 'googleclassroom' 'googlecloud' 'googlecolab' 'googledomains' 'googledrive' 'googleearth' 'googlefit' 'googlefonts' 'googlehangouts' 'googlekeep' 'googlelens' 'googlemaps' 'googlemeet' 'googlemessages' 'googlemybusiness' 'googlenearby' 'googlenews' 'googleoptimize' 'googlepay' 'googlephotos' 'googleplay' 'googlepodcasts' 'googlescholar' 'googlesearchconsole' 'googlesheets' 'googlestreetview' 'googletagmanager' 'googletranslate' 'gotomeeting' 'gov-dot-uk' 'gradle' 'grafana' 'grammarly' 'graphcool' 'graphql' 'grav' 'gravatar' 'graylog' 'greensock' 'griddotai' 'gridsome' 'groupon' 'grubhub' 'grunt' 'guangzhoumetro' 'gulp' 'gumroad' 'gumtree' 'gutenberg' 'habr' 'hackaday' 'hackclub' 'hackerearth' 'hackerone' 'hackerrank' 'hackhands' 'hackster' 'hackthebox' 'handshake' 'handshake_protocol' 'happycow' 'harbor' 'hashnode' 'haskell' 'hasura' 'hatenabookmark' 'haveibeenpwned' 'haxe' 'hbo' 'hcl' 'headspace' 'hellofresh' 'hellyhansen' 'helm' 'helpdesk' 'here' 'heroku' 'hexo' 'hey' 'hibernate' 'highly' 'hilton' 'hipchat' 'hitachi' 'hive' 'hive_blockchain' 'hockeyapp' 'homeadvisor' 'homeassistant' 'homeassistantcommunitystore' 'homebrew' 'homebridge' 'homify' 'honda' 'hootsuite' 'hoppscotch' 'hotels-dot-com' 'hotjar' 'houdini' 'houzz' 'hp' 'html5' 'htmlacademy' 'huawei' 'hubspot' 'hugo' 'hulu' 'humblebundle' 'hungryjacks' 'hurriyetemlak' 'husqvarna' 'hyper' 'hyperledger' 'hypothesis' 'hyundai' 'iata' 'ibeacon' 'ibm' 'ibmwatson' 'icinga' 'icloud' 'icomoon' 'icon' 'iconfinder' 'iconify' 'iconjar' 'icq' 'ideal' 'ieee' 'ifixit' 'ifood' 'ifttt' 'iheartradio' 'ikea' 'imagej' 'imdb' 'imgur' 'immer' 'imou' 'indeed' 'infiniti' 'influxdb' 'informatica' 'infosys' 'ingress' 'inkscape' 'insomnia' 'instacart' 'instagram' 'instapaper' 'instructables' 'integromat' 'intel' 'intellijidea' 'intercom' 'internetarchive' 'internetexplorer' 'intigriti' 'invision' 'invoiceninja' 'iobroker' 'ionic' 'ios' 'iota' 'ipfs' 'issuu' 'itch-dot-io' 'itunes' 'iveco' 'jabber' 'jaguar' 'jamboard' 'jameson' 'jamstack' 'jasmine' 'java' 'javascript' 'jbl' 'jcb' 'jeep' 'jekyll' 'jellyfin' 'jenkins' 'jenkinsx' 'jest' 'jet' 'jetbrains' 'jfrog' 'jfrogbintray' 'jinja' 'jira' 'jirasoftware' 'jitsi' 'johndeere' 'joomla' 'jpeg' 'jquery' 'jrgroup' 'jsdelivr' 'jsfiddle' 'json' 'jsonwebtokens' 'jss' 'julia' 'junipernetworks' 'junit5' 'jupyter' 'justeat' 'justgiving' 'kaggle' 'kahoot' 'kaios' 'kakao' 'kakaotalk' 'kalilinux' 'karlsruherverkehrsverbund' 'kasasmart' 'kashflow' 'kaspersky' 'katacoda' 'katana' 'kde' 'kdenlive' 'keepassxc' 'kentico' 'keras' 'keybase' 'keycdn' 'khanacademy' 'khronosgroup' 'kia' 'kibana' 'kickstarter' 'kik' 'kirby' 'kitsu' 'klarna' 'klm' 'klook' 'klout' 'knowledgebase' 'known' 'ko-fi' 'kodi' 'koding' 'kofax' 'komoot' 'kongregate' 'kotlin' 'krita' 'ktm' 'kubernetes' 'kubuntu' 'kyocera' 'labview' 'lada' 'lamborghini' 'landrover' 'laragon' 'laravel' 'laravelhorizon' 'laravelnova' 'last-dot-fm' 'lastpass' 'latex' 'launchpad' 'lbry' 'leaflet' 'leanpub' 'leetcode' 'lenovo' 'less' 'letsencrypt' 'letterboxd' 'lg' 'lgtm' 'liberapay' 'libraries-dot-io' 'librarything' 'libreoffice' 'libuv' 'lichess' 'lifx' 'lighthouse' 'line' 'lineageos' 'linewebtoon' 'linkedin' 'linktree' 'linode' 'linux' 'linuxcontainers' 'linuxfoundation' 'linuxmint' 'lionair' 'lit' 'litecoin' 'livechat' 'livejournal' 'livestream' 'llvm' 'lmms' 'logitech' 'logmein' 'logstash' 'looker' 'loom' 'loop' 'lospec' 'lotpolishairlines' 'lua' 'lubuntu' 'lufthansa' 'lumen' 'lydia' 'lyft' 'maas' 'macos' 'macys' 'magento' 'magisk' 'mail-dot-ru' 'mailchimp' 'majorleaguehacking' 'makerbot' 'man' 'manageiq' 'manjaro' 'mapbox' 'mariadb' 'mariadbfoundation' 'markdown' 'marketo' 'marriott' 'maserati' 'mastercard' 'mastercomfig' 'mastodon' 'material-ui' 'materialdesign' 'materialdesignicons' 'mathworks' 'matomo' 'matrix' 'mattermost' 'matternet' 'max-planck-gesellschaft' 'max' 'maytag' 'mazda' 'mcafee' 'mcdonalds' 'mclaren' 'mdnwebdocs' 'mediafire' 'mediatek' 'mediatemple' 'medium' 'meetup' 'mega' 'mendeley' 'mercedes' 'mercurial' 'messenger' 'metabase' 'metafilter' 'meteor' 'metro' 'metrodelaciudaddemexico' 'metrodemadrid' 'metrodeparis' 'mewe' 'micro-dot-blog' 'microbit' 'microgenetics' 'micropython' 'microsoft' 'microsoftacademic' 'microsoftaccess' 'microsoftazure' 'microsoftedge' 'microsoftexcel' 'microsoftexchange' 'microsoftoffice' 'microsoftonedrive' 'microsoftonenote' 'microsoftoutlook' 'microsoftpowerpoint' 'microsoftsharepoint' 'microsoftsqlserver' 'microsoftteams' 'microsoftvisio' 'microsoftword' 'microstrategy' 'midi' 'minds' 'minecraft' 'minetest' 'mini' 'minutemailer' 'miro' 'mitsubishi' 'mix' 'mixcloud' 'mobx-state-tree' 'mobx' 'mocha' 'modx' 'mojangstudios' 'moleculer' 'momenteo' 'monero' 'mongodb' 'monkeytie' 'monogram' 'monster' 'monzo' 'moo' 'moscowmetro' 'motorola' 'mozilla' 'mta' 'mtr' 'mumble' 'musescore' 'musicbrainz' 'mxlinux' 'myanimelist' 'myob' 'myspace' 'mysql' 'n26' 'namebase' 'namecheap' 'nano' 'nasa' 'nationalgrid' 'nativescript' 'naver' 'nba' 'nbb' 'ndr' 'nec' 'neo4j' 'neovim' 'nestjs' 'netapp' 'netflix' 'netlify' 'newjapanpro-wrestling' 'newrelic' 'newyorktimes' 'next-dot-js' 'nextcloud' 'nextdoor' 'nfc' 'nginx' 'ngrok' 'niconico' 'nim' 'nintendo' 'nintendo3ds' 'nintendogamecube' 'nintendonetwork' 'nintendoswitch' 'nissan' 'nixos' 'node-dot-js' 'node-red' 'nodemon' 'nokia' 'norwegian' 'notepadplusplus' 'notion' 'notist' 'nounproject' 'npm' 'nrwl' 'nubank' 'nucleo' 'nuget' 'nuke' 'numba' 'numpy' 'nutanix' 'nuxt-dot-js' 'nvidia' 'nx' 'observable' 'obsstudio' 'ocaml' 'octave' 'octopusdeploy' 'oculus' 'odnoklassniki' 'odysee' 'okcupid' 'okta' 'oneplus' 'onlyfans' 'onnx' 'onstar' 'opel' 'openaccess' 'openai' 'openaigym' 'openapiinitiative' 'openbadges' 'openbsd' 'openbugbounty' 'opencollective' 'opencontainersinitiative' 'opencv' 'openfaas' 'opengl' 'openid' 'openlayers' 'opennebula' 'opensourceinitiative' 'openssl' 'openstack' 'openstreetmap' 'opensuse' 'openvpn' 'openwrt' 'opera' 'opnsense' 'opsgenie' 'opslevel' 'oracle' 'orcid' 'org' 'origin' 'osano' 'oshkosh' 'osmc' 'osu' 'overcast' 'overleaf' 'ovh' 'owasp' 'oxygen' 'oyo' 'p5-dot-js' 'packagist' 'pagekit' 'pagerduty' 'pagespeedinsights' 'pagseguro' 'palantir' 'paloaltosoftware' 'pandas' 'pandora' 'pantheon' 'paritysubstrate' 'parse-dot-ly' 'passport' 'pastebin' 'patreon' 'payoneer' 'paypal' 'paytm' 'pcgamingwiki' 'peertube' 'pegasusairlines' 'pelican' 'peloton' 'pepsi' 'perforce' 'periscope' 'perl' 'peugeot' 'pexels' 'pfsense' 'phabricator' 'philipshue' 'phonepe' 'photobucket' 'photocrowd' 'photopea' 'php' 'phpstorm' 'pi-hole' 'picarto-dot-tv' 'picnic' 'picpay' 'pimcore' 'pinboard' 'pingdom' 'pingup' 'pinterest' 'pioneerdj' 'pivotaltracker' 'piwigo' 'pixabay' 'pixiv' 'pjsip' 'planet' 'plangrid' 'platzi' 'playcanvas' 'player-dot-me' 'playerfm' 'playstation' 'playstation2' 'playstation3' 'playstation4' 'playstation5' 'playstationvita' 'pleroma' 'plesk' 'plex' 'plotly' 'pluralsight' 'plurk' 'pluscodes' 'pm2' 'pnpm' 'pocket' 'pocketcasts' 'podcastaddict' 'podman' 'pointy' 'pokemon' 'poly' 'polymerproject' 'pop_os' 'porsche' 'postcss' 'postgresql' 'postman' 'postmates' 'powerbi' 'powers' 'powershell' 'pr-dot-co' 'pre-commit' 'premierleague' 'prestashop' 'presto' 'prettier' 'prezi' 'prime' 'primevideo' 'prisma' 'prismic' 'privateinternetaccess' 'probot' 'processingfoundation' 'processwire' 'producthunt' 'progate' 'progress' 'prometheus' 'prosieben' 'proto-dot-io' 'protocols-dot-io' 'protondb' 'protonmail' 'protonvpn' 'protools' 'proxmox' 'publons' 'pubmed' 'pug' 'puppet' 'puppeteer' 'purescript' 'purgecss' 'purism' 'pusher' 'pycharm' 'pypi' 'pypy' 'python' 'pytorch' 'pytorchlightning' 'pyup' 'qantas' 'qatarairways' 'qemu' 'qgis' 'qi' 'qiita' 'qiskit' 'qiwi' 'qt' 'qualcomm' 'qualtrics' 'quantcast' 'quantconnect' 'quantopian' 'quarkus' 'quasar' 'qubesos' 'quest' 'quickbooks' 'quicktime' 'quip' 'quora' 'qwiklabs' 'qzone' 'r' 'r3' 'rabbitmq' 'racket' 'radar' 'radiopublic' 'rainmeter' 'rakuten' 'ram' 'rancher' 'raspberrypi' 'razer' 'react' 'reactivex' 'reactos' 'reactrouter' 'readthedocs' 'realm' 'reason' 'reasonstudios' 'redbubble' 'reddit' 'redhat' 'redhatopenshift' 'redis' 'redux-saga' 'redux' 'redwoodjs' 'relianceindustrieslimited' 'renault' 'renovatebot' 'renpy' 'renren' 'repl-dot-it' 'researchgate' 'resurrectionremixos' 'retroarch' 'retropie' 'reveal-dot-js' 'reverbnation' 'revolut' 'revue' 'rewe' 'rezgo' 'rhinoceros' 'rider' 'ring' 'riotgames' 'ripple' 'riseup' 'roamresearch' 'roblox' 'robotframework' 'rocket-dot-chat' 'roku' 'rolls-royce' 'rollup-dot-js' 'roots' 'rootsbedrock' 'rootssage' 'ros' 'rottentomatoes' 'roundcube' 'rss' 'rstudio' 'rte' 'rtl' 'rtlzwei' 'ruby' 'rubygems' 'rubyonrails' 'runkeeper' 'runkit' 'rust' 'rxdb' 'ryanair' 's7airlines' 'safari' 'sahibinden' 'salesforce' 'saltstack' 'samsung' 'samsungpay' 'sanfranciscomunicipalrailway' 'saopaulometro' 'sap' 'sass' 'sat-dot-1' 'saucelabs' 'scala' 'scaleway' 'scania' 'scikit-learn' 'scipy' 'scopus' 'scratch' 'screencastify' 'scribd' 'scrimba' 'scrollreveal' 'scrumalliance' 'scrutinizerci' 'seagate' 'seat' 'sefaria' 'sega' 'selenium' 'sellfy' 'semantic-release' 'semanticuireact' 'semanticweb' 'semaphoreci' 'semver' 'sencha' 'sennheiser' 'sensu' 'sentry' 'sepa' 'serverfault' 'serverless' 'sfml' 'shanghaimetro' 'sharp' 'shazam' 'shell' 'shelly' 'shenzhenmetro' 'shields-dot-io' 'shikimori' 'shopify' 'shopware' 'shotcut' 'showpad' 'showtime' 'shutterstock' 'siemens' 'signal' 'simkl' 'simpleanalytics' 'simpleicons' 'sinaweibo' 'singlestore' 'sitepoint' 'sketch' 'sketchfab' 'sketchup' 'skillshare' 'skoda' 'sky' 'skyliner' 'skype' 'skypeforbusiness' 'slack' 'slackware' 'slashdot' 'slickpic' 'slides' 'slideshare' 'smart' 'smartthings' 'smashingmagazine' 'smrt' 'smugmug' 'snapchat' 'snapcraft' 'snowflake' 'snyk' 'society6' 'socket-dot-io' 'sogou' 'solidity' 'sololearn' 'solus' 'sonarcloud' 'sonarlint' 'sonarqube' 'sonarsource' 'songkick' 'songoda' 'sonicwall' 'sonos' 'soundcloud' 'sourceengine' 'sourceforge' 'sourcegraph' 'southwestairlines' 'spacemacs' 'spacex' 'sparkar' 'sparkasse' 'sparkfun' 'sparkpost' 'spdx' 'speakerdeck' 'spectrum' 'speedtest' 'spinnaker' 'spinrilla' 'splunk' 'spotify' 'spotlight' 'spreaker' 'spring' 'springboot' 'sprint' 'spyderide' 'sqlite' 'square' 'squareenix' 'squarespace' 'ssrn' 'stackbit' 'stackexchange' 'stackoverflow' 'stackpath' 'stackshare' 'stadia' 'staffbase' 'starlingbank' 'starship' 'startrek' 'starz' 'statamic' 'staticman' 'statuspage' 'statuspal' 'steam' 'steamdb' 'steamworks' 'steem' 'steemit' 'steinberg' 'stellar' 'stencyl' 'stimulus' 'stitcher' 'stmicroelectronics' 'storify' 'storyblok' 'storybook' 'strapi' 'strava' 'streamlit' 'stripe' 'strongswan' 'stubhub' 'styled-components' 'stylelint' 'styleshare' 'stylus' 'subaru' 'sublimetext' 'substack' 'subversion' 'suckless' 'sumologic' 'supabase' 'superuser' 'surveymonkey' 'suse' 'suzuki' 'svelte' 'svg' 'svgo' 'swagger' 'swarm' 'swift' 'swiggy' 'swiper' 'symantec' 'symfony' 'symphony' 'sympy' 'synology' 't-mobile' 'tableau' 'tado' 'tails' 'tailwindcss' 'talend' 'tampermonkey' 'taobao' 'tapas' 'tasmota' 'tata' 'taxbuzz' 'teamcity' 'teamspeak' 'teamviewer' 'ted' 'teespring' 'tekton' 'tele5' 'telegram' 'telegraph' 'tencentqq' 'tencentweibo' 'tensorflow' 'teradata' 'teratail' 'terraform' 'tesla' 'testin' 'testinglibrary' 'textpattern' 'theconversation' 'theirishtimes' 'themighty' 'themodelsresource' 'themoviedatabase' 'theregister' 'thesoundsresource' 'thespritersresource' 'thewashingtonpost' 'thingiverse' 'thinkpad' 'three-dot-js' 'threema' 'thumbtack' 'thunderbird' 'thymeleaf' 'ticketmaster' 'tidal' 'tide' 'tiktok' 'tile' 'timescale' 'tinder' 'tinyletter' 'tmux' 'todoist' 'toggl' 'tokyometro' 'tomorrowland' 'topcoder' 'toptal' 'torbrowser' 'torproject' 'toshiba' 'toyota' 'tp-link' 'tqdm' 'trainerroad' 'trakt' 'transferwise' 'transportforireland' 'transportforlondon' 'travisci' 'treehouse' 'trello' 'trendmicro' 'treyarch' 'triller' 'trino' 'trip-dot-com' 'tripadvisor' 'trove' 'truenas' 'trulia' 'trustedshops' 'trustpilot' 'tryhackme' 'tryitonline' 'ts-node' 'tui' 'tumblr' 'tunein' 'turbosquid' 'turkishairlines' 'tutanota' 'tvtime' 'twilio' 'twitch' 'twitter' 'twoo' 'typescript' 'typo3' 'uber' 'ubereats' 'ubiquiti' 'ubisoft' 'ublockorigin' 'ubuntu' 'udacity' 'udemy' 'ufc' 'uikit' 'ulule' 'umbraco' 'unacademy' 'undertale' 'unicode' 'unilever' 'unitedairlines' 'unity' 'unraid' 'unrealengine' 'unsplash' 'untangle' 'untappd' 'upcloud' 'uplabs' 'uploaded' 'ups' 'upwork' 'usps' 'v' 'v8' 'vaadin' 'vagrant' 'valve' 'vapor' 'vault' 'vauxhall' 'vbulletin' 'vectorlogozone' 'vectorworks' 'veeam' 'veepee' 'venmo' 'vercel' 'verdaccio' 'veritas' 'verizon' 'vfairs' 'viadeo' 'viber' 'vim' 'vimeo' 'vimeolivestream' 'vine' 'virb' 'virtualbox' 'virustotal' 'visa' 'visualstudio' 'visualstudiocode' 'vite' 'vivaldi' 'vivino' 'vk' 'vlcmediaplayer' 'vmware' 'vodafone' 'volkswagen' 'volvo' 'vonage' 'vox' 'vsco' 'vue-dot-js' 'vuetify' 'vulkan' 'vultr' 'w3c' 'wagtail' 'wakatime' 'walkman' 'wappalyzer' 'warnerbros-dot' 'wattpad' 'waze' 'wearos' 'weasyl' 'webassembly' 'webauthn' 'webcomponents-dot-org' 'webdriverio' 'webflow' 'webgl' 'webhint' 'weblate' 'webmin' 'webmoney' 'webpack' 'webrtc' 'webstorm' 'wechat' 'weights-and-biases' 'wemo' 'wetransfer' 'whatsapp' 'wheniwork' 'whitesource' 'wii' 'wiiu' 'wikidata' 'wikimediacommons' 'wikipedia' 'wikiquote' 'wikivoyage' 'windows' 'windows95' 'windowsterminal' 'windowsxp' 'winmate' 'wipro' 'wire' 'wireguard' 'wireshark' 'wish' 'wistia' 'wix' 'wizzair' 'wolfram' 'wolframlanguage' 'wolframmathematica' 'woo' 'woocommerce' 'wordpress' 'workplace' 'worldhealthorganization' 'wpengine' 'wprocket' 'write-dot-as' 'wwe' 'wwise' 'x-dot-org' 'x-pack' 'xamarin' 'xaml' 'xampp' 'xbox' 'xcode' 'xdadevelopers' 'xero' 'xfce' 'xiaomi' 'xilinx' 'xing' 'xmpp' 'xrp' 'xsplit' 'xstate' 'yahoo' 'yale' 'yamahacorporation' 'yamahamotorcorporation' 'yammer' 'yandex' 'yarn' 'ycombinator' 'yelp' 'yoast' 'yourtravel-dot-tv' 'youtube' 'youtubegaming' 'youtubemusic' 'youtubestudio' 'youtubetv' 'z-wave' 'zalando' 'zapier' 'zdf' 'zelle' 'zend' 'zendesk' 'zendframework' 'zenn' 'zerodha' 'zeromq' 'zerply' 'zhihu' 'zigbee' 'zillow' 'zingat' 'zoho' 'zoiper' 'zomato' 'zoom' 'zorin' 'zotero' 'zulip' ) } function Remove-DiscardedReports { [CmdletBinding()] param( [Array] $FilePathsGenerated, [string] $FolderPath, [string] $Extension ) $FilePathsCurrent = Get-ChildItem -LiteralPath $FolderPath -File -Filter "*$($Extension)" | Select-Object -ExpandProperty FullName foreach ($File in $FilePathsCurrent) { if ($File -notin $FilePathsGenerated) { Write-Color -Text '[i]', '[FILE ] ', "Removing discarded report: $File" -Color Yellow, DarkGray, Yellow Remove-Item -LiteralPath $File -Force } } } function Set-FolderConfiguration { [CmdletBinding()] param( [System.Collections.IDictionary]$Folders, [Array] $FoldersConfiguration, [System.Collections.IDictionary]$FolderLimit ) foreach ($Folder in $FoldersConfiguration) { if (-not $Folder.Name -and $Folder.Url) { $Folder.Name = $Folder.Url } elseif (-not $Folder.Url -and $Folder.Name) { $Folder.Url = $Folder.Name } if ($FolderLimit -and -not $Folder.DisableGlobalLimits) { $Folder.LimitsConfiguration[$FolderLimit.Name] = $FolderLimit } $Folders[$Folder.Name] = $Folder } } function New-DashboardFolder { [alias('New-TheDashboardFolder')] [CmdletBinding()] param( [Parameter(Position = 0)][scriptblock] $Entries, [Parameter(Mandatory)][string] $Name, [Parameter(Mandatory)][string] $Path, [Parameter(Mandatory)][string] $UrlName, [string] $CopyFrom, [string] $MoveFrom, [switch] $DisableGlobalReplacement, [switch] $DisableGlobalLimits, # ICON BRANDS [ArgumentCompleter( { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) ($Global:HTMLIcons.FontAwesomeBrands.Keys) } )] [ValidateScript( { $_ -in (($Global:HTMLIcons.FontAwesomeBrands.Keys)) } )] [parameter(ParameterSetName = "FontAwesomeBrands")][string] $IconBrands, # ICON REGULAR [ArgumentCompleter( { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) ($Global:HTMLIcons.FontAwesomeRegular.Keys) } )] [ValidateScript( { $_ -in (($Global:HTMLIcons.FontAwesomeRegular.Keys)) } )] [parameter(ParameterSetName = "FontAwesomeRegular")][string] $IconRegular, # ICON SOLID [ArgumentCompleter( { param($CommandName, $ParameterName, $WordToComplete, $CommandAst, $FakeBoundParameters) ($Global:HTMLIcons.FontAwesomeSolid.Keys) } )] [ValidateScript( { $_ -in (($Global:HTMLIcons.FontAwesomeSolid.Keys)) } )] [parameter(ParameterSetName = "FontAwesomeSolid")][string] $IconSolid ) if ($IconBrands) { $IconType = 'IconBrands' $Icon = $IconBrands } elseif ($IconRegular) { $IconType = 'IconRegular' $Icon = $IconRegular } elseif ($IconSolid) { $IconType = 'IconSolid' $Icon = $IconSolid } else { $IconType = 'IconSolid' $Icon = 'folder' } if ($Entries) { $ReplacementConfiguration = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() $LimitsConfiguration = [ordered] @{} $OutputElements = & $Entries foreach ($E in $OutputElements) { if ($E.Type -eq 'Replacement') { $ReplacementConfiguration.Add($E.Settings) } elseif ($E.Type -eq 'FolderLimit') { $LimitsConfiguration[$E.Settings.Name] = $E.Settings } } $ReplacementsConfiguration = Convert-MultipleReplacements -ReplacementConfiguration $ReplacementConfiguration } else { $LimitsConfiguration = [ordered] @{} $ReplacementsConfiguration = $null } $Folder = [ordered] @{ Type = 'Folder' Settings = [ordered] @{ Name = $Name IconType = $IconType Icon = $Icon Path = $Path Url = $UrlName CopyFrom = $CopyFrom MoveFrom = $MoveFrom ReplacementsGlobal = -not $DisableGlobalReplacement.IsPresent Replacements = $ReplacementsConfiguration LimitsConfiguration = $LimitsConfiguration DisableGlobalLimits = $DisableGlobalLimits.IsPresent } } Remove-EmptyValue -Hashtable $Folder $Folder } function New-DashboardGage { [alias('New-TheDashboardGage')] [cmdletBinding()] param( [Parameter(Mandatory)][string] $Label, [Parameter()][int] $MinValue, [Parameter(Mandatory)][int] $MaxValue, [Parameter(Mandatory)][int] $Value, [Parameter(Mandatory)][DateTime] $Date ) [ordered] @{ Type = 'Gage' Settings = [ordered] @{ Label = $Label Value = $Value Date = $Date MinValue = $MinValue MaxValue = $MaxValue } } } function New-DashboardLimit { [CmdletBinding()] param( [string] $Name, [nullable[int]] $LimitItem, [nullable[DateTime]] $LimitDate, [switch] $IncludeHistory ) if (-not $Name) { $Name = '*' } $Limit = [ordered] @{ Type = 'FolderLimit' Settings = [ordered] @{ Name = $Name LimitItem = $LimitItem LimitDate = $LimitDate IncludeHistory = $IncludeHistory } } Remove-EmptyValue -Hashtable $Limit.Settings $Limit } function New-DashboardReplacement { [alias('New-TheDashboardReplacement')] [CmdletBinding()] param( [string] $SplitOn, [Array] $BeforeSplit, [Array] $AfterSplit, [switch] $AddSpaceToName ) $BeforeEntry = [ordered] @{} foreach ($Before in $BeforeSplit) { foreach ($Key in $Before.Keys) { $BeforeEntry[$Key] = $Before[$Key] } } $AfterEntry = [ordered] @{} foreach ($After in $AfterSplit) { foreach ($Key in $After.Keys) { $AfterEntry[$Key] = $After[$Key] } } $Replacements = [ordered] @{ Type = 'Replacement' Settings = @{ SplitOn = if ($PSBoundParameters.ContainsKey('SplitOn')) { $SplitOn } else { $null } BeforeSplit = if ($PSBoundParameters.ContainsKey('BeforeSplit')) { $BeforeEntry } else { $null } AfterSplit = if ($PSBoundParameters.ContainsKey('AfterSplit')) { $AfterEntry } else { $null } AddSpaceToName = if ($PSBoundParameters.ContainsKey('AddSpaceToName')) { $AddSpaceToName } else { $null } } } $Replacements } function Start-TheDashboard { <# .SYNOPSIS Generates TheDashboard from multiple provided reports in form of HTML files. .DESCRIPTION Generates TheDashboard from multiple provided reports in form of HTML files. It also generates statistics and charts based on the data provided by additional data. .PARAMETER Elements ScriptBlock that accepts New-Dashboard* functions, allowing for configuration of TheDashboard. .PARAMETER HTMLPath Path to HTML files that will be generated. .PARAMETER StatisticsPath Path to XML file that will save some of the data that is used to generate charts .PARAMETER Logo Path to logo that will be used in the header. .PARAMETER Folders Folders that will be used to generate TheDashboard. Can co-exist with Elements parameter, and configuration using both will be merged. .PARAMETER Replacements Replacements that will be used to replace names within TheDashboard. .PARAMETER ShowHTML Show TheDashboard in browser after generating it. .PARAMETER Online Tells Dashboard to use CSS/JS from CDN instead of local files. .EXAMPLE An example .NOTES General notes #> [cmdletBinding()] param( [Parameter(Position = 0)][ScriptBlock] $Elements, [Parameter(Position = 1, Mandatory)][alias('FilePath')][string] $HTMLPath, [string] $StatisticsPath, [string] $Logo, [System.Collections.IDictionary] $Folders, [System.Collections.IDictionary] $Replacements, [switch] $ShowHTML, [switch] $Online ) $Script:Reporting = [ordered] @{} $Script:Reporting['Version'] = Get-GitHubVersion -Cmdlet 'Start-TheDashboard' -RepositoryOwner 'evotecit' -RepositoryName 'TheDashboard' Write-Color '[i]', "[TheDashboard] ", 'Version', ' [Informative] ', $Script:Reporting['Version'] -Color Yellow, DarkGray, Yellow, DarkGray, Magenta $TopStats = [ordered] @{} if (-not $Folders) { $Folders = [ordered] @{} } $GageConfiguration = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() $FoldersConfiguration = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() $ReplacementConfiguration = [System.Collections.Generic.List[System.Collections.IDictionary]]::new() if ($Elements) { $TimeLogElements = Start-TimeLog Write-Color -Text '[i]', "[TheDashboard] ", 'Executing nested elements (data gathering/conversions)', ' [Informative] ' -Color Yellow, DarkGray, Yellow, DarkGray, Magenta $OutputElements = & $Elements foreach ($E in $OutputElements) { if ($E.Type -eq 'Gage') { $GageConfiguration.Add($E.Settings) } elseif ($E.Type -eq 'Folder') { $FoldersConfiguration.Add($E.Settings) } elseif ($E.Type -eq 'Replacement') { $ReplacementConfiguration.Add($E.Settings) } elseif ($E.Type -eq 'FolderLimit') { $FolderLimit = $E.Settings } } $TimeLogElements = Stop-TimeLog -Time $TimeLogElements -Option OneLiner Write-Color -Text '[i]', "[TheDashboard] ", 'Executing nested elements (data gathering/conversions)', ' [Time to execute: ', $TimeLogElements, ']' -Color Yellow, DarkGray, Yellow, DarkGray, Magenta } if ($StatisticsPath -and (Test-Path -LiteralPath $StatisticsPath)) { Write-Color -Text '[i]', "[TheDashboard] ", 'Importing Statistics', ' [Informative] ', $StatisticsPath -Color Yellow, DarkGray, Yellow, DarkGray, Magenta $TopStats = Import-Clixml -LiteralPath $StatisticsPath } $Extension = [io.path]::GetExtension($HTMLPath) $FolderPath = [io.path]::GetDirectoryName($HTMLPath) foreach ($E in $GageConfiguration) { $TopStats[$E.Date] = [ordered] @{} $TopStats[$E.Date].Date = $E.Date } $Replacements = Convert-MultipleReplacements -Replacements $Replacements -ReplacementConfiguration $ReplacementConfiguration Set-FolderConfiguration -Folders $Folders -FoldersConfiguration $FoldersConfiguration -FolderLimit $FolderLimit Copy-HTMLFiles -Folders $Folders -Extension $Extension $Files = Convert-FilesToMenuData -Folders $Folders -Replacements $Replacements -Extension $Extension $MenuBuilder = Convert-FilesToMenu -Files $Files -Folders $Folders $FilePathsGenerated = New-HTMLReport -OutputElements $GageConfiguration -Logo $Logo -MenuBuilder $MenuBuilder -Configuration $Configuration -TopStats $TopStats -Files $Files -ShowHTML:$ShowHTML.IsPresent -HTMLPath $HTMLPath -Online:$Online.IsPresent -Force:$Force.IsPresent -Extension $Extension Remove-DiscardedReports -FilePathsGenerated $FilePathsGenerated -FolderPath $FolderPath -Extension $Extension if ($StatisticsPath) { try { $TopStats | Export-Clixml -Depth 3 -LiteralPath $StatisticsPath -ErrorAction Stop } catch { Write-Color -Text '[e]', "[TheDashboard] ", 'Failed to export statistics', ' [Error] ', $_.Exception.Message -Color Yellow, DarkGray, Yellow, DarkGray, Red } } Write-Color -Text '[i]', "[TheDashboard] ", 'Done', ' [Informative] ' -Color Yellow, DarkGray, Yellow, DarkGray, Magenta } Export-ModuleMember -Function @('New-DashboardFolder', 'New-DashboardGage', 'New-DashboardLimit', 'New-DashboardReplacement', 'Start-TheDashboard') -Alias @('New-TheDashboardFolder', 'New-TheDashboardGage', 'New-TheDashboardReplacement') # SIG # Begin signature block # MIItsQYJKoZIhvcNAQcCoIItojCCLZ4CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBHCZ2TLB1Q2nFw # D46Ytr0IeP/UX30jZ0Agbj6Z0A1CwKCCJrQwggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggWQMIIDeKADAgECAhAFmxtXno4hMuI5B72nd3VcMA0GCSqG # SIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0zODAxMTUxMjAwMDBaMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIw # aTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLK # EdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4Tm # dDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembu # d8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnD # eMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1 # XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVld # QnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTS # YW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSm # M9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzT # QRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6Kx # fgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1UdEwEB/wQFMAMBAf8wDgYD # VR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzANBgkq # hkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNkaA9Wz3eucPn9mkqZucl4 # XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjSPMFDQK4dUPVS/JA7u5iZ # aWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK7VB6fWIhCoDIc2bRoAVg # X+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eBcg3AFDLvMFkuruBx8lbk # apdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp5aPNoiBB19GcZNnqJqGL # FNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msgdDDS4Dk0EIUhFQEI6FUy # 3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vriRbgjU2wGb2dVf0a1TD9u # KFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ79ARj6e/CVABRoIoqyc54 # zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5nLGbsQAe79APT0JsyQq8 # 7kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3i0objwG2J5VT6LaJbVu8 # aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0HEEcRrYc9B9F1vM/zZn4w # ggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3DQEBCwUAMGIx # CzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3 # dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBH # NDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 # c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0EwggIiMA0GCSqG # SIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE8pE3qZdRodbS # g9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBMLJnOWbfhXqAJ9 # /UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU5ygt69OxtXXn # HwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLydkf3YYMZ3V+0 # VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFkdECnwHLFuk4f # sbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgmf6AaRyBD40Nj # gHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9abJTyUpURK1h0 # QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwYSH8UNM/STKvv # mz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80VgvCONWPfcYd6T # /jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5FBASA31fI7tk # 42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9Rp6103a50g5r # mQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4E # FgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5n # P+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcG # CCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQu # Y29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNV # HSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIB # AH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp+3CKDaopafxp # wc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9qVbPFXONASIl # zpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8ZCaHbJK9nXzQ # cAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6ZJxurJB4mwbfe # Kuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnEtp/Nh4cku0+j # Sbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fxZsNBzU+2QJsh # IUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV77QpfMzmHQXh6 # OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT1ObyF5lZynDw # N7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkPCr2B2RP+v6TR # 81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvmfxqkhQ/8mJb2 # VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGsDCCBJigAwIBAgIQ # CK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0BAQwFADBiMQswCQYDVQQGEwJVUzEV # MBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29t # MSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjEwNDI5MDAw # MDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBT # aWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5WRuxiEL1M4zrPYGXcMW7xIUmMJ+k # jmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJPDqFX/IiZwZHMgQM+TXAkZLON4gh9 # NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXzENOLsvsI8IrgnQnAZaf6mIBJNYc9 # URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bqHPNlaJGiTUyCEUhSaN4QvRRXXegY # E2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTCfMjqGzLmysL0p6MDDnSlrzm2q2AS # 4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaDG7dqZy3SvUQakhCBj7A7CdfHmzJa # wv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urOkfW+0/tvk2E0XLyTRSiDNipmKF+w # c86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7ADK5GyNnm+960IHnWmZcy740hQ83eR # Gv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4R+Z1MI3sMJN2FKZbS110YU0/EpF2 # 3r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlNWdt4z4FKPkBHX8mBUHOFECMhWWCK # ZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0IU0F8WD1Hs/q27IwyCQLMbDwMVhEC # AwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFGg34Ou2 # O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9P # MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDAzB3BggrBgEFBQcB # AQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggr # BgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwHAYDVR0gBBUwEzAH # BgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcNAQEMBQADggIBADojRD2NCHbuj7w6 # mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcTEp6QRJ9L/Z6jfCbVN7w6XUhtldU/ # SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WTauPrINHVUHmImoqKwba9oUgYftzY # gBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9ntSZz0rdKOtfJqGVWEjVGv7XJz/9 # kNF2ht0csGBc8w2o7uCJob054ThO2m67Np375SFTWsPK6Wrxoj7bQ7gzyE84FJKZ # 9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0HKKlS43Nb3Y3LIU/Gs4m6Ri+kAew # Q3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL6TEa/y4ZXDlx4b6cpwoG1iZnt5Lm # Tl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+16oh7cGvmoLr9Oj9FpsToFpFSi0HA # SIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8M4+uKIw8y4+ICw2/O/TOHnuO77Xr # y7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrFhsP2JjMMB0ug0wcCampAMEhLNKhR # ILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy1lKQ/a+FSCH5Vzu0nAPthkX0tGFu # v2jiJmCG6sivqf6UHedjGzqGVnhOMIIGwjCCBKqgAwIBAgIQBUSv85SdCDmmv9s/ # X+VhFjANBgkqhkiG9w0BAQsFADBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGln # aUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5 # NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4XDTIzMDcxNDAwMDAwMFoXDTM0MTAx # MzIzNTk1OVowSDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu # MSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3RhbXAgMjAyMzCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBAKNTRYcdg45brD5UsyPgz5/X5dLnXaEOCdwvSKOX # ejsqnGfcYhVYwamTEafNqrJq3RApih5iY2nTWJw1cb86l+uUUI8cIOrHmjsvlmbj # aedp/lvD1isgHMGXlLSlUIHyz8sHpjBoyoNC2vx/CSSUpIIa2mq62DvKXd4ZGIX7 # ReoNYWyd/nFexAaaPPDFLnkPG2ZS48jWPl/aQ9OE9dDH9kgtXkV1lnX+3RChG4PB # uOZSlbVH13gpOWvgeFmX40QrStWVzu8IF+qCZE3/I+PKhu60pCFkcOvV5aDaY7Mu # 6QXuqvYk9R28mxyyt1/f8O52fTGZZUdVnUokL6wrl76f5P17cz4y7lI0+9S769Sg # LDSb495uZBkHNwGRDxy1Uc2qTGaDiGhiu7xBG3gZbeTZD+BYQfvYsSzhUa+0rRUG # FOpiCBPTaR58ZE2dD9/O0V6MqqtQFcmzyrzXxDtoRKOlO0L9c33u3Qr/eTQQfqZc # ClhMAD6FaXXHg2TWdc2PEnZWpST618RrIbroHzSYLzrqawGw9/sqhux7UjipmAmh # cbJsca8+uG+W1eEQE/5hRwqM/vC2x9XH3mwk8L9CgsqgcT2ckpMEtGlwJw1Pt7U2 # 0clfCKRwo+wK8REuZODLIivK8SgTIUlRfgZm0zu++uuRONhRB8qUt+JQofM604qD # y0B7AgMBAAGjggGLMIIBhzAOBgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAW # BgNVHSUBAf8EDDAKBggrBgEFBQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglg # hkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0O # BBYEFKW27xPn783QZKHVVqllMaPe1eNJMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6 # Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEy # NTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZT # SEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQwDQYJKoZIhvcNAQELBQADggIBAIEa1t6g # qbWYF7xwjU+KPGic2CX/yyzkzepdIpLsjCICqbjPgKjZ5+PF7SaCinEvGN1Ott5s # 1+FgnCvt7T1IjrhrunxdvcJhN2hJd6PrkKoS1yeF844ektrCQDifXcigLiV4JZ0q # BXqEKZi2V3mP2yZWK7Dzp703DNiYdk9WuVLCtp04qYHnbUFcjGnRuSvExnvPnPp4 # 4pMadqJpddNQ5EQSviANnqlE0PjlSXcIWiHFtM+YlRpUurm8wWkZus8W8oM3NG6w # QSbd3lqXTzON1I13fXVFoaVYJmoDRd7ZULVQjK9WvUzF4UbFKNOt50MAcN7MmJ4Z # iQPq1JE3701S88lgIcRWR+3aEUuMMsOI5ljitts++V+wQtaP4xeR0arAVeOGv6wn # LEHQmjNKqDbUuXKWfpd5OEhfysLcPTLfddY2Z1qJ+Panx+VPNTwAvb6cKmx5Adza # ROY63jg7B145WPR8czFVoIARyxQMfq68/qTreWWqaNYiyjvrmoI1VygWy2nyMpqy # 0tg6uLFGhmu6F/3Ed2wVbK6rr3M66ElGt9V/zLY4wNjsHPW2obhDLN9OTH0eaHDA # dwrUAuBcYLso/zjlUlrWrBciI0707NMX+1Br/wd3H3GXREHJuEbTbDJ8WC9nR2Xl # G3O2mflrLAZG70Ee8PBf4NvZrZCARK+AEEGKMIIHXzCCBUegAwIBAgIQB8JSdCgU # otar/iTqF+XdLjANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UE # ChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQg # Q29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExMB4XDTIzMDQxNjAw # MDAwMFoXDTI2MDcwNjIzNTk1OVowZzELMAkGA1UEBhMCUEwxEjAQBgNVBAcMCU1p # a2/FgsOzdzEhMB8GA1UECgwYUHJ6ZW15c8WCYXcgS8WCeXMgRVZPVEVDMSEwHwYD # VQQDDBhQcnplbXlzxYJhdyBLxYJ5cyBFVk9URUMwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCUmgeXMQtIaKaSkKvbAt8GFZJ1ywOH8SwxlTus4McyrWmV # OrRBVRQA8ApF9FaeobwmkZxvkxQTFLHKm+8knwomEUslca8CqSOI0YwELv5EwTVE # h0C/Daehvxo6tkmNPF9/SP1KC3c0l1vO+M7vdNVGKQIQrhxq7EG0iezBZOAiukNd # GVXRYOLn47V3qL5PwG/ou2alJ/vifIDad81qFb+QkUh02Jo24SMjWdKDytdrMXi0 # 235CN4RrW+8gjfRJ+fKKjgMImbuceCsi9Iv1a66bUc9anAemObT4mF5U/yQBgAuA # o3+jVB8wiUd87kUQO0zJCF8vq2YrVOz8OJmMX8ggIsEEUZ3CZKD0hVc3dm7cWSAw # 8/FNzGNPlAaIxzXX9qeD0EgaCLRkItA3t3eQW+IAXyS/9ZnnpFUoDvQGbK+Q4/bP # 0ib98XLfQpxVGRu0cCV0Ng77DIkRF+IyR1PcwVAq+OzVU3vKeo25v/rntiXCmCxi # W4oHYO28eSQ/eIAcnii+3uKDNZrI15P7VxDrkUIc6FtiSvOhwc3AzY+vEfivUkFK # RqwvSSr4fCrrkk7z2Qe72Zwlw2EDRVHyy0fUVGO9QMuh6E3RwnJL96ip0alcmhKA # BGoIqSW05nXdCUbkXmhPCTT5naQDuZ1UkAXbZPShKjbPwzdXP2b8I9nQ89VSgQID # AQABo4ICAzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHQYD # VR0OBBYEFHrxaiVZuDJxxEk15bLoMuFI5233MA4GA1UdDwEB/wQEAwIHgDATBgNV # HSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3Js # My5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQw # OTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAy # MUNBMS5jcmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcCARYbaHR0 # cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGUBggrBgEFBQcBAQSBhzCBhDAkBggr # BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUFBzAChlBo # dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2Rl # U2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAAMA0GCSqG # SIb3DQEBCwUAA4ICAQC3EeHXUPhpe31K2DL43Hfh6qkvBHyR1RlD9lVIklcRCR50 # ZHzoWs6EBlTFyohvkpclVCuRdQW33tS6vtKPOucpDDv4wsA+6zkJYI8fHouW6Tqa # 1W47YSrc5AOShIcJ9+NpNbKNGih3doSlcio2mUKCX5I/ZrzJBkQpJ0kYha/pUST2 # CbE3JroJf2vQWGUiI+J3LdiPNHmhO1l+zaQkSxv0cVDETMfQGZKKRVESZ6Fg61b0 # djvQSx510MdbxtKMjvS3ZtAytqnQHk1ipP+Rg+M5lFHrSkUlnpGa+f3nuQhxDb7N # 9E8hUVevxALTrFifg8zhslVRH5/Df/CxlMKXC7op30/AyQsOQxHW1uNx3tG1DMgi # zpwBasrxh6wa7iaA+Lp07q1I92eLhrYbtw3xC2vNIGdMdN7nd76yMIjdYnAn7r38 # wwtaJ3KYD0QTl77EB8u/5cCs3ShZdDdyg4K7NoJl8iEHrbqtooAHOMLiJpiL2i9Y # n8kQMB6/Q6RMO3IUPLuycB9o6DNiwQHf6Jt5oW7P09k5NxxBEmksxwNbmZvNQ65Z # n3exUAKqG+x31Egz5IZ4U/jPzRalElEIpS0rgrVg8R8pEOhd95mEzp5WERKFyXhe # 6nB6bSYHv8clLAV0iMku308rpfjMiQkqS3LLzfUJ5OHqtKKQNMLxz9z185UCszGC # BlMwggZPAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBS # U0E0MDk2IFNIQTM4NCAyMDIxIENBMQIQB8JSdCgUotar/iTqF+XdLjANBglghkgB # ZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgAChAoAAMBkGCSqGSIb3DQEJ # AzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8G # CSqGSIb3DQEJBDEiBCCZ2YQ6sNB8rfnGpMeLfaiar0qGYTqH7QCt3x3fyQUjBDAN # BgkqhkiG9w0BAQEFAASCAgCHuw5WRv6FTHnoDO+8XOpS/dwWG7oweQB653N793F0 # YWchx2fxhTOjET+7dMIHQSWTvXnco1AEHbpYDmNArUSCBgUqhLRZ15uFoqIeYM+/ # 9dDNMV35/EfOmTlIrHHJRDidfgRXLncogdE/5oMYCVqUWKiLde8XUVZ1v6R+vMt9 # 98K2OvrQ5GeoOsmMxhgCZfAgfkfd4AQ1A2gnrZ+cXXPaRKNb6plw+Ze8xwSVPGw9 # MwhKiCx7M1bzpTNWnFdvzpMrCxHDGfuirDe0ANiPmUxn8Vl4pGyqtjuZ1qjjjHbC # AapRwtOXBl0GUPOk5AW6k/lTobQc5v13O5EPYJoQP61R/mufeCkKCOOxNfssyd2V # RAZYOMoD/TPDM4oVWzrocsdYczDZgpi8Ka0YjosdM9MqgHuhOy/hOjflfO9pLELi # EwqvgmgbBixFmypfnc4T/KL9ReFzS5NaAPwH3jVJjlhijUO2uknskXm4rDArtkea # KsaR1pR091lU8vOMMHpYCcxrwYwfWpeDVycXfZv0OsZZqxGsCpPNhVGnFMBXV8e1 # o6CtaBCxS5q89zwCzwkEI2EFB6cgB//eijjIZ3JKk5gOmMKJ0YmsS/4ajWHeKqRB # +laKCZyS2NXdEd6aQGVSJhsGSO8cc3JiHRvTK3ItwVviIoL6b+2DjFBWabsotnkn # n6GCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYTAlVT # MRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1 # c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OUnQg5 # pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZIhvcN # AQcBMBwGCSqGSIb3DQEJBTEPFw0yMzExMTcwNzM0MzhaMC8GCSqGSIb3DQEJBDEi # BCDWxgWLGqfPyTe4UAL6fzCUrxqmX4AetqIedInCP54nRjANBgkqhkiG9w0BAQEF # AASCAgB1WBiUsUuOub5AAotvXH/V8gTdomGKpZAB18LV8Z2kb7WJKKPufXvA9d/Q # J14Xq6sAlt90uiRm+TCYOLeySV/rLDOhtPihWOkbJuG2yutM665HUnyOKWqPu5Bg # Iwu0e/JMhjU3tw7eytoYR1ok+hBKHi76HZN9Z5bmUoppYLunWDnPzXZnd20RlgfM # fRgwEAw1Jkpe6tZKRegEAwgY38hFRYYwXZMKE6lJZE/f5kFPh2xUzNZrv943cbEn # 6xPm6cslpMwb6LN6B5LFU4lSkRm0P+jVUPH5yz/cVc77WmA/UIWlrKxf+je5S33i # NPn1WllowdedhghNdm/HqbcUADXeQ+wpO7LzGEzZND3CIP/hSieQFhGHm1cSCKkX # Vw+t2EiMYYSfbpJuQtDPDyxUJZ43hYKwQeXFRz750vsaUxZsqHsjkg4HnpqAaecV # S1V0OHNNfBol2aa4KNgKpDZFEo6VVlyvaXMDXEX5wllkJug4aTcPnNWdyCepwiWp # bZAdrn29YbepwzyTfqDp2i43pZlbghqVs55oNEJfA5iNNzsy2vI174xoP1E8DNiK # /pego4/Z4DjUS1Oe97P8qTQoSmrEwo3Cwde0nBlrp8Is6dpuF5+U70noHvqIvSVe # SVpTIIQu+6ptBB67lmsaQG8SDSE1rCj2FB/QSBZG2HO3mUzCCw== # SIG # End signature block |