375 lines
17 KiB
PowerShell
375 lines
17 KiB
PowerShell
<#
|
|
.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.
|
|
|
|
|
|
#>
|
|
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
|
|
# MIIaVgYJKoZIhvcNAQcCoIIaRzCCGkMCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD+OCVx/PDssJke
|
|
# lhLLB+DoYOXVGOQfEDGSHpBCLzyqjKCCFBgwggPuMIIDV6ADAgECAhB+k+v7fMZO
|
|
# WepLmnfUBvw7MA0GCSqGSIb3DQEBBQUAMIGLMQswCQYDVQQGEwJaQTEVMBMGA1UE
|
|
# CBMMV2VzdGVybiBDYXBlMRQwEgYDVQQHEwtEdXJiYW52aWxsZTEPMA0GA1UEChMG
|
|
# VGhhd3RlMR0wGwYDVQQLExRUaGF3dGUgQ2VydGlmaWNhdGlvbjEfMB0GA1UEAxMW
|
|
# VGhhd3RlIFRpbWVzdGFtcGluZyBDQTAeFw0xMjEyMjEwMDAwMDBaFw0yMDEyMzAy
|
|
# MzU5NTlaMF4xCzAJBgNVBAYTAlVTMR0wGwYDVQQKExRTeW1hbnRlYyBDb3Jwb3Jh
|
|
# dGlvbjEwMC4GA1UEAxMnU3ltYW50ZWMgVGltZSBTdGFtcGluZyBTZXJ2aWNlcyBD
|
|
# QSAtIEcyMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAsayzSVRLlxwS
|
|
# CtgleZEiVypv3LgmxENza8K/LlBa+xTCdo5DASVDtKHiRfTot3vDdMwi17SUAAL3
|
|
# Te2/tLdEJGvNX0U70UTOQxJzF4KLabQry5kerHIbJk1xH7Ex3ftRYQJTpqr1SSwF
|
|
# eEWlL4nO55nn/oziVz89xpLcSvh7M+R5CvvwdYhBnP/FA1GZqtdsn5Nph2Upg4XC
|
|
# YBTEyMk7FNrAgfAfDXTekiKryvf7dHwn5vdKG3+nw54trorqpuaqJxZ9YfeYcRG8
|
|
# 4lChS+Vd+uUOpyyfqmUg09iW6Mh8pU5IRP8Z4kQHkgvXaISAXWp4ZEXNYEZ+VMET
|
|
# fMV58cnBcQIDAQABo4H6MIH3MB0GA1UdDgQWBBRfmvVuXMzMdJrU3X3vP9vsTIAu
|
|
# 3TAyBggrBgEFBQcBAQQmMCQwIgYIKwYBBQUHMAGGFmh0dHA6Ly9vY3NwLnRoYXd0
|
|
# ZS5jb20wEgYDVR0TAQH/BAgwBgEB/wIBADA/BgNVHR8EODA2MDSgMqAwhi5odHRw
|
|
# Oi8vY3JsLnRoYXd0ZS5jb20vVGhhd3RlVGltZXN0YW1waW5nQ0EuY3JsMBMGA1Ud
|
|
# JQQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIBBjAoBgNVHREEITAfpB0wGzEZ
|
|
# MBcGA1UEAxMQVGltZVN0YW1wLTIwNDgtMTANBgkqhkiG9w0BAQUFAAOBgQADCZuP
|
|
# ee9/WTCq72i1+uMJHbtPggZdN1+mUp8WjeockglEbvVt61h8MOj5aY0jcwsSb0ep
|
|
# rjkR+Cqxm7Aaw47rWZYArc4MTbLQMaYIXCp6/OJ6HVdMqGUY6XlAYiWWbsfHN2qD
|
|
# IQiOQerd2Vc/HXdJhyoWBl6mOGoiEqNRGYN+tjCCBKMwggOLoAMCAQICEA7P9DjI
|
|
# /r81bgTYapgbGlAwDQYJKoZIhvcNAQEFBQAwXjELMAkGA1UEBhMCVVMxHTAbBgNV
|
|
# BAoTFFN5bWFudGVjIENvcnBvcmF0aW9uMTAwLgYDVQQDEydTeW1hbnRlYyBUaW1l
|
|
# IFN0YW1waW5nIFNlcnZpY2VzIENBIC0gRzIwHhcNMTIxMDE4MDAwMDAwWhcNMjAx
|
|
# MjI5MjM1OTU5WjBiMQswCQYDVQQGEwJVUzEdMBsGA1UEChMUU3ltYW50ZWMgQ29y
|
|
# cG9yYXRpb24xNDAyBgNVBAMTK1N5bWFudGVjIFRpbWUgU3RhbXBpbmcgU2Vydmlj
|
|
# ZXMgU2lnbmVyIC0gRzQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCi
|
|
# Yws5RLi7I6dESbsO/6HwYQpTk7CY260sD0rFbv+GPFNVDxXOBD8r/amWltm+YXkL
|
|
# W8lMhnbl4ENLIpXuwitDwZ/YaLSOQE/uhTi5EcUj8mRY8BUyb05Xoa6IpALXKh7N
|
|
# S+HdY9UXiTJbsF6ZWqidKFAOF+6W22E7RVEdzxJWC5JH/Kuu9mY9R6xwcueS51/N
|
|
# ELnEg2SUGb0lgOHo0iKl0LoCeqF3k1tlw+4XdLxBhircCEyMkoyRLZ53RB9o1qh0
|
|
# d9sOWzKLVoszvdljyEmdOsXF6jML0vGjG/SLvtmzV4s73gSneiKyJK4ux3DFvk6D
|
|
# Jgj7C72pT5kI4RAocqrNAgMBAAGjggFXMIIBUzAMBgNVHRMBAf8EAjAAMBYGA1Ud
|
|
# JQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIHgDBzBggrBgEFBQcBAQRn
|
|
# MGUwKgYIKwYBBQUHMAGGHmh0dHA6Ly90cy1vY3NwLndzLnN5bWFudGVjLmNvbTA3
|
|
# BggrBgEFBQcwAoYraHR0cDovL3RzLWFpYS53cy5zeW1hbnRlYy5jb20vdHNzLWNh
|
|
# LWcyLmNlcjA8BgNVHR8ENTAzMDGgL6AthitodHRwOi8vdHMtY3JsLndzLnN5bWFu
|
|
# dGVjLmNvbS90c3MtY2EtZzIuY3JsMCgGA1UdEQQhMB+kHTAbMRkwFwYDVQQDExBU
|
|
# aW1lU3RhbXAtMjA0OC0yMB0GA1UdDgQWBBRGxmmjDkoUHtVM2lJjFz9eNrwN5jAf
|
|
# BgNVHSMEGDAWgBRfmvVuXMzMdJrU3X3vP9vsTIAu3TANBgkqhkiG9w0BAQUFAAOC
|
|
# AQEAeDu0kSoATPCPYjA3eKOEJwdvGLLeJdyg1JQDqoZOJZ+aQAMc3c7jecshaAba
|
|
# tjK0bb/0LCZjM+RJZG0N5sNnDvcFpDVsfIkWxumy37Lp3SDGcQ/NlXTctlzevTcf
|
|
# Q3jmeLXNKAQgo6rxS8SIKZEOgNER/N1cdm5PXg5FRkFuDbDqOJqxOtoJcRD8HHm0
|
|
# gHusafT9nLYMFivxf1sJPZtb4hbKE4FtAC44DagpjyzhsvRaqQGvFZwsL0kb2yK7
|
|
# w/54lFHDhrGCiF3wPbRRoXkzKy57udwgCRNx62oZW8/opTBXLIlJP7nPf8m/PiJo
|
|
# Y1OavWl0rMUdPH+S4MO8HNgEdTCCBTAwggQYoAMCAQICEAQJGBtf1btmdVNDtW+V
|
|
# UAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
|
|
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGln
|
|
# aUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAy
|
|
# MjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ
|
|
# MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hB
|
|
# MiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQAD
|
|
# ggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wondsy13Hq
|
|
# dp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawOeSg6funRZ9PG+yknx9N7I5TkkSOW
|
|
# kHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJRdQtoaPpiCwgla4cSocI3wz14k1g
|
|
# GL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5sy350OTYN
|
|
# kO/ktU6kqepqCquE86xnTrXE94zRICUj6whkPlKWwfIPEvTFjg/BougsUfdzvL2F
|
|
# sWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJMBIGA1Ud
|
|
# EwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUF
|
|
# BwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGln
|
|
# aWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5j
|
|
# b20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2
|
|
# hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290
|
|
# Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRB
|
|
# c3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARIMEYwOAYKYIZIAYb9bAACBDAqMCgG
|
|
# CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMAoGCGCGSAGG
|
|
# /WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSMEGDAWgBRF
|
|
# 66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG9w0BAQsFAAOCAQEAPuwNWiSz8yLR
|
|
# FcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1D1G0bqWO
|
|
# WuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3nEZOXP+QsRsHDpEV+7qvtVHCjSSu
|
|
# JMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4xRJon89A
|
|
# y0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOwjNXpDd32
|
|
# ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ92JuoVP6EpQYhS6SkepobEQysmah
|
|
# 5xikmmRR7zCCBkcwggUvoAMCAQICEAM+1e2gZdG4yR38+Spsm9gwDQYJKoZIhvcN
|
|
# AQELBQAwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcG
|
|
# A1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBB
|
|
# c3N1cmVkIElEIENvZGUgU2lnbmluZyBDQTAeFw0xODEyMTgwMDAwMDBaFw0yMTEy
|
|
# MjIxMjAwMDBaMIGDMQswCQYDVQQGEwJVUzEWMBQGA1UECBMNTmV3IEhhbXBzaGly
|
|
# ZTESMBAGA1UEBxMJV29sZmVib3JvMSMwIQYDVQQKExpQeXRob24gU29mdHdhcmUg
|
|
# Rm91bmRhdGlvbjEjMCEGA1UEAxMaUHl0aG9uIFNvZnR3YXJlIEZvdW5kYXRpb24w
|
|
# ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCqvaRLsnW5buglHGWx2sRM
|
|
# CMpqt+gflMjw9ZJPphvbE+ig/u8dPiJpVfIvkvN7V/ncnDrtKn67nbh8ld/fSodW
|
|
# IRbG6bLZFYbSdyJTZ36YyrOOVoBZJk0XS7hFy/IMmiQRXRFQ6ojkIbnM8jdb25Do
|
|
# uJSTccJhbqSkfXvsDlPenD8+jw7woSskafVqdqq0ggKr33JLGsxp3/aE8wFF/o11
|
|
# qHt/sc+fWCRJJMCh6PK6oXmH4HSojj4krn5Uu/Prn1VNsBYmxhqSTFnFVZikW/gp
|
|
# 5BJLCijQPMy+YRGxPM29UExaG706uIk2D5B8WZ/3rNVO73dxn6vvEyltfJ8g4YqE
|
|
# cxpG5nyKG5YjHeAj1YcMVfp8EpHz4eWF2RqIERYixdGjL4RBTIrvNSz4Wo6jaxFi
|
|
# 21uzwxMX1gMoVnDI+Of1af6AsZ3k1QRXI28P1BUYES03u/Hztt24lQHwXgPKUSwy
|
|
# 1lN+PD9q7oCY6ead4rlRypIm7BHJloY2TvLeqPTq63H4dNOoeCL3vlSnF/KvACqS
|
|
# i+hkRYFVKm+S7w9WGQFdwuY17owQeUWJoyiIAMB4qZflEVGQ35WuZgZODjNqPF90
|
|
# d4hjxO8t/jy1N+adAl33yB4lC//TU1TL8XG7CoC5ORp7Pk2XUvE/QKlMeGCHM7gV
|
|
# EPiK1PbCpOHiOmiPD1BmewIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoK
|
|
# o6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFPwqv37Uvqzzgpykz3siATu4jwfyMA4G
|
|
# A1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWg
|
|
# M6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcx
|
|
# LmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJl
|
|
# ZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcC
|
|
# ARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEwgYQGCCsG
|
|
# AQUFBwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t
|
|
# ME4GCCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNl
|
|
# cnRTSEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADAN
|
|
# BgkqhkiG9w0BAQsFAAOCAQEAS3WhLbVfRrGJp8+PJj6+ViqNYq5S79gW5hYgSrqJ
|
|
# FFoVps0OGP1EEVAX9omITmaytAQ58APr/qBVIf3WVlYGqDo0R4b1P1JduIA+8n0I
|
|
# RYWx2RdSuNtaG8Ke5nuSpS5TkEC6YjVBFuliBkvdQD6JleSaNsaHWWfytSFYjFsF
|
|
# gvhKDaeqkHjinsJQViQ+P8xvBTaC8FXaleOPlZqyShm2wAIy/mDjYE2hUuhECL56
|
|
# /qzTs8634m0dEibzuVPK5zzCHSzBM9TCSwpstTVl2P0Kmq3Nee5UTTDnR7Em9FIr
|
|
# dW3iD7S+KCkjeo+YN2mR/37gy/LRcw1yqu2HDbRH4+QiUzGCBZQwggWQAgEBMIGG
|
|
# MHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT
|
|
# EHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJl
|
|
# ZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEAM+1e2gZdG4yR38+Spsm9gwDQYJYIZIAWUD
|
|
# BAIBBQCggdAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB
|
|
# CzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIKwuMOP9xUoz8IY/qorw
|
|
# oGtxknrVrNkjKQ2ycWeqndzkMGQGCisGAQQBgjcCAQwxVjBUoFKAUABCAHUAaQBs
|
|
# AHQAOgAgAFIAZQBsAGUAYQBzAGUAXwBtAGEAcwB0AGUAcgBfAHYAMwAuADgALgAy
|
|
# AF8AMgAwADIAMAAwADIAMgA1AC4AMAAxMA0GCSqGSIb3DQEBAQUABIICAIxhia1z
|
|
# q5Ne1RC0EjQ5Dwxz9WbhsGBoGrqEdFPevbtsrDkGfYjJSn/+lcm513FHHaswZ5Oe
|
|
# 4cYOdYx+CGLeQfKI2Ex8X32mHjBJ05x9WgrVjyNaZgmfEGdgjHQJ0HR8S2zslhMK
|
|
# OVmXPQ5z/yrp8XKyfcz1YxWv6adLEe5VCF23hQrg0X9kAtXRCHl5sYzIGdiN0ZtU
|
|
# qhF/opkiE6RUQbnQNzOdPBHFcmUGXq6QMago4PlajZ9qSV0Jmbz9X3G3m9g7OKUM
|
|
# pMfgcOMh6u8+CgTjfUvzNhQpzpMaRuscMbeLtdPt7Vx3O7zHJkV2IahCNnqg3+yr
|
|
# nrtuGcHgL2UjNCnByAtTZwl9gu8HbWzhfpM/Yeik7EvnuIJjpawgiTYJCdB4nQiN
|
|
# +zAChfqn5EyRJOdKYOD7Le7setZjSz2YhoLu9+ZTqAVIyEQuR+mLr5xZ/NdCtWM5
|
|
# E0lfMACTM811zLBVtWUNDmGrjEsC5YXi0EYro9wxC1C7fr3zio0Riqec6yXGZIXy
|
|
# ZlmcpQX08x94wyhXDu6PxPROibzeH1oxPY8gqdz3GBhBVJ1syPwwe5hpq18npiFa
|
|
# kaUHnmTh5G66ob8KfrW0pLxFYtm0PC01SJFbneId4Nba37vJRz8ljcMOUGG9V1xB
|
|
# wYYv9omIwDcxvej2DriM1+G16VgXgW2i+HSooYICCzCCAgcGCSqGSIb3DQEJBjGC
|
|
# AfgwggH0AgEBMHIwXjELMAkGA1UEBhMCVVMxHTAbBgNVBAoTFFN5bWFudGVjIENv
|
|
# cnBvcmF0aW9uMTAwLgYDVQQDEydTeW1hbnRlYyBUaW1lIFN0YW1waW5nIFNlcnZp
|
|
# Y2VzIENBIC0gRzICEA7P9DjI/r81bgTYapgbGlAwCQYFKw4DAhoFAKBdMBgGCSqG
|
|
# SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIwMDIyNTIzMjcx
|
|
# NVowIwYJKoZIhvcNAQkEMRYEFFeoNP35f0GEPRx1lIAvgGS7kQaOMA0GCSqGSIb3
|
|
# DQEBAQUABIIBAEEQv1uOdJtm72308aLHvgJ/ydvSwEQtG/hcLBf9hlBcKtkAF/jL
|
|
# hAiMw2ABZ5EYlXkSTREecbS+cNluC0kCG1pei9kkVp+zqk2GxTY1zROE4a5de4f/
|
|
# dgOPpLrSKeu74sbnhGZcaGKP8U2ZpJzq9zVVTGNICgwaZu2meszWkfcisO6GKBYs
|
|
# EASTWqWwd89pNI/ZU6Dxjy6JMC3q8dOm/PwmN92/wd8rK2xJuGacIPKlI9KaMBmZ
|
|
# 67jWuSAyk3T2xW4u38+mo+JSayoP7Vzksk8mIy5JOA4jjK/5V93psJP0HGZoznu1
|
|
# aiQFqc3z8uRQZZXpD0YXo6Zlkr9fbhoRXPQ=
|
|
# SIG # End signature block
|