ozo-ad-lab-implement-customization-prerequisites.ps1

#Requires -Modules @{ModuleName="OZO"; ModuleVersion="1.7.0"},OZOLogger -RunAsAdministrator

<#PSScriptInfo
    .VERSION 1.1.0
    .GUID 2a8769c1-6be2-44f3-ae17-47b4138ea2fa
    .AUTHOR Andy Lievertz <alievertz@onezeroone.dev>
    .COMPANYNAME One Zero One
    .COPYRIGHT This script is released under the terms of the GNU General Public License ("GPL") version 2.0.
    .TAGS
    .LICENSEURI https://github.com/onezeroone-dev/OZO-AD-Lab-Implement-Customization-Prerequisites/blob/main/LICENSE
    .PROJECTURI https://github.com/onezeroone-dev/OZO-AD-Lab-Implement-Customization-Prerequisites
    .ICONURI
    .EXTERNALMODULEDEPENDENCIES
    .REQUIREDSCRIPTS
    .EXTERNALSCRIPTDEPENDENCIES
    .RELEASENOTES https://github.com/onezeroone-dev/OZO-AD-Lab-Implement-Customization-Prerequisites/blob/main/CHANGELOG.md
    .PRIVATEDATA
#>


<#
    .SYNOPSIS
    See description.
    .DESCRIPTION
    Implements the customization prerequisites for the One Zero One AD Lab.
    .PARAMETER FeatureName
    The name of the Windows feature to install. Default is "Microsoft-Hyper-V-All".
    .PARAMETER InternalIP
    The internal IP address for the lab network. Default is "172.16.1.1".
    .PARAMETER InternalSwitchName
    The name of the internal virtual switch. Default is "OZO AD Lab NAT".
    .PARAMETER LocalGroup
    The local group to which the current user should be added. Default is "Hyper-V Administrators".
    .PARAMETER OscdimgExePath
    The path to the Oscdimg executable. Default is the typical installation path within the Windows Kits directory.
    .PARAMETER OZOADLabDirLike
    The pattern to identify the OZO AD Lab directory. Default is "onezeroone-dev-OZO-AD-Lab*".
    .PARAMETER OZOADLabPath
    The path to the OZO AD Lab directory. Default is "$Env:SystemDrive\ozo-ad-lab".
    .PARAMETER OZOADLabISOs
    A hashtable of ISO filenames and their corresponding download URIs.
    .PARAMETER OZOADLabZipPath
    The path to the OZO AD Lab ZIP file. Default is "$Env:SystemDrive\ozo-ad-lab.zip".
    .PARAMETER OZOADLabZipUri
    The URI to download the latest OZO AD Lab ZIP file. Default is "https://api.github.com/repos/onezeroone-dev/OZO-AD-Lab/releases/latest".
    .PARAMETER PrefixLength
    The prefix length for the lab network subnet. Default is 24.
    .PARAMETER SimExePath
    The path to the SIM executable. Default is the typical installation path within the Windows Kits directory.
    .PARAMETER Subnet
    The subnet for the lab network. Default is "172.16.1.0".
    .PARAMETER WinAdkFileUri
    The URI to download the Windows ADK setup file. Default is "https://go.microsoft.com/fwlink/?linkid=2128854".
    .PARAMETER WinAdkPath
    The path to the Windows ADK setup file. Default is "$Env:USERPROFILE\Downloads\adksetup.exe".
    .EXAMPLE
    ozo-ad-lab-implement-customization-prerequisites
    .LINK
    https://github.com/onezeroone-dev/OZO-AD-Lab-Implement-Customization-Prerequisites/blob/main/README.md
#>


#PARAMETERS
[CmdletBinding()] Param(
    [Parameter(Mandatory=$false,HelpMessage="The name of the Windows feature to install.")][String] $FeatureName = "Microsoft-Hyper-V-All",
    [Parameter(Mandatory=$false,HelpMessage="The internal IP address for the lab network.")][String] $InternalIP = "172.16.1.1",
    [Parameter(Mandatory=$false,HelpMessage="The name of the internal virtual switch.")][String] $InternalSwitchName = "OZO AD Lab NAT",
    [Parameter(Mandatory=$false,HelpMessage="The local group to which the current user should be added.")][String] $LocalGroup = "Hyper-V Administrators",
    [Parameter(Mandatory=$false,HelpMessage="The path to the Oscdimg executable.")][String] $OscdimgExePath = (Join-Path -Path ${Env:ProgramFiles(x86)} -ChildPath "Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\amd64\Oscdimg\oscdimg.exe"),
    [Parameter(Mandatory=$false,HelpMessage="The pattern to identify the OZO AD Lab directory.")][String] $OZOADLabDirLike = "onezeroone-dev-OZO-AD-Lab*",
    [Parameter(Mandatory=$false,HelpMessage="The path to the OZO AD Lab directory.")][String] $OZOADLabPath = (Join-Path -Path $Env:SystemDrive -ChildPath "ozo-ad-lab"),
    [Parameter(Mandatory=$false,HelpMessage="A hashtable of ISO filenames and their corresponding download URIs.")][HashTable] $OZOADLabISOs = @{
        "microsoft-windows-client-evaluation.iso" = "https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/26100.1742.240906-0331.ge_release_svc_refresh_CLIENTENTERPRISEEVAL_OEMRET_x64FRE_en-us.iso"
        "microsoft-windows-server-evaluation.iso" = "https://software-static.download.prss.microsoft.com/dbazure/888969d5-f34g-4e03-ac9d-1f9786c66749/26100.1742.240906-0331.ge_release_svc_refresh_SERVER_EVAL_x64FRE_en-us.iso"
    },
    [Parameter(Mandatory=$false,HelpMessage="The path to the OZO AD Lab ZIP file.")][String] $OZOADLabZipPath = (Join-Path -Path $Env:USERPROFILE -ChildPath "Downloads\ozo-ad-lab-latest.zip"),
    [Parameter(Mandatory=$false,HelpMessage="The URI to download the latest OZO AD Lab ZIP file.")][String] $OZOADLabZipUri = "https://api.github.com/repos/onezeroone-dev/OZO-AD-Lab/releases/latest",
    [Parameter(Mandatory=$false,HelpMessage="The prefix length for the lab network subnet.")][Int32] $PrefixLength = 24,
    [Parameter(Mandatory=$false,HelpMessage="The path to the SIM executable.")][String] $SimExePath = (Join-Path -Path ${Env:ProgramFiles(x86)} -ChildPath "Windows Kits\10\Assessment and Deployment Kit\Deployment Tools\WSIM\x86\imgmgr.exe"),
    [Parameter(Mandatory=$false,HelpMessage="The subnet for the lab network.")][String] $Subnet = "172.16.1.0",
    [Parameter(Mandatory=$false,HelpMessage="The URI to download the Windows ADK setup file.")][String] $WinAdkFileUri = "https://go.microsoft.com/fwlink/?linkid=2128854",
    [Parameter(Mandatory=$false,HelpMessage="The path to the Windows ADK setup file.")][String] $WinAdkPath = (Join-Path -Path (Join-Path -Path $Env:USERPROFILE -ChildPath "Downloads") -Childpath "adksetup.exe")
)

# CLASSES
Class Main {
    # PROPERTIES: Booleans
    [Boolean] $prerequisitesSatisfied = $true
    # PROPERTIES: PSCustomObjects
    [PSCustomObject] $ozoLogger = @()
    # METHODS: Constructor method
    Main($FeatureName,$InternalIP,$InternalSwitchName,$LocalGroup,$OscdimgExePath,$OZOADLabDirLike,$OZOADLabPath,$OZOADLabISOs,$OZOADLabZipPath,$OZOADLabZipUri,$PrefixLength,$SimExePath,$Subnet,$WinAdkFileUri,$WinAdkPath) {
        # Populate the ozoADLabISOs list
        # Create a logger object
        $this.ozoLogger = (New-OZOLogger)
        # Call ValidateEnvironment to determine if we can proceed
        If ($this.ValidateEnvironment($OZOADLabDirLike,$OZOADLabPath) -eq $true) {
            # Determine if the feature is not installed
            If ($this.InstallFeature($FeatureName) -eq $false) {
                # Feature is not installed
                $this.prerequisitesSatisfied = $false
            } Else {
                # Feature is installed; determine if a restart is required
                If ($this.RestartRequired($FeatureName) -eq $true) {
                    # Restart is required
                    $this.prerequisitesSatisfied = $false
                }
            }
            # Determine if the user not is added to the local group
            If ($this.ManageLocalGroup(([System.Security.Principal.WindowsIdentity]::GetCurrent().Name),$LocalGroup) -eq $false) { $this.prerequisitesSatisfied = $false }
            # Determine if the VM switches are not created
            If ($this.CreateVMSwitch($InternalIP,$InternalSwitchName,$PrefixLength,$Subnet) -eq $false) { $this.prerequisitesSatisfied = $false }
            # Determine if the Microsoft ADK is not installed
            If ($this.InstallMicrosoftADK($OscdimgExePath,$SimExePath,$WinAdkFileUri,$WinAdkPath) -eq $false) { $this.prerequisitesSatisfied = $false }
            # Determine if the OZO AD Lab resources are not downloaded and extracted
            If ($this.GetOZOADLabResources($OZOADLabPath,$OZOADLabDirLike,$OZOADLabZipPath,$OZOADLabZipUri) -eq $false) { $this.prerequisitesSatisfied = $false }
            # Determine if the source ISOs are not downloaded
            If ($this.DownloadISOs($OZOADLabISOs,$OZOADLabPath) -eq $false) { $this.prerequisitesSatisfied = $false }
            # Determine if all prerequisites were met
            If ($this.prerequisitesSatisfied -eq $true) {
                # All prerequisites are satisfied
                $this.ozoLogger.Write("All prerequisites are satisfied. Please see https://onezeroone.dev/active-directory-lab-customize-the-windows-installer-isos for the next steps.","Information")
            }
        } Else {
            # Environment did not validate
            $this.ozoLogger.Write("The environment did not validate.","Error")
        }
    }
    # METHODS: Environment validation method
    Hidden [Boolean] ValidateEnvironment($OZOADLabDirLike,$OZOADLabPath) {
        # Control variable
        [Boolean] $Return = $true
        # Determine if this a user-interactive session
        If ((Get-OZOUserInteractive) -eq $false) {
            # Session is not user-interactive
            $this.ozoLogger.Write("Please run this script in a user-interactive session.","Error")
            $Return = $false
        }
        # Determine if there is already an "ozo-ad-lab" folder off the root of the SystemDrive
        If ([Boolean](Test-Path -Path $OZOADLabPath -ErrorAction SilentlyContinue) -eq $true) {
            # There is already an "ozo-ad-lab" folder
            $this.ozoLogger.Write(("Found " + $OZOADLabPath + ". This directory must be removed before proceeding."),"Error")
            $Return = $false
        }
        # Try to make sure any previous downloaded + extracted releases of OZO-AD-Lab are wiped
        Try {
            Get-ChildItem -Path $Env:TEMP -ErrorAction Stop | Where-Object {$_.Name -Like $OZOADLabDirLike} | Remove-Item -Recurse -Force -ErrorAction Stop
            # Success
        } Catch {
            # Failure
            $this.ozoLogger.Write("Unable to clean up previous OZO-AD-Lab releases from the TEMP directory.","Error")
            $Return = $false
        }
        # Return
        return $Return
    }
    # METHODS: Install feature method
    Hidden [Boolean] InstallFeature($FeatureName) {
        # Control variable
        [Boolean] $Return = $true
        # Determine if the feature is present
        If ([Boolean](Get-WindowsOptionalFeature -Online -FeatureName $FeatureName -ErrorAction SilentlyContinue) -eq $false) {
            # Report
            $this.ozoLogger.Write(("Installing " + $FeatureName + " feature."),"Information")
            # Feature is not present; try to install it
            Try {
                Enable-WindowsOptionalFeature -Online -FeatureName $FeatureName -ErrorAction Stop
                # Success
            } Catch {
                # Failure
                $this.ozoLogger.Write(("Error installing the " + $FeatureName + " feature. Please manually install this feature and then run this script again to continue. See https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites/ for more information."),"Error")
                $Return = $false
            }
        }
        # Return
        return $Return
    }
    # METHODS: Restart required method
    Hidden [Boolean] RestartRequired($FeatureName) {
        # Control variable
        [Boolean] $Return = $false
        # Determine if a restart is required
        If ((Get-WindowsOptionalFeature -Online -FeatureName $FeatureName).RestartRequired -eq "Required") {
            # Restart is required
            $this.ozoLogger.Write(("Please restart to complete the " + $FeatureName + " feature installation and then run this script again to continue."),"Warning")
            $Return = $true
            # Get restart decision
            If ((Get-OZOYesNo) -eq "y") {
                # User elects to restart
                Restart-Computer
            }
        }
        # Return
        return $Return
    }
    # METHODS: Manage local group membership
    Hidden [Boolean] ManageLocalGroup($CurrentUser,$LocalGroup) {
        # Control variable
        [Boolean] $Return = $true
        # Determine if the current user is a member of the local group
        If ((Get-LocalGroupMember -Name $LocalGroup).Name -NotContains $CurrentUser) {
            # Report
            $this.ozoLogger.Write(("Adding user to the local " + $LocalGroup + " group."),"Information")
            # User is not in the local group; try to add them
            Try {
                Add-LocalGroupMember -Group $LocalGroup -Member $CurrentUser -ErrorAction Stop
                # Success
            } Catch {
                # Failure
                $this.ozoLogger.Write(("Failure adding user " + $CurrentUser + " to the " + $LocalGroup + " group. Please manually add this user to this group then run this script again to continue. See https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites/ for more information."),"Error")
                $Return = $false
            }
        }
        # Return
        return $Return
    }
    # METHODS: Create VM switch method
    Hidden [Boolean] CreateVMSwitch($InternalIP,$InternalSwitchName,$PrefixLength,$Subnet) {
        # Control variable
        [Boolean] $Return = $true
        # Determine if the Get-VMSwitch cmdlet is available
        If ([Boolean](Get-Command -Name Get-VMSwitch -ErrorAction SilentlyContinue) -eq $true) {
            # Get-VMSwtich cmdlet is available; determine if the NAT switch does not already exist
            If ([Boolean](Get-VMSwitch -Name $InternalSwitchName -ErrorAction SilentlyContinue) -eq $false) {
                # NAT switch does not already exist; try to create it and set the IP address
                Try {
                    New-VMSwitch -SwitchName $InternalSwitchName -SwitchType Internal -ErrorAction Stop | Out-Null
                    New-NetIPAddress -IPAddress $InternalIP -PrefixLength $PrefixLength -InterfaceIndex (Get-NetAdapter -ErrorAction Stop | Where-Object { $_.Name -eq ("vEthernet (" + $InternalSwitchName + ")") }).ifIndex -ErrorAction Stop | Out-Null
                    # Success
                } Catch {
                    # Failure
                    $this.ozoLogger.Write(("Error creating the NAT switch with error " + $_ + ". You may need to log out and back in to refresh your group membership. If that does not resolve the issue, then run this script again to continue. See https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites/ for more information."),"Error")
                    $Return = $false
                }
            }
            # Determine if the NAT network already exists
            If ([Boolean](Get-NetNat -Name $InternalSwitchName -ErrorAction SilentlyContinue) -eq $false) {
                # NAT network does not already exist; try to create it
                Try {
                    New-NetNat -Name $InternalSwitchName -InternalIPInterfaceAddressPrefix ($Subnet + "/" + $PrefixLength.ToString()) -ErrorAction Stop | Out-Null
                    # Success
                } Catch {
                    # Failure
                    $this.ozoLogger.Write(("Error creating the NAT network with error " + $_ + ". You may need to manually create this network, then run this script again to continue."),"Error")
                    $Return = $false
                }
            }
        } Else {
            # Get-VMSwitch cmdlet is not available
            $Return = $false
        }
        # Return
        return $Return
    }
    # METHODS: Install Microsoft ADK method
    Hidden [Boolean] InstallMicrosoftADK($OscdimgExePath,$SimExePath,$WinAdkFileUri,$WinAdkPath) {
        # Control variable
        [Boolean] $Return = $true
        # Local variables
        # Determine if oscdimg.exe is not present
        If ([Boolean](Test-Path -Path $OscdimgExePath -ErrorAction SilentlyContinue) -eq $false -Or [Boolean](Test-Path $SimExePath -ErrorAction SilentlyContinue) -eq $false) {
            # Report
            $this.ozoLogger.Write("Downloading and installing the Microsoft ADK (Deployment Tools).","Information")
            # Did not find oscdimg.exe; try to download and install
            Try {
                Invoke-WebRequest -Uri $WinAdkFileUri -OutFile $WinAdkPath -ErrorAction Stop
                # Success; try to install
                Try {
                    Invoke-Command -ScriptBlock { & $WinAdkPath /quiet /norestart /features OptionId.DeploymentTools } -ErrorAction Stop | Out-Null
                    # Success; sleep until the installation is complete
                    Do {
                        Start-Sleep -Seconds 1
                    } Until ([Boolean](Test-Path -Path $OscdimgExePath -ErrorAction SilentlyContinue) -eq $true -And [Boolean](Test-Path $SimExePath -ErrorAction SilentlyContinue) -eq $true)
                } Catch {
                    # Failure
                    $this.ozoLogger.Write("Error attempting to download the Microsoft ADK. Please manually download and install and then run this script again to continue. See https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites/ for more information.","Error")
                    $Return = $false
                }
            } Catch {
                # Failure
                $this.ozoLogger.Write("Error attempting to install the Microsoft ADK. Please manually download and install and then run this script again to continue. See https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites/ for more information.","Error")
                $Return = $false
            }
        }
        # Return
        return $Return
    }
    # METHODS: Get AD Lab resources method
    Hidden [Boolean] GetOZOADLabResources($OZOADLabPath,$OZOADLabDirLike,$OZOADLabZipPath,$OZOADLabZipUri) {
        # Control variable
        [Boolean] $Return = $true
        # Report
        $this.ozoLogger.Write("Downloading and extracting the latest release of the OZO AD Lab resources.","Information")
        # Try to get the latest zipball
        Try {
            Invoke-WebRequest -UseBasicParsing -Uri (Invoke-WebRequest -UseBasicParsing -Uri $OZOADLabZipUri -ErrorAction Stop | ConvertFrom-Json -ErrorAction Stop).zipball_url -OutFile $OZOADLabZipPath -ErrorAction Stop
            # Success; expand the archive
            Expand-Archive -Force -Path $OZOADLabZipPath -DestinationPath $Env:TEMP -ErrorAction Stop
            # Remove the archive
            Remove-Item -Path $OZOADLabZipPath -Force
            # Move the extracted folder to the ozoAdLab
            Move-Item -Force -Path (Get-ChildItem -Path $Env:TEMP -ErrorAction Stop | Where-Object {$_.Name -Like $OZOADLabDirLike} | Select-Object -First 1).FullName -Destination $OZOADLabPath
            # Create required (empty) Mount subdirectory
            New-Item -ItemType Directory -Path (Join-Path -Path $OZOADLabPath -ChildPath "Mount") -ErrorAction Stop
        } Catch {
            # Failure
            $this.ozoLogger.Write("Error downloading and extracting the latest OZO AD Lab resources with error " + $_ + ". Please manually download and extract the latest release and run this script again to continue. See https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites for more information.","Error")
            $Return = $false
        }
        # Return
        return $Return
    }
    # METHODS: Download ISOs method
    Hidden [Boolean] DownloadISOs($OZOADLabISOs,$OZOADLabPath) {
        # Control variable
        [Boolean] $Return = $true
        # Iterate through the ISOs Hashtable
        Foreach ($ozoADLabIso in $OZOADLabISOs.GetEnumerator()) {
            # Generate the ISO path
            [String] $isoPath = (Join-Path -Path $OZOADLabPath -ChildPath (Join-Path -Path "ISO" -ChildPath $($ozoADLabIso.Key)))
            # Determine if the file does not already exist
            If ([Boolean](Test-Path -Path $isoPath -ErrorAction SilentlyContinue) -eq $false) {
                # Report
                $this.ozoLogger.Write(("Downloading " + $($ozoADLabIso.Key) + " (this could take some time)."),"Information")
                # The ISO does not already exist; try to download
                Try {
                    Invoke-WebRequest -Uri $($ozoADLabIso.Value) -OutFile $isoPath -ErrorAction Stop
                    # Success
                } Catch {
                    # Failure
                    $this.ozoLogger.Write("Error downloading " + $($ozoADLabIso.Key) + ". Please manually download the required ISOs and name them as described in https://onezeroone.dev/active-directory-lab-part-ii-customization-prerequisites.","Error")
                    $Return = $false
                }
            }
        }
        # Return
        return $Return
    }
}

# MAIN
[Main]::new($FeatureName,$InternalIP,$InternalSwitchName,$LocalGroup,$OscdimgExePath,$OZOADLabDirLike,$OZOADLabPath,$OZOADLabISOs,$OZOADLabZipPath,$OZOADLabZipUri,$PrefixLength,$SimExePath,$Subnet,$WinAdkFileUri,$WinAdkPath) | Out-Null

# SIG # Begin signature block
# MIIvrwYJKoZIhvcNAQcCoIIvoDCCL5wCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCKWXNlsslo1Ilp
# LLVU7bZDRMAB//vjW/KU9I3P6gGWsaCCEgUwggVvMIIEV6ADAgECAhBI/JO0YFWU
# jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI
# DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM
# EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy
# dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG
# EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv
# IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA
# A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s
# hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD
# J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7
# P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme
# me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz
# T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q
# RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz
# mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc
# QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T
# OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/
# AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID
# AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD
# VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV
# HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE
# VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v
# ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE
# KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI
# hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF
# OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC
# J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ
# pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl
# d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH
# +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYaMIIEAqADAgECAhBiHW0M
# UgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEBDAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYD
# VQQKEw9TZWN0aWdvIExpbWl0ZWQxLTArBgNVBAMTJFNlY3RpZ28gUHVibGljIENv
# ZGUgU2lnbmluZyBSb290IFI0NjAeFw0yMTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5
# NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxKzAp
# BgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYwggGiMA0G
# CSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCbK51T+jU/jmAGQ2rAz/V/9shTUxjI
# ztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgCsJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NV
# DgFigOMYzB2OKhdqfWGVoYW3haT29PSTahYkwmMv0b/83nbeECbiMXhSOtbam+/3
# 6F09fy1tsB8je/RV0mIk8XL/tfCK6cPuYHE215wzrK0h1SWHTxPbPuYkRdkP05Zw
# mRmTnAO5/arnY83jeNzhP06ShdnRqtZlV59+8yv+KIhE5ILMqgOZYAENHNX9SJDm
# +qxp4VqpB3MV/h53yl41aHU5pledi9lCBbH9JeIkNFICiVHNkRmq4TpxtwfvjsUe
# dyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz4
# 4MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ/ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBM
# dlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZb1sCAwEAAaOCAWQwggFgMB8GA1UdIwQY
# MBaAFDLrkpr/NZZILyhAQnAgNpFcF4XmMB0GA1UdDgQWBBQPKssghyi47G9IritU
# pimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNV
# HSUEDDAKBggrBgEFBQcDAzAbBgNVHSAEFDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsG
# A1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1
# YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5jcmwwewYIKwYBBQUHAQEEbzBtMEYGCCsG
# AQUFBzAChjpodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2Rl
# U2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0
# aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOCAgEABv+C4XdjNm57oRUgmxP/BP6YdURh
# w1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5jUug2oeunbYAowbFC2AKK+cMcXIBD0Zd
# OaWTsyNyBBsMLHqafvIhrCymlaS98+QpoBCyKppP0OcxYEdU0hpsaqBBIZOtBajj
# cw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd099iChnyIMvY5HexjO2AmtsbpVn0OhNc
# WbWDRF/3sBp6fWXhz7DcML4iTAWS+MVXeNLj1lJziVKEoroGs9Mlizg0bUMbOalO
# hOfCipnx8CaLZeVme5yELg09Jlo8BMe80jO37PU8ejfkP9/uPak7VLwELKxAMcJs
# zkyeiaerlphwoKx1uHRzNyE6bxuSKcutisqmKL5OTunAvtONEoteSiabkPVSZ2z7
# 6mKnzAfZxCl/3dq3dUNw4rg3sTCggkHSRqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5J
# KdGvspbOrTfOXyXvmPL6E52z1NZJ6ctuMFBQZH3pwWvqURR8AgQdULUvrxjUYbHH
# j95Ejza63zdrEcxWLDX6xWls/GDnVNueKjWUH3fTv1Y8Wdho698YADR7TNx8X8z2
# Bev6SivBBOHY+uqiirZtg0y9ShQoPzmCcn63Syatatvx157YK9hlcPmVoa1oDE5/
# L9Uo2bC5a4CH2RwwggZwMIIE2KADAgECAhAbV4ef7ZvUwZ6AKRT0hWSAMA0GCSqG
# SIb3DQEBDAUAMFQxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBDQSBSMzYw
# HhcNMjYwOTE0MDAwMDAwWhcNMjcwOTE0MjM1OTU5WjBiMQswCQYDVQQGEwJVUzER
# MA8GA1UECAwIQ29sb3JhZG8xHzAdBgNVBAoMFkxpZXZlcnR6IEFuZHJldyBIdWJl
# cnQxHzAdBgNVBAMMFkxpZXZlcnR6IEFuZHJldyBIdWJlcnQwggIiMA0GCSqGSIb3
# DQEBAQUAA4ICDwAwggIKAoICAQCZl/Kqmb1yMMbn0868VlBqxo7LGu/SDy7bO3wz
# D6jMoxzh2UT4iFxNnIEpHJq9SzxkhNgy60Lhzr0kGxBXypLJVGKP3JpS9inmF3zn
# e/DWJcOFkQPkwYAsqEoJ6xt/klQlJqnwaN7AJUwUIgZ/72j37//UcWxltCMxnwT2
# wVUQ357c3GOafCKfBMUN9dEgUhwxt4x5GZ6Re/WSGKlh+eFtP1wNBsBXoT6Hme5E
# u2L5vTYl0fmKVAsTGJ9k7eHvLE7IUWXOD6NI548uxFQ2FeISOdCRt0WmYmpWgi6S
# j1Aoh1zLhsMaLgUPP+BXcOy0cO3zDJ+SZky+S4AB37Y0UBqy9hNvX0WbfQh3BF+2
# uWYGxHYc3FtefKKAbhQGNo9EO4pB0SBh/19a/EbbUpv67CRlO8PmGf8hEk6ic8O6
# 28OjkFi5ByIB7y/XKPKCZmeS/TWDrkyMpu8h9NGqHyWONE5oxpqCYMm3a0L92kfd
# zY5e6vSLDuZZjlANRUm3VLnbxZcD8znUvaDbR+ALdJeSZryev8NVMnfOzwZM6vKz
# fTPbYpFRBo0owFluKK85CKeZ8z+NyKQfvWh5gYXZw0JFZwdE4SE46fnNLJ3z9loF
# Qly+7Dn2zUd/+CxwlRgkuEO1ng6EJ1OAAeA7PixyZob0gjg7ob7YzSK2v4AV/QdQ
# oXa04QIDAQABo4IBrjCCAaowHwYDVR0jBBgwFoAUDyrLIIcouOxvSK4rVKYpqhek
# zQwwHQYDVR0OBBYEFMiE5GpeP6V7hsDSdHBbSjojZscBMA4GA1UdDwEB/wQEAwIH
# gDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMDMEoGA1UdIARDMEEw
# NQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5j
# b20vQ1BTMAgGBmeBDAEEATBJBgNVHR8EQjBAMD6gPKA6hjhodHRwOi8vY3JsLnNl
# Y3RpZ28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ0NBUjM2LmNybDB5Bggr
# BgEFBQcBAQRtMGswRAYIKwYBBQUHMAKGOGh0dHA6Ly9jcnQuc2VjdGlnby5jb20v
# U2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3J0MCMGCCsGAQUFBzABhhdo
# dHRwOi8vb2NzcC5zZWN0aWdvLmNvbTAjBgNVHREEHDAagRhhbGlldmVydHpAb25l
# emVyb29uZS5kZXYwDQYJKoZIhvcNAQEMBQADggGBACvVVz+HNOH8p+CBcwmrYBVx
# mlWNkTz84gmJZ/57FF5XK4kHeo6+QFalQkBSkiDheZa13+FdwUYf1zcJu5hfymkZ
# 9zmBhLlIkdluT1llv9GKr/tQaJFd2NXoLiJ7ysqRDbu47U1RR7XGU42HZHLUHa00
# Ha8KDHKYeRcCBMhltjpBK4Hw5daTzT+5fLhMHaOy3ZuWn4Fgx8zEcH1/cdEqnWNn
# NxxCWbKcp4sRI0v9uStoUYGpvX8LkYtMUUuWPr7tZAAZiPws6ctOrdROmdEwfyah
# IMt2drMfTXZVPpL/5okl37qOYhzV+u6vEvbc3xeAicAgsgOYkvvx5L2iUyFfGdLb
# JN4ioPTCKcvN7oXFPwHfyGqwBxARyJy3so2OAFvY4AGY/9DwQVE8KZuplrkktC7Y
# MzjB9SjEtvqnyW+h0fHd3H85B8GJiL8slRmIb5f+jJDvmu5RgoaoaMAYeX/V4HXY
# gpSD92Hq5AwUjjUvj1WPk+AagPBupA+J4OM2S6eO0DGCHQAwghz8AgEBMGgwVDEL
# MAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDErMCkGA1UEAxMi
# U2VjdGlnbyBQdWJsaWMgQ29kZSBTaWduaW5nIENBIFIzNgIQG1eHn+2b1MGegCkU
# 9IVkgDANBglghkgBZQMEAgEFAKB8MBAGCisGAQQBgjcCAQwxAjAAMBkGCSqGSIb3
# DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEV
# MC8GCSqGSIb3DQEJBDEiBCDPwX++UIzag6tiAJq9R738DR2Bm1sM7P6jzNaxwVdp
# yTANBgkqhkiG9w0BAQEFAASCAgBuN57gV0glBnGX+6u/d3+zZvst8nOn4cHq6HAL
# 5ussesg5dvKl1Zqw9oatIsd80MCdISBYfry3IwXmbvFpdTt6jI1tFFikyQo5zkn8
# Vm0HKzmcn6rSxJTjuBrnPvmSAbhwQxnj6xE+6Gjw0w//iSocl6L6vZoyjkF5ydqe
# /IRYzCscmIzPrsZZvsnmg1pYVfWgzyyPyj02pXdcj5yxuKUZa+iuuk90R7U+FGUp
# c/HdcUe9mb9Y7ZjUwagnhA+HDWo27yPfpLfAqlGsIY+VChYU7XRvvcUm7Xc0mrZj
# 7IxVydfhXuYRRzdpLA8kAwFi4WyAbegjvR/ZTKew4FKwIxGpgaW/toXah+L/aZ1W
# D4wWXi9PShgcrKwecCIteUEXk5T5Eydy7aHosMIP+zGLA5S7OvB3r42+0oEgN2Eu
# Ze5Ha6/+hDb84LvxtQ/YUhlhFhCApsLKsgj0Io2ZTejDhOTCMwBnuIujA4KCKjSF
# 8kJasZhohnprNEOK/ul7WAE3tYmlUmrq5mJB5hF5ymuex22lPTRF/WJgZOt+fLVy
# LuHybJW1RtO4zcelw1YRfqfvqwH9/LPA1c+QTZdVnPIpjX89fKwbL+Vsa1WFfOj2
# 3pkaH660CmaEoGOP6GSH6i9RmQzG3+sY/4izMWyt/avkDVfgcYR5ifDfkcSFxrpC
# Naqn0aGCGeswghnnBgorBgEEAYI3AwMBMYIZ1zCCGdMGCSqGSIb3DQEHAqCCGcQw
# ghnAAgEDMQ8wDQYJYIZIAWUDBAICBQAwgfcGCyqGSIb3DQEJEAEEoIHnBIHkMIHh
# AgEBBgorBgEEAbIxAgEBMDEwDQYJYIZIAWUDBAIBBQAEIOJ8w5lYH2rqLJmeG9Uh
# cOe5WdH9USMwUqWYkxdQQ0tpAhQUOevzSIfJbV5x1gfKKptccMvlLRgPMjAyNjA5
# MjgxNTQ2MzFaoHakdDByMQswCQYDVQQGEwJHQjEXMBUGA1UECBMOR3JlYXRlciBM
# b25kb24xGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEwMC4GA1UEAxMnU2VjdGln
# byBQdWJsaWMgVGltZSBTdGFtcGluZyBTaWduZXIgUjM3oIIUFzCCBuIwggTKoAMC
# AQICEQDnTvJVsFBP+tum3/f8i6MVMA0GCSqGSIb3DQEBDAUAMFUxCzAJBgNVBAYT
# AkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAqBgNVBAMTI1NlY3RpZ28g
# UHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjQxMB4XDTI2MDMyNTAwMDAwMFoXDTM3
# MDYyNDIzNTk1OVowcjELMAkGA1UEBhMCR0IxFzAVBgNVBAgTDkdyZWF0ZXIgTG9u
# ZG9uMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxMDAuBgNVBAMTJ1NlY3RpZ28g
# UHVibGljIFRpbWUgU3RhbXBpbmcgU2lnbmVyIFIzNzCCAiIwDQYJKoZIhvcNAQEB
# BQADggIPADCCAgoCggIBALL/w21L3FDZRS0FEXfZuPtUrefibnRSqOT/NNyJLOJh
# XjQfUspqHT+gSSVgbjYThUI/cO+wFQHoOakKQNnSMKdkE8gR69ofXlkk5DAVY/Zl
# evliOUmlvrw2Vuz4SU28rHfb/Vgd17eqpRIvJuO6XE8vPpPzn4c4iorszUF6nwuy
# nKEQ/+rqfDmQbFNKsa+5+Z4f4kXwKdUFxUwUDjQWUhiHRwMlUWGF9N91aAvL+9a4
# sxCgqR/ez8W8HJ/XqvSu1vIeb+J6bDFKKgkv3PJkMMpQ0BsdeXR2FejZXFRXY1w9
# dZe6gqyMv7px+TpWbYMefECUV0WxoEMgXUk6RKcLo94uUHOdmfZu4Xe8ghglyro3
# /N4VEKTj8dcPPvOBGxFEx1QH6uHKTkWhloGPDScurcZnd8KUtTHl6zmlQDHM04Mw
# GfsmQViKnYEAYE8RHl5XRE6GTq0ZMb59SIyJX6+CODVic/kW+dhbIS1Z5AP8HaGn
# e/PRG+12QzSneKDJp3Ot+k4GrmmlWT9iy6FNCQ/32K+d4cAZ+Ll7uWbEn6Z6gE+t
# Eu7MyZvzWvPNsRKMkcyyflFW1zpRyzutwypALXc9Qg7sFsYERNXa58KZXqU9Onc/
# tck6+adQJFM9tW8xOnE//P5I4eDj84IGGKqzgUD37ihC+WST3DfY0YBKWL0Zaubn
# AgMBAAGjggGOMIIBijAfBgNVHSMEGDAWgBQ6dKUMZ8ZCUML9tfzHuyk0gvR6uTAd
# BgNVHQ4EFgQUYRDpehKvUcSF1PLPpHQPUM0gr/gwDgYDVR0PAQH/BAQDAgbAMAwG
# A1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwSgYDVR0gBEMwQTAI
# BgZngQwBBAIwNQYMKwYBBAGyMQECAQMIMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8v
# c2VjdGlnby5jb20vQ1BTMEoGA1UdHwRDMEEwP6A9oDuGOWh0dHA6Ly9jcmwuc2Vj
# dGlnby5jb20vU2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjQxLmNybDB6Bggr
# BgEFBQcBAQRuMGwwRQYIKwYBBQUHMAKGOWh0dHA6Ly9jcnQuc2VjdGlnby5jb20v
# U2VjdGlnb1B1YmxpY1RpbWVTdGFtcGluZ0NBUjQxLmNydDAjBggrBgEFBQcwAYYX
# aHR0cDovL29jc3Auc2VjdGlnby5jb20wDQYJKoZIhvcNAQEMBQADggIBAAPqPY3R
# rM36GXqTpsoHn9TpW5I6z3dkFvc9zPL1W0Egq7j3jtnkbAvRoWeAjGX4ZK4sWsmA
# +u4EJG8okQmybuS/4tDUI5UIQb21n4hG2vihxShrneWB0VoQ2VLQ3jCCRmRtAQ+/
# 7H7WVKNiH5Pgl4v2ZTOdPsStzpKnl1YuRrmww/+bcZmLqgk909ywIpZqAfubYfbE
# MYjIckLk90f2mG+L8qaGSS2JJVM02pV5XltZ1fbOFETpRN/PQhwygIv33qUUjJ1f
# E4ITgw0McMzRqziWdOJP8ocxxw7qXxz1OdRWCalyL1qvUgAFnZTVdSRiMYZKf0wL
# cQcM/1Xf1W4FW9nff8ERX8RZJGt/TtPuMWmUpf6BCv9Q6o8YyUTtknvZRpSQ0nLt
# tWXdtwsrN2mMgfMuR//gxVrVXvDzCoK/lbiA6dEZOW53lQwBFtEzwE/FH8Jdhegy
# Yg4PymZOTZrGBEvgsbxe25yEhJ0IdGa1pwCYsarldJhJVMdNcAOU7jyIMqHcczav
# 3wtIXp/SwbXZ3xX0mfsLfANSJ47G4qPgx1atb6GIlTaQXzu/p4fTQeAIUVzZXT4K
# 984IyfuO7NLjWMtog1wGUpZD98pv+4Mt9Y5bvfPUjaUVjtePy1DVdi0rl5ESNYi0
# zyOmXVxtA5zzxu1H7RdLZOZugT/XjX69rY9bMIIGpzCCBI+gAwIBAgIRAJCsCHIg
# /cWnxGtcxw33PQYwDQYJKoZIhvcNAQEMBQAwVzELMAkGA1UEBhMCR0IxGDAWBgNV
# BAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMlU2VjdGlnbyBQdWJsaWMgVGlt
# ZSBTdGFtcGluZyBSb290IFI0NjAeFw0yNjAzMjUwMDAwMDBaFw00MTAzMjQyMzU5
# NTlaMFUxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAq
# BgNVBAMTI1NlY3RpZ28gUHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjQxMIICIjAN
# BgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAruRKogGtghxi+WYtW5oDzPDVF8GG
# SfgbUKh6bONxi0wvrI1S8qbAYfvLr/ky5ILVRg//70pgNKq8xC3/WEQodjEwAP2h
# mkGShoNAUQps4kd6Wwp74Fo7RlwQ1Mp949ytpWQDvCsYBbZccDmBAJC/ggqiuL/c
# 805fGcMw6TzIgyBWuUx5PGp9YnheSNPXFzaz0MPtREdZYk4WhtM+hazqasMWVpj0
# WUAcNhN9vO/FAdWy9Gafdb7lmYLDKTTYjwqAY9P9RfixPPjUaJH6mnBSNBdrX7a0
# Qdlux0ApS0fc48RW1m+W3tq3HiHzch1FHyhiLzCNjc6MUpcV5xalBvPOw/FtQo/A
# xaJOvPCSsVrx0f/WkMpEm3fvVbrY9+oo9rIKv9ducE6VGfwIAtKYedG0bO4Ba1Mm
# lxPcErDqjLwggvrBJu73fwXpkhtE0hzV0psgm2vhQs3pHll9N00SHBdy2qndEcNu
# Dh+46XouM2hoXCO533YQQOHPEUnMTWOo3hyxx5kjDE5PVqp+x+HS4VAT+WBMG4Gz
# eLr9YvZbU5x5YvLdcR1dErV/QRYK55rp019fZFF2NR+TkSW0WcmQ3b5taGcrXg49
# EpzKM6/mEpnSJXg1E13X6GO29rWs/LNvkGzsS8XGoRCGBls6ruofeebSsHADR3Ge
# IE5gIU927bjokLECAwEAAaOCAW4wggFqMB8GA1UdIwQYMBaAFPZ3at0//QET/xah
# bIICL9AKPRQlMB0GA1UdDgQWBBQ6dKUMZ8ZCUML9tfzHuyk0gvR6uTAOBgNVHQ8B
# Af8EBAMCAYYwEgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcD
# CDAjBgNVHSAEHDAaMAgGBmeBDAEEAjAOBgwrBgEEAbIxAQIBAwgwTAYDVR0fBEUw
# QzBBoD+gPYY7aHR0cDovL2NybC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljVGlt
# ZVN0YW1waW5nUm9vdFI0Ni5jcmwwfAYIKwYBBQUHAQEEcDBuMEcGCCsGAQUFBzAC
# hjtodHRwOi8vY3J0LnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNUaW1lU3RhbXBp
# bmdSb290UjQ2LnA3YzAjBggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5j
# b20wDQYJKoZIhvcNAQEMBQADggIBADLeUkdm8Z4DZvjfKHOhqu+hsdXNt+X5F+48
# PB6PTAJCRgA3qxxO3YbAV7baps4K/+2WWoWUspBkT4T2NXK49NvJAfCsztHSgtqk
# AQMLX4KjCypJF/+m2Ktrk993g+gcgKdv1yg9C3JmYdJCnnL0ga+pZ/Wo1+rtXZ8d
# nwO8RCstTN6gYX0ElFi7Y7NpxbdBC1S6bc05V/SA9HC/ojj33W6GdwnpU/iVylSk
# dkoHtHeGIhQLT2ZH0qPM9Wdce8v2fZsDCJQQJ8rll7OGLDbsXa2CLf0MRN9Twzif
# Q3rEuAXOx/TkzkZRFfwL34hf1XqSmaYq2tTMy2LgsPrqC2Z/6ZKb3fgrzU0vphB4
# wSTWulitY/KlxbvoyKvrBvUCCx4sgeqf8aR65CbvM5MN/d/lahfXipU2NlY0cXcn
# GS61XpmeGKd8It92/lufApZR9x6o5qMJWe0jq4JsfGMGDpIKx7FzkB8gaejuBUW/
# CJ9Phc40+xJRonvVewn4S9yJVRWeM47irGbR9YlN3xruM/yZzhk+rAm9AW06nv7o
# b6RQkAXR+cTxiAPy620FF41NrViYB4UyKpzfx7x8jh4ubTOMz954YIdqyeiqqtsb
# BwXjWLP0dfMUPA3iIPnPdBKGnodGJTdSlPAMmKJdyvTPqmOXs/LMnf+2Za0Z6FXs
# IB9z9aXLMIIGgjCCBGqgAwIBAgIQNsKwvXwbOuejs902y8l1aDANBgkqhkiG9w0B
# AQwFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNV
# BAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsx
# LjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkw
# HhcNMjEwMzIyMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjBXMQswCQYDVQQGEwJHQjEY
# MBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS4wLAYDVQQDEyVTZWN0aWdvIFB1Ymxp
# YyBUaW1lIFN0YW1waW5nIFJvb3QgUjQ2MIICIjANBgkqhkiG9w0BAQEFAAOCAg8A
# MIICCgKCAgEAiJ3YuUVnnR3d6LkmgZpUVMB8SQWbzFoVD9mUEES0QUCBdxSZqdTk
# dizICFNeINCSJS+lV1ipnW5ihkQyC0cRLWXUJzodqpnMRs46npiJPHrfLBOifjfh
# pdXJ2aHHsPHggGsCi7uE0awqKggE/LkYw3sqaBia67h/3awoqNvGqiFRJ+OTWYmU
# CO2GAXsePHi+/JUNAax3kpqstbl3vcTdOGhtKShvZIvjwulRH87rbukNyHGWX5tN
# K/WABKf+Gnoi4cmisS7oSimgHUI0Wn/4elNd40BFdSZ1EwpuddZ+Wr7+Dfo0lcHf
# lm/FDDrOJ3rWqauUP8hsokDoI7D/yUVI9DAE/WK3Jl3C4LKwIpn1mNzMyptRwsXK
# rop06m7NUNHdlTDEMovXAIDGAvYynPt5lutv8lZeI5w3MOlCybAZDpK3Dy1MKo+6
# aEtE9vtiTMzz/o2dYfdP0KWZwZIXbYsTIlg1YIetCpi5s14qiXOpRsKqFKqav9R1
# R5vj3NgevsAsvxsAnI8Oa5s2oy25qhsoBIGo/zi6GpxFj+mOdh35Xn91y72J4RGO
# JEoqzEIbW3q0b2iPuWLA911cRxgY5SJYubvjay3nSMbBPPFsyl6mY4/WYucmyS9l
# o3l7jk27MAe145GWxK4O3m3gEFEIkv7kRmefDR7Oe2T1HxAnICQvr9sCAwEAAaOC
# ARYwggESMB8GA1UdIwQYMBaAFFN5v1qqK0rPVIDh2JvAnfKyA2bLMB0GA1UdDgQW
# BBT2d2rdP/0BE/8WoWyCAi/QCj0UJTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/
# BAUwAwEB/zATBgNVHSUEDDAKBggrBgEFBQcDCDARBgNVHSAECjAIMAYGBFUdIAAw
# UAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2VydHJ1c3QuY29tL1VTRVJU
# cnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMDUGCCsGAQUFBwEBBCkw
# JzAlBggrBgEFBQcwAYYZaHR0cDovL29jc3AudXNlcnRydXN0LmNvbTANBgkqhkiG
# 9w0BAQwFAAOCAgEADr5lQe1oRLjlocXUEYfktzsljOt+2sgXke3Y8UPEooU5y39r
# AARaAdAxUeiX1ktLJ3+lgxtoLQhn5cFb3GF2SSZRX8ptQ6IvuD3wz/LNHKpQ5nX8
# hjsDLRhsyeIiJsms9yAWnvdYOdEMq1W61KE9JlBkB20XBee6JaXx4UBErc+YuoSb
# 1SxVf7nkNtUjPfcxuFtrQdRMRi/fInV/AobE8Gw/8yBMQKKaHt5eia8ybT8Y/Ffa
# 6HAJyz9gvEOcF1VWXG8OMeM7Vy7Bs6mSIkYeYtddU1ux1dQLbEGur18ut97wgGwD
# iGinCwKPyFO7ApcmVJOtlw9FVJxw/mL1TbyBns4zOgkaXFnnfzg4qbSvnrwyj1Ni
# urMp4pmAWjR+Pb/SIduPnmFzbSN/G8reZCL4fvGlvPFk4Uab/JVCSmj59+/mB2Gn
# 6G/UYOy8k60mKcmaAZsEVkhOFuoj4we8CYyaR9vd9PGZKSinaZIkvVjbH/3nlLb0
# a7SBIkiRzfPfS9T+JesylbHa1LtRV9U/7m0q7Ma2CQ/t392ioOssXW7oKLdOmMBl
# 14suVFBmbzrt5V5cQPnwtd3UOTpS9oCG+ZZheiIvPgkDmA8FzPsnfXW5qHELB43E
# T7HHFHeRPRYrMBKjkb8/IN7Po0d0hQoF4TeMM+zYAJzoKQnVKOLg8pZVPT8xggST
# MIIEjwIBATBqMFUxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0
# ZWQxLDAqBgNVBAMTI1NlY3RpZ28gUHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjQx
# AhEA507yVbBQT/rbpt/3/IujFTANBglghkgBZQMEAgIFAKCCAfowGgYJKoZIhvcN
# AQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNjA5MjgxNTQ2MzFa
# MD8GCSqGSIb3DQEJBDEyBDCweyFofBEZMIOiYeJEd16PM+NNpo3ppNqZePUfmGd+
# MET40s2gHSjKKzxoUk7n+ekwggF7BgsqhkiG9w0BCRACDDGCAWowggFmMIIBYjAW
# BBTpeBipKNoVCp/hv5zMequ5oA7urDCBiAQUZcMoaW99TlAs/QPHwgaXGMr7908w
# cDBbpFkwVzELMAkGA1UEBhMCR0IxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEu
# MCwGA1UEAxMlU2VjdGlnbyBQdWJsaWMgVGltZSBTdGFtcGluZyBSb290IFI0NgIR
# AJCsCHIg/cWnxGtcxw33PQYwgbwEFIU9Yy2TgoJhfNCQNcSR3pLBQtrHMIGjMIGO
# pIGLMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKTmV3IEplcnNleTEUMBIGA1UE
# BxMLSmVyc2V5IENpdHkxHjAcBgNVBAoTFVRoZSBVU0VSVFJVU1QgTmV0d29yazEu
# MCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eQIQ
# NsKwvXwbOuejs902y8l1aDANBgkqhkiG9w0BAQEFAASCAgBweQFDHJD19EQXKlau
# 4EuNQBo0obhdXAcJkSsPs+SCT7rwN4xUWkUwz7zKXbrnHyI+Rl/umcAS00ZHURWf
# orNjHp6a6JplHd2UCVrJXicvsA9OZOuzpGTIE1f6Mb8iiZoEbMEH0oc4Tr5pXfQA
# MR2jd6lqlo+x8XpDsbFTFdoEcFC53p1UOm35Yn3YLBslyPocjnTQOAtXXbtImW6K
# bPHZgCxI4k5ph1hoGZChXQGw6J33xBsNqMVlEMdysDWVy5yASa4CIdSO9m8hFGdd
# fYqlsMild3Au4hnk3PrxP3RsHRB46+TT07lsRYRMCBb9CyUy0Jq+E3TanwlvzAed
# RpFqVBQEVRJJNfA66Ll32SzHeIaR5DxJRnhezbEOzPhE7r5cNmLnZIkkDfyOyQMW
# 05EJyfVxQLTRthWaRVh/6Uuslwdclsd0UnEQfQxbW+vB66WR8zJXmBMg6DlS3ULT
# 65MlmqjQE2meLEHH/uYITX9bBa20tBA9lNj2LJvOG/3bJjNXEAQlq9oFP/3EIT2I
# cNK9aFvYvLeSFfIUUwV+dN5Gj14XrgP/x3myjE7W2uyPYag6OzdWDRM28Mp/Rbpl
# sQzetq79ZASUIr1QDUFDX9M0rsXHuvQ1DMYljccBfVNE3qwTq2QSIGIB3ey3SriL
# WAmhvrYJjaSnnVdMmSkBwSgoHg==
# SIG # End signature block