<#
.NOTES
    Intel VCA Software Stack (VCASS)

    Copyright(c) 2016 Intel Corporation.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License, version 2, as
    published by the Free Software Foundation.

    This program is distributed in the hope that it will be useful, but
    WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
    General Public License for more details.

    The full GNU General Public License is included in this distribution in
    the file called "COPYING".

    Intel VCA Scripts.

.SYNOPSIS
    Creates a bootable ISO image based on Windows installation media to use with VCA BlockIO & KVM or Xen.

.DESCRIPTION
    Creates a bootable ISO image based on Windows installation media to use with VCA BlockIO & KVM or Xen.
#>

param(
    [string]$iso,
    [string]$output_dir = (Join-Path $pwd.path -ChildPath 'out'),
    [string]$mount_dir = (Join-Path $pwd.path -ChildPath 'mount_dir'),
    [string]$tmp_dir = (Join-Path $pwd.path -ChildPath 'tmp'),
    [string]$driver_dir,
    [string]$vcagent_dir,
    [string]$answer_file,
    [string]$dism_path = $(Join-Path (Get-item env:\windir).value "system32\dism.exe"),
    [string]$vca_image_version = '0.0.0',
    [string]$gfx_drv_dir,
    [string]$win_edition,
    [string]$netkvm_drv_dir,
    [string]$virtualbox,
    [string]$xen_driver_dir,
    [string]$openssh_dir,
    [string]$boot_part_type = 'GPT',
    [string]$zip_img = 'vca_windows_baremetal.zip',
    [long]$vhd_size = 32GB
)

# variable used to indicate if GFX/KVM/Xen driver installation should be attempted
[Bool]$install_gfx_drv_status = 0
[Bool]$install_xen_drv_status = 0
[Bool]$install_netkvm_drv_status = 0
$LASTEXITCODE = 0
$ErrorActionPreference = "Stop"

if (-Not $iso) { Write-Error "Missing -iso parameter"; Exit 1 }
if (-Not $answer_file) { Write-Error "Missing -answer_file parameter"; Exit 1 }
if (-Not $driver_dir) { Write-Error "Missing -driver_dir parameter"; Exit 1 }
if (-Not $vcagent_dir) { Write-Error "Missing -vcagent_dir parameter"; Exit 1 }
if (-Not $win_edition) { Write-Error "Missing -win_edition parameter"; Exit 1 }
if (-Not $virtualbox) { Write-Error "Missing -virtualbox parameter"; Exit 1 }
if (-Not $zip_img) {Write-Error "Missing -zip_img parameter" Exit 1}
if ($gfx_drv_dir) {$install_gfx_drv_status = 1}
if ($xen_driver_dir) {$install_xen_drv_status = 1}
if ($openssh_dir) {$install_openssh_status = 1}
if ($netkvm_drv_dir) {$install_netkvm_drv_status = 1}

# create default directories if they do not exist
if (-Not (Test-Path $output_dir))
{
    New-Item $output_dir -type directory
    Write-Host "Output directory created: " $output_dir
}

if (-Not (Test-Path $mount_dir))
{
    New-Item $mount_dir -type directory
    Write-Host "Mount directory created: " $mount_dir
}

if (-Not (Test-Path $tmp_dir))
{
    New-Item $tmp_dir -type directory
    Write-Host "Tmp directory created: " $tmp_dir
}

# check each parameter if exist, not only if was provided by user
if(-Not (Test-Path $iso)) { Write-Error "ISO file" $iso "does not exist"; Exit 1}
if(-Not (Test-Path $answer_file)) { Write-Error "Answer file" $answer_file "does not exist"; Exit 1 }
if(-Not (Test-Path $vcagent_dir)) { Write-Error "VCAgent directory" $vcagent_dir "does not exist"; Exit 1 }
if(-Not (Test-Path $driver_dir)) { Write-Error "Driver directory" $driver_dir "does not exist"; Exit 1 }
if ($gfx_drv_dir -ne "")
{
    if(-Not (Test-Path $gfx_drv_dir)) { Write-Error "GFX driver directory " $gfx_drv_dir " does not exist"; Exit 1 }
}
if ($xen_driver_dir -ne "")
{
    if(-Not (Test-Path $xen_driver_dir)) { Write-Error "Xen driver directory " $xen_driver_dir " does not exist"; Exit 1 }
}
if ($netkvm_drv_dir -ne "")
{
    if(-Not (Test-Path $netkvm_drv_dir)) { Write-Error "NetKVM driver directory " $netkvm_drv_dir " does not exist"; Exit 1 }
}
if ($openssh_dir -ne "")
{
    if(-Not (Test-Path $openssh_dir)) { Write-Error "OpenSSH driver directory " $openssh_dir " does not exist"; Exit 1 }
}

$driver_vca = Join-Path $driver_dir -ChildPath 'VCA Package\Vca.inf'
if(-Not (Test-Path $driver_vca)) { Write-Error "VCA driver's .inf file not exist"; Exit 1 }

$driver_blk = Join-Path $driver_dir -ChildPath 'VcaBlockIo Package\VcaBlockIo.inf'
if(-Not (Test-Path $driver_blk)) { Write-Error "VcaBlockIo driver's .inf file not exist"; Exit 1 }

$driver_veth = Join-Path $driver_dir -ChildPath 'VcaVeth Package\VcaVeth.inf'
if(-Not (Test-Path $driver_veth)) { Write-Error "VcaVeth driver's .inf file not exist"; Exit 1 }

if ($netkvm_drv_dir -ne "")
{
    $driver_netkvm = Join-Path $netkvm_drv_dir -ChildPath 'amd64\netkvm.inf'
    if(-Not (Test-Path $driver_netkvm)) { Write-Error "NetKVM driver's .inf file not exist"; Exit 1 }
}

if ($xen_driver_dir -ne "")
{
    $driver_xenbus = Join-Path $xen_driver_dir -ChildPath 'xenbus\x64\xenbus.inf'
    if(-Not (Test-Path $driver_xenbus)) { Write-Error "XenBus driver's .inf file not exist"; Exit 1 }

    $driver_xennet = Join-Path $xen_driver_dir -ChildPath 'xennet\x64\xennet.inf'
    if(-Not (Test-Path $driver_xenbus)) { Write-Error "XenNet driver's .inf file not exist"; Exit 1 }

    $driver_xenvif = Join-Path $xen_driver_dir -ChildPath 'xenvif\x64\xenvif.inf'
    if(-Not (Test-Path $driver_xenbus)) { Write-Error "Xenvif driver's .inf file not exist"; Exit 1 }
}


$workdir = $pwd.path
$output_name = 'windows_image.vhd'
$output_iso_name = 'windows_image_@_version.img'
$output_full_path = Join-Path $output_dir -ChildPath $output_name
$output_iso_full_path = Join-Path $output_dir -ChildPath $output_iso_name

function DisplayInGBytes($num)
{
    $num = $num / 1GB
    Write-Host $num"GB"
}


function SummarizeParameters
{
    Write-Host ""
    Write-Host "Working Directory: " $workdir
    Write-Host "Setup script: " $setup_script
    Write-Host "Windows ISO: " $iso
    Write-Host "Output dir: " $output_dir
    Write-Host "Output vhd name: " $output_name
    Write-Host "Mount dir: " $mount_dir
    Write-Host "VcaWinKmd drivers path: " $driver_dir
    Write-Host "driver_vca path: " $driver_vca
    Write-Host "driver_blk path: " $driver_blk
    Write-Host "driver_veth path: " $driver_veth
    Write-Host "VCAgent path: " $vcagent_dir
    Write-Host "Answer file path: " $answer_file
    Write-Host "Dism.exe path: " $dism_path
    Write-Host "VirtualBox path: " $virtualbox
    Write-Host -NoNewline "VHD size: "
        DisplayInGBytes $vhd_size

    if ($gfx_drv_dir -ne "")
    {
        Write-Host "GFX driver path: " $gfx_drv_dir
    }

    if ($netkvm_drv_dir -ne "")
    {
        Write-Host "NetKVM driver path: " $driver_netkvm
    }

    if ($xen_driver_dir -ne "")
    {
        Write-Host "XenBus driver path: " $driver_xenbus
        Write-Host "XenNet driver path: " $driver_xennet
        Write-Host "XenVif driver path: " $driver_xenvif
    }

    Write-Host ""
}

function CopyAndRenameCatalogFromTo
{
    $from = $args[0]
    $to = $args[1]
    $newname = $args[2]

    $returned_object = Copy-Item $from $to -recurse -PassThru # if force added then override, if not then ask about confirmation
    if ($returned_object)
    {
        $tempname_dir = Join-Path $to -ChildPath (Split-Path $from -Leaf)
        if ($tempname_dir -ne (Join-Path $to -ChildPath $newname))
        {
            $returned_object = Rename-Item $tempname_dir $newname -PassThru
            if (-Not $returned_object)
                {
                Write-Error "`nCannot rename $tempname_dir directory to $newname"
                Return 1
                }
        }
        Write-Host "`n $from copied to : " (Join-Path $to -ChildPath $newname)
        Return 0
    }

    Write-Error "`nCannot copy $from directory to " (Join-Path $to -ChildPath $newname)
    Return 1
}

function GenerateImage
{
 
   
    $newVhd = New-VHD -Path $output_full_path -Dynamic -SizeBytes $vhd_size
    if (-Not $newVhd)
          {
           Write-Error "`nCannot create $newVhd file"
           Return 1
          }
   
    Write-Host "`nAttaching VHD file..."
    Mount-VHD –Path $output_full_path

    $newVhd = get-vhd -path $output_full_path -Verbose
    
    if ($boot_part_type -eq "MBR" ) {

        Initialize-Disk -Number $newVhd.DiskNumber -PartitionStyle MBR

        Write-Host "`nWe are partitioning VHD with MBR..."    

        $disk_no = Get-Disk -Number $newVhd.DiskNumber

        $partition       = New-Partition -DiskNumber $newVhd.DiskNumber -Size $disk_no.LargestFreeExtent -MbrType IFS -IsActive
                        Write-Host "`nVHD disk has been partitioned..."

        $volume    = Format-Volume -Partition $partition -Force -Confirm:$false -FileSystem NTFS
                        Write-Host "`nVHD system volume has been formatted..."

        $partition       | Add-PartitionAccessPath -AssignDriveLetter
        $drive           = $(Get-Partition -Disk $disk_no).AccessPaths[0]
        
        Write-Host "`nDrive letter ($drive) for system volume has been assigned..."



    } elseif ($boot_part_type -eq "GPT" ) {
        Initialize-Disk -Number $newVhd.DiskNumber -PartitionStyle GPT
        
        Write-Host "`nWe are partitioning VHD with GPT..."

        $disk_no = Get-Disk -Number $newVhd.DiskNumber

        $WindowsPartition = New-Partition -DiskNumber $newVhd.DiskNumber -Size 100MB -GptType '{c12a7328-f81f-11d2-ba4b-00a0c93ec93b}'
                            Write-Host "`nVHD's Windows partition has been created"

        $partition       = New-Partition -DiskNumber $newVhd.DiskNumber -UseMaximumSize -GptType '{ebd0a0a2-b9e5-4433-87c0-68b6b72699c7}'
                            Write-Host "`nVHD's boot partition has been created"

        @"
        select disk $($disk_no.Number)
        select partition $($WindowsPartition.PartitionNumber)
        format fs=fat32 label="System"
"@ | & $env:SystemRoot\System32\DiskPart.exe | Out-Null
        
        $volume          = Format-Volume -Partition $partition -FileSystem NTFS -Force -Confirm:$false
                        Write-Host "Boot Volume formatted (with Format-Volume)..."

        $WindowsPartition | Add-PartitionAccessPath -AssignDriveLetter

        $WindowsDrive     = $(Get-Partition -Disk $disk_no).AccessPaths[1]

        Write-Host "Access path ($WindowsDrive) has been assigned to the Windows System Volume..."

        New-Item $WindowsDrive\startup.nsh -type file -force -value "fs0:\EFI\Boot\bootx64.efi"

        $partition       | Add-PartitionAccessPath -AssignDriveLetter

        $drive           = $(Get-Partition -Disk $disk_no).AccessPaths[2]

        Write-Host "`nAccess path ($drive) has been assigned to the Boot Volume..."


      }

    #-----------------------------------------------------------------------------------
    #---------------------------Copying WIM image from install ISO ---------------------
    #-----------------------------------------------------------------------------------

    $iso_full = Resolve-Path -Path "$iso"

    Write-host "`nMounting Windows installation ISO ($iso)"

    Mount-DiskImage -ImagePath $iso_full -StorageType ISO -PassThru

    $iso_mount_info = get-diskimage -imagepath  $iso_full

    $iso_drive_letter = ($iso_mount_info | Get-Volume).DriveLetter

    $wim_image = "$($iso_drive_letter):\sources\install.wim"

    Write-host "`nCopying WIM file from Windows installation ISO"

    Copy-Item -Path $wim_image -Destination $tmp_dir -Force

    Write-host "`nDismounting ISO"
    Dismount-DiskImage -ImagePath $iso_full -StorageType ISO -PassThru

    $wim_image = Join-Path $tmp_dir -ChildPath 'install.wim'
    set-itemproperty $wim_image isreadonly $false

    Write-host "`nMounting WIM"

    #-----------------------------------------------------------------------------------
    #---------------------------Mounting WIM image to mount directory ------------------
    #-----------------------------------------------------------------------------------

    $wim_image_info = Get-WindowsImage -ImagePath $wim_image | Where-Object {$_.ImageName -ilike "*$($win_edition)"}
    $img_index = $wim_image_info[0].ImageIndex
    Write-Host "`nMounting WIM image=$wim_image, index=$img_index, mount_dir=$mount_dir"
    $process = Start-Process -PassThru -NoNewWindow -FilePath $dism_path `
                        -ArgumentList /Mount-wim, /wimfile:"$wim_image", /index:"$img_index", /MountDir:"$mount_dir"
    $process.WaitForExit()
    Write-Host $process.ExitCode
    if ($process.ExitCode)
    {
        Start-Process -FilePath $dism_path -ArgumentList /Unmount-wim, /MountDir:`"$mount_dir`", /discard
        Write-Error "`nMounting $wim_image failed! Unmounting directory $mount_dir"
        Return $process.ExitCode
    }

    Write-Host "`nMounting WIM done."

    $StopWatch.Elapsed

    #-----------------------------------------------------------------------------------
    #---------------------------Applying drivers to WIM file ---------------------------
    #-----------------------------------------------------------------------------------

       $process = Start-Process -FilePath $dism_path -Wait -NoNewWindow -PassThru `
                    -ArgumentList /Image:`"$mount_dir`",  /Add-Driver, /Driver:`"$driver_vca`", /forceunsigned

    if ($process.ExitCode -ne 0)
    {
        Start-Process -FilePath $dism_path -ArgumentList /Unmount-wim, /MountDir:`"$mount_dir`", /discard
        Write-Error "`nInstalling driver $driver_vca failed! See Dism log for details"
        Return $process.ExitCode
    }

    $process = Start-Process -FilePath $dism_path -Wait -NoNewWindow -PassThru `
                    -ArgumentList /Image:`"$mount_dir`",  /Add-Driver, /Driver:`"$driver_blk`", /forceunsigned

    if ($process.ExitCode -ne 0)
    {
        Write-Error "`nInstalling driver $driver_blk failed! See Dism log for details"
        Return $process.ExitCode
    }

    $process = Start-Process -FilePath $dism_path -Wait -NoNewWindow -PassThru `
                    -ArgumentList /Image:`"$mount_dir`",  /Add-Driver, /Driver:`"$driver_veth`", /forceunsigned

    if ($process.ExitCode -ne 0)
    {
        Write-Error "`nInstalling driver $driver_veth failed! See Dism log for details"
        Return $process.ExitCode
    }

    Write-Host "`nInstalling VCA drivers done"

    #-----------------------------------------------------------------------------------
    #-----------------------Installing KVM driver to WIM file -------------------------
    #-----------------------------------------------------------------------------------

    if ($netkvm_drv_dir -ne "")
    {
        Write-Host "`nInstalling KVM driver"
        $process = Start-Process -FilePath $dism_path -Wait -NoNewWindow -PassThru `
                     -ArgumentList /Image:`"$mount_dir`",  /Add-Driver, /Driver:`"$driver_netkvm`", /forceunsigned

        if ($process.ExitCode -ne 0)
        {
            Write-Error "`nInstalling driver $driver_netkvm failed! See Dism log for details"
            Return $process.ExitCode
        }
        Write-Host "`nInstalling KVM driver done"
    }

    #-----------------------------------------------------------------------------------
    #--------Copying answerfile / GFX driver / Xen drivers to WIM file -----------------
    #-----------------------------------------------------------------------------------

    $dest_answer_file = Join-Path $mount_dir -ChildPath 'unattend.xml'
    Copy-Item -Path $answer_file -Destination $dest_answer_file -Force

    $workfiles_dir = Join-Path $mount_dir -ChildPath 'VCA'
    if (-Not (Test-Path $workfiles_dir))
    {
        New-Item $workfiles_dir -type directory
        Write-Host "`nVCA directory created: " $workfiles_dir
    }

    if ( $status -eq 0 -And $install_gfx_drv_status -eq 1)
    {
    	$rc = CopyAndRenameCatalogFromTo $gfx_drv_dir $workfiles_dir GFX_driver
    	if ($rc -ne 0)
    	{
		    $status = 2
	    }
    }

    if ($status -eq 0)
    {
        $rc = ((CopyAndRenameCatalogFromTo $vcagent_dir $workfiles_dir VCAgent)[-1])
        if ($rc -ne 0)
        {
            $status = 3
        }
    }

    if ( $status -eq 0 -And $install_openssh_status -eq 1)
    {
    	$rc = CopyAndRenameCatalogFromTo $openssh_dir $workfiles_dir OpenSSH
    	if ($rc -ne 0)
    	{
		    $status = 4
	    }
    }

    if ( $status -eq 0 -And $install_xen_drv_status -eq 1)
    {
    	$rc = CopyAndRenameCatalogFromTo $xen_driver_dir $workfiles_dir Xen
    	if ($rc -ne 0)
    	{
		    $status = 5
	    }
    }

    $process  = Start-Process -Passthru -Wait -NoNewWindow -FilePath $dism_path `
                            -ArgumentList /Unmount-wim, /MountDir:`"$mount_dir`", /Commit
    if ($process.ExitCode -ne 0)
    {
        Write-Error "`nUnmounting WIM $wim_image failed!"
        Return $process.ExitCode
    }

    Write-Host "`nUnmounting WIM $wim_image done."

    #-----------------------------------------------------------------------------------
    #---------------------------Applying WIM image with drivers to VHD------------------
    #-----------------------------------------------------------------------------------

    $StopWatch.Elapsed
    
    $wim_image = Join-Path $tmp_dir -ChildPath 'install.wim'
    
    Write-Host "`nWIM image: " $wim_image

    Write-Host "`nApplying WIM to VHD"
    
    $wim_image_info = Get-WindowsImage -ImagePath $wim_image | Where-Object {$_.ImageName -ilike "*$($win_edition)"}
    
    $img_index = $wim_image_info[0].ImageIndex

    Write-Host $wim_image_info[0].ImageName
    Write-Host $wim_image_info[0].ImagePath
    Write-Host $wim_image_info[0].ImageIndex
    
    $process = Start-Process -FilePath $dism_path -Wait -NoNewWindow -PassThru `
                    -ArgumentList /Apply-Image, /Imagefile:$wim_image,  /index:$img_index, /ApplyDir:$drive
    do {start-sleep -Milliseconds 500}
      until ($process.HasExited)

    if ($LASTEXITCODE -ne 0)
        {
            Write-Error "`nApplying WIM failed! See Dism log file for details"
            Return $process.ExitCode
        }
    
    Write-Host "`nDeleting temporary WIM file"
    del $wim_image

    #-----------------------------------------------------------------------------------
    #----------------------------------Creating Boot files------------------------------
    #-----------------------------------------------------------------------------------


    if ($boot_part_type -eq "MBR" ) {

        $process = Start-Process -RedirectStandardOutput null -Passthru -Wait -NoNewWindow -FilePath "bcdboot.exe"`
        -ArgumentList @("$($drive)Windows", "/f BIOS", "/v", "/s $drive")
        
        if ($process.ExitCode -ne 0)
        {
            Write-Error "`nCan't create boot files on ($drive)"
            Return $process.ExitCode
        }

        $process = Start-Process -RedirectStandardOutput null -WindowStyle Hidden -Passthru -Wait -FilePath "bcdedit.exe"`
        -ArgumentList @("/store $($drive)boot\bcd", "/set `{bootmgr`} device locate")

        if ($process.ExitCode -ne 0)
        {
            Write-Error "`nCan't modify BCD on " $drive
            Return $process.ExitCode
        }

        $process = Start-Process -RedirectStandardOutput null -WindowStyle Hidden -Passthru -Wait -FilePath "bcdedit.exe"`
        -ArgumentList @("/store $($drive)boot\bcd", "/set `{default`} osdevice locate")

        if ($process.ExitCode -ne 0)
        {
            Write-Error "`nCan't modify BCD on " $drive
            Return $process.ExitCode
        }


    } elseif ($boot_part_type -eq "GPT" ) {
        
        $process = Start-Process -RedirectStandardOutput null -WindowStyle Hidden -Passthru -Wait -FilePath "bcdboot.exe"`
        -ArgumentList @("$($drive)Windows", "/f UEFI", "/v", "/s $WindowsDrive")

        if ($process.ExitCode -ne 0)
        {
            Write-Error "`nCan't create UEFI boot files on " $WindowsDrive
            Return $process.ExitCode
        }

    }
    
    Write-Host "`nClosing VHD file..."
    dismount-vhd -path $output_full_path
   
   Return 0
}


function CreateIsoFromVhd
{
    Write-Host "`nConverting VHD to IMG"
    
    $process = Start-Process -FilePath $virtualbox -Wait -NoNewWindow -PassThru `
                    -ArgumentList clonehd, `"$output_full_path`", `"$output_iso_full_path`", --format, RAW

    if ($process.ExitCode -ne 0)
    {
        Write-Error "`nConversion of " $output_full_path " to " $output_iso_full_path " failed! See Dism log for details"
        Return $process.ExitCode
    }

    del $output_full_path

    $img_new_name_prefix_t = $zip_img -split 'baremetal'
    $img_new_name_prefix = $img_new_name_prefix_t[0] + "baremetal"

    $img_new_name = $output_iso_full_path.Replace("version", "$vca_image_version")
    $img_new_name = $img_new_name.Replace("@", "$boot_part_type")
    $img_new_name = $img_new_name.Replace("windows_image", "$img_new_name_prefix")
    $returned_object = Rename-Item -Path $output_iso_full_path -NewName $img_new_name -PassThru
    if (-Not $returned_object)
    {
        Write-Error "`nCannot rename " $output_iso_full_path " to " $img_new_name
        Return 1
    }

    Write-Host "`nConversion of VHD to IMG done"
    Return $process.ExitCode
}

function CopyAndRenameCatalogFromTo
{
$from = $args[0]
$to = $args[1]
$newname = $args[2]

 $returned_object = Copy-Item $from $to -recurse -PassThru # if force added then override, if not then ask about confirmation
    if ($returned_object)
    {
        $tempname_dir = Join-Path $to -ChildPath (Split-Path $from -Leaf)
        if ($tempname_dir -ne (Join-Path $to -ChildPath $newname))
        {
            $returned_object = Rename-Item $tempname_dir $newname -PassThru
            if (-Not $returned_object)
                {
                Write-Error "`nCannot rename " $tempname_dir " directory to " $newname
                Return 1
                }
        }
        Write-Host "`n" $from " copied to : " (Join-Path $to -ChildPath $newname)
        Return 0
    }

    Write-Error "`nCannot copy " $from " directory to " (Join-Path $to -ChildPath $newname)
    Return 1
}

function ZipImage
{
    Write-Host "`nCompressing IMG file"
    $new_zip_img = $zip_img.Replace(".zip", "_$vca_image_version.zip")
    $destination =  (Join-Path $output_dir -ChildPath $new_zip_img)

    If(Test-path $destination) {Remove-item $destination}

    Move-Item ($output_dir + '\*.img') $tmp_dir

    Add-Type -assembly "system.io.compression.filesystem"
    $compressionLevel= [System.IO.Compression.CompressionLevel]::Fastest
    $includeBaseDirectory = $false

    [io.compression.zipfile]::CreateFromDirectory($tmp_dir, $destination, $compressionLevel, $includeBaseDirectory)
    Write-Host "`nDeleting IMG file"

    del ($tmp_dir + '\*.img')

    if(-Not (Test-Path $destination)) { Write-Error "Compression failed"; Return 1 }
    Return 0
}


# Main flow


$status = 0
$rc=0

$StopWatch = [System.Diagnostics.Stopwatch]::StartNew()

# not need to check return code, function only print variable used in execution of script
SummarizeParameters

$rc = ((GenerateImage)[-1])
if ($rc -ne 0)
{
    Write-Host "`nGenerating vhd image failed"
    Exit $rc
}


$rc = CreateIsoFromVhd
if ($rc -ne 0)
{
    Exit $rc
}

$rc = ((ZipImage)[-1])
	if ($rc -ne 0)
	{
		Exit $rc
	}

$StopWatch.Elapsed

if ($status -eq 0)
{
    Write-Host "`nSuccessfully created ISO file with Windows over blockio"
}
else
{
    Write-Error "`nISO creation completed with error:"
    Switch ($status)
    {
        1 {Write-Error " install VCA drivers to VHD error`n"}
        2 {Write-Error " copy GFX driver error`n"}
        3 {Write-Error " copy VCAgent error`n"}
        4 {Write-Error " copy OpenSSH error`n"}
        5 {Write-Error " copy Xen error`n"}
    }
    Throw $status
}
$Stopwatch.Stop()
# SIG # Begin signature block
# MIIoFQYJKoZIhvcNAQcCoIIoBjCCKAICAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD+FenwOsFs7mlA
# a4dWlwSKwSV+PMGxFWiovbTYNYzD9KCCI0swggXQMIIDuKADAgECAhNWAAABKLFh
# +N0T9Py/AAAAAAEoMA0GCSqGSIb3DQEBCwUAMHMxCzAJBgNVBAYTAlVTMQswCQYD
# VQQIEwJDQTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExGjAYBgNVBAoTEUludGVsIENv
# cnBvcmF0aW9uMSUwIwYDVQQDExxJbnRlbCBFeHRlcm5hbCBJc3N1aW5nIENBIDdC
# MB4XDTE2MDkxMjE1MDI0MloXDTE4MDkxMjE1MDI0MlowejELMAkGA1UEBhMCVVMx
# CzAJBgNVBAgTAkNBMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEaMBgGA1UEChMRSW50
# ZWwgQ29ycG9yYXRpb24xLDAqBgNVBAMTI0ludGVsKFIpIFZpc3VhbCBDb21wdXRl
# IEFjY2VsZXJhdG9yMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxo4K
# sIhNrve1IHa5Clp7Tx7NiF38RQTu6WBQ56K34RfvCrcZz7U5DbjPSuBTf5Tlz0KZ
# 8PJXs8J8Jjy/H1exraIva6TTpQQgPPRZE+NTsI4I0IPc99AMuIO+NmnvdBR4GtHs
# 55DFvCaBfmhBNlbKQXrqxwdUq16kaZIMPOTSBn+dk0k7zBl2QyEK5NacLR2XcsVb
# Sz41eigE6ONKnnRKrR92WU/6SZe1aiE0AupLfWl6Ir5gk/KQgaB9XLYPZF3mVaF6
# WynuBN27yifQYWf9OmgxNF+Qb8rlzKsQaSCY0U3dpylzC/L7sKO8FIwMaIeezCcz
# +N4cWKfjsgn9TszYhwIDAQABo4IBVDCCAVAwHQYDVR0OBBYEFK/yiUcu59sYDCC/
# o1frN4OYqu//MB8GA1UdIwQYMBaAFLLAZ6ZWjSd5EHTD9cWliWbW8S42MDcGA1Ud
# HwQwMC4wLKAqoCiGJmh0dHA6Ly9wa2kuaW50ZWwuY29tL2NybC9JbnRlbENBN0Iu
# Y3JsMGYGCCsGAQUFBwEBBFowWDAyBggrBgEFBQcwAoYmaHR0cDovL3BraS5pbnRl
# bC5jb20vY3J0L0ludGVsQ0E3Qi5jcnQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9PQ1NQ
# LmludGVsLmNvbS8wDAYDVR0TAQH/BAIwADALBgNVHQ8EBAMCB4AwPQYJKwYBBAGC
# NxUHBDAwLgYmKwYBBAGCNxUIhsOMdYSZ5VGD/YEohY6fU4KRwAlnhYn2ZIXpklAC
# AWQCARAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDQYJKoZIhvcNAQELBQADggIBALdv
# YWQ5hi/8Wp5Kdhp8pLv0pHziAivyVu6Wa4yUV+MmkCzTmPVIx45NY4U6hWKEda49
# lEwh6q10dvPtHP/7GAo0DFuXeQqtHHZd/ScbhHu/mxrkAygGBBOwtoyCa3Y1vaTB
# ITEzryWIhejaUGpAe/480YDKhR4HYFJn6mMRCIAbnit6m0HlULw5gANsvCFkITuy
# NlIF5Lhi2FA3n7gYWEW19Be4O+NMNjNPDZA68aaEwk07O9+esvSoUMlHqjjGFP4F
# KGZahb7ovVN6+iuoe0MZSSy7P9HgM3mWhtV34ptWFT/nQuoJRFYTuLo+nWp6Yhzz
# 48hpF98+nQDGq6WHJYJf6cXngFQ8gaAPUSdX9wLz0VpSDtK8c6E1sRT0du6k89ud
# WziS4hpLQyZM2mZYWAVKdxsTwEPGkVhkMKHz8rNB4WrOyPwHNiOAUA/SWSum9lCp
# iAdYpY8z3z18wE3fBHduAR5xLFWOVgLofR11rH8VtzZ8lpF8vEZ+K5d0KXCxy0lX
# VvGtzHVIChcPbz79k3sYKgqJUTT1W1v8E0ymzQtIyyxntUte9u3jTiRrTLAJ/lwC
# G6eeGx5EaGor7zdAjei2cPhvmiv02LVD53eUZ7sT0VIobztqKw4IIHhO+74Iwb3z
# LrW+vN72lJrEGlJcdH/+o1UdqPyiHyrTG2Vsna4DMIIHSTCCBTGgAwIBAgIQBpte
# mSdyhMh2fxNop96w8zANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UEBhMCR0IxGzAZ
# BgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG
# A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2Vy
# dGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTUxMDI4MDAwMDAwWhcNMjEwNjE3MjM1
# OTU5WjBzMQswCQYDVQQGEwJVUzELMAkGA1UECBMCQ0ExFDASBgNVBAcTC1NhbnRh
# IENsYXJhMRowGAYDVQQKExFJbnRlbCBDb3Jwb3JhdGlvbjElMCMGA1UEAxMcSW50
# ZWwgRXh0ZXJuYWwgSXNzdWluZyBDQSA3QjCCAiIwDQYJKoZIhvcNAQEBBQADggIP
# ADCCAgoCggIBALpab/FfGgtUEBK6kNai6w5erD3OFYWaShHKZH8iimkWV88gOiSA
# 17vgU9ypS89sgbG+GqIB4EV7bAxm1E+PbiLt81KYono1N4ps7LgxhklnKce0s4hw
# 0JkeK8QS9+4e87wkjhGGA5PSeQvnrtxaMami54AJ+lqSUWcw7zux9LH9TqsaaCXn
# 21Vgc3sVvwBMkEKeKWYPejzjfaBCmZCeNVyDHOVI30F8s57plyrD+gNGI6kmwmXx
# leJXTaaqgLOJUbcylkMl9C+Q+A7Mz3h0dQ2uL52hoAv8HU0jxoa23WHHpr+XEe0V
# DEDj/eUQLZ2zwe/t62R5F4wGrmmS60YDKtQh0Vn6/DbplxZGeSgzo1krGfQV5nA8
# SomyyT6Nd0jUCnysReVEKVwT88hNjiae8FSFAO2f6+7P4hPBuq3TqtVErbR0HqsA
# 3QdyXpymtJDj9kahAFRXyCYX40hz0Zho0ZGsrDp27EvjNoWTGWLAIUhoC4rFlCUd
# KNUC1Afp/lBTg5ETbGEAB/xA95fNjzJ7DXo3DAij++xe+o1z47rEktBx9PscYZVt
# V1seZi1qIH5VMLusiV/Kce1cE44GhSByRswh/Q5jEN8cRz8S0vlQSwQb32/SzJuO
# VwUgla9jVoshUAnPle+fNvcre/+AcVCvfUuantD3RBiwYBqUo4owCJ7rAgMBAAGj
# ggHEMIIBwDAfBgNVHSMEGDAWgBS7r34CPfqm8TyEjq3uOJjs2TIy1DAdBgNVHQ4E
# FgQUssBnplaNJ3kQdMP1xaWJZtbxLjYwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB
# /wQIMAYBAf8CAQAwPgYDVR0lBDcwNQYIKwYBBQUHAwMGCCsGAQUFBwMEBggrBgEF
# BQcDCAYKKwYBBAGCNwoDDAYJKwYBBAGCNxUFMCIGA1UdIAQbMBkwDQYLKoZIhvhN
# AQUBaQEwCAYGZ4EMAQQBMEwGA1UdHwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmwuY29t
# b2RvY2EuY29tL0NPTU9ET1JTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHEG
# CCsGAQUFBwEBBGUwYzA7BggrBgEFBQcwAoYvaHR0cDovL2NydC5jb21vZG9jYS5j
# b20vQ09NT0RPUlNBQWRkVHJ1c3RDQS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v
# Y3NwLmNvbW9kb2NhLmNvbTA1BgNVHR4ELjAsoCowC4EJaW50ZWwuY29tMBugGQYK
# KwYBBAGCNxQCA6ALDAlpbnRlbC5jb20wDQYJKoZIhvcNAQEMBQADggIBADW7A+rM
# m2AaE9B1Uo6AlUVOnr9uwLtkqsNusQIdRl4v6C9IzIQQ962ZO//6hWgpsNN8MeIa
# tHvBZuKlO8cpGJg1rmMBqEUglWHbEE25DWvTmWTOX4u4bBNGoG5aDT7nkOu3MaEh
# 9Y3eO3tpNvEIALmqvxxWYVbXzJI/KdTZa9giLw5W9WrRRuiAjzl6kjxnSLfi+hkP
# N2fi3yktAqpDKC6uLEZCJL5tu2qISaZMIN/lZU/64cG+cdX4XvWdZpKyO2Th6K6s
# mVUXvdsb36CTTz9W8juD1dK3wQhaUkBC4z6RIPc1tJHwTeE0aUh5wO0wyZMahNVy
# GY9tgDn0WasgFtj5/3AmI3vsxQAzInw9IDrttCi8eoEM5wvBP3wwDE5QuGcP12QX
# t8PFIIXKj87VJioSVLn/IvioJzzKDoU3FO4C5S9mFWJjh2pezynTuJF4t2FyF3vB
# GaYYCCLa0JEl9gYJCSawLayAiHQzX8fgRMEwmXbYd7FHAe9pkivtrlgpY6A1juQd
# twTx2jqyMoCxyLzw5w9xAHozOgbopNh52dlTzZv+smhbiISFawdx0E+TCgdgAzQI
# 0nO/FBrf48cEGy2ZnpMclbOHmEJaHJFjUjmKj0oqwkx7cGk6PPH7L/8OCoeU5AFq
# z5u0H6MOqeoq3K8rjEQB/TpYfTJ4ohnVyXTFMIIFdDCCBFygAwIBAgIQJ2buVutJ
# 846r13Ci/ITeIjANBgkqhkiG9w0BAQwFADBvMQswCQYDVQQGEwJTRTEUMBIGA1UE
# ChMLQWRkVHJ1c3QgQUIxJjAkBgNVBAsTHUFkZFRydXN0IEV4dGVybmFsIFRUUCBO
# ZXR3b3JrMSIwIAYDVQQDExlBZGRUcnVzdCBFeHRlcm5hbCBDQSBSb290MB4XDTAw
# MDUzMDEwNDgzOFoXDTIwMDUzMDEwNDgzOFowgYUxCzAJBgNVBAYTAkdCMRswGQYD
# VQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNV
# BAoTEUNPTU9ETyBDQSBMaW1pdGVkMSswKQYDVQQDEyJDT01PRE8gUlNBIENlcnRp
# ZmljYXRpb24gQXV0aG9yaXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
# AgEAkehUktIKVrGsDSTdxc9EZ3SZKzejfSNwAHG8U9/E+ioSj0t/EFa9n3Byt2F/
# yUsPF6c947AEYe7/EZfH9IY+Cvo+XPmT5jR62RRr55yzhaCCenavcZDX7P0N+pxs
# +t+wgvQUfvm+xKYvT3+Zf7X8Z0NyvQwA1onrayzT7Y+YHBSrfuXjbvzYqOSSJNpD
# a2K4Vf3qwbxstovzDo2a5JtsaZn4eEgwRdWt4Q08RWD8MpZRJ7xnw8outmvqRsfH
# IKCxH2XeSAi6pE6p8oNGN4Tr6MyBSENnTnIqm1y9TBsoilwie7SrmNnu4FGDwwlG
# Tm0+mfqVF9p8M1dBPI1R7Qu2XK8sYxrfV8g/vOldxJuvRZnio1oktLqpVj3Pb6r/
# SVi+8Kj/9Lit6Tf7urj0Czr56ENCHonYhMsT8dm74YlguIwoVqwUHZwK53Hrzw7d
# PamWoUi9PPevtQ0iTMARgexWO/bTouJbt7IEIlKVgJNp6I5MZfGRAy1wdALqi2cV
# KWlSArvX31BqVUa/oKMoYX9w0MOiqiwhqkfOKJwGRXa/ghgntNWutMtQ5mv0TIZx
# MOmm3xaG4Nj/QN370EKIf6MzOi5cHkERgWPOGHFrK+ymircxXDpqR+DDeVnWIBqv
# 8mqYqnK8V0rSS527EPywTEHl7R09XiidnMy/s1Hap0flhFMCAwEAAaOB9DCB8TAf
# BgNVHSMEGDAWgBStvZh6NLQm9/rEJlTvA73gJMtUGjAdBgNVHQ4EFgQUu69+Aj36
# pvE8hI6t7jiY7NkyMtQwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8w
# EQYDVR0gBAowCDAGBgRVHSAAMEQGA1UdHwQ9MDswOaA3oDWGM2h0dHA6Ly9jcmwu
# dXNlcnRydXN0LmNvbS9BZGRUcnVzdEV4dGVybmFsQ0FSb290LmNybDA1BggrBgEF
# BQcBAQQpMCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20w
# DQYJKoZIhvcNAQEMBQADggEBAGS/g/FfmoXQzbihKVcN6Fr30ek+8nYEbvFScLse
# PP9NDXRqzIGCJdPDoCpdTPW6i6FtxFQJdcfjJw5dhHk3QBN39bSsHNA7qxcS1u80
# GH4r6XnTq1dFDK8o+tDb5VCViLvfhVdpfZLYUspzgb8c8+a4bmYRBbMelC1/kZWS
# WfFMzqORcUx8Rww7Cxn2obFshj5cqsQugsv5B5a6SE2Q8pTIqXOi6wZ7I53eovNN
# VZ96YUWYGGjHXkBrI/V5eu+MtWuLt29G9HvxPUsE2JOAWVrgQSQdso8VYFhH2+9u
# Rv0V9dlfmrPb2LjkQLPNlzmuhbsdjrzch5vRpu/xO28QOG8wggWAMIIEaKADAgEC
# AhRpstHM8C4g3MlcYolPf55fX8BXvzANBgkqhkiG9w0BAQsFADB/MQswCQYDVQQG
# EwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDElMCMGA1UECxMcUm9vdCBD
# ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEuMCwGA1UEAxMlUXVvVmFkaXMgUm9vdCBD
# ZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTAeFw0xNDA1MzAxNjM1NTVaFw0yMTAzMTcx
# ODMzMzNaMEkxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1pdGVk
# MR8wHQYDVQQDExZRdW9WYWRpcyBJc3N1aW5nIENBIEc0MIICIjANBgkqhkiG9w0B
# AQEFAAOCAg8AMIICCgKCAgEAxFGo/S/4GVzomXoxmkaTYkznYlslpJfLQAMQ95k8
# 2dZxzPOBJtzVP1lopp5keaUnwEHMmPbIJECJxKEqW0cgCRLw/8yOZL7u0QFfx6D8
# /JxWGbpRXbw6xc8Pqurg7eoeZN3zGZOhS+dRkFsyArQFu1lc8MIXpMiJkrVXRNq8
# CDxKEzNyzwTaJ2/tdskoUkk4Ycuut3CKLYhYqBFjA4GMMqLTIMIqu2AocgEbwtP4
# y/oePDt1ZjuIj09iPm06qXC3i2aSTY3qnOHk/IRcEbGFMad0baSXdLaPPYt87/zB
# mM+82KohTJJJx+LHo/c0lLcULxwJ5Lre1NNnOC0CP7I45uD0OIQZD5Wg7wxw7jjM
# g2VneRtAnLvEyUqQucYEChLRxZE4HEcBVQxKVa40SoioSEAQWcgJzJ5ngAsgulNp
# oV8Aip2FbMm2cqLDFVP704ysbkw9AVoSdRo17rH7RA5DOM8hVJ/1SgMf4cZr14xr
# mz0rx2/wFYrxwKT2JepbMy3TJoxFehYSbOWUFym4QWAz2klgNY+X/oIxsou0I2SE
# NPZkVhuiV4lirEI5rAep/Gjh/D4WXfHEbwgpUtOvSovzfIDTu1aJafZaKsOzLEjL
# t9+LrwQdLUG2Odd5QdPGdhpQOY6HhJ1OfNM1cOVir+qqx1NQcTs9RVJh/7nB1zoZ
# u00CAwEAAaOCASgwggEkMBIGA1UdEwEB/wQIMAYBAf8CAQAwEQYDVR0gBAowCDAG
# BgRVHSAAMHEGCCsGAQUFBwEBBGUwYzAqBggrBgEFBQcwAYYeaHR0cDovL29jc3Au
# cXVvdmFkaXNnbG9iYWwuY29tMDUGCCsGAQUFBzAChilodHRwOi8vdHJ1c3QucXVv
# dmFkaXNnbG9iYWwuY29tL3F2cmNhLmNydDAOBgNVHQ8BAf8EBAMCAQYwHwYDVR0j
# BBgwFoAUi0tt7dMpuQYZ7Dk5qfCXhGrL798wOAYDVR0fBDEwLzAtoCugKYYnaHR0
# cDovL2NybC5xdW92YWRpc2dsb2JhbC5jb20vcXZyY2EuY3JsMB0GA1UdDgQWBBTz
# NBIR8YzG9rKntJlLcIrKYKHLRTANBgkqhkiG9w0BAQsFAAOCAQEAufYTUrUXpypN
# hHdDCaTboGe0YA5C9AO9xP8sWg+QLnjFY8hK7Cf2fOQp0M9gGPpoItoCUnYN8hdU
# xvYIHqHMguTDOm2ZInzEwHe05gUgR5NAOc/cVa3DRq8pTXmcZEwgX4ocVvxGoF/L
# mN2Rejm0r8R3mWuerN5vLXnqf9cTJJhSHP1pPu1yrD/QtAEZFO2w8MvznFEUI4zH
# 3Gl9MoGW5B1HjwF2lIM+iI2SWxhYmGkDx/XT8mFSUOs0oP0mMDAPtf1w5ycsNwsc
# 8+cepiwHQ7ZLiF6XH8EwfWBkKvMMcGhEUWNZn9tXwh//gOXCEZLYL+/VF0P/ZC1k
# hFxSGmPCZzCCBdowggPCoAMCAQICFBnD/PDmBIJE9yxOzDni8mHWyK7XMA0GCSqG
# SIb3DQEBCwUAMEkxCzAJBgNVBAYTAkJNMRkwFwYDVQQKExBRdW9WYWRpcyBMaW1p
# dGVkMR8wHQYDVQQDExZRdW9WYWRpcyBJc3N1aW5nIENBIEc0MB4XDTE4MDQyMzIw
# MjUyNVoXDTIxMDMxNzE4MzMzM1owgZIxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJD
# QTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExGjAYBgNVBAoTEUludGVsIENvcnBvcmF0
# aW9uMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjowRTM3LTk2NDktMDhDNTEcMBoG
# A1UEAxMTdGltZXN0YW1wLmludGVsLmNvbTCCASIwDQYJKoZIhvcNAQEBBQADggEP
# ADCCAQoCggEBAKdliYAGlfC0eKVgxq5ZSQuThENUdboS9MpMujmvk+eAXccihGqu
# p6fqk5DcJbuNuUrDSRx5HUn2RmWCvUG6aLAzLezRqPcil/KfonHYSulzpLdC0etn
# sKnOqEDhuLFXvNN1AhWCWshGlZWEAWBVttmevszVgO3hr2dRk7IBGSg4OY26WexN
# UryujnfCL1lUasdgSuWCBsYomCv07+opy5fButLu1Crs6yY7Aox0k9iq5bG7KevV
# 1/JqeSmul2ZsRdO3qz4s7ipgW+LHyyV5KOp/R3eETLfj3dMWXxK1mWkuA+Ge3k6g
# JH22ORvtAYwweHsUoG7DJ3xylvb+Rwz1U+sCAwEAAaOCAW4wggFqMHMGCCsGAQUF
# BwEBBGcwZTAqBggrBgEFBQcwAYYeaHR0cDovL29jc3AucXVvdmFkaXNnbG9iYWwu
# Y29tMDcGCCsGAQUFBzAChitodHRwOi8vdHJ1c3QucXVvdmFkaXNnbG9iYWwuY29t
# L3F2aWNhZzQuY3J0ME8GA1UdIARIMEYwRAYKKwYBBAG+WAGEWDA2MDQGCCsGAQUF
# BwIBFihodHRwOi8vd3d3LnF1b3ZhZGlzZ2xvYmFsLmNvbS9yZXBvc2l0b3J5MA4G
# A1UdDwEB/wQEAwIGwDAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAfBgNVHSMEGDAW
# gBTzNBIR8YzG9rKntJlLcIrKYKHLRTA6BgNVHR8EMzAxMC+gLaArhilodHRwOi8v
# Y3JsLnF1b3ZhZGlzZ2xvYmFsLmNvbS9xdmljYWc0LmNybDAdBgNVHQ4EFgQUDs3q
# rezFJa4H6rL55SZ7eREANrcwDQYJKoZIhvcNAQELBQADggIBADFufu8ZU0tlilxV
# 8ipeexw3lBgYoIXrnhZ8TJm+I+yDv1WV986DTeh1GwdMh3eWJp49R5iurDcGph9d
# epK/al5DJbibsLnUvt0kHRCwIgKxxhXT8pXBt2NpeoYisxnb9s07nphI14YCdVTd
# CKoffGlXUPoYXMHKw1mb6erPvB2tBE02PjWfqZ4vBqLVqXQK92RX9tw8ViuGpkLp
# ZtqXWcnyMyLzuzrnXlK4e9Uv4q+Lc7FtO6qh5+bx5HG7pItTJD/mo6e3D0uhOEbn
# nP5xZpEDjpBFEZ3X7VVjLWPDrvCCQBDwwfn+yCi7aUm60QRAu/rEuvCoaAvcPi2N
# VjKnwkX3JQ1CWXsh74Gc/ZWmsM1lKtKFZeGkTSSleUTbdV6qtYf1WBcANRyM9m9B
# HlSEG26rNy4kqbwbATtCAqqVG5M6jW6vdWJhERnwevUP9xVVRUxfJgg+D4+/uikg
# 4B3GUJFmiZjXAUVIK/Q0ZrpWnprKYif6sOsyWVTRYB+MrXj7x6AS7dhmtsoirhyS
# 4GpC+YlR70SyMNaKDtX39XGuUmYc5Lya6FebHJO950aM+9xQvyWPjSYizZScISaz
# YnEkAXnCjDaxpKwYrHLIwHdwOjpNuJCtywLkKhb5Da1oc3xRIYsiHHzUxZxuwh/O
# NigS5M0XIyaD2IdY9FI3QTbqktCHMIIFTDCCAzSgAwIBAgITMwAAADXY1VlbBnFB
# KwAAAAAANTANBgkqhkiG9w0BAQUFADB/MQswCQYDVQQGEwJVUzETMBEGA1UECBMK
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMSkwJwYDVQQDEyBNaWNyb3NvZnQgQ29kZSBWZXJpZmljYXRp
# b24gUm9vdDAeFw0xMzA4MTUyMDI2MzBaFw0yMzA4MTUyMDM2MzBaMG8xCzAJBgNV
# BAYTAlNFMRQwEgYDVQQKEwtBZGRUcnVzdCBBQjEmMCQGA1UECxMdQWRkVHJ1c3Qg
# RXh0ZXJuYWwgVFRQIE5ldHdvcmsxIjAgBgNVBAMTGUFkZFRydXN0IEV4dGVybmFs
# IENBIFJvb3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC39xoz5vIA
# BC054E5b7R+8bA/Ntfojts7emxEzl6QpTH2Tn71KvJPtAxrjj8/lbVBa1pcplFqA
# sEl62y6V/bjKvzc4LR4+kUGtcFbH8E8/6DKedMrIkFTpxl8PeJ2aQDwOrGGqXhSP
# noehalDc15pOrwWzpnGUnHGzUGAKxxOdOAeGAqjpqGkmGJCrTLBPI6s6T4TY386f
# 4Wlvu9dC12tE5Met7m1BX3JacQg3s3llpFmglDf3AC8NwpJy2tA4ctsUqEXEXSp9
# t7TWxO6szRNEt8kr3UMAJfphuWlqWCMRt6czj1Z1WfXNKddGtworZbbTQm8Vsrh7
# ++/pXVPVNFonAgMBAAGjgdAwgc0wEwYDVR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0T
# AQH/BAgwBgEB/wIBAjAdBgNVHQ4EFgQUrb2YejS0Jvf6xCZU7wO94CTLVBowCwYD
# VR0PBAQDAgGGMB8GA1UdIwQYMBaAFGL7CiFbf0NuEdoJVFBr9dKWcfGeMFUGA1Ud
# HwROMEwwSqBIoEaGRGh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By
# b2R1Y3RzL01pY3Jvc29mdENvZGVWZXJpZlJvb3QuY3JsMA0GCSqGSIb3DQEBBQUA
# A4ICAQA2K6Ly4TMf5JP38mmFxmQOyZtjL+RwN5j9lOx7z/ihQkb57WpOjTRpNgVV
# eh67rYyZQpYG6SWoJoS+wb8WqXyqWwS3/dHA9AK+KO31d8eb/jr26MF704Kr+hRO
# zyvP5dW1SECxo4+Di60rJVOrpjTO8kP3Tyzp3R5OWra66DsQmSQAvFD9ePblI6iJ
# lJP3t0EwN0pXt+ZE2cnfmQWqRPx0r4JkzAfLAbYJwy7j6DKntJ9BeMehhDZUYvLs
# FQrI6tCE+PHga/RWEl+V4Pzdt3aT/ilKJekEAPG0EQ7JhJ7bF331HqWONikZOm1s
# RkvXq3AkKI0Fo9nVJPL4oNE8gjnUqIIOaTqBCfwG8MdZM4Q2kwZBkSMsIqWnAStQ
# tCiu20awWRuGs5uH6ElOOQttFN9MAzAeH190rvVbWQNT7JgW4NBiNXUbSLh9E+V6
# SLh3UqQHmCU7Bpt6TmpvRIZPFE8neSc9UHNBTJxBPt0pDHOxx/sfdgwXZQTr0lAQ
# kkFJ7OQGfTYVRG+Jv2l9+U1AwTqYtqB+MdK1rsr7U9U/UIbNXpM7bV18mj8/96kl
# WITdEUkAosfInjfdd45tcYvgW4E0XVS6zPWTR4ht5+9b4ijkgBtA5A8q0X8jFWVa
# rJmUQz9GVSbWxPqIleKRmqMtC4XerIzg+Wdwn3F5AjH3YaIpxDGCBCAwggQcAgEB
# MIGKMHMxCzAJBgNVBAYTAlVTMQswCQYDVQQIEwJDQTEUMBIGA1UEBxMLU2FudGEg
# Q2xhcmExGjAYBgNVBAoTEUludGVsIENvcnBvcmF0aW9uMSUwIwYDVQQDExxJbnRl
# bCBFeHRlcm5hbCBJc3N1aW5nIENBIDdCAhNWAAABKLFh+N0T9Py/AAAAAAEoMA0G
# CWCGSAFlAwQCAQUAoGowGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYB
# BAGCNwIBCzEOMAwGCisGAQQBgjcCARYwLwYJKoZIhvcNAQkEMSIEIJGeN73zTxgy
# tRlz/zLRG/aCqjgA1ZnSG3QZoSSpf3q9MA0GCSqGSIb3DQEBAQUABIIBACSk5n4D
# DXiZIxNDSDAQe+dVuy3aBYIVb2cs3k0q6Mi8ltS7zTzKUGODPEUCP4gWHqXnpLyg
# aiHS0WRGJyXWdzXtOmSQlEKY/6qoI8TJ+ZIAHVeCvJx9DdVuadFZMqIZC4aAo2OH
# X7q/sFX564/Kt0Gu+RFIzGtrXM6nOU+oOneHifCX9m5sB1rczFoI3MRo2Z6yVm5J
# S+m3v+xWd36dqvCbqrXIjXDSoBilLnXbfg9MtVAWvOzVW5sK/1YpC5833EWHwGOQ
# 6wyPEpvMUHGE4P0ZokNP1cyxanYA+qLRaTl7ZbGEknW/2h4GyS0tAtbLGPPCIm4Y
# NBVd0p07bgLnvfOhggH6MIIB9gYJKoZIhvcNAQkGMYIB5zCCAeMCAQEwYTBJMQsw
# CQYDVQQGEwJCTTEZMBcGA1UEChMQUXVvVmFkaXMgTGltaXRlZDEfMB0GA1UEAxMW
# UXVvVmFkaXMgSXNzdWluZyBDQSBHNAIUGcP88OYEgkT3LE7MOeLyYdbIrtcwCQYF
# Kw4DAhoFAKBdMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkF
# MQ8XDTE4MDcwNDA5NDI0NVowIwYJKoZIhvcNAQkEMRYEFKNRdvM9i9e+/uPZKxDf
# fubDxfRvMA0GCSqGSIb3DQEBBQUABIIBAHiv1QRzsQd1whsy066BwXkGzbCe2MJH
# avErsdTbILyk9FAecJkGS9XW1EEsa8RKXkpeqcmk/cm9VgUi6+0bMOCPuH+zTtja
# E/i5EphF958FiIb3rGbNz4MQYOM9Ew24aOInzi2GxiFmlDbDnsqWyPgo/0Ee9m6x
# CtesceFB533ifSRiVkVzPPqJbk+P5lPEXd9yiywQErNONQudiKBQAZsR9FRkva1E
# s2bl+BpmDTLF1+h3uLXUOzbT7R5NQwmrtCy4O7lKxH6l4qpEtU5tP9Tqb5aV+Vdw
# 0ZI/Hbuod0cKizAq6LO+6UKfU3eC+FPg88bY350YLHzNRZcibnCIyWs=
# SIG # End signature block
