AnyPackage.PowerShellGet.psm1
# Copyright (c) Thomas Nieto - All Rights Reserved # You may use, distribute and modify this code under the # terms of the MIT license. using module AnyPackage using module PowerShellGet using namespace System.Collections.Generic using namespace AnyPackage.Provider using namespace Microsoft.PowerShell.PowerShellGet.UtilClasses [PackageProvider('PowerShellGet')] class PowerShellGetProvider : PackageProvider, IGetPackage, IFindPackage, IInstallPackage, ISavePackage, IUninstallPackage, IUpdatePackage, IPublishPackage, IGetSource, ISetSource { PowerShellGetProvider() : base('c9a39544-274b-4935-9cad-7423e8c47e6b') { } #region GetPackage [void] GetPackage([PackageRequest] $request) { $params = @{ Name = $request.Name } if ($request.Version) { $params['Version'] = $request.Version } if ($request.DynamicParameters.Path) { $params['Path'] = $request.DynamicParameters.Path } if ($request.DynamicParameters.Scope) { $params['Scope'] = $request.DynamicParameters.Scope } [List[PSResourceInfo]] $resources = [List[PSResourceInfo]]::new() try { $resources = Get-PSResource @params -ErrorAction Stop } catch { throw $_ } $this.ProcessResources($resources, $request) } #endregion #region FindPackage [void] FindPackage([PackageRequest] $request) { $params = @{ Name = $request.Name Prerelease = $request.Prerelease } if ($request.Version) { $params['Version'] = $request.Version } if ($request.Source) { $params['Repository'] = $request.Source } if ($request.DynamicParameters.Tag) { $params['Tag'] = $request.DynamicParameters.Tag } if ($request.DynamicParameters.Type) { $params['Type'] = $request.DynamicParameters.Type } [List[PSResourceInfo]] $resources = [List[PSResourceInfo]]::new() try { $resources = Find-PSResource @params -ErrorAction Stop } catch { throw $_ } $this.ProcessResources($resources, $request) } #endregion #region InstallPackage [void] InstallPackage([PackageRequest] $request) { $params = @{ Name = $request.Name Prerelease = $request.Prerelease TrustRepository = $true PassThru = $true } if ($request.Version) { $params['Version'] = $request.Version } if ($request.Source) { $params['Source'] = $request.Source } [List[PSResourceInfo]] $resources = [List[PSResourceInfo]]::new() try { $resources = Install-PSResource @params -ErrorAction Stop } catch { throw $_ } $this.ProcessResources($resources, $request) } #endregion #region SavePackage [void] SavePackage([PackageRequest] $request) { $params = @{ Name = $request.Name Path = $request.Path Prerelease = $request.Prerelease TrustRepository = $true PassThru = $true } if ($request.Version) { $params['Version'] = $request.Version } if ($request.Source) { $params['Source'] = $request.Source } [List[PSResourceInfo]] $resources = [List[PSResourceInfo]]::new() try { $resources = Save-PSResource @params -ErrorAction Stop } catch { throw $_ } $this.ProcessResources($resources, $request) } #endregion #region UninstallPackage [void] UninstallPackage([PackageRequest] $request) { $params = @{ Name = $request.Name } if ($request.Version) { $params['Version'] = $request.Version } [List[PSResourceInfo]] $beforeResources = [List[PSResourceInfo]]::new() $beforeResources = Get-PSResource @params if (-not $beforeResources) { return } # Issue to get PassThru parameter added # https://github.com/PowerShell/PowerShellGet/issues/667 # Prerelease parameter causes it to silently fail # https://github.com/PowerShell/PowerShellGet/issues/842 try { Uninstall-PSResource @params -ErrorAction Stop } catch { throw $_ } $afterResources = Get-PSResource @params if ($afterResources) { throw "Failed uninstalling package '$($request.Name)'. One or more versions are still installed." } else { $this.ProcessResources($beforeResources, $request) } } #endregion #region UpdatePackage [void] UpdatePackage([PackageRequest] $request) { $params = @{ Name = $request.Name Prerelease = $request.Prerelease TrustRepository = $true PassThru = $true } if ($request.Version) { $params['Version'] = $request.Version } if ($request.Source) { $params['Source'] = $request.Source } [List[PSResourceInfo]] $resources = [List[PSResourceInfo]]::new() try { $resources = Update-PSResource @params -ErrorAction Stop } catch { throw $_ } $this.ProcessResources($resources, $request) } #endregion #region PublishPackage [void] PublishPackage([PackageRequest] $request) { $params = @{ Path = $request.Path } if ($request.Source) { $params['Source'] = $request.Source } try { Publish-PSResource @params -ErrorAction Stop $resourceName = Get-Item -Path $request.Path | Select-Object -ExpandProperty BaseName if ($request.Source) { $resource = Find-PSResource -Name $resourceName -Source $request.Source } else { $resource = Find-PSResource -Name $resourceName } $this.ProcessResource($resource, $request) } catch { throw $_ } } #endregion #region Source [void] GetSource([SourceRequest] $request) { $repos = Get-PSResourceRepository -Name $request.Name -ErrorAction SilentlyContinue foreach ($repo in $repos) { $request.WriteSource($repo.Name, $repo.Uri, [bool]::Parse($repo.Trusted), @{ Priority = $repo.Priority }) } } [void] SetSource([SourceRequest] $request) { $params = @{ Name = $request.Name PassThru = $true } if ($request.Location) { $params.Uri = $request.Location } if ($null -ne $request.Trusted) { $params.Trusted = $request.Trusted } $repo = Set-PSResourceRepository @params $request.WriteSource($repo.Name, $repo.Uri, [bool]::Parse($repo.Trusted), @{ Priority = $repo.Priority }) } [void] RegisterSource([SourceRequest] $request) { $params = @{ Name = $request.Name Uri = $request.Location Trusted = $request.Trusted PassThru = $true } $repo = Register-PSResourceRepository @params $request.WriteSource($repo.Name, $repo.Uri, [bool]::Parse($repo.Trusted), @{ Priority = $repo.Priority }) } [void] UnregisterSource([SourceRequest] $request) { $params = @{ Name = $request.Name PassThru = $true } $repo = Unregister-PSResourceRepository @params $request.WriteSource($repo.Name, $repo.Uri, [bool]::Parse($repo.Trusted), @{ Priority = $repo.Priority }) } #endregion [object] GetDynamicParameters([string] $commandName) { switch ($commandName) { 'Get-Package' { return [GetPackageDynamicParameters]::new() } 'Find-Package' { return [FindPackageDynamicParameters]::new() } default { return $null } } #bug shouldn't have to do this. return $null } #region ProcessResource hidden [void] ProcessResources([IEnumerable[PSResourceInfo]] $resources, [PackageRequest] $request) { foreach ($resource in $resources) { $this.ProcessResource($resource, $request) } } hidden [void] ProcessResource([PSResourceInfo] $resource, [PackageRequest] $request) { $request.WriteVerbose("Processing '$($resource.Name)' resource.") $repo = Get-PSResourceRepository -Name $resource.Repository $ht = ConvertTo-PackageMetadata $resource $deps = [List[PackageDependency]]::new() foreach ($dep in $resource.Dependencies) { $dependency = [PackageDependency]::new($dep.Name, $dep.VersionRange) $deps.Add($dependency) } if ($repo) { $repoInfo = $request.NewSourceInfo($repo.Name, $repo.Url, [bool]::Parse($repo.Trusted), @{ Priority = $repo.Priority; CredentialInfo = $repo.CredentialInfo }) } else { $repoInfo = $request.NewSourceInfo($resource.Repository, $resource.RepositorySourceLocation, $false, $null) } $version = $resource.Version.ToString() if ($resource.Prerelease) { $version = $version + '-' + $resource.Prerelease } $request.WritePackage($resource.Name, $version, $resource.Description, $repoInfo, $ht, $deps) } #endregion } class GetPackageDynamicParameters { [Parameter()] [string] $Path [Parameter()] [ScopeType] $Scope } class FindPackageDynamicParameters { [Parameter()] [string[]] $Tag [Parameter()] [ResourceType] $Type } [PackageProviderManager]::RegisterProvider([PowerShellGetProvider], $MyInvocation.MyCommand.ScriptBlock.Module) $MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { [PackageProviderManager]::UnregisterProvider([PowerShellGetProvider]) } function ConvertTo-PackageMetadata { [CmdletBinding()] [OutputType([hashtable])] param ( [PSResourceInfo] [Parameter(Position = 0, ValueFromPipeline, ValueFromPipelineByPropertyName)] $InputObject ) begin { $properties = $InputObject | Get-Member -MemberType Properties | Select-Object -ExpandProperty Name } process { $hashtable = @{} foreach ($property in $properties) { $hashtable[$property] = $InputObject.$property } $hashtable } } # SIG # Begin signature block # MIIfNQYJKoZIhvcNAQcCoIIfJjCCHyICAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAjrtC0uqBYEmUU # L5uyd9Pc1FbqpR3sp7UKKGt+daRF9qCCGPgwggURMIID+aADAgECAhATixZVeYWc # HXmMNSvpIJGBMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAkdCMRswGQYDVQQI # ExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoT # D1NlY3RpZ28gTGltaXRlZDEkMCIGA1UEAxMbU2VjdGlnbyBSU0EgQ29kZSBTaWdu # aW5nIENBMB4XDTIwMDExMDAwMDAwMFoXDTIyMTIwOTIzNTk1OVowZDELMAkGA1UE # BhMCVVMxDzANBgNVBAgMBkthbnNhczEWMBQGA1UEBwwNT3ZlcmxhbmQgUGFyazEV # MBMGA1UECgwMVGhvbWFzIE5pZXRvMRUwEwYDVQQDDAxUaG9tYXMgTmlldG8wggEi # MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCd4um34YFz0hPHGIEnLecf/i/Q # 8LBmTqD9h04IApHwyIanvbOuY5f/BziNUHnLNZSlHuq8eqlpQ59r4D5pmy+cm0de # S/qqYYoloLb9ZLvBS0e8fSx+o/ZL5wveakN6TMfCwXxSA3slEEiHVnUmlH0I57JT # Md3/QHIsBzw0Rk15lEOlw/lYQZNIi0md8yKdAWk+ABmcuLnkmPXK2wlXebmONfiO # iDj5TpN2QzmZ3OGFExER8sfdhuOnlehbv7q3/sDhFCKYIY6LxED3CA4cHjOMs2Of # Z9Sl66ee3J75fY7484jgiMjrTCY6ED2LVLwYwpluBuAUBklpd2VjH5LP2QFfAgMB # AAGjggGlMIIBoTAfBgNVHSMEGDAWgBQO4TqoUzox1Yq+wbutZxoDha00DjAdBgNV # HQ4EFgQU8gLY5rCOaNmN211EfMTJfYdbvAAwDgYDVR0PAQH/BAQDAgeAMAwGA1Ud # EwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYJYIZIAYb4QgEBBAQDAgQQ # MEAGA1UdIAQ5MDcwNQYMKwYBBAGyMQECAQMCMCUwIwYIKwYBBQUHAgEWF2h0dHBz # Oi8vc2VjdGlnby5jb20vQ1BTMEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwu # c2VjdGlnby5jb20vU2VjdGlnb1JTQUNvZGVTaWduaW5nQ0EuY3JsMHMGCCsGAQUF # BwEBBGcwZTA+BggrBgEFBQcwAoYyaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0 # aWdvUlNBQ29kZVNpZ25pbmdDQS5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3Nw # LnNlY3RpZ28uY29tMB0GA1UdEQQWMBSBEnRuaWV0bzg4QGdtYWlsLmNvbTANBgkq # hkiG9w0BAQsFAAOCAQEAPwFaeuhYzcuenOU8fhxgfxpjkPFwov9yV9rTkkozAw73 # qJzbxf1VBDvRbtbcz9bvwytdeVY4sF1lAccn8df/QVdf7Xlk7RaObNxPwXuY6T5C # vZT8GvzE4RtBUyq2xxwV/SMDZ9X3qh3OFxyxZD/XyU08+s39jHUuAYAzMX/QTnLX # 9v7eM7W8Ls+282Sd0onzaRLTk9hD6ZH552hAJQG3ftUGDP4YDLz77utwCdRK9Fne # Qo+jic/jr6JD0LdsCTlfOH+5q2/AJcShLCrV0WXvKZaVsZkFKpQD2uJ24C719pkn # dHoFP7S9hhdQFQ4YBI5Kce5HOTXA+3VfDBFG9PXDhTCCBfUwggPdoAMCAQICEB2i # SDBvmyYY0ILgln0z02owDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYDVQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UE # ChMVVGhlIFVTRVJUUlVTVCBOZXR3b3JrMS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNB # IENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTE4MTEwMjAwMDAwMFoXDTMwMTIz # MTIzNTk1OVowfDELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hl # c3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVk # MSQwIgYDVQQDExtTZWN0aWdvIFJTQSBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqG # SIb3DQEBAQUAA4IBDwAwggEKAoIBAQCGIo0yhXoYn0nwli9jCB4t3HyfFM/jJrYl # ZilAhlRGdDFixRDtsocnppnLlTDAVvWkdcapDlBipVGREGrgS2Ku/fD4GKyn/+4u # MyD6DBmJqGx7rQDDYaHcaWVtH24nlteXUYam9CflfGqLlR5bYNV+1xaSnAAvaPeX # 7Wpyvjg7Y96Pv25MQV0SIAhZ6DnNj9LWzwa0VwW2TqE+V2sfmLzEYtYbC43HZhtK # n52BxHJAteJf7wtF/6POF6YtVbC3sLxUap28jVZTxvC6eVBJLPcDuf4vZTXyIuos # B69G2flGHNyMfHEo8/6nxhTdVZFuihEN3wYklX0Pp6F8OtqGNWHTAgMBAAGjggFk # MIIBYDAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4EFgQU # DuE6qFM6MdWKvsG7rWcaA4WtNA4wDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQI # MAYBAf8CAQAwHQYDVR0lBBYwFAYIKwYBBQUHAwMGCCsGAQUFBwMIMBEGA1UdIAQK # MAgwBgYEVR0gADBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVz # dC5jb20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYI # KwYBBQUHAQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5j # b20vVVNFUlRydXN0UlNBQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6 # Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAE1jUO1HNEph # pNveaiqMm/EAAB4dYns61zLC9rPgY7P7YQCImhttEAcET7646ol4IusPRuzzRl5A # RokS9At3WpwqQTr81vTr5/cVlTPDoYMot94v5JT3hTODLUpASL+awk9KsY8k9LOB # N9O3ZLCmI2pZaFJCX/8E6+F0ZXkI9amT3mtxQJmWunjxucjiwwgWsatjWsgVgG10 # Xkp1fqW4w2y1z99KeYdcx0BNYzX2MNPPtQoOCwR/oEuuu6Ol0IQAkz5TXTSlADVp # bL6fICUQDRn7UJBhvjmPeo5N9p8OHv4HURJmgyYZSJXOSsnBf/M6BZv5b9+If8Aj # ntIeQ3pFMcGcTanwWbJZGehqjSkEAnd8S0vNcL46slVaeD68u28DECV3FTSK+TbM # Q5Lkuk/xYpMoJVcp+1EZx6ElQGqEV8aynbG8HArafGd+fS7pKEwYfsR7MUFxmksp # 7As9V1DSyt39ngVR5UR43QHesXWYDVQk/fBO4+L4g71yuss9Ou7wXheSaG3IYfmm # 8SoKC6W59J7umDIFhZ7r+YMp08Ysfb06dy6LN0KgaoLtO0qqlBCk4Q34F8W2Wnkz # GJLjtXX4oemOCiUe5B7xn1qHI/+fpFGe+zmAEc3btcSnqIBv5VPU4OOiwtJbGvoy # Ji1qV3AcPKRYLqPzW0sH3DJZ84enGm1YMIIG7DCCBNSgAwIBAgIQMA9vrN1mmHR8 # qUY2p3gtuTANBgkqhkiG9w0BAQwFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Ck5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVUaGUg # VVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlm # aWNhdGlvbiBBdXRob3JpdHkwHhcNMTkwNTAyMDAwMDAwWhcNMzgwMTE4MjM1OTU5 # WjB9MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw # DgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxJTAjBgNV # BAMTHFNlY3RpZ28gUlNBIFRpbWUgU3RhbXBpbmcgQ0EwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQDIGwGv2Sx+iJl9AZg/IJC9nIAhVJO5z6A+U++zWsB2 # 1hoEpc5Hg7XrxMxJNMvzRWW5+adkFiYJ+9UyUnkuyWPCE5u2hj8BBZJmbyGr1XEQ # eYf0RirNxFrJ29ddSU1yVg/cyeNTmDoqHvzOWEnTv/M5u7mkI0Ks0BXDf56iXNc4 # 8RaycNOjxN+zxXKsLgp3/A2UUrf8H5VzJD0BKLwPDU+zkQGObp0ndVXRFzs0IXuX # AZSvf4DP0REKV4TJf1bgvUacgr6Unb+0ILBgfrhN9Q0/29DqhYyKVnHRLZRMyIw8 # 0xSinL0m/9NTIMdgaZtYClT0Bef9Maz5yIUXx7gpGaQpL0bj3duRX58/Nj4OMGcr # Rrc1r5a+2kxgzKi7nw0U1BjEMJh0giHPYla1IXMSHv2qyghYh3ekFesZVf/QOVQt # Ju5FGjpvzdeE8NfwKMVPZIMC1Pvi3vG8Aij0bdonigbSlofe6GsO8Ft96XZpkyAc # Spcsdxkrk5WYnJee647BeFbGRCXfBhKaBi2fA179g6JTZ8qx+o2hZMmIklnLqEbA # yfKm/31X2xJ2+opBJNQb/HKlFKLUrUMcpEmLQTkUAx4p+hulIq6lw02C0I3aa7fb # 9xhAV3PwcaP7Sn1FNsH3jYL6uckNU4B9+rY5WDLvbxhQiddPnTO9GrWdod6VQXqn # gwIDAQABo4IBWjCCAVYwHwYDVR0jBBgwFoAUU3m/WqorSs9UgOHYm8Cd8rIDZssw # HQYDVR0OBBYEFBqh+GEZIA/DQXdFKI7RNV8GEgRVMA4GA1UdDwEB/wQEAwIBhjAS # BgNVHRMBAf8ECDAGAQH/AgEAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBEGA1UdIAQK # MAgwBgYEVR0gADBQBgNVHR8ESTBHMEWgQ6BBhj9odHRwOi8vY3JsLnVzZXJ0cnVz # dC5jb20vVVNFUlRydXN0UlNBQ2VydGlmaWNhdGlvbkF1dGhvcml0eS5jcmwwdgYI # KwYBBQUHAQEEajBoMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0LnVzZXJ0cnVzdC5j # b20vVVNFUlRydXN0UlNBQWRkVHJ1c3RDQS5jcnQwJQYIKwYBBQUHMAGGGWh0dHA6 # Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZIhvcNAQEMBQADggIBAG1UgaUzXRbh # tVOBkXXfA3oyCy0lhBGysNsqfSoF9bw7J/RaoLlJWZApbGHLtVDb4n35nwDvQMOt # 0+LkVvlYQc/xQuUQff+wdB+PxlwJ+TNe6qAcJlhc87QRD9XVw+K81Vh4v0h24URn # bY+wQxAPjeT5OGK/EwHFhaNMxcyyUzCVpNb0llYIuM1cfwGWvnJSajtCN3wWeDmT # k5SbsdyybUFtZ83Jb5A9f0VywRsj1sJVhGbks8VmBvbz1kteraMrQoohkv6ob1ol # cGKBc2NeoLvY3NdK0z2vgwY4Eh0khy3k/ALWPncEvAQ2ted3y5wujSMYuaPCRx3w # Xdahc1cFaJqnyTdlHb7qvNhCg0MFpYumCf/RoZSmTqo9CfUFbLfSZFrYKiLCS53x # OV5M3kg9mzSWmglfjv33sVKRzj+J9hyhtal1H3G/W0NdZT1QgW6r8NDT/LKzH7aZ # lib0PHmLXGTMze4nmuWgwAxyh8FuTVrTHurwROYybxzrF06Uw3hlIDsPQaof6aFB # nf6xuKBlKjTg3qj5PObBMLvAoGMs/FwWAKjQxH/qEZ0eBsambTJdtDgJK0kHqv3s # MNrxpy/Pt/360KOE2See+wFmd7lWEOEgbsausfm2usg1XTN2jvF8IAwqd661ogKG # uinutFoAsYyr4/kKyVRd1LlqdJ69SK6YMIIG9jCCBN6gAwIBAgIRAJA5f5rSSjoT # 8r2RXwg4qUMwDQYJKoZIhvcNAQEMBQAwfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgT # EkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UEChMP # U2VjdGlnbyBMaW1pdGVkMSUwIwYDVQQDExxTZWN0aWdvIFJTQSBUaW1lIFN0YW1w # aW5nIENBMB4XDTIyMDUxMTAwMDAwMFoXDTMzMDgxMDIzNTk1OVowajELMAkGA1UE # BhMCR0IxEzARBgNVBAgTCk1hbmNoZXN0ZXIxGDAWBgNVBAoTD1NlY3RpZ28gTGlt # aXRlZDEsMCoGA1UEAwwjU2VjdGlnbyBSU0EgVGltZSBTdGFtcGluZyBTaWduZXIg # IzMwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCQsnE/eeHUuYoXzMOX # wpCUcu1aOm8BQ39zWiifJHygNUAG+pSvCqGDthPkSxUGXmqKIDRxe7slrT9bCqQf # L2x9LmFR0IxZNz6mXfEeXYC22B9g480Saogfxv4Yy5NDVnrHzgPWAGQoViKxSxnS # 8JbJRB85XZywlu1aSY1+cuRDa3/JoD9sSq3VAE+9CriDxb2YLAd2AXBF3sPwQmnq # /ybMA0QfFijhanS2nEX6tjrOlNEfvYxlqv38wzzoDZw4ZtX8fR6bWYyRWkJXVVAW # DUt0cu6gKjH8JgI0+WQbWf3jOtTouEEpdAE/DeATdysRPPs9zdDn4ZdbVfcqA23V # zWLazpwe/OpwfeZ9S2jOWilh06BcJbOlJ2ijWP31LWvKX2THaygM2qx4Qd6S7w/F # 7KvfLW8aVFFsM7ONWWDn3+gXIqN5QWLP/Hvzktqu4DxPD1rMbt8fvCKvtzgQmjSn # C//+HV6k8+4WOCs/rHaUQZ1kHfqA/QDh/vg61MNeu2lNcpnl8TItUfphrU3qJo5t # /KlImD7yRg1psbdu9AXbQQXGGMBQ5Pit/qxjYUeRvEa1RlNsxfThhieThDlsdeAd # DHpZiy7L9GQsQkf0VFiFN+XHaafSJYuWv8at4L2xN/cf30J7qusc6es9Wt340pDV # SZo6HYMaV38cAcLOHH3M+5YVxQIDAQABo4IBgjCCAX4wHwYDVR0jBBgwFoAUGqH4 # YRkgD8NBd0UojtE1XwYSBFUwHQYDVR0OBBYEFCUuaDxrmiskFKkfot8mOs8UpvHg # MA4GA1UdDwEB/wQEAwIGwDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsG # AQUFBwMIMEoGA1UdIARDMEEwNQYMKwYBBAGyMQECAQMIMCUwIwYIKwYBBQUHAgEW # F2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMAgGBmeBDAEEAjBEBgNVHR8EPTA7MDmg # N6A1hjNodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29SU0FUaW1lU3RhbXBp # bmdDQS5jcmwwdAYIKwYBBQUHAQEEaDBmMD8GCCsGAQUFBzAChjNodHRwOi8vY3J0 # LnNlY3RpZ28uY29tL1NlY3RpZ29SU0FUaW1lU3RhbXBpbmdDQS5jcnQwIwYIKwYB # BQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IC # AQBz2u1ocsvCuUChMbu0A6MtFHsk57RbFX2o6f2t0ZINfD02oGnZ85ow2qxp1nRX # JD9+DzzZ9cN5JWwm6I1ok87xd4k5f6gEBdo0wxTqnwhUq//EfpZsK9OU67Rs4EVN # LLL3OztatcH714l1bZhycvb3Byjz07LQ6xm+FSx4781FoADk+AR2u1fFkL53VJB0 # ngtPTcSqE4+XrwE1K8ubEXjp8vmJBDxO44ISYuu0RAx1QcIPNLiIncgi8RNq2xgv # bnitxAW06IQIkwf5fYP+aJg05Hflsc6MlGzbA20oBUd+my7wZPvbpAMxEHwa+zwZ # gNELcLlVX0e+OWTOt9ojVDLjRrIy2NIphskVXYCVrwL7tNEunTh8NeAPHO0bR0ic # ImpVgtnyughlA+XxKfNIigkBTKZ58qK2GpmU65co4b59G6F87VaApvQiM5DkhFP8 # KvrAp5eo6rWNes7k4EuhM6sLdqDVaRa3jma/X/ofxKh/p6FIFJENgvy9TZntyeZs # Nv53Q5m4aS18YS/to7BJ/lu+aSSR/5P8V2mSS9kFP22GctOi0MBk0jpCwRoD+9Dt # miG4P6+mslFU1UzFyh8SjVfGOe1c/+yfJnatZGZn6Kow4NKtt32xakEnbgOKo3Tg # igmCbr/j9re8ngspGGiBoZw/bhZZSxQJCZrmrr9gFd2G9TGCBZMwggWPAgEBMIGQ # MHwxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO # BgNVBAcTB1NhbGZvcmQxGDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEkMCIGA1UE # AxMbU2VjdGlnbyBSU0EgQ29kZSBTaWduaW5nIENBAhATixZVeYWcHXmMNSvpIJGB # MA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJ # KoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQB # gjcCARUwLwYJKoZIhvcNAQkEMSIEIHYJWed9GzQexLWE6pUFFGmCGtEiHIbp59ll # ZKVzBf7lMA0GCSqGSIb3DQEBAQUABIIBADRfIcTJ7aZWYOQv4Uh7Zn9l89pp4gzc # 3ciEobmwZx3slsB1HFpde6baG37XBR5XBt+miugHW3wZl0HnF3NWKKxuLSPzNKJI # zpC9ka6yclIRokxmMuMjUTFYwIBCUqFdAM4qi+nsJFZsH0nycM8JoUtcljvJplLv # RDbj6bqa4pu69Is/Bv2/yAqPpK6To5rYh++a+YGBzPFi60LuafJ12ZOs5xtJh1ux # yGfSfgM+QgWk471I2Zbm0qUB6Dau123xMnya7ihdoBD4KAXlccSMGd8xz5Rjm5MG # gnpt98TOF5Ibec+x7y87XYn4z+bMNFeQLecH3jopCHi1pmMFMZgGZeOhggNMMIID # SAYJKoZIhvcNAQkGMYIDOTCCAzUCAQEwgZIwfTELMAkGA1UEBhMCR0IxGzAZBgNV # BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYGA1UE # ChMPU2VjdGlnbyBMaW1pdGVkMSUwIwYDVQQDExxTZWN0aWdvIFJTQSBUaW1lIFN0 # YW1waW5nIENBAhEAkDl/mtJKOhPyvZFfCDipQzANBglghkgBZQMEAgIFAKB5MBgG # CSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIyMTAyODAw # NDI0NlowPwYJKoZIhvcNAQkEMTIEMKRSSlX5cKCpVNOW0RrW15hwI1APVL7NmLxh # i8ZTTkRMRFbkxuMVElyq7Gi2Z43JaDANBgkqhkiG9w0BAQEFAASCAgBNVTis7Trk # r1EkpQ/HznO3Gn7PxmlKG/lumm7jgvWRs57Op6XSTvpuiAMp0c8SZXR6mD+sZiAw # zWd6OejZbcpjF6WnllpmGYuIPszMcKhdjkSckXXGSplt54eJfpoKofWkTxcZO3Ko # 2IHfOvnFNx0KWN/57ad9M//mN8ZzalgoEzLGhCdniVPQf5bF1a1cPFtOqPbNY8LX # nxpiD7uHupRPlMrmGEoXHhMAPi56BAnyTLSaJ2F7ekI+Y2xKw0gqazte2zhwPIqc # U7ufk5TDNySRGPWKRZMuFNqgUMSCvgIJ23ywgg1n2C8iy1P/rqzs9g2q29+UwJS+ # oL0E9lQV3U1p8XbX/VThkWTumUZL8n3/hG5xMIM/fERaptdvR6fjghSRr+uy0kSq # nsgBvo2To7EbuKPuq8Ip/fLEnyLPv1krBB2QUyD+2H/y4TPJDC6SqFoBL/ydWe8J # x2biHG19PBEl4nHMxjVfccybH5ot+Z2+7JqxtI8/0VpDxrpBpBfv3dOFdrkEGRrg # Bhb11lqavk6BFnk4Y7x/Ez2yv16j2xfOVtTmWTga74HYrFeuktzc/GyBysrkzQLj # RPthjZo4BmlQbpeUAIHJvPq63OcEDNjCTkglhouwixTyoXo124CJVAtiLl1wmWVy # zHkcuxMC9Hi4mZcEDynA56bSa4pea2nUlQ== # SIG # End signature block |