<# | |
.Synopsis | |
Activate a Python virtual environment for the current PowerShell session. | |
.Description | |
Pushes the python executable for a virtual environment to the front of the | |
$Env:PATH environment variable and sets the prompt to signify that you are | |
in a Python virtual environment. Makes use of the command line switches as | |
well as the `pyvenv.cfg` file values present in the virtual environment. | |
.Parameter VenvDir | |
Path to the directory that contains the virtual environment to activate. The | |
default value for this is the parent of the directory that the Activate.ps1 | |
script is located within. | |
.Parameter Prompt | |
The prompt prefix to display when this virtual environment is activated. By | |
default, this prompt is the name of the virtual environment folder (VenvDir) | |
surrounded by parentheses and followed by a single space (ie. '(.venv) '). | |
.Example | |
Activate.ps1 | |
Activates the Python virtual environment that contains the Activate.ps1 script. | |
.Example | |
Activate.ps1 -Verbose | |
Activates the Python virtual environment that contains the Activate.ps1 script, | |
and shows extra information about the activation as it executes. | |
.Example | |
Activate.ps1 -VenvDir C:\Users\MyUser\Common\.venv | |
Activates the Python virtual environment located in the specified location. | |
.Example | |
Activate.ps1 -Prompt "MyPython" | |
Activates the Python virtual environment that contains the Activate.ps1 script, | |
and prefixes the current prompt with the specified string (surrounded in | |
parentheses) while the virtual environment is active. | |
.Notes | |
On Windows, it may be required to enable this Activate.ps1 script by setting the | |
execution policy for the user. You can do this by issuing the following PowerShell | |
command: | |
PS C:\> Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser | |
For more information on Execution Policies: | |
https://go.microsoft.com/fwlink/?LinkID=135170 | |
#> | |
Param( | |
[Parameter(Mandatory = $false)] | |
[String] | |
$VenvDir, | |
[Parameter(Mandatory = $false)] | |
[String] | |
$Prompt | |
) | |
<# Function declarations --------------------------------------------------- #> | |
<# | |
.Synopsis | |
Remove all shell session elements added by the Activate script, including the | |
addition of the virtual environment's Python executable from the beginning of | |
the PATH variable. | |
.Parameter NonDestructive | |
If present, do not remove this function from the global namespace for the | |
session. | |
#> | |
function global:deactivate ([switch]$NonDestructive) { | |
# Revert to original values | |
# The prior prompt: | |
if (Test-Path -Path Function:_OLD_VIRTUAL_PROMPT) { | |
Copy-Item -Path Function:_OLD_VIRTUAL_PROMPT -Destination Function:prompt | |
Remove-Item -Path Function:_OLD_VIRTUAL_PROMPT | |
} | |
# The prior PYTHONHOME: | |
if (Test-Path -Path Env:_OLD_VIRTUAL_PYTHONHOME) { | |
Copy-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME -Destination Env:PYTHONHOME | |
Remove-Item -Path Env:_OLD_VIRTUAL_PYTHONHOME | |
} | |
# The prior PATH: | |
if (Test-Path -Path Env:_OLD_VIRTUAL_PATH) { | |
Copy-Item -Path Env:_OLD_VIRTUAL_PATH -Destination Env:PATH | |
Remove-Item -Path Env:_OLD_VIRTUAL_PATH | |
} | |
# Just remove the VIRTUAL_ENV altogether: | |
if (Test-Path -Path Env:VIRTUAL_ENV) { | |
Remove-Item -Path env:VIRTUAL_ENV | |
} | |
# Just remove the _PYTHON_VENV_PROMPT_PREFIX altogether: | |
if (Get-Variable -Name "_PYTHON_VENV_PROMPT_PREFIX" -ErrorAction SilentlyContinue) { | |
Remove-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Scope Global -Force | |
} | |
# Leave deactivate function in the global namespace if requested: | |
if (-not $NonDestructive) { | |
Remove-Item -Path function:deactivate | |
} | |
} | |
<# | |
.Description | |
Get-PyVenvConfig parses the values from the pyvenv.cfg file located in the | |
given folder, and returns them in a map. | |
For each line in the pyvenv.cfg file, if that line can be parsed into exactly | |
two strings separated by `=` (with any amount of whitespace surrounding the =) | |
then it is considered a `key = value` line. The left hand string is the key, | |
the right hand is the value. | |
If the value starts with a `'` or a `"` then the first and last character is | |
stripped from the value before being captured. | |
.Parameter ConfigDir | |
Path to the directory that contains the `pyvenv.cfg` file. | |
#> | |
function Get-PyVenvConfig( | |
[String] | |
$ConfigDir | |
) { | |
Write-Verbose "Given ConfigDir=$ConfigDir, obtain values in pyvenv.cfg" | |
# Ensure the file exists, and issue a warning if it doesn't (but still allow the function to continue). | |
$pyvenvConfigPath = Join-Path -Resolve -Path $ConfigDir -ChildPath 'pyvenv.cfg' -ErrorAction Continue | |
# An empty map will be returned if no config file is found. | |
$pyvenvConfig = @{ } | |
if ($pyvenvConfigPath) { | |
Write-Verbose "File exists, parse `key = value` lines" | |
$pyvenvConfigContent = Get-Content -Path $pyvenvConfigPath | |
$pyvenvConfigContent | ForEach-Object { | |
$keyval = $PSItem -split "\s*=\s*", 2 | |
if ($keyval[0] -and $keyval[1]) { | |
$val = $keyval[1] | |
# Remove extraneous quotations around a string value. | |
if ("'""".Contains($val.Substring(0, 1))) { | |
$val = $val.Substring(1, $val.Length - 2) | |
} | |
$pyvenvConfig[$keyval[0]] = $val | |
Write-Verbose "Adding Key: '$($keyval[0])'='$val'" | |
} | |
} | |
} | |
return $pyvenvConfig | |
} | |
<# Begin Activate script --------------------------------------------------- #> | |
# Determine the containing directory of this script | |
$VenvExecPath = Split-Path -Parent $MyInvocation.MyCommand.Definition | |
$VenvExecDir = Get-Item -Path $VenvExecPath | |
Write-Verbose "Activation script is located in path: '$VenvExecPath'" | |
Write-Verbose "VenvExecDir Fullname: '$($VenvExecDir.FullName)" | |
Write-Verbose "VenvExecDir Name: '$($VenvExecDir.Name)" | |
# Set values required in priority: CmdLine, ConfigFile, Default | |
# First, get the location of the virtual environment, it might not be | |
# VenvExecDir if specified on the command line. | |
if ($VenvDir) { | |
Write-Verbose "VenvDir given as parameter, using '$VenvDir' to determine values" | |
} | |
else { | |
Write-Verbose "VenvDir not given as a parameter, using parent directory name as VenvDir." | |
$VenvDir = $VenvExecDir.Parent.FullName.TrimEnd("\\/") | |
Write-Verbose "VenvDir=$VenvDir" | |
} | |
# Next, read the `pyvenv.cfg` file to determine any required value such | |
# as `prompt`. | |
$pyvenvCfg = Get-PyVenvConfig -ConfigDir $VenvDir | |
# Next, set the prompt from the command line, or the config file, or | |
# just use the name of the virtual environment folder. | |
if ($Prompt) { | |
Write-Verbose "Prompt specified as argument, using '$Prompt'" | |
} | |
else { | |
Write-Verbose "Prompt not specified as argument to script, checking pyvenv.cfg value" | |
if ($pyvenvCfg -and $pyvenvCfg['prompt']) { | |
Write-Verbose " Setting based on value in pyvenv.cfg='$($pyvenvCfg['prompt'])'" | |
$Prompt = $pyvenvCfg['prompt']; | |
} | |
else { | |
Write-Verbose " Setting prompt based on parent's directory's name. (Is the directory name passed to venv module when creating the virutal environment)" | |
Write-Verbose " Got leaf-name of $VenvDir='$(Split-Path -Path $venvDir -Leaf)'" | |
$Prompt = Split-Path -Path $venvDir -Leaf | |
} | |
} | |
Write-Verbose "Prompt = '$Prompt'" | |
Write-Verbose "VenvDir='$VenvDir'" | |
# Deactivate any currently active virtual environment, but leave the | |
# deactivate function in place. | |
deactivate -nondestructive | |
# Now set the environment variable VIRTUAL_ENV, used by many tools to determine | |
# that there is an activated venv. | |
$env:VIRTUAL_ENV = $VenvDir | |
if (-not $Env:VIRTUAL_ENV_DISABLE_PROMPT) { | |
Write-Verbose "Setting prompt to '$Prompt'" | |
# Set the prompt to include the env name | |
# Make sure _OLD_VIRTUAL_PROMPT is global | |
function global:_OLD_VIRTUAL_PROMPT { "" } | |
Copy-Item -Path function:prompt -Destination function:_OLD_VIRTUAL_PROMPT | |
New-Variable -Name _PYTHON_VENV_PROMPT_PREFIX -Description "Python virtual environment prompt prefix" -Scope Global -Option ReadOnly -Visibility Public -Value $Prompt | |
function global:prompt { | |
Write-Host -NoNewline -ForegroundColor Green "($_PYTHON_VENV_PROMPT_PREFIX) " | |
_OLD_VIRTUAL_PROMPT | |
} | |
} | |
# Clear PYTHONHOME | |
if (Test-Path -Path Env:PYTHONHOME) { | |
Copy-Item -Path Env:PYTHONHOME -Destination Env:_OLD_VIRTUAL_PYTHONHOME | |
Remove-Item -Path Env:PYTHONHOME | |
} | |
# Add the venv to the PATH | |
Copy-Item -Path Env:PATH -Destination Env:_OLD_VIRTUAL_PATH | |
$Env:PATH = "$VenvExecDir$([System.IO.Path]::PathSeparator)$Env:PATH" | |
# SIG # Begin signature block | |
# MIIcvwYJKoZIhvcNAQcCoIIcsDCCHKwCAQExDzANBglghkgBZQMEAgEFADB5Bgor | |
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG | |
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAwnDYwEHaCQq0n | |
# 8NAvsN7H7BO7/48rXCNwrg891FS5vaCCC38wggUwMIIEGKADAgECAhAECRgbX9W7 | |
# ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK | |
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV | |
# BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBa | |
# Fw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy | |
# dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lD | |
# ZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3 | |
# DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/l | |
# qJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fT | |
# eyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqH | |
# CN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+ | |
# bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLo | |
# LFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIB | |
# yTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK | |
# BggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9v | |
# Y3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGln | |
# aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHow | |
# eDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJl | |
# ZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0Rp | |
# Z2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwA | |
# AgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAK | |
# BghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0j | |
# BBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7s | |
# DVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGS | |
# dQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6 | |
# r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo | |
# +MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qz | |
# sIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHq | |
# aGxEMrJmoecYpJpkUe8wggZHMIIFL6ADAgECAhADPtXtoGXRuMkd/PkqbJvYMA0G | |
# CSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ | |
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0 | |
# IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcNMTgxMjE4MDAwMDAw | |
# WhcNMjExMjIyMTIwMDAwWjCBgzELMAkGA1UEBhMCVVMxFjAUBgNVBAgTDU5ldyBI | |
# YW1wc2hpcmUxEjAQBgNVBAcTCVdvbGZlYm9ybzEjMCEGA1UEChMaUHl0aG9uIFNv | |
# ZnR3YXJlIEZvdW5kYXRpb24xIzAhBgNVBAMTGlB5dGhvbiBTb2Z0d2FyZSBGb3Vu | |
# ZGF0aW9uMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAqr2kS7J1uW7o | |
# JRxlsdrETAjKarfoH5TI8PWST6Yb2xPooP7vHT4iaVXyL5Lze1f53Jw67Sp+u524 | |
# fJXf30qHViEWxumy2RWG0nciU2d+mMqzjlaAWSZNF0u4RcvyDJokEV0RUOqI5CG5 | |
# zPI3W9uQ6LiUk3HCYW6kpH177A5T3pw/Po8O8KErJGn1anaqtIICq99ySxrMad/2 | |
# hPMBRf6Ndah7f7HPn1gkSSTAoejyuqF5h+B0qI4+JK5+VLvz659VTbAWJsYakkxZ | |
# xVWYpFv4KeQSSwoo0DzMvmERsTzNvVBMWhu9OriJNg+QfFmf96zVTu93cZ+r7xMp | |
# bXyfIOGKhHMaRuZ8ihuWIx3gI9WHDFX6fBKR8+HlhdkaiBEWIsXRoy+EQUyK7zUs | |
# +FqOo2sRYttbs8MTF9YDKFZwyPjn9Wn+gLGd5NUEVyNvD9QVGBEtN7vx87bduJUB | |
# 8F4DylEsMtZTfjw/au6AmOnmneK5UcqSJuwRyZaGNk7y3qj06utx+HTTqHgi975U | |
# pxfyrwAqkovoZEWBVSpvku8PVhkBXcLmNe6MEHlFiaMoiADAeKmX5RFRkN+VrmYG | |
# Tg4zajxfdHeIY8TvLf48tTfmnQJd98geJQv/01NUy/FxuwqAuTkaez5Nl1LxP0Cp | |
# THhghzO4FRD4itT2wqTh4jpojw9QZnsCAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaA | |
# FFrEuXsqCqOl6nEDwGD5LfZldQ5YMB0GA1UdDgQWBBT8Kr9+1L6s84KcpM97IgE7 | |
# uI8H8jAOBgNVHQ8BAf8EBAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0f | |
# BHAwbjA1oDOgMYYvaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl | |
# ZC1jcy1nMS5jcmwwNaAzoDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEy | |
# LWFzc3VyZWQtY3MtZzEuY3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYI | |
# KwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQB | |
# MIGEBggrBgEFBQcBAQR4MHYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2lj | |
# ZXJ0LmNvbTBOBggrBgEFBQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29t | |
# L0RpZ2lDZXJ0U0hBMkFzc3VyZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB | |
# /wQCMAAwDQYJKoZIhvcNAQELBQADggEBAEt1oS21X0axiafPjyY+vlYqjWKuUu/Y | |
# FuYWIEq6iRRaFabNDhj9RBFQF/aJiE5msrQEOfAD6/6gVSH91lZWBqg6NEeG9T9S | |
# XbiAPvJ9CEWFsdkXUrjbWhvCnuZ7kqUuU5BAumI1QRbpYgZL3UA+iZXkmjbGh1ln | |
# 8rUhWIxbBYL4Sg2nqpB44p7CUFYkPj/MbwU2gvBV2pXjj5WaskoZtsACMv5g42BN | |
# oVLoRAi+ev6s07POt+JtHRIm87lTyuc8wh0swTPUwksKbLU1Zdj9CpqtzXnuVE0w | |
# 50exJvRSK3Vt4g+0vigpI3qPmDdpkf9+4Mvy0XMNcqrthw20R+PkIlMxghCWMIIQ | |
# kgIBATCBhjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw | |
# FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEy | |
# IEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBAhADPtXtoGXRuMkd/PkqbJvYMA0G | |
# CWCGSAFlAwQCAQUAoIGYMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisG | |
# AQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMCwGCisGAQQBgjcCAQwxHjAcoBqAGABQ | |
# AHkAdABoAG8AbgAgADMALgA5AC4ANDAvBgkqhkiG9w0BCQQxIgQgBrni4mcRv7sM | |
# JHsxpROjRopOz2wuQVrJnn+lD7X7y+gwDQYJKoZIhvcNAQEBBQAEggIAgnraC5Ax | |
# LdvDJz/AUld/6WGZ21jxAG4ijZvDnAS7Hopm0vclO2+7jtddNTP0w1tbebW2o987 | |
# AjD16hqG+D96N/sB3vfZ86fVjARf3XuyCWBYuIkLnjir+MfaXNU1n+kJuT7DNpo6 | |
# H+BIUM8PYqLGo4SwHXC2H2d+VfMLNyZ+91LmqT9qAAC6aT+VuTvlC+BUF/J4N81f | |
# 3TCa0F7C9KT1cdAmKtt6EMIdAYqWp8r1merIFjD/olBTq9nLcyjTqE9lCb4Nf6J9 | |
# jyM8/FA8hD41nHZTCKRSPCFKNZRqVYOaiWBHxQxPtYKuLJzMgxK0QHQhjWNpXTLs | |
# C1G1hQxX0MOWzLmcgtvxh5AhlQS+oHUs4/ebzmaovVzjbQRPqZHLDzYOQeG+79JM | |
# qi5gQt4L7TksfvmQ/dI4nJtzVDYAjN1v9rJY1snSqBlnSWgOyyZJX7aYBgVM3uJV | |
# u6j5tKXnPW7/u6USlVjtD4yKxKKoctomYiSIjjJA7DVL9CoCSF2ZyqxtuXDR8VD7 | |
# fb8gS2XklEJ3wi8MbUg9LJtI5Q3e/Qursr9RpEL5uTjhW9xTV+ubc6SWMWMEj3RT | |
# +7PUi23Vdh2917qGR+jyrUap+GMCXrUyUsLkMR5UkiltErrubmRnSPTbkFJTfEcf | |
# aniVMNn3x63CGwXdmSgVJleq1n28KcM/A02hgg1FMIINQQYKKwYBBAGCNwMDATGC | |
# DTEwgg0tBgkqhkiG9w0BBwKggg0eMIINGgIBAzEPMA0GCWCGSAFlAwQCAQUAMHgG | |
# CyqGSIb3DQEJEAEEoGkEZzBlAgEBBglghkgBhv1sBwEwMTANBglghkgBZQMEAgEF | |
# AAQgnJMkz3GdNmSHANJI2WUD6lOcmRKl+QqVqKICyZcEo3wCEQCoQmR+Bv/7IKIC | |
# +H/HED8fGA8yMDIxMDQwNjE0MDc1MFqgggo3MIIE/jCCA+agAwIBAgIQDUJK4L46 | |
# iP9gQCHOFADw3TANBgkqhkiG9w0BAQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UE | |
# ChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYD | |
# VQQDEyhEaWdpQ2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBMB4X | |
# DTIxMDEwMTAwMDAwMFoXDTMxMDEwNjAwMDAwMFowSDELMAkGA1UEBhMCVVMxFzAV | |
# BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSAwHgYDVQQDExdEaWdpQ2VydCBUaW1lc3Rh | |
# bXAgMjAyMTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMLmYYRnxYr1 | |
# DQikRcpja1HXOhFCvQp1dU2UtAxQtSYQ/h3Ib5FrDJbnGlxI70Tlv5thzRWRYlq4 | |
# /2cLnGP9NmqB+in43Stwhd4CGPN4bbx9+cdtCT2+anaH6Yq9+IRdHnbJ5MZ2djpT | |
# 0dHTWjaPxqPhLxs6t2HWc+xObTOKfF1FLUuxUOZBOjdWhtyTI433UCXoZObd048v | |
# V7WHIOsOjizVI9r0TXhG4wODMSlKXAwxikqMiMX3MFr5FK8VX2xDSQn9JiNT9o1j | |
# 6BqrW7EdMMKbaYK02/xWVLwfoYervnpbCiAvSwnJlaeNsvrWY4tOpXIc7p96AXP4 | |
# Gdb+DUmEvQECAwEAAaOCAbgwggG0MA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8E | |
# AjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMEEGA1UdIAQ6MDgwNgYJYIZIAYb9 | |
# bAcBMCkwJwYIKwYBBQUHAgEWG2h0dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAf | |
# BgNVHSMEGDAWgBT0tuEgHf4prtLkYaWyoiWyyBc1bjAdBgNVHQ4EFgQUNkSGjqS6 | |
# sGa+vCgtHUQ23eNqerwwcQYDVR0fBGowaDAyoDCgLoYsaHR0cDovL2NybDMuZGln | |
# aWNlcnQuY29tL3NoYTItYXNzdXJlZC10cy5jcmwwMqAwoC6GLGh0dHA6Ly9jcmw0 | |
# LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtdHMuY3JsMIGFBggrBgEFBQcBAQR5 | |
# MHcwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBPBggrBgEF | |
# BQcwAoZDaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFz | |
# c3VyZWRJRFRpbWVzdGFtcGluZ0NBLmNydDANBgkqhkiG9w0BAQsFAAOCAQEASBzc | |
# temaI7znGucgDo5nRv1CclF0CiNHo6uS0iXEcFm+FKDlJ4GlTRQVGQd58NEEw4bZ | |
# O73+RAJmTe1ppA/2uHDPYuj1UUp4eTZ6J7fz51Kfk6ftQ55757TdQSKJ+4eiRgNO | |
# /PT+t2R3Y18jUmmDgvoaU+2QzI2hF3MN9PNlOXBL85zWenvaDLw9MtAby/Vh/HUI | |
# AHa8gQ74wOFcz8QRcucbZEnYIpp1FUL1LTI4gdr0YKK6tFL7XOBhJCVPst/JKahz | |
# Q1HavWPWH1ub9y4bTxMd90oNcX6Xt/Q/hOvB46NJofrOp79Wz7pZdmGJX36ntI5n | |
# ePk2mOHLKNpbh6aKLzCCBTEwggQZoAMCAQICEAqhJdbWMht+QeQF2jaXwhUwDQYJ | |
# KoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu | |
# YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQg | |
# QXNzdXJlZCBJRCBSb290IENBMB4XDTE2MDEwNzEyMDAwMFoXDTMxMDEwNzEyMDAw | |
# MFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UE | |
# CxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1 | |
# cmVkIElEIFRpbWVzdGFtcGluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC | |
# AQoCggEBAL3QMu5LzY9/3am6gpnFOVQoV7YjSsQOB0UzURB90Pl9TWh+57ag9I2z | |
# iOSXv2MhkJi/E7xX08PhfgjWahQAOPcuHjvuzKb2Mln+X2U/4Jvr40ZHBhpVfgsn | |
# fsCi9aDg3iI/Dv9+lfvzo7oiPhisEeTwmQNtO4V8CdPuXciaC1TjqAlxa+DPIhAP | |
# dc9xck4Krd9AOly3UeGheRTGTSQjMF287DxgaqwvB8z98OpH2YhQXv1mblZhJymJ | |
# hFHmgudGUP2UKiyn5HU+upgPhH+fMRTWrdXyZMt7HgXQhBlyF/EXBu89zdZN7wZC | |
# /aJTKk+FHcQdPK/P2qwQ9d2srOlW/5MCAwEAAaOCAc4wggHKMB0GA1UdDgQWBBT0 | |
# tuEgHf4prtLkYaWyoiWyyBc1bjAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd | |
# 823IDzASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUE | |
# DDAKBggrBgEFBQcDCDB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6 | |
# Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMu | |
# ZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0f | |
# BHoweDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNz | |
# dXJlZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29t | |
# L0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBQBgNVHSAESTBHMDgGCmCGSAGG | |
# /WwAAgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQ | |
# UzALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggEBAHGVEulRh1Zpze/d2nyq | |
# Y3qzeM8GN0CE70uEv8rPAwL9xafDDiBCLK938ysfDCFaKrcFNB1qrpn4J6Jmvwmq | |
# YN92pDqTD/iy0dh8GWLoXoIlHsS6HHssIeLWWywUNUMEaLLbdQLgcseY1jxk5R9I | |
# EBhfiThhTWJGJIdjjJFSLK8pieV4H9YLFKWA1xJHcLN11ZOFk362kmf7U2GJqPVr | |
# lsD0WGkNfMgBsbkodbeZY4UijGHKeZR+WfyMD+NvtQEmtmyl7odRIeRYYJu6DC0r | |
# baLEfrvEJStHAgh8Sa4TtuF8QkIoxhhWz0E0tmZdtnR79VYzIi8iNrJLokqV2PWm | |
# jlIxggJNMIICSQIBATCBhjByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNl | |
# cnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdp | |
# Q2VydCBTSEEyIEFzc3VyZWQgSUQgVGltZXN0YW1waW5nIENBAhANQkrgvjqI/2BA | |
# Ic4UAPDdMA0GCWCGSAFlAwQCAQUAoIGYMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B | |
# CRABBDAcBgkqhkiG9w0BCQUxDxcNMjEwNDA2MTQwNzUwWjArBgsqhkiG9w0BCRAC | |
# DDEcMBowGDAWBBTh14Ko4ZG+72vKFpG1qrSUpiSb8zAvBgkqhkiG9w0BCQQxIgQg | |
# 5mFO2l6qrJzEhKgscyI4e20+BlIPLZai0pXpS+XFVIowDQYJKoZIhvcNAQEBBQAE | |
# ggEApEkQXZn24/PS2O3rXicGnIfxtSxqOLcJFE8C4TcyBsvtgHfiDXPbbctdnpbb | |
# KZhX60fHqjr98I17Lqg7GHop2SOZHrR3NOEJcbHxHsI74qrCg6b70MHXh2Q1OLzQ | |
# hCc4JQUv7O/63bzVyJ9H4W1MgHOdmAlNSc3fWGtj4K4jhcM3uHnVl1gF4bJOWhMs | |
# W5IxHeBmpO4/Xv0upkbQXtmPooNgxwYRTosEyU6tkuDWRvQlddhNndOgX53r6Qsz | |
# CWdCDv2CiUaUyKOJW8vhO+DKqyK9Cobq537UKIl047zb5yFXfzQ4u/YGeMukkoBt | |
# 10uT/66Q5dEY8U/Y04CnnzJ83w== | |
# SIG # End signature block | |