Files

187 lines
36 KiB
PowerShell

$Esc = [char]27
$Reset = "$Esc[0m"
$BlockFull = [char]0x2588
$BlockLower = [char]0x2584
$BlockUpper = [char]0x2580
$BlockLeft = [char]0x258C
function Enable-VTMode {
$sig = @"
using System;
using System.Runtime.InteropServices;
public static class SpoTUIInstallerNative {
[DllImport("kernel32.dll")]
public static extern IntPtr GetStdHandle(int nStdHandle);
[DllImport("kernel32.dll")]
public static extern bool GetConsoleMode(IntPtr hConsoleHandle, out uint lpMode);
[DllImport("kernel32.dll")]
public static extern bool SetConsoleMode(IntPtr hConsoleHandle, uint dwMode);
}
"@
try {
Add-Type -TypeDefinition $sig -ErrorAction SilentlyContinue
$handle = [SpoTUIInstallerNative]::GetStdHandle(-11)
$mode = 0
[SpoTUIInstallerNative]::GetConsoleMode($handle, [ref]$mode) | Out-Null
[SpoTUIInstallerNative]::SetConsoleMode($handle, $mode -bor 0x0004) | Out-Null
} catch {}
}
Enable-VTMode
try {
[Console]::OutputEncoding = [System.Text.Encoding]::UTF8
} catch {}
$ProgressPreference = 'SilentlyContinue'
function Get-RGBCode($r, $g, $b) {
return "$Esc[38;2;$r;$g;${b}m"
}
$OrangeLight = Get-RGBCode 255 140 66
$OrangeDark = Get-RGBCode 224 123 57
$OrangeMid = Get-RGBCode 240 131 61
$GreenAnsi = Get-RGBCode 140 255 140
$RedAnsi = Get-RGBCode 255 110 110
$GrayAnsi = Get-RGBCode 130 130 130
function Get-GradientColor($index, $total) {
$r1 = 255; $g1 = 140; $b1 = 66
$r2 = 224; $g2 = 123; $b2 = 57
$t = if ($total -le 1) { 0 } else { $index / ($total - 1) }
$r = [int]($r1 + ($r2 - $r1) * $t)
$g = [int]($g1 + ($g2 - $g1) * $t)
$b = [int]($b1 + ($b2 - $b1) * $t)
return Get-RGBCode $r $g $b
}
function Get-AsciiArtLine($template) {
$out = $template
$out = $out.Replace("A", $BlockFull)
$out = $out.Replace("B", $BlockLower)
$out = $out.Replace("C", $BlockUpper)
$out = $out.Replace("D", $BlockLeft)
return $out
}
function Show-Header {
Clear-Host
$templates = @(
" BAAAAAAAA BAAAAAAAB BAAAAAAAB AAA AAA AB BA ",
" AAA AAA AAA AAA AAA AAA CAAAAAAAAAB AAA AAA AAA ",
" AAA AC AAA AAA AAA AAA CAAACCAA AAA AAA AAAD ",
" AAA AAA AAA AAA AAA AAA C AAA AAA AAAD ",
"CAAAAAAAAAAA CAAAAAAAAAC AAA AAA AAA AAA AAA AAAD ",
" AAA AAA AAA AAA AAA AAA AAA AAA ",
" BA AAA AAA AAA AAA AAA AAA AAA AAA ",
" BAAAAAAAAC BAAAAC CAAAAAAC BAAAAC AAAAAAAAC AC "
)
Write-Host ""
for ($i = 0; $i -lt $templates.Count; $i++) {
$color = Get-GradientColor $i $templates.Count
$line = Get-AsciiArtLine $templates[$i]
Write-Host "$color$line$Reset"
}
Write-Host ""
Write-Host "$OrangeMid Installer$Reset"
Write-Host "$OrangeDark =============================================================$Reset"
Write-Host ""
}
$SpinnerCodes = @(0x280B,0x2819,0x2839,0x2838,0x283C,0x2834,0x2826,0x2827,0x2807,0x280F)
$SpinnerFrames = $SpinnerCodes | ForEach-Object { [char]$_ }
$CheckMark = [char]0x2713
$CrossMark = [char]0x2715
$CR = [char]13
function Invoke-Step {
param(
[string]$Label,
[scriptblock]$Work
)
try { [Console]::CursorVisible = $false } catch {}
$job = Start-Job -ScriptBlock $Work
$frameIndex = 0
while ($job.State -eq "Running") {
$frame = $SpinnerFrames[$frameIndex % $SpinnerFrames.Count]
$color = Get-GradientColor ($frameIndex % 8) 8
Write-Host ($CR + " " + $color + $frame + $Reset + " " + $Label) -NoNewline
Start-Sleep -Milliseconds 80
$frameIndex++
}
Receive-Job -Job $job | Out-Null
$failed = $job.State -eq "Failed" -or ($job.ChildJobs[0].Error.Count -gt 0)
Remove-Job -Job $job -Force | Out-Null
$pad = " " * 40
if ($failed) {
Write-Host ($CR + " " + $RedAnsi + $CrossMark + $Reset + " " + $Label + $pad)
}
else {
Write-Host ($CR + " " + $GreenAnsi + $CheckMark + $Reset + " " + $Label + $pad)
}
try { [Console]::CursorVisible = $true } catch {}
return -not $failed
}
Show-Header
$targetDir = "$env:APPDATA\spotui"
$scriptPath = "$targetDir\install.ps1"
$wrapperPath = "$targetDir\spotui.ps1"
$batchPath = "$targetDir\spotui.bat"
$spotuiScriptContentBase64 = "JFRoZW1lTmFtZSAgID0gIlNwb1RVSSINCiRSZXBvVXJsICAgICA9ICJodHRwczovL2dpdGh1Yi5jb20vU2tlblNNYXN0ZVIvU3BvVFVJIg0KJFRoZW1lc0RpciAgID0gSm9pbi1QYXRoICRlbnY6QVBQREFUQSAic3BpY2V0aWZ5XFRoZW1lcyINCiRUaGVtZVBhdGggICA9IEpvaW4tUGF0aCAkVGhlbWVzRGlyICRUaGVtZU5hbWUNCg0KJEVzYyAgID0gW2NoYXJdMjcNCiRSZXNldCA9ICIkRXNjWzBtIg0KJEFuc2lQYXR0ZXJuID0gIiRFc2NcW1swLTk7XSptIg0KDQokQmxvY2tGdWxsICA9IFtjaGFyXTB4MjU4OA0KJEJsb2NrTG93ZXIgPSBbY2hhcl0weDI1ODQNCiRCbG9ja1VwcGVyID0gW2NoYXJdMHgyNTgwDQokQmxvY2tMZWZ0ICA9IFtjaGFyXTB4MjU4Qw0KDQpmdW5jdGlvbiBFbmFibGUtVlRNb2RlIHsNCiAgICAkc2lnID0gQCINCnVzaW5nIFN5c3RlbTsNCnVzaW5nIFN5c3RlbS5SdW50aW1lLkludGVyb3BTZXJ2aWNlczsNCnB1YmxpYyBzdGF0aWMgY2xhc3MgU3BvVFVJTmF0aXZlIHsNCiAgICBbRGxsSW1wb3J0KCJrZXJuZWwzMi5kbGwiKV0NCiAgICBwdWJsaWMgc3RhdGljIGV4dGVybiBJbnRQdHIgR2V0U3RkSGFuZGxlKGludCBuU3RkSGFuZGxlKTsNCiAgICBbRGxsSW1wb3J0KCJrZXJuZWwzMi5kbGwiKV0NCiAgICBwdWJsaWMgc3RhdGljIGV4dGVybiBib29sIEdldENvbnNvbGVNb2RlKEludFB0ciBoQ29uc29sZUhhbmRsZSwgb3V0IHVpbnQgbHBNb2RlKTsNCiAgICBbRGxsSW1wb3J0KCJrZXJuZWwzMi5kbGwiKV0NCiAgICBwdWJsaWMgc3RhdGljIGV4dGVybiBib29sIFNldENvbnNvbGVNb2RlKEludFB0ciBoQ29uc29sZUhhbmRsZSwgdWludCBkd01vZGUpOw0KfQ0KIkANCiAgICB0cnkgew0KICAgICAgICBBZGQtVHlwZSAtVHlwZURlZmluaXRpb24gJHNpZyAtRXJyb3JBY3Rpb24gU2lsZW50bHlDb250aW51ZQ0KICAgICAgICAkaGFuZGxlID0gW1Nwb1RVSU5hdGl2ZV06OkdldFN0ZEhhbmRsZSgtMTEpDQogICAgICAgICRtb2RlID0gMA0KICAgICAgICBbU3BvVFVJTmF0aXZlXTo6R2V0Q29uc29sZU1vZGUoJGhhbmRsZSwgW3JlZl0kbW9kZSkgfCBPdXQtTnVsbA0KICAgICAgICBbU3BvVFVJTmF0aXZlXTo6U2V0Q29uc29sZU1vZGUoJGhhbmRsZSwgJG1vZGUgLWJvciAweDAwMDQpIHwgT3V0LU51bGwNCiAgICB9IGNhdGNoIHt9DQp9DQpFbmFibGUtVlRNb2RlDQoNCnRyeSB7DQogICAgW0NvbnNvbGVdOjpPdXRwdXRFbmNvZGluZyA9IFtTeXN0ZW0uVGV4dC5FbmNvZGluZ106OlVURjgNCn0gY2F0Y2gge30NCg0KZnVuY3Rpb24gR2V0LVJHQkNvZGUoJHIsICRnLCAkYikgew0KICAgIHJldHVybiAiJEVzY1szODsyOyRyOyRnOyR7Yn1tIg0KfQ0KDQokT3JhbmdlTGlnaHQgPSBHZXQtUkdCQ29kZSAyNTUgMTQwIDY2DQokT3JhbmdlRGFyayAgPSBHZXQtUkdCQ29kZSAyMjQgMTIzIDU3DQokT3JhbmdlTWlkICAgPSBHZXQtUkdCQ29kZSAyNDAgMTMxIDYxDQokR3JlZW5BbnNpICAgPSBHZXQtUkdCQ29kZSAxNDAgMjU1IDE0MA0KJFNlbGVjdEJnICAgID0gIiRFc2NbNDg7MjsyNTU7MTQwOzY2bSRFc2NbMzg7MjswOzA7MG0iDQoNCiRXaGl0ZSA9ICJXaGl0ZSINCiRHcmF5ICA9ICJEYXJrR3JheSINCiRSZWQgICA9ICJSZWQiDQokR3JlZW4gPSAiR3JlZW4iDQokQ3lhbiAgPSAiQ3lhbiINCg0KIyBUcmFja3Mgd2hldGhlciB3ZSd2ZSBhbHJlYWR5IGF0dGVtcHRlZCBhIHdpbmdldCB1cGRhdGUgdGhpcyBzZXNzaW9uLA0KIyBzbyBUZXN0LURlcGVuZGVuY2llcyBkb2Vzbid0IHJlLXJ1biBpdCBvbiBldmVyeSBtZW51IGFjdGlvbi4NCiRzY3JpcHQ6V2luZ2V0VXBkYXRlQXR0ZW1wdGVkID0gJGZhbHNlDQoNCmZ1bmN0aW9uIEdldC1HcmFkaWVudENvbG9yKCRpbmRleCwgJHRvdGFsKSB7DQogICAgJHIxID0gMjU1OyAkZzEgPSAxNDA7ICRiMSA9IDY2DQogICAgJHIyID0gMjI0OyAkZzIgPSAxMjM7ICRiMiA9IDU3DQogICAgJHQgPSBpZiAoJHRvdGFsIC1sZSAxKSB7IDAgfSBlbHNlIHsgJGluZGV4IC8gKCR0b3RhbCAtIDEpIH0NCiAgICAkciA9IFtpbnRdKCRyMSArICgkcjIgLSAkcjEpICogJHQpDQogICAgJGcgPSBbaW50XSgkZzEgKyAoJGcyIC0gJGcxKSAqICR0KQ0KICAgICRiID0gW2ludF0oJGIxICsgKCRiMiAtICRiMSkgKiAkdCkNCiAgICByZXR1cm4gR2V0LVJHQkNvZGUgJHIgJGcgJGINCn0NCg0KZnVuY3Rpb24gR2V0LUFzY2lpQXJ0TGluZSgkdGVtcGxhdGUpIHsNCiAgICAkb3V0ID0gJHRlbXBsYXRlDQogICAgJG91dCA9ICRvdXQuUmVwbGFjZSgiQSIsICRCbG9ja0Z1bGwpDQogICAgJG91dCA9ICRvdXQuUmVwbGFjZSgiQiIsICRCbG9ja0xvd2VyKQ0KICAgICRvdXQgPSAkb3V0LlJlcGxhY2UoIkMiLCAkQmxvY2tVcHBlcikNCiAgICAkb3V0ID0gJG91dC5SZXBsYWNlKCJEIiwgJEJsb2NrTGVmdCkNCiAgICByZXR1cm4gJG91dA0KfQ0KDQpmdW5jdGlvbiBHZXQtSGVhZGVyTGluZXMgew0KICAgICRsaW5lcyA9IEAoKQ0KICAgICRsaW5lcyArPSAiIg0KICAgICR0ZW1wbGF0ZXMgPSBAKA0KICAgICAgICAiICAgQkFBQUFBQUFBICAgIEJBQUFBQUFBQiAgQkFBQUFBQUFCICAgICAgQUFBICAgIEFBQSAgICBBQiAgIEJBICAiLA0KICAgICAgICAiICBBQUEgICAgQUFBICAgQUFBICAgIEFBQSBBQUEgICAgQUFBIENBQUFBQUFBQUFCIEFBQSAgICBBQUEgQUFBICAiLA0KICAgICAgICAiICBBQUEgICAgQUMgICAgQUFBICAgIEFBQSBBQUEgICAgQUFBICAgIENBQUFDQ0FBIEFBQSAgICBBQUEgQUFBRCAiLA0KICAgICAgICAiICBBQUEgICAgICAgICAgQUFBICAgIEFBQSBBQUEgICAgQUFBICAgICBBQUEgICBDIEFBQSAgICBBQUEgQUFBRCAiLA0KICAgICAgICAiQ0FBQUFBQUFBQUFBIENBQUFBQUFBQUFDICBBQUEgICAgQUFBICAgICBBQUEgICAgIEFBQSAgICBBQUEgQUFBRCAiLA0KICAgICAgICAiICAgICAgICAgQUFBICAgQUFBICAgICAgICBBQUEgICAgQUFBICAgICBBQUEgICAgIEFBQSAgICBBQUEgQUFBICAiLA0KICAgICAgICAiICAgQkEgICAgQUFBICAgQUFBICAgICAgICBBQUEgICAgQUFBICAgICBBQUEgICAgIEFBQSAgICBBQUEgQUFBICAiLA0KICAgICAgICAiIEJBQUFBQUFBQUMgICBCQUFBQUMgICAgICAgQ0FBQUFBQUMgICAgIEJBQUFBQyAgIEFBQUFBQUFBQyAgQUMgICAiDQogICAgKQ0KICAgIGZvciAoJGkgPSAwOyAkaSAtbHQgJHRlbXBsYXRlcy5Db3VudDsgJGkrKykgew0KICAgICAgICAkY29sb3IgPSBHZXQtR3JhZGllbnRDb2xvciAkaSAkdGVtcGxhdGVzLkNvdW50DQogICAgICAgICRsaW5lID0gR2V0LUFzY2lpQXJ0TGluZSAkdGVtcGxhdGVzWyRpXQ0KICAgICAgICAkbGluZXMgKz0gIiRjb2xvciRsaW5lJFJlc2V0Ig0KICAgIH0NCiAgICAkbGluZXMgKz0gIiINCiAgICAkbGluZXMgKz0gIiRPcmFuZ2VNaWQgICAgICAgICAgICAgICAgICAgICBTcGljZXRpZnkgVGhlbWUgTWFuYWdlciRSZXNldCINCiAgICAkbGluZXMgKz0gIiRPcmFuZ2VEYXJrICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09JFJlc2V0Ig0KICAgICRsaW5lcyArPSAiIg0KICAgIHJldHVybiAkbGluZXMNCn0NCg0KZnVuY3Rpb24gU2hvdy1IZWFkZXIgew0KICAgIENsZWFyLUhvc3QNCiAgICBmb3JlYWNoICgkbGluZSBpbiAoR2V0LUhlYWRlckxpbmVzKSkgew0KICAgICAgICBXcml0ZS1Ib3N0ICRsaW5lDQogICAgfQ0KfQ0KDQpmdW5jdGlvbiBHZXQtVmlzaWJsZUxlbmd0aCgkdGV4dCkgew0KICAgICRzdHJpcHBlZCA9ICR0ZXh0IC1yZXBsYWNlICRBbnNpUGF0dGVybiwgIiINCiAgICByZXR1cm4gJHN0cmlwcGVkLkxlbmd0aA0KfQ0KDQpmdW5jdGlvbiBXcml0ZS1GcmFtZSgkbGluZXMpIHsNCiAgICB0cnkgeyBbQ29uc29sZV06OlNldEN1cnNvclBvc2l0aW9uKDAsIDApIH0gY2F0Y2gge30NCiAgICAkd2lkdGggPSA4MA0KICAgIHRyeSB7ICR3aWR0aCA9ICRIb3N0LlVJLlJhd1VJLldpbmRvd1NpemUuV2lkdGggfSBjYXRjaCB7fQ0KICAgIGZvcmVhY2ggKCRsaW5lIGluICRsaW5lcykgew0KICAgICAgICAkdmlzaWJsZSA9IEdldC1WaXNpYmxlTGVuZ3RoICRsaW5lDQogICAgICAgICRwYWQgPSAkd2lkdGggLSAkdmlzaWJsZSAtIDENCiAgICAgICAgaWYgKCRwYWQgLWx0IDApIHsgJHBhZCA9IDAgfQ0KICAgICAgICBXcml0ZS1Ib3N0ICgkbGluZSArICgiICIgKiAkcGFkKSkNCiAgICB9DQp9DQoNCmZ1bmN0aW9uIEdldC1Db25zb2xlSGVpZ2h0IHsNCiAgICAkaGVpZ2h0ID0gMzANCiAgICB0cnkgeyAkaGVpZ2h0ID0gJEhvc3QuVUkuUmF3VUkuV2luZG93U2l6ZS5IZWlnaHQgfSBjYXRjaCB7fQ0KICAgIHJldHVybiAkaGVpZ2h0DQp9DQoNCmZ1bmN0aW9uIFJlZnJlc2gtUGF0aCB7DQogICAgJG1hY2hpbmVQYXRoID0gW1N5c3RlbS5FbnZpcm9ubWVudF06OkdldEVudmlyb25tZW50VmFyaWFibGUoIlBhdGgiLCAiTWFjaGluZSIpDQogICAgJHVzZXJQYXRoID0gW1N5c3RlbS5FbnZpcm9ubWVudF06OkdldEVudmlyb25tZW50VmFyaWFibGUoIlBhdGgiLCAiVXNlciIpDQogICAgJGVudjpQYXRoID0gIiRtYWNoaW5lUGF0aDskdXNlclBhdGgiDQp9DQoNCmZ1bmN0aW9uIFVwZGF0ZS1XaW5nZXQgew0KICAgIFdyaXRlLUhvc3QgIiRPcmFuZ2VNaWQgIFVwZGF0aW5nIHdpbmdldC4uLiRSZXNldCINCg0KICAgIGlmIChHZXQtQ29tbWFuZCB3aW5nZXQgLUVycm9yQWN0aW9uIFNpbGVudGx5Q29udGludWUpIHsNCiAgICAgICAgdHJ5IHsNCiAgICAgICAgICAgICRwcm9jID0gU3RhcnQtUHJvY2VzcyAtRmlsZVBhdGggIndpbmdldCIgLUFyZ3VtZW50TGlzdCAidXBncmFkZSIsIi0taWQiLCJNaWNyb3NvZnQuQXBwSW5zdGFsbGVyIiwiLWUiLCItLXNvdXJjZSIsIndpbmdldCIsIi0tYWNjZXB0LXBhY2thZ2UtYWdyZWVtZW50cyIsIi0tYWNjZXB0LXNvdXJjZS1hZ3JlZW1lbnRzIiAtV2FpdCAtUGFzc1RocnUgLVdpbmRvd1N0eWxlIEhpZGRlbg0KICAgICAgICAgICAgV3JpdGUtSG9zdCAiICB3aW5nZXQgdXBncmFkZSBleGl0ZWQgd2l0aCBjb2RlICQoJHByb2MuRXhpdENvZGUpIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgICAgIH0gY2F0Y2ggew0KICAgICAgICAgICAgV3JpdGUtSG9zdCAiICB3aW5nZXQgdXBncmFkZSBjb21tYW5kIGZhaWxlZCB0byBydW4uIiAtRm9yZWdyb3VuZENvbG9yICRSZWQNCiAgICAgICAgfQ0KDQogICAgICAgIHRyeSB7DQogICAgICAgICAgICB3aW5nZXQgc291cmNlIHJlc2V0IC0tZm9yY2UgfCBPdXQtTnVsbA0KICAgICAgICB9IGNhdGNoIHt9DQoNCiAgICAgICAgcmV0dXJuDQogICAgfQ0KDQogICAgV3JpdGUtSG9zdCAiICB3aW5nZXQgY29tbWFuZCBub3QgZm91bmQuIEluc3RhbGxpbmcgQXBwIEluc3RhbGxlciBmcm9tIEdpdEh1YiByZWxlYXNlLi4uIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgdHJ5IHsNCiAgICAgICAgJHJlbGVhc2UgPSBJbnZva2UtUmVzdE1ldGhvZCAtVXJpICJodHRwczovL2FwaS5naXRodWIuY29tL3JlcG9zL21pY3Jvc29mdC93aW5nZXQtY2xpL3JlbGVhc2VzL2xhdGVzdCINCiAgICAgICAgJGFzc2V0ID0gJHJlbGVhc2UuYXNzZXRzIHwgV2hlcmUtT2JqZWN0IHsgJF8ubmFtZSAtbGlrZSAiKi5tc2l4YnVuZGxlIiB9IHwgU2VsZWN0LU9iamVjdCAtRmlyc3QgMQ0KDQogICAgICAgIGlmICgtbm90ICRhc3NldCkgew0KICAgICAgICAgICAgV3JpdGUtSG9zdCAiICBDb3VsZCBub3QgZmluZCBhIC5tc2l4YnVuZGxlIGFzc2V0IGluIHRoZSBsYXRlc3QgcmVsZWFzZS4iIC1Gb3JlZ3JvdW5kQ29sb3IgJFJlZA0KICAgICAgICAgICAgcmV0dXJuDQogICAgICAgIH0NCg0KICAgICAgICAkZG93bmxvYWRQYXRoID0gSm9pbi1QYXRoICRlbnY6VEVNUCAkYXNzZXQubmFtZQ0KICAgICAgICBXcml0ZS1Ib3N0ICIgIERvd25sb2FkaW5nICQoJGFzc2V0Lm5hbWUpLi4uIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgICAgIEludm9rZS1XZWJSZXF1ZXN0IC1VcmkgJGFzc2V0LmJyb3dzZXJfZG93bmxvYWRfdXJsIC1PdXRGaWxlICRkb3dubG9hZFBhdGgNCg0KICAgICAgICBXcml0ZS1Ib3N0ICIgIEluc3RhbGxpbmcgcGFja2FnZS4uLiIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgICAgICBBZGQtQXBweFBhY2thZ2UgLVBhdGggJGRvd25sb2FkUGF0aCAtRXJyb3JBY3Rpb24gU3RvcA0KDQogICAgICAgIFdyaXRlLUhvc3QgIiAgQXBwIEluc3RhbGxlciBpbnN0YWxsZWQgc3VjY2Vzc2Z1bGx5LiIgLUZvcmVncm91bmRDb2xvciAkR3JlZW4NCiAgICAgICAgUmVtb3ZlLUl0ZW0gJGRvd25sb2FkUGF0aCAtRm9yY2UgLUVycm9yQWN0aW9uIFNpbGVudGx5Q29udGludWUNCiAgICB9DQogICAgY2F0Y2ggew0KICAgICAgICBXcml0ZS1Ib3N0ICIgIEZhaWxlZCB0byBpbnN0YWxsIEFwcCBJbnN0YWxsZXIgYXV0b21hdGljYWxseTogJCgkXy5FeGNlcHRpb24uTWVzc2FnZSkiIC1Gb3JlZ3JvdW5kQ29sb3IgJFJlZA0KICAgICAgICBXcml0ZS1Ib3N0ICIgIFlvdSBjYW4gaW5zdGFsbCBpdCBtYW51YWxseSBmcm9tIHRoZSBNaWNyb3NvZnQgU3RvcmUgKHNlYXJjaCAnQXBwIEluc3RhbGxlcicpLiIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgIH0NCg0KICAgIFJlZnJlc2gtUGF0aA0KfQ0KDQpmdW5jdGlvbiBJbnN0YWxsLURlcGVuZGVuY3koJG5hbWUpIHsNCiAgICBpZiAoJG5hbWUgLWVxICJnaXQiKSB7DQogICAgICAgIGlmIChHZXQtQ29tbWFuZCB3aW5nZXQgLUVycm9yQWN0aW9uIFNpbGVudGx5Q29udGludWUpIHsNCiAgICAgICAgICAgIFdyaXRlLUhvc3QgIiAgTGF1bmNoaW5nIHdpbmdldCB0byBpbnN0YWxsIEdpdC4uLiIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgICAgICAgICAgJHByb2MgPSBTdGFydC1Qcm9jZXNzIC1GaWxlUGF0aCAid2luZ2V0IiAtQXJndW1lbnRMaXN0ICJpbnN0YWxsIiwiLS1pZCIsIkdpdC5HaXQiLCItZSIsIi0tc291cmNlIiwid2luZ2V0IiwiLS1hY2NlcHQtcGFja2FnZS1hZ3JlZW1lbnRzIiwiLS1hY2NlcHQtc291cmNlLWFncmVlbWVudHMiIC1XYWl0IC1QYXNzVGhydQ0KICAgICAgICAgICAgV3JpdGUtSG9zdCAiICB3aW5nZXQgZXhpdGVkIHdpdGggY29kZSAkKCRwcm9jLkV4aXRDb2RlKSIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KDQogICAgICAgICAgICAjIDB4QzAwMDAwMDUgPSBhY2Nlc3MgdmlvbGF0aW9uIC8gd2luZ2V0IGNyYXNoLiBVcGRhdGUgd2luZ2V0IG9uY2UgYW5kIHJldHJ5Lg0KICAgICAgICAgICAgaWYgKCRwcm9jLkV4aXRDb2RlIC1lcSAtMTA3Mzc0MTgxOSAtYW5kIC1ub3QgJHNjcmlwdDpXaW5nZXRVcGRhdGVBdHRlbXB0ZWQpIHsNCiAgICAgICAgICAgICAgICBXcml0ZS1Ib3N0ICIgIHdpbmdldCBjcmFzaGVkLiBBdHRlbXB0aW5nIHRvIHVwZGF0ZSB3aW5nZXQgYW5kIHJldHJ5Li4uIiAtRm9yZWdyb3VuZENvbG9yICRSZWQNCiAgICAgICAgICAgICAgICAkc2NyaXB0OldpbmdldFVwZGF0ZUF0dGVtcHRlZCA9ICR0cnVlDQogICAgICAgICAgICAgICAgVXBkYXRlLVdpbmdldA0KDQogICAgICAgICAgICAgICAgV3JpdGUtSG9zdCAiICBSZXRyeWluZyBHaXQgaW5zdGFsbC4uLiIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgICAgICAgICAgICAgICRwcm9jID0gU3RhcnQtUHJvY2VzcyAtRmlsZVBhdGggIndpbmdldCIgLUFyZ3VtZW50TGlzdCAiaW5zdGFsbCIsIi0taWQiLCJHaXQuR2l0IiwiLWUiLCItLXNvdXJjZSIsIndpbmdldCIsIi0tYWNjZXB0LXBhY2thZ2UtYWdyZWVtZW50cyIsIi0tYWNjZXB0LXNvdXJjZS1hZ3JlZW1lbnRzIiAtV2FpdCAtUGFzc1RocnUNCiAgICAgICAgICAgICAgICBXcml0ZS1Ib3N0ICIgIHdpbmdldCBleGl0ZWQgd2l0aCBjb2RlICQoJHByb2MuRXhpdENvZGUpIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgICAgICAgICB9DQoNCiAgICAgICAgICAgIFJlZnJlc2gtUGF0aA0KICAgICAgICAgICAgJHRyaWVzID0gMA0KICAgICAgICAgICAgd2hpbGUgKC1ub3QgKEdldC1Db21tYW5kIGdpdCAtRXJyb3JBY3Rpb24gU2lsZW50bHlDb250aW51ZSkgLWFuZCAkdHJpZXMgLWx0IDEwKSB7DQogICAgICAgICAgICAgICAgU3RhcnQtU2xlZXAgLVNlY29uZHMgMQ0KICAgICAgICAgICAgICAgIFJlZnJlc2gtUGF0aA0KICAgICAgICAgICAgICAgICR0cmllcysrDQogICAgICAgICAgICB9DQogICAgICAgIH0NCiAgICAgICAgZWxzZSB7DQogICAgICAgICAgICBXcml0ZS1Ib3N0ICIgIHdpbmdldCB3YXMgbm90IGZvdW5kLiBJbnN0YWxsIEdpdCBtYW51YWxseSBmcm9tIGh0dHBzOi8vZ2l0LXNjbS5jb20vZG93bmxvYWQvd2luIiAtRm9yZWdyb3VuZENvbG9yICRSZWQNCiAgICAgICAgfQ0KICAgIH0NCiAgICBlbHNlaWYgKCRuYW1lIC1lcSAic3BpY2V0aWZ5Iikgew0KICAgICAgICAkaW5zdGFsbENvbW1hbmQgPSAiaXdyIC11c2ViIGh0dHBzOi8vcmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbS9zcGljZXRpZnkvY2xpL21haW4vaW5zdGFsbC5wczEgfCBpZXgiDQogICAgICAgIFdyaXRlLUhvc3QgIiAgT3BlbmluZyBhIG5ldyB3aW5kb3cgdG8gaW5zdGFsbCBTcGljZXRpZnkuIFdhaXRpbmcgZm9yIGl0IHRvIGZpbmlzaC4uLiIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgICAgICBTdGFydC1Qcm9jZXNzIC1GaWxlUGF0aCAicG93ZXJzaGVsbC5leGUiIC1Bcmd1bWVudExpc3QgIi1Ob1Byb2ZpbGUiLCAiLUV4ZWN1dGlvblBvbGljeSIsICJCeXBhc3MiLCAiLUNvbW1hbmQiLCAkaW5zdGFsbENvbW1hbmQgLVdhaXQNCiAgICAgICAgV3JpdGUtSG9zdCAiICBTcGljZXRpZnkgaW5zdGFsbGVyIHdpbmRvdyBjbG9zZWQuIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgICAgIFJlZnJlc2gtUGF0aA0KICAgIH0NCn0NCg0KZnVuY3Rpb24gVGVzdC1EZXBlbmRlbmNpZXMgew0KICAgICRtaXNzaW5nID0gQCgpDQogICAgaWYgKC1ub3QgKEdldC1Db21tYW5kIGdpdCAtRXJyb3JBY3Rpb24gU2lsZW50bHlDb250aW51ZSkpIHsgJG1pc3NpbmcgKz0gImdpdCIgfQ0KICAgIGlmICgtbm90IChHZXQtQ29tbWFuZCBzcGljZXRpZnkgLUVycm9yQWN0aW9uIFNpbGVudGx5Q29udGludWUpKSB7ICRtaXNzaW5nICs9ICJzcGljZXRpZnkiIH0NCg0KICAgIGlmICgkbWlzc2luZy5Db3VudCAtZXEgMCkgew0KICAgICAgICByZXR1cm4gJHRydWUNCiAgICB9DQoNCiAgICBXcml0ZS1Ib3N0ICIgIE1pc3NpbmcgZGVwZW5kZW5jaWVzOiAkKCRtaXNzaW5nIC1qb2luICcsICcpIiAtRm9yZWdyb3VuZENvbG9yICRSZWQNCiAgICBXcml0ZS1Ib3N0ICIiDQogICAgJGNvbmZpcm0gPSBSZWFkLUhvc3QgIiAgUHJlc3MgSSB0byBpbnN0YWxsIHRoZW0gbm93LCBvciBhbnkgb3RoZXIga2V5IHRvIGNhbmNlbCINCiAgICBpZiAoJGNvbmZpcm0gLW5lICJJIiAtYW5kICRjb25maXJtIC1uZSAiaSIpIHsNCiAgICAgICAgcmV0dXJuICRmYWxzZQ0KICAgIH0NCg0KICAgIGZvcmVhY2ggKCRkZXAgaW4gJG1pc3NpbmcpIHsNCiAgICAgICAgV3JpdGUtSG9zdCAiIg0KICAgICAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTWlkICBJbnN0YWxsaW5nICRkZXAuLi4kUmVzZXQiDQogICAgICAgIEluc3RhbGwtRGVwZW5kZW5jeSAkZGVwDQogICAgfQ0KDQogICAgV3JpdGUtSG9zdCAiIg0KICAgIFdyaXRlLUhvc3QgIiRPcmFuZ2VNaWQgIFJlZnJlc2hpbmcgZW52aXJvbm1lbnQgUEFUSC4uLiRSZXNldCINCiAgICBSZWZyZXNoLVBhdGgNCg0KICAgICRzdGlsbE1pc3NpbmcgPSBAKCkNCiAgICBpZiAoLW5vdCAoR2V0LUNvbW1hbmQgZ2l0IC1FcnJvckFjdGlvbiBTaWxlbnRseUNvbnRpbnVlKSkgeyAkc3RpbGxNaXNzaW5nICs9ICJnaXQiIH0NCiAgICBpZiAoLW5vdCAoR2V0LUNvbW1hbmQgc3BpY2V0aWZ5IC1FcnJvckFjdGlvbiBTaWxlbnRseUNvbnRpbnVlKSkgeyAkc3RpbGxNaXNzaW5nICs9ICJzcGljZXRpZnkiIH0NCg0KICAgIGlmICgkc3RpbGxNaXNzaW5nLkNvdW50IC1ndCAwKSB7DQogICAgICAgIFdyaXRlLUhvc3QgIiINCiAgICAgICAgV3JpdGUtSG9zdCAiICBTdGlsbCBtaXNzaW5nOiAkKCRzdGlsbE1pc3NpbmcgLWpvaW4gJywgJykuIFlvdSBtYXkgbmVlZCB0byByZXN0YXJ0IHlvdXIgdGVybWluYWwuIiAtRm9yZWdyb3VuZENvbG9yICRSZWQNCiAgICAgICAgcmV0dXJuICRmYWxzZQ0KICAgIH0NCg0KICAgIFdyaXRlLUhvc3QgIiINCiAgICBXcml0ZS1Ib3N0ICIgIEFsbCBkZXBlbmRlbmNpZXMgaW5zdGFsbGVkIHN1Y2Nlc3NmdWxseS4iIC1Gb3JlZ3JvdW5kQ29sb3IgJEdyZWVuDQogICAgcmV0dXJuICR0cnVlDQp9DQoNCmZ1bmN0aW9uIEdldC1EZWZhdWx0QnJhbmNoIHsNCiAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICAkcmVmID0gZ2l0IHN5bWJvbGljLXJlZiByZWZzL3JlbW90ZXMvb3JpZ2luL0hFQUQgMj4kbnVsbA0KICAgIFBvcC1Mb2NhdGlvbg0KICAgIGlmICgkcmVmKSB7DQogICAgICAgICRwYXJ0cyA9ICRyZWYgLXNwbGl0ICIvIg0KICAgICAgICByZXR1cm4gJHBhcnRzWyRwYXJ0cy5Db3VudCAtIDFdDQogICAgfQ0KICAgIHJldHVybiAibWFpbiINCn0NCg0KZnVuY3Rpb24gVGVzdC1Jc0RldGFjaGVkIHsNCiAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICBnaXQgc3ltYm9saWMtcmVmIC1xIEhFQUQgfCBPdXQtTnVsbA0KICAgICRhdHRhY2hlZCA9ICQ/DQogICAgUG9wLUxvY2F0aW9uDQogICAgcmV0dXJuIC1ub3QgJGF0dGFjaGVkDQp9DQoNCmZ1bmN0aW9uIEdldC1UaGVtZVN0YXR1c0RldGFpbGVkIHsNCiAgICBpZiAoLW5vdCAoVGVzdC1QYXRoICRUaGVtZVBhdGgpKSB7DQogICAgICAgIHJldHVybiBAeyBUZXh0ID0gIk5vdCBJbnN0YWxsZWQiOyBDb2xvciA9ICRSZWQgfQ0KICAgIH0NCg0KICAgIGlmICgtbm90IChHZXQtQ29tbWFuZCBnaXQgLUVycm9yQWN0aW9uIFNpbGVudGx5Q29udGludWUpKSB7DQogICAgICAgIHJldHVybiBAeyBUZXh0ID0gIkluc3RhbGxlZCI7IENvbG9yID0gJEdyZWVuIH0NCiAgICB9DQoNCiAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICBnaXQgZmV0Y2ggb3JpZ2luIC0tcXVpZXQgMj4kbnVsbA0KICAgICRsb2NhbEhhc2ggPSAoZ2l0IHJldi1wYXJzZSBIRUFEIDI+JG51bGwpDQogICAgUG9wLUxvY2F0aW9uDQoNCiAgICBpZiAoVGVzdC1Jc0RldGFjaGVkKSB7DQogICAgICAgICRzaG9ydEhhc2ggPSBpZiAoJGxvY2FsSGFzaCkgeyAkbG9jYWxIYXNoLlN1YnN0cmluZygwLCA3KSB9IGVsc2UgeyAidW5rbm93biIgfQ0KICAgICAgICByZXR1cm4gQHsgVGV4dCA9ICJJbnN0YWxsZWQgKGN1c3RvbSBjb21taXQgJHNob3J0SGFzaCkiOyBDb2xvciA9ICRDeWFuIH0NCiAgICB9DQoNCiAgICAkYnJhbmNoID0gR2V0LURlZmF1bHRCcmFuY2gNCiAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICAkcmVtb3RlSGFzaCA9IChnaXQgcmV2LXBhcnNlICJvcmlnaW4vJGJyYW5jaCIgMj4kbnVsbCkNCiAgICBQb3AtTG9jYXRpb24NCg0KICAgIGlmICgtbm90ICRsb2NhbEhhc2ggLW9yIC1ub3QgJHJlbW90ZUhhc2gpIHsNCiAgICAgICAgcmV0dXJuIEB7IFRleHQgPSAiSW5zdGFsbGVkIjsgQ29sb3IgPSAkR3JlZW4gfQ0KICAgIH0NCg0KICAgIGlmICgkbG9jYWxIYXNoIC1lcSAkcmVtb3RlSGFzaCkgew0KICAgICAgICByZXR1cm4gQHsgVGV4dCA9ICJJbnN0YWxsZWQgKHVwIHRvIGRhdGUpIjsgQ29sb3IgPSAkR3JlZW4gfQ0KICAgIH0NCg0KICAgIHJldHVybiBAeyBUZXh0ID0gIkluc3RhbGxlZCAob3V0ZGF0ZWQpIjsgQ29sb3IgPSAkUmVkIH0NCn0NCg0KZnVuY3Rpb24gSW5zdGFsbC1UaGVtZSB7DQogICAgU2hvdy1IZWFkZXINCiAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTGlnaHQgIEluc3RhbGxpbmcgJFRoZW1lTmFtZS4uLiRSZXNldCINCiAgICBXcml0ZS1Ib3N0ICIiDQoNCiAgICBpZiAoLW5vdCAoVGVzdC1EZXBlbmRlbmNpZXMpKSB7DQogICAgICAgIFBhdXNlLVJldHVybg0KICAgICAgICByZXR1cm4NCiAgICB9DQoNCiAgICBpZiAoLW5vdCAoVGVzdC1QYXRoICRUaGVtZXNEaXIpKSB7DQogICAgICAgIE5ldy1JdGVtIC1JdGVtVHlwZSBEaXJlY3RvcnkgLVBhdGggJFRoZW1lc0RpciAtRm9yY2UgfCBPdXQtTnVsbA0KICAgIH0NCg0KICAgIGlmIChUZXN0LVBhdGggJFRoZW1lUGF0aCkgew0KICAgICAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTWlkICBUaGVtZSBhbHJlYWR5IGV4aXN0cyBsb2NhbGx5LiBQdWxsaW5nIGxhdGVzdCBjaGFuZ2VzLi4uJFJlc2V0Ig0KICAgICAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICAgICAgZ2l0IHB1bGwNCiAgICAgICAgUG9wLUxvY2F0aW9uDQogICAgfQ0KICAgIGVsc2Ugew0KICAgICAgICBQdXNoLUxvY2F0aW9uICRUaGVtZXNEaXINCiAgICAgICAgZ2l0IGNsb25lICRSZXBvVXJsICRUaGVtZU5hbWUNCiAgICAgICAgUG9wLUxvY2F0aW9uDQogICAgfQ0KDQogICAgaWYgKFRlc3QtUGF0aCAkVGhlbWVQYXRoKSB7DQogICAgICAgIFdyaXRlLUhvc3QgIiINCiAgICAgICAgV3JpdGUtSG9zdCAiJE9yYW5nZU1pZCAgU2V0dGluZyBjdXJyZW50IHRoZW1lIHRvICRUaGVtZU5hbWUuLi4kUmVzZXQiDQogICAgICAgIHNwaWNldGlmeSBjb25maWcgY3VycmVudF90aGVtZSAkVGhlbWVOYW1lDQoNCiAgICAgICAgV3JpdGUtSG9zdCAiJE9yYW5nZU1pZCAgQXBwbHlpbmcgU3BpY2V0aWZ5Li4uJFJlc2V0Ig0KICAgICAgICBzcGljZXRpZnkgYXBwbHkNCg0KICAgICAgICBXcml0ZS1Ib3N0ICIiDQogICAgICAgIFdyaXRlLUhvc3QgIiAgJFRoZW1lTmFtZSBpbnN0YWxsZWQgYW5kIGFwcGxpZWQgc3VjY2Vzc2Z1bGx5LiIgLUZvcmVncm91bmRDb2xvciAkR3JlZW4NCiAgICB9DQogICAgZWxzZSB7DQogICAgICAgIFdyaXRlLUhvc3QgIiINCiAgICAgICAgV3JpdGUtSG9zdCAiICBJbnN0YWxsYXRpb24gZmFpbGVkLiBDaGVjayB0aGUgZXJyb3JzIGFib3ZlLiIgLUZvcmVncm91bmRDb2xvciAkUmVkDQogICAgfQ0KDQogICAgUGF1c2UtUmV0dXJuDQp9DQoNCmZ1bmN0aW9uIFVwZGF0ZS1UaGVtZSB7DQogICAgU2hvdy1IZWFkZXINCiAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTGlnaHQgIFVwZGF0aW5nICRUaGVtZU5hbWUuLi4kUmVzZXQiDQogICAgV3JpdGUtSG9zdCAiIg0KDQogICAgaWYgKC1ub3QgKFRlc3QtUGF0aCAkVGhlbWVQYXRoKSkgew0KICAgICAgICBXcml0ZS1Ib3N0ICIgICRUaGVtZU5hbWUgaXMgbm90IGluc3RhbGxlZC4gVXNlIEluc3RhbGwgaW5zdGVhZC4iIC1Gb3JlZ3JvdW5kQ29sb3IgJFJlZA0KICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgcmV0dXJuDQogICAgfQ0KDQogICAgaWYgKC1ub3QgKFRlc3QtRGVwZW5kZW5jaWVzKSkgew0KICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgcmV0dXJuDQogICAgfQ0KDQogICAgaWYgKFRlc3QtSXNEZXRhY2hlZCkgew0KICAgICAgICAkYnJhbmNoID0gR2V0LURlZmF1bHRCcmFuY2gNCiAgICAgICAgV3JpdGUtSG9zdCAiJE9yYW5nZU1pZCAgQ3VycmVudGx5IG9uIGEgY3VzdG9tIGNvbW1pdC4gUmV0dXJuaW5nIHRvICRicmFuY2guLi4kUmVzZXQiDQogICAgICAgIFB1c2gtTG9jYXRpb24gJFRoZW1lUGF0aA0KICAgICAgICBnaXQgY2hlY2tvdXQgJGJyYW5jaCAtLXF1aWV0DQogICAgICAgIFBvcC1Mb2NhdGlvbg0KICAgIH0NCg0KICAgIFB1c2gtTG9jYXRpb24gJFRoZW1lUGF0aA0KICAgIGdpdCBwdWxsDQogICAgUG9wLUxvY2F0aW9uDQoNCiAgICBXcml0ZS1Ib3N0ICIiDQogICAgV3JpdGUtSG9zdCAiJE9yYW5nZU1pZCAgUmUtYXBwbHlpbmcgU3BpY2V0aWZ5Li4uJFJlc2V0Ig0KICAgIHNwaWNldGlmeSBhcHBseQ0KDQogICAgV3JpdGUtSG9zdCAiIg0KICAgIFdyaXRlLUhvc3QgIiAgJFRoZW1lTmFtZSB1cGRhdGVkIHN1Y2Nlc3NmdWxseS4iIC1Gb3JlZ3JvdW5kQ29sb3IgJEdyZWVuDQogICAgUGF1c2UtUmV0dXJuDQp9DQoNCmZ1bmN0aW9uIFVuaW5zdGFsbC1UaGVtZSB7DQogICAgU2hvdy1IZWFkZXINCiAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTGlnaHQgIFVuaW5zdGFsbGluZyAkVGhlbWVOYW1lLi4uJFJlc2V0Ig0KICAgIFdyaXRlLUhvc3QgIiINCg0KICAgIGlmICgtbm90IChUZXN0LVBhdGggJFRoZW1lUGF0aCkpIHsNCiAgICAgICAgV3JpdGUtSG9zdCAiICAkVGhlbWVOYW1lIGlzIG5vdCBpbnN0YWxsZWQuIiAtRm9yZWdyb3VuZENvbG9yICRSZWQNCiAgICAgICAgUGF1c2UtUmV0dXJuDQogICAgICAgIHJldHVybg0KICAgIH0NCg0KICAgIFdyaXRlLUhvc3QgIiAgVGhpcyB3aWxsIHJlbW92ZSB0aGUgdGhlbWUgZm9sZGVyIGFuZCBzd2l0Y2ggdG8gTWFya2V0cGxhY2UuIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgJGNvbmZpcm0gPSBSZWFkLUhvc3QgIiAgVHlwZSBZIHRvIGNvbmZpcm0iDQogICAgaWYgKCRjb25maXJtIC1uZSAiWSIgLWFuZCAkY29uZmlybSAtbmUgInkiKSB7DQogICAgICAgIFdyaXRlLUhvc3QgIiAgQ2FuY2VsbGVkLiIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgcmV0dXJuDQogICAgfQ0KDQogICAgaWYgKEdldC1Db21tYW5kIHNwaWNldGlmeSAtRXJyb3JBY3Rpb24gU2lsZW50bHlDb250aW51ZSkgew0KICAgICAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTWlkICBTd2l0Y2hpbmcgU3BpY2V0aWZ5IHRoZW1lLi4uJFJlc2V0Ig0KICAgICAgICBzcGljZXRpZnkgY29uZmlnIGN1cnJlbnRfdGhlbWUgU3BvVFVJLQ0KICAgICAgICBzcGljZXRpZnkgY29uZmlnIGN1cnJlbnRfdGhlbWUgbWFya2V0cGxhY2UNCiAgICAgICAgc3BpY2V0aWZ5IGFwcGx5DQogICAgfQ0KDQogICAgUmVtb3ZlLUl0ZW0gLVBhdGggJFRoZW1lUGF0aCAtUmVjdXJzZSAtRm9yY2UNCg0KICAgIFdyaXRlLUhvc3QgIiINCiAgICBXcml0ZS1Ib3N0ICIgICRUaGVtZU5hbWUgaGFzIGJlZW4gdW5pbnN0YWxsZWQuIiAtRm9yZWdyb3VuZENvbG9yICRHcmVlbg0KICAgIFBhdXNlLVJldHVybg0KfQ0KDQpmdW5jdGlvbiBSZWFkLUFycm93U2VsZWN0aW9uIHsNCiAgICBwYXJhbSgNCiAgICAgICAgW3N0cmluZ1tdXSRJdGVtcywNCiAgICAgICAgW2ludF0kQ3VycmVudEluZGV4ID0gLTEsDQogICAgICAgIFtzdHJpbmdbXV0kVGl0bGVMaW5lcw0KICAgICkNCg0KICAgICRzZWxlY3RlZEluZGV4ID0gMA0KICAgIGlmICgkQ3VycmVudEluZGV4IC1nZSAwKSB7ICRzZWxlY3RlZEluZGV4ID0gJEN1cnJlbnRJbmRleCB9DQoNCiAgICAkaGVhZGVyTGluZXMgPSBHZXQtSGVhZGVyTGluZXMNCiAgICAkb3ZlcmhlYWRMaW5lcyA9ICRoZWFkZXJMaW5lcy5Db3VudCArICRUaXRsZUxpbmVzLkNvdW50ICsgNA0KDQogICAgJHBhZ2VTaXplID0gKEdldC1Db25zb2xlSGVpZ2h0KSAtICRvdmVyaGVhZExpbmVzDQogICAgaWYgKCRwYWdlU2l6ZSAtZ3QgJEl0ZW1zLkNvdW50KSB7ICRwYWdlU2l6ZSA9ICRJdGVtcy5Db3VudCB9DQogICAgaWYgKCRwYWdlU2l6ZSAtbHQgMSkgeyAkcGFnZVNpemUgPSAxIH0NCg0KICAgIENsZWFyLUhvc3QNCiAgICB0cnkgeyBbQ29uc29sZV06OkN1cnNvclZpc2libGUgPSAkZmFsc2UgfSBjYXRjaCB7fQ0KDQogICAgd2hpbGUgKCR0cnVlKSB7DQogICAgICAgICR0b3RhbFBhZ2VzID0gW01hdGhdOjpDZWlsaW5nKCRJdGVtcy5Db3VudCAvICRwYWdlU2l6ZSkNCiAgICAgICAgaWYgKCR0b3RhbFBhZ2VzIC1sdCAxKSB7ICR0b3RhbFBhZ2VzID0gMSB9DQogICAgICAgICRjdXJyZW50UGFnZSA9IFtNYXRoXTo6Rmxvb3IoJHNlbGVjdGVkSW5kZXggLyAkcGFnZVNpemUpDQogICAgICAgICRwYWdlU3RhcnQgPSAkY3VycmVudFBhZ2UgKiAkcGFnZVNpemUNCiAgICAgICAgJHBhZ2VFbmQgPSAkcGFnZVN0YXJ0ICsgJHBhZ2VTaXplIC0gMQ0KICAgICAgICBpZiAoJHBhZ2VFbmQgLWd0ICgkSXRlbXMuQ291bnQgLSAxKSkgeyAkcGFnZUVuZCA9ICRJdGVtcy5Db3VudCAtIDEgfQ0KDQogICAgICAgICRmcmFtZSA9IEAoKQ0KICAgICAgICAkZnJhbWUgKz0gJGhlYWRlckxpbmVzDQogICAgICAgICRmcmFtZSArPSAkVGl0bGVMaW5lcw0KDQogICAgICAgIGZvciAoJGkgPSAkcGFnZVN0YXJ0OyAkaSAtbGUgJHBhZ2VFbmQ7ICRpKyspIHsNCiAgICAgICAgICAgICRwcmVmaXggPSBpZiAoJGkgLWVxICRDdXJyZW50SW5kZXgpIHsgIj4gIiB9IGVsc2UgeyAiICAiIH0NCiAgICAgICAgICAgICR0ZXh0ID0gIiRwcmVmaXgkKCRJdGVtc1skaV0pIg0KICAgICAgICAgICAgaWYgKCRpIC1lcSAkc2VsZWN0ZWRJbmRleCkgew0KICAgICAgICAgICAgICAgICRmcmFtZSArPSAiJFNlbGVjdEJnJHRleHQkUmVzZXQiDQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlaWYgKCRpIC1lcSAkQ3VycmVudEluZGV4KSB7DQogICAgICAgICAgICAgICAgJGZyYW1lICs9ICIkR3JlZW5BbnNpJHRleHQkUmVzZXQiDQogICAgICAgICAgICB9DQogICAgICAgICAgICBlbHNlIHsNCiAgICAgICAgICAgICAgICAkZnJhbWUgKz0gJHRleHQNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KDQogICAgICAgICRsaW5lc1VzZWQgPSAkcGFnZUVuZCAtICRwYWdlU3RhcnQgKyAxDQogICAgICAgIGZvciAoJHAgPSAkbGluZXNVc2VkOyAkcCAtbHQgJHBhZ2VTaXplOyAkcCsrKSB7DQogICAgICAgICAgICAkZnJhbWUgKz0gIiINCiAgICAgICAgfQ0KDQogICAgICAgICRmcmFtZSArPSAiIg0KICAgICAgICAkZnJhbWUgKz0gIiRPcmFuZ2VEYXJrICA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09JFJlc2V0Ig0KICAgICAgICAkZnJhbWUgKz0gIiAgVXAvRG93biB0byBtb3ZlLCBFbnRlciB0byBzZWxlY3QsIEVzYyB0byBnbyBiYWNrICAgUGFnZSAkKCRjdXJyZW50UGFnZSArIDEpIG9mICR0b3RhbFBhZ2VzIg0KDQogICAgICAgIFdyaXRlLUZyYW1lICRmcmFtZQ0KDQogICAgICAgICRrZXkgPSAkSG9zdC5VSS5SYXdVSS5SZWFkS2V5KCJOb0VjaG8sSW5jbHVkZUtleURvd24iKQ0KICAgICAgICAkY29kZSA9ICRrZXkuVmlydHVhbEtleUNvZGUNCg0KICAgICAgICBpZiAoJGNvZGUgLWVxIDM4KSB7DQogICAgICAgICAgICBpZiAoJHNlbGVjdGVkSW5kZXggLWd0IDApIHsgJHNlbGVjdGVkSW5kZXgtLSB9IGVsc2UgeyAkc2VsZWN0ZWRJbmRleCA9ICRJdGVtcy5Db3VudCAtIDEgfQ0KICAgICAgICB9DQogICAgICAgIGVsc2VpZiAoJGNvZGUgLWVxIDQwKSB7DQogICAgICAgICAgICBpZiAoJHNlbGVjdGVkSW5kZXggLWx0ICRJdGVtcy5Db3VudCAtIDEpIHsgJHNlbGVjdGVkSW5kZXgrKyB9IGVsc2UgeyAkc2VsZWN0ZWRJbmRleCA9IDAgfQ0KICAgICAgICB9DQogICAgICAgIGVsc2VpZiAoJGNvZGUgLWVxIDEzKSB7DQogICAgICAgICAgICB0cnkgeyBbQ29uc29sZV06OkN1cnNvclZpc2libGUgPSAkdHJ1ZSB9IGNhdGNoIHt9DQogICAgICAgICAgICByZXR1cm4gJHNlbGVjdGVkSW5kZXgNCiAgICAgICAgfQ0KICAgICAgICBlbHNlaWYgKCRjb2RlIC1lcSAyNykgew0KICAgICAgICAgICAgdHJ5IHsgW0NvbnNvbGVdOjpDdXJzb3JWaXNpYmxlID0gJHRydWUgfSBjYXRjaCB7fQ0KICAgICAgICAgICAgcmV0dXJuIC0xDQogICAgICAgIH0NCiAgICB9DQp9DQoNCmZ1bmN0aW9uIEdldC1Db21taXRMaXN0IHsNCiAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICBnaXQgZmV0Y2ggb3JpZ2luIC0tcXVpZXQgMj4kbnVsbA0KICAgICRyYXdMb2cgPSBnaXQgbG9nIC0tYWxsIC0tcHJldHR5PWZvcm1hdDoiJUh8JWh8JWFkfCVzIiAtLWRhdGU9c2hvcnQNCiAgICBQb3AtTG9jYXRpb24NCg0KICAgICRjb21taXRzID0gQCgpDQogICAgZm9yZWFjaCAoJGxpbmUgaW4gJHJhd0xvZykgew0KICAgICAgICAkcGFydHMgPSAkbGluZSAtc3BsaXQgIlx8IiwgNA0KICAgICAgICBpZiAoJHBhcnRzLkNvdW50IC1lcSA0KSB7DQogICAgICAgICAgICAkY29tbWl0cyArPSBbUFNDdXN0b21PYmplY3RdQHsNCiAgICAgICAgICAgICAgICBGdWxsSGFzaCAgPSAkcGFydHNbMF0NCiAgICAgICAgICAgICAgICBTaG9ydEhhc2ggPSAkcGFydHNbMV0NCiAgICAgICAgICAgICAgICBEYXRlICAgICAgPSAkcGFydHNbMl0NCiAgICAgICAgICAgICAgICBTdWJqZWN0ICAgPSAkcGFydHNbM10NCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgIH0NCiAgICByZXR1cm4gJGNvbW1pdHMNCn0NCg0KZnVuY3Rpb24gU2hvdy1Db21taXRIaXN0b3J5IHsNCiAgICBpZiAoLW5vdCAoVGVzdC1QYXRoICRUaGVtZVBhdGgpKSB7DQogICAgICAgIFNob3ctSGVhZGVyDQogICAgICAgIFdyaXRlLUhvc3QgIiAgJFRoZW1lTmFtZSBpcyBub3QgaW5zdGFsbGVkLiIgLUZvcmVncm91bmRDb2xvciAkUmVkDQogICAgICAgIFBhdXNlLVJldHVybg0KICAgICAgICByZXR1cm4NCiAgICB9DQoNCiAgICBpZiAoLW5vdCAoVGVzdC1EZXBlbmRlbmNpZXMpKSB7DQogICAgICAgIFBhdXNlLVJldHVybg0KICAgICAgICByZXR1cm4NCiAgICB9DQoNCiAgICAkdmlld2luZyA9ICR0cnVlDQogICAgd2hpbGUgKCR2aWV3aW5nKSB7DQogICAgICAgICRjb21taXRzID0gR2V0LUNvbW1pdExpc3QNCiAgICAgICAgaWYgKCRjb21taXRzLkNvdW50IC1lcSAwKSB7DQogICAgICAgICAgICBTaG93LUhlYWRlcg0KICAgICAgICAgICAgV3JpdGUtSG9zdCAiICBObyBjb21taXRzIGZvdW5kLiIgLUZvcmVncm91bmRDb2xvciAkUmVkDQogICAgICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgICAgIHJldHVybg0KICAgICAgICB9DQoNCiAgICAgICAgUHVzaC1Mb2NhdGlvbiAkVGhlbWVQYXRoDQogICAgICAgICRjdXJyZW50SGFzaCA9IChnaXQgcmV2LXBhcnNlIEhFQUQgMj4kbnVsbCkNCiAgICAgICAgUG9wLUxvY2F0aW9uDQoNCiAgICAgICAgJGN1cnJlbnRJbmRleCA9IC0xDQogICAgICAgICRpdGVtcyA9IEAoKQ0KICAgICAgICBmb3IgKCRpID0gMDsgJGkgLWx0ICRjb21taXRzLkNvdW50OyAkaSsrKSB7DQogICAgICAgICAgICAkY29tbWl0ID0gJGNvbW1pdHNbJGldDQogICAgICAgICAgICAkaXRlbXMgKz0gIiQoJGNvbW1pdC5TaG9ydEhhc2gpICAkKCRjb21taXQuRGF0ZSkgICQoJGNvbW1pdC5TdWJqZWN0KSINCiAgICAgICAgICAgIGlmICgkY29tbWl0LkZ1bGxIYXNoIC1lcSAkY3VycmVudEhhc2gpIHsNCiAgICAgICAgICAgICAgICAkY3VycmVudEluZGV4ID0gJGkNCiAgICAgICAgICAgIH0NCiAgICAgICAgfQ0KICAgICAgICAkcmV0dXJuTGF0ZXN0SW5kZXggPSAkaXRlbXMuQ291bnQNCiAgICAgICAgJGl0ZW1zICs9ICJSZXR1cm4gdG8gbGF0ZXN0IHZlcnNpb24iDQogICAgICAgICRiYWNrSW5kZXggPSAkaXRlbXMuQ291bnQNCiAgICAgICAgJGl0ZW1zICs9ICJCYWNrIg0KDQogICAgICAgICR0aXRsZUxpbmVzID0gQCgiJE9yYW5nZUxpZ2h0ICBDb21taXQgSGlzdG9yeSRSZXNldCIsICIiKQ0KDQogICAgICAgICRzZWxlY3Rpb24gPSBSZWFkLUFycm93U2VsZWN0aW9uIC1JdGVtcyAkaXRlbXMgLUN1cnJlbnRJbmRleCAkY3VycmVudEluZGV4IC1UaXRsZUxpbmVzICR0aXRsZUxpbmVzDQoNCiAgICAgICAgaWYgKCRzZWxlY3Rpb24gLWVxIC0xIC1vciAkc2VsZWN0aW9uIC1lcSAkYmFja0luZGV4KSB7DQogICAgICAgICAgICAkdmlld2luZyA9ICRmYWxzZQ0KICAgICAgICB9DQogICAgICAgIGVsc2VpZiAoJHNlbGVjdGlvbiAtZXEgJHJldHVybkxhdGVzdEluZGV4KSB7DQogICAgICAgICAgICBVcGRhdGUtVGhlbWUNCiAgICAgICAgfQ0KICAgICAgICBlbHNlaWYgKCRzZWxlY3Rpb24gLWdlIDAgLWFuZCAkc2VsZWN0aW9uIC1sdCAkY29tbWl0cy5Db3VudCkgew0KICAgICAgICAgICAgQ2hlY2tvdXQtQ29tbWl0ICRjb21taXRzWyRzZWxlY3Rpb25dDQogICAgICAgIH0NCiAgICB9DQp9DQoNCmZ1bmN0aW9uIENoZWNrb3V0LUNvbW1pdCgkY29tbWl0KSB7DQogICAgU2hvdy1IZWFkZXINCiAgICBXcml0ZS1Ib3N0ICIkT3JhbmdlTGlnaHQgIENoZWNraW5nIG91dCBjb21taXQgJCgkY29tbWl0LlNob3J0SGFzaCkuLi4kUmVzZXQiDQogICAgV3JpdGUtSG9zdCAiICAkKCRjb21taXQuRGF0ZSkgICQoJGNvbW1pdC5TdWJqZWN0KSIgLUZvcmVncm91bmRDb2xvciAkR3JheQ0KICAgIFdyaXRlLUhvc3QgIiINCiAgICBXcml0ZS1Ib3N0ICIgIFRoaXMgd2lsbCBzd2l0Y2ggdGhlIHRoZW1lIHRvIHRoaXMgc3BlY2lmaWMgdmVyc2lvbi4iIC1Gb3JlZ3JvdW5kQ29sb3IgJEdyYXkNCiAgICAkY29uZmlybSA9IFJlYWQtSG9zdCAiICBUeXBlIFkgdG8gY29uZmlybSINCiAgICBpZiAoJGNvbmZpcm0gLW5lICJZIiAtYW5kICRjb25maXJtIC1uZSAieSIpIHsNCiAgICAgICAgV3JpdGUtSG9zdCAiICBDYW5jZWxsZWQuIiAtRm9yZWdyb3VuZENvbG9yICRHcmF5DQogICAgICAgIFBhdXNlLVJldHVybg0KICAgICAgICByZXR1cm4NCiAgICB9DQoNCiAgICBQdXNoLUxvY2F0aW9uICRUaGVtZVBhdGgNCiAgICBnaXQgY2hlY2tvdXQgJGNvbW1pdC5GdWxsSGFzaCAtLXF1aWV0DQogICAgUG9wLUxvY2F0aW9uDQoNCiAgICBpZiAoR2V0LUNvbW1hbmQgc3BpY2V0aWZ5IC1FcnJvckFjdGlvbiBTaWxlbnRseUNvbnRpbnVlKSB7DQogICAgICAgIFdyaXRlLUhvc3QgIiINCiAgICAgICAgV3JpdGUtSG9zdCAiJE9yYW5nZU1pZCAgQXBwbHlpbmcgU3BpY2V0aWZ5Li4uJFJlc2V0Ig0KICAgICAgICBzcGljZXRpZnkgYXBwbHkNCiAgICB9DQoNCiAgICBXcml0ZS1Ib3N0ICIiDQogICAgV3JpdGUtSG9zdCAiICAkVGhlbWVOYW1lIGlzIG5vdyBvbiBjb21taXQgJCgkY29tbWl0LlNob3J0SGFzaCkuIiAtRm9yZWdyb3VuZENvbG9yICRHcmVlbg0KICAgIFBhdXNlLVJldHVybg0KfQ0KDQpmdW5jdGlvbiBDaGVjay1Gb3JVcGRhdGVzIHsNCiAgICBTaG93LUhlYWRlcg0KICAgIFdyaXRlLUhvc3QgIiRPcmFuZ2VMaWdodCAgQ2hlY2tpbmcgZm9yIHVwZGF0ZXMuLi4kUmVzZXQiDQogICAgV3JpdGUtSG9zdCAiIg0KDQogICAgaWYgKC1ub3QgKFRlc3QtUGF0aCAkVGhlbWVQYXRoKSkgew0KICAgICAgICBXcml0ZS1Ib3N0ICIgICRUaGVtZU5hbWUgaXMgbm90IGluc3RhbGxlZC4iIC1Gb3JlZ3JvdW5kQ29sb3IgJFJlZA0KICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgcmV0dXJuDQogICAgfQ0KDQogICAgaWYgKC1ub3QgKFRlc3QtRGVwZW5kZW5jaWVzKSkgew0KICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgcmV0dXJuDQogICAgfQ0KDQogICAgJHN0YXR1cyA9IEdldC1UaGVtZVN0YXR1c0RldGFpbGVkDQogICAgV3JpdGUtSG9zdCAiICBTdGF0dXM6ICIgLU5vTmV3bGluZSAtRm9yZWdyb3VuZENvbG9yICRXaGl0ZQ0KICAgIFdyaXRlLUhvc3QgJHN0YXR1cy5UZXh0IC1Gb3JlZ3JvdW5kQ29sb3IgJHN0YXR1cy5Db2xvcg0KDQogICAgaWYgKCRzdGF0dXMuVGV4dCAtZXEgIkluc3RhbGxlZCAob3V0ZGF0ZWQpIikgew0KICAgICAgICBXcml0ZS1Ib3N0ICIiDQogICAgICAgIFdyaXRlLUhvc3QgIiAgQSBuZXdlciB2ZXJzaW9uIGlzIGF2YWlsYWJsZS4iIC1Gb3JlZ3JvdW5kQ29sb3IgJEdyYXkNCiAgICAgICAgJGNvbmZpcm0gPSBSZWFkLUhvc3QgIiAgVHlwZSBZIHRvIHVwZGF0ZSBub3ciDQogICAgICAgIGlmICgkY29uZmlybSAtZXEgIlkiIC1vciAkY29uZmlybSAtZXEgInkiKSB7DQogICAgICAgICAgICBVcGRhdGUtVGhlbWUNCiAgICAgICAgICAgIHJldHVybg0KICAgICAgICB9DQogICAgfQ0KDQogICAgUGF1c2UtUmV0dXJuDQp9DQoNCmZ1bmN0aW9uIFBhdXNlLVJldHVybiB7DQogICAgV3JpdGUtSG9zdCAiIg0KICAgIFdyaXRlLUhvc3QgIiAgUHJlc3MgYW55IGtleSB0byByZXR1cm4gdG8gdGhlIG1lbnUuLi4iIC1Gb3JlZ3JvdW5kQ29sb3IgJEdyYXkNCiAgICAkbnVsbCA9ICRIb3N0LlVJLlJhd1VJLlJlYWRLZXkoIk5vRWNobyxJbmNsdWRlS2V5RG93biIpDQp9DQoNCmZ1bmN0aW9uIFNob3ctTWVudSB7DQogICAgU2hvdy1IZWFkZXINCiAgICAkc3RhdHVzID0gR2V0LVRoZW1lU3RhdHVzRGV0YWlsZWQNCg0KICAgIFdyaXRlLUhvc3QgIiAgU3RhdHVzOiAiIC1Ob05ld2xpbmUgLUZvcmVncm91bmRDb2xvciAkV2hpdGUNCiAgICBXcml0ZS1Ib3N0ICRzdGF0dXMuVGV4dCAtRm9yZWdyb3VuZENvbG9yICRzdGF0dXMuQ29sb3INCiAgICBXcml0ZS1Ib3N0ICIiDQogICAgV3JpdGUtSG9zdCAiICBbMV0gSW5zdGFsbCAkVGhlbWVOYW1lIiAgICAgICAtRm9yZWdyb3VuZENvbG9yICRXaGl0ZQ0KICAgIFdyaXRlLUhvc3QgIiAgWzJdIFVwZGF0ZSAkVGhlbWVOYW1lIiAgICAgICAgLUZvcmVncm91bmRDb2xvciAkV2hpdGUNCiAgICBXcml0ZS1Ib3N0ICIgIFszXSBVbmluc3RhbGwgJFRoZW1lTmFtZSIgICAgIC1Gb3JlZ3JvdW5kQ29sb3IgJFdoaXRlDQogICAgV3JpdGUtSG9zdCAiICBbNF0gQ29tbWl0IEhpc3RvcnkgLyBEb3duZ3JhZGUiIC1Gb3JlZ3JvdW5kQ29sb3IgJFdoaXRlDQogICAgV3JpdGUtSG9zdCAiICBbNV0gQ2hlY2sgZm9yIFVwZGF0ZXMiICAgICAgICAtRm9yZWdyb3VuZENvbG9yICRXaGl0ZQ0KICAgIFdyaXRlLUhvc3QgIiAgWzZdIEV4aXQiICAgICAgICAgICAgICAgICAgICAgLUZvcmVncm91bmRDb2xvciAkV2hpdGUNCiAgICBXcml0ZS1Ib3N0ICIiDQogICAgV3JpdGUtSG9zdCAiJE9yYW5nZURhcmsgID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0kUmVzZXQiDQogICAgV3JpdGUtSG9zdCAiIg0KICAgICRjaG9pY2UgPSBSZWFkLUhvc3QgIiAgU2VsZWN0IGFuIG9wdGlvbiINCiAgICByZXR1cm4gJGNob2ljZQ0KfQ0KDQokcnVubmluZyA9ICR0cnVlDQp3aGlsZSAoJHJ1bm5pbmcpIHsNCiAgICAkY2hvaWNlID0gU2hvdy1NZW51DQogICAgc3dpdGNoICgkY2hvaWNlKSB7DQogICAgICAgICIxIiB7IEluc3RhbGwtVGhlbWUgfQ0KICAgICAgICAiMiIgeyBVcGRhdGUtVGhlbWUgfQ0KICAgICAgICAiMyIgeyBVbmluc3RhbGwtVGhlbWUgfQ0KICAgICAgICAiNCIgeyBTaG93LUNvbW1pdEhpc3RvcnkgfQ0KICAgICAgICAiNSIgeyBDaGVjay1Gb3JVcGRhdGVzIH0NCiAgICAgICAgIjYiIHsgJHJ1bm5pbmcgPSAkZmFsc2UgfQ0KICAgICAgICBkZWZhdWx0IHsNCiAgICAgICAgICAgIFNob3ctSGVhZGVyDQogICAgICAgICAgICBXcml0ZS1Ib3N0ICIgIEludmFsaWQgb3B0aW9uLiIgLUZvcmVncm91bmRDb2xvciAkUmVkDQogICAgICAgICAgICBQYXVzZS1SZXR1cm4NCiAgICAgICAgfQ0KICAgIH0NCn0NCg0KQ2xlYXItSG9zdA=="
$ok = $true
$ok = (Invoke-Step "Creating install directory" {
if (-not (Test-Path $using:targetDir)) {
New-Item -ItemType Directory -Path $using:targetDir -Force | Out-Null
}
}) -and $ok
$ok = (Invoke-Step "Writing SpoTUI script" {
$decodedContent = [System.Text.Encoding]::UTF8.GetString([System.Convert]::FromBase64String($using:spotuiScriptContentBase64))
Set-Content -Path $using:scriptPath -Value $decodedContent
}) -and $ok
$ok = (Invoke-Step "Creating wrapper script" {
$wrapperContent = '& "' + $using:scriptPath + '" @args'
Set-Content -Path $using:wrapperPath -Value $wrapperContent
}) -and $ok
$ok = (Invoke-Step "Updating PATH" {
$userPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($userPath -notlike "*$using:targetDir*") {
[Environment]::SetEnvironmentVariable("Path", "$userPath;$using:targetDir", "User")
}
}) -and $ok
$env:Path = "$env:Path;$targetDir"
$ok = (Invoke-Step "Creating launcher" {
$batchContent = '@echo off' + [Environment]::NewLine + 'powershell -ExecutionPolicy Bypass -File "' + $using:wrapperPath + '" %*'
Set-Content -Path $using:batchPath -Value $batchContent
}) -and $ok
Write-Host ""
Write-Host "$OrangeDark =============================================================$Reset"
Write-Host ""
if ($ok) {
Write-Host (" " + $GreenAnsi + $CheckMark + " SpoTUI installed successfully." + $Reset)
Write-Host (" " + $GrayAnsi + " Open a new terminal and run: spotui" + $Reset)
}
else {
Write-Host (" " + $RedAnsi + $CrossMark + " Installation finished with errors. See above." + $Reset)
}
Write-Host ""