winget-cli

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

PackageManagementDscUtilities.psm1 (24136B)


      1 #
      2 # Copyright (c) Microsoft Corporation.
      3 #
      4 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      5 # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      6 # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      7 # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      8 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      9 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     10 # THE SOFTWARE.
     11 #
     12 #Helper functions for PackageManagement DSC Resouces
     13 
     14 Import-LocalizedData -BindingVariable LocalizedData -filename PackageManagementDscUtilities.strings.psd1
     15 
     16 
     17  Function ExtractArguments
     18 {
     19     <#
     20     .SYNOPSIS
     21 
     22     This is a helper function that extract the parameters from a given table. 
     23 
     24     .PARAMETER FunctionBoundParameters
     25     Specifies the hashtable containing a set of parameters to be extracted
     26 
     27     .PARAMETER ArgumentNames
     28     Specifies A list of arguments you want to extract
     29     #>
     30 
     31     Param
     32     (
     33         [parameter(Mandatory = $true)]
     34         [System.Collections.Hashtable]
     35         $FunctionBoundParameters,
     36 
     37         #A list of arguments you want to extract
     38         [parameter(Mandatory = $true)]
     39         [System.String[]]$ArgumentNames
     40     )
     41 
     42     Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))
     43 
     44     $returnValue=@{}
     45 
     46     foreach ($arg in $ArgumentNames)
     47     {
     48         if($FunctionBoundParameters.ContainsKey($arg))
     49         {
     50             #Found an argument we are looking for, so we add it to return collection
     51             $returnValue.Add($arg,$FunctionBoundParameters[$arg])
     52         }
     53     }
     54 
     55     return $returnValue
     56  }
     57 
     58 function ThrowError
     59 {
     60     <#
     61     .SYNOPSIS
     62 
     63     This is a helper function that throws an error. 
     64 
     65     .PARAMETER ExceptionName
     66     Specifies the type of errors, e.g. System.ArgumentException
     67 
     68     .PARAMETER ExceptionMessage
     69     Specifies the exception message
     70 
     71     .PARAMETER ErrorId
     72     Specifies an identifier of the error
     73 
     74     .PARAMETER ErrorCategory
     75     Specifies the error category, e.g., InvalidArgument defined in System.Management.Automation. 
     76 
     77     #>
     78 
     79     param
     80     (        
     81         [parameter(Mandatory = $true)]
     82         [ValidateNotNullOrEmpty()]
     83         [System.String]        
     84         $ExceptionName,
     85 
     86         [parameter(Mandatory = $true)]
     87         [ValidateNotNullOrEmpty()]
     88         [System.String]
     89         $ExceptionMessage,      
     90         
     91         [parameter(Mandatory = $true)]
     92         [ValidateNotNullOrEmpty()]
     93         [System.String]
     94         $ErrorId,
     95 
     96         [parameter(Mandatory = $true)]
     97         [ValidateNotNull()]
     98         [System.Management.Automation.ErrorCategory]
     99         $ErrorCategory
    100     )
    101     
    102     Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))
    103         
    104     $exception   = New-Object -TypeName $ExceptionName -ArgumentList $ExceptionMessage;
    105     $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList ($exception, $ErrorId, $ErrorCategory, $null)    
    106     throw $errorRecord
    107 }
    108 
    109 Function ValidateArgument
    110 {
    111     <#
    112     .SYNOPSIS
    113 
    114     This is a helper function that validates the arguments. 
    115 
    116     .PARAMETER Argument
    117     Specifies the argument to be validated.
    118 
    119     .PARAMETER Type
    120     Specifies the type of argument.
    121     #>
    122 
    123     [CmdletBinding()]
    124     param
    125     (
    126         [parameter(Mandatory = $true)]
    127         [ValidateNotNullOrEmpty()]
    128         [string]$Argument,
    129 
    130         [parameter(Mandatory = $true)]
    131         [ValidateNotNullOrEmpty()]
    132         [String]$Type,
    133 
    134         [parameter(Mandatory = $true)]
    135         [ValidateNotNullOrEmpty()]
    136         [String]$ProviderName
    137     )
    138 
    139     Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))
    140 
    141     switch ($Type)
    142     {
    143 
    144         "SourceUri"
    145         {
    146             # Checks whether given URI represents specific scheme
    147             # Most common schemes: file, http, https, ftp        
    148             $scheme =@('http', 'https', 'file', 'ftp')
    149  
    150             $newUri = $Argument -as [System.URI]  
    151             $returnValue = ($newUri -and $newUri.AbsoluteURI -and ($scheme -icontains $newuri.Scheme)) 
    152 
    153             if ($returnValue -eq $false)
    154             {                
    155                 ThrowError  -ExceptionName "System.ArgumentException" `
    156                             -ExceptionMessage ($LocalizedData.InValidUri -f $Argument)`
    157                             -ErrorId "InValidUri" `
    158                             -ErrorCategory InvalidArgument
    159             }
    160             
    161             #Check whether it's a valid uri. Wait for the response within 2mins.
    162             <#$result = Invoke-WebRequest $newUri -TimeoutSec 120 -UseBasicParsing -ErrorAction SilentlyContinue
    163 
    164             if ($null -eq (([xml]$result.Content).service ))
    165             {
    166                 ThrowError  -ExceptionName "System.ArgumentException" `
    167                             -ExceptionMessage ($LocalizedData.InValidUri -f $Argument)`
    168                             -ErrorId "InValidUri" `
    169                             -ErrorCategory InvalidArgument
    170             }#>
    171                                          
    172         }
    173         "DestinationPath"
    174         {
    175             $returnValue = Test-Path -Path $Argument
    176             if ($returnValue -eq $false)
    177             {
    178                 ThrowError  -ExceptionName "System.ArgumentException" `
    179                             -ExceptionMessage ($LocalizedData.PathDoesNotExist -f $Argument)`
    180                             -ErrorId "PathDoesNotExist" `
    181                             -ErrorCategory InvalidArgument
    182             }
    183         }
    184         "PackageSource"
    185         {      
    186             #Argument can be either the package source Name or source Uri.  
    187             
    188             #Check if the source is a uri 
    189             $uri = $Argument -as [System.URI]  
    190 
    191             if($uri -and $uri.AbsoluteURI) 
    192             {
    193                 # Check if it's a valid Uri
    194                 ValidateArgument -Argument $Argument -Type "SourceUri" -ProviderName $ProviderName
    195             }
    196             else
    197             {
    198                 #Check if it's a registered package source name                                                             
    199                 $source = PackageManagement\Get-PackageSource -Name $Argument -ProviderName $ProviderName -verbose -ErrorVariable ev
    200                 if ((-not $source) -or $ev) 
    201                 {
    202                     #We do not need to throw error here as Get-PackageSource does already
    203                     Write-Verbose -Message ($LocalizedData.SourceNotFound -f $source)                
    204                 }
    205             }
    206         }
    207         default
    208         {
    209             ThrowError  -ExceptionName "System.ArgumentException" `
    210                         -ExceptionMessage ($LocalizedData.UnexpectedArgument -f $Type)`
    211                         -ErrorId "UnexpectedArgument" `
    212                         -ErrorCategory InvalidArgument
    213         }
    214      }           
    215 }
    216 
    217 Function ValidateVersionArgument
    218 {
    219     <#
    220     .SYNOPSIS
    221 
    222     This is a helper function that does the version validation. 
    223 
    224     .PARAMETER RequiredVersion
    225     Provides the required version.
    226 
    227     .PARAMETER MaximumVersion
    228     Provides the maximum version.
    229 
    230     .PARAMETER MinimumVersion
    231     Provides the minimum version.
    232     #>
    233 
    234     [CmdletBinding()]
    235     param
    236     (
    237         [string]$RequiredVersion,
    238         [string]$MinimumVersion,
    239         [string]$MaximumVersion
    240 
    241     )
    242          
    243     Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))
    244 
    245     $isValid = $false
    246          
    247     #Case 1: No further check required if a user provides either none or one of these: minimumVersion, maximumVersion, and requiredVersion
    248     if ($PSBoundParameters.Count -le 1)
    249     {
    250         return $true
    251     }
    252 
    253     #Case 2: #If no RequiredVersion is provided 
    254     if (-not $PSBoundParameters.ContainsKey('RequiredVersion'))
    255     {
    256         #If no RequiredVersion, both MinimumVersion and MaximumVersion are provided. Otherwise fall into the Case #1
    257         $isValid = $PSBoundParameters['MinimumVersion'] -le $PSBoundParameters['MaximumVersion']
    258     }
    259     
    260     #Case 3: RequiredVersion is provided. 
    261     #        In this case  MinimumVersion and/or MaximumVersion also are provided. Otherwise fall in to Case #1.
    262     #        This is an invalid case. When RequiredVersion is provided, others are not allowed. so $isValid is false, which is already set in the init
    263 
    264     if ($isValid -eq $false)
    265     {        
    266         ThrowError  -ExceptionName "System.ArgumentException" `
    267                     -ExceptionMessage ($LocalizedData.VersionError)`
    268                     -ErrorId "VersionError" `
    269                     -ErrorCategory InvalidArgument
    270     }
    271 }
    272 
    273 Function Get-InstallationPolicy
    274 {
    275     <#
    276     .SYNOPSIS
    277 
    278     This is a helper function that retrives the InstallationPolicy from the given repository. 
    279 
    280     .PARAMETER RepositoryName
    281     Provides the repository Name.
    282 
    283     #>
    284 
    285     Param
    286     (
    287         [parameter(Mandatory = $true)]
    288         [ValidateNotNullOrEmpty()]
    289         [System.String]$RepositoryName
    290     )
    291 
    292     Write-Verbose -Message ($LocalizedData.CallingFunction -f $($MyInvocation.mycommand))
    293 
    294     $repositoryobj = PackageManagement\Get-PackageSource -Name $RepositoryName -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
    295 
    296     if ($repositoryobj)
    297     {      
    298         return $repositoryobj.IsTrusted
    299     }                  
    300 }
    301 
    302 # SIG # Begin signature block
    303 # MIInoQYJKoZIhvcNAQcCoIInkjCCJ44CAQExDzANBglghkgBZQMEAgEFADB5Bgor
    304 # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
    305 # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD+xe8u4YoS6UEO
    306 # jtW70wceL89huvuluOvdcbeefpOXLqCCDYEwggX/MIID56ADAgECAhMzAAACUosz
    307 # qviV8znbAAAAAAJSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
    308 # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
    309 # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
    310 # bmcgUENBIDIwMTEwHhcNMjEwOTAyMTgzMjU5WhcNMjIwOTAxMTgzMjU5WjB0MQsw
    311 # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
    312 # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
    313 # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
    314 # AQDQ5M+Ps/X7BNuv5B/0I6uoDwj0NJOo1KrVQqO7ggRXccklyTrWL4xMShjIou2I
    315 # sbYnF67wXzVAq5Om4oe+LfzSDOzjcb6ms00gBo0OQaqwQ1BijyJ7NvDf80I1fW9O
    316 # L76Kt0Wpc2zrGhzcHdb7upPrvxvSNNUvxK3sgw7YTt31410vpEp8yfBEl/hd8ZzA
    317 # v47DCgJ5j1zm295s1RVZHNp6MoiQFVOECm4AwK2l28i+YER1JO4IplTH44uvzX9o
    318 # RnJHaMvWzZEpozPy4jNO2DDqbcNs4zh7AWMhE1PWFVA+CHI/En5nASvCvLmuR/t8
    319 # q4bc8XR8QIZJQSp+2U6m2ldNAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
    320 # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUNZJaEUGL2Guwt7ZOAu4efEYXedEw
    321 # UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
    322 # ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDY3NTk3MB8GA1UdIwQYMBaAFEhu
    323 # ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
    324 # bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
    325 # Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
    326 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
    327 # MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAFkk3
    328 # uSxkTEBh1NtAl7BivIEsAWdgX1qZ+EdZMYbQKasY6IhSLXRMxF1B3OKdR9K/kccp
    329 # kvNcGl8D7YyYS4mhCUMBR+VLrg3f8PUj38A9V5aiY2/Jok7WZFOAmjPRNNGnyeg7
    330 # l0lTiThFqE+2aOs6+heegqAdelGgNJKRHLWRuhGKuLIw5lkgx9Ky+QvZrn/Ddi8u
    331 # TIgWKp+MGG8xY6PBvvjgt9jQShlnPrZ3UY8Bvwy6rynhXBaV0V0TTL0gEx7eh/K1
    332 # o8Miaru6s/7FyqOLeUS4vTHh9TgBL5DtxCYurXbSBVtL1Fj44+Od/6cmC9mmvrti
    333 # yG709Y3Rd3YdJj2f3GJq7Y7KdWq0QYhatKhBeg4fxjhg0yut2g6aM1mxjNPrE48z
    334 # 6HWCNGu9gMK5ZudldRw4a45Z06Aoktof0CqOyTErvq0YjoE4Xpa0+87T/PVUXNqf
    335 # 7Y+qSU7+9LtLQuMYR4w3cSPjuNusvLf9gBnch5RqM7kaDtYWDgLyB42EfsxeMqwK
    336 # WwA+TVi0HrWRqfSx2olbE56hJcEkMjOSKz3sRuupFCX3UroyYf52L+2iVTrda8XW
    337 # esPG62Mnn3T8AuLfzeJFuAbfOSERx7IFZO92UPoXE1uEjL5skl1yTZB3MubgOA4F
    338 # 8KoRNhviFAEST+nG8c8uIsbZeb08SeYQMqjVEmkwggd6MIIFYqADAgECAgphDpDS
    339 # AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
    340 # V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
    341 # IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
    342 # ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
    343 # MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
    344 # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
    345 # H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
    346 # AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
    347 # OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
    348 # 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
    349 # y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
    350 # 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
    351 # M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
    352 # X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
    353 # XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
    354 # 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
    355 # l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
    356 # RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
    357 # CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
    358 # BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
    359 # DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
    360 # 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
    361 # LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
    362 # Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
    363 # Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
    364 # Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
    365 # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
    366 # cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
    367 # XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
    368 # 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
    369 # 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
    370 # d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
    371 # Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
    372 # wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
    373 # aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
    374 # NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
    375 # xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
    376 # eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
    377 # r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
    378 # RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIZdjCCGXICAQEwgZUwfjELMAkG
    379 # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
    380 # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
    381 # b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAlKLM6r4lfM52wAAAAACUjAN
    382 # BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
    383 # BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgCZ2K5xbK
    384 # 27tyibqtMV5AHpyNN7lNy3nCNEZ+gshCPtAwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
    385 # AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
    386 # BgkqhkiG9w0BAQEFAASCAQCyqH1a6wilw9tLp1PBwdpHqB1Ami+jaRaJh0DD1pMa
    387 # 0Wv61B/88vYVxgOsFfBcBqZvVoQsYtlAjEcx/dg5Vamacy+LfO+8cm8uRq1uSXOq
    388 # gn3FDJ6Xy0j3pcU44/X1uzh8KoUaQJzNpcjLn8WpqABD0w7WfIA7A+o1yMZUcUsP
    389 # XejK8HpbV8Qrtz9okvl/hsK0zQuajckvm/odt+IgmwBr4yomlRFJ1AAqyKYp//4H
    390 # 7gPo5CBjh3H7wHn0mXMkES24T37LXmxxSncAShECTMvJMhiuM01TN6PziqI6ER0S
    391 # XFvKYHyfqwXvsfn71rcKAIWWjtWXz4a1mIZjkXJfUcf7oYIXADCCFvwGCisGAQQB
    392 # gjcDAwExghbsMIIW6AYJKoZIhvcNAQcCoIIW2TCCFtUCAQMxDzANBglghkgBZQME
    393 # AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB
    394 # MDEwDQYJYIZIAWUDBAIBBQAEIB/6Ll6BcpT6c9557ujfliR3kAn4lZRikouo1ahJ
    395 # /NiIAgZitNXDgmUYEzIwMjIwNzAxMjEwMDAwLjQ0OVowBIACAfSggdCkgc0wgcox
    396 # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
    397 # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p
    398 # Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg
    399 # RVNOOjhBODItRTM0Ri05RERBMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
    400 # cCBTZXJ2aWNloIIRVzCCBwwwggT0oAMCAQICEzMAAAGZyI+vrbZ9vosAAQAAAZkw
    401 # DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
    402 # b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
    403 # dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN
    404 # MjExMjAyMTkwNTE2WhcNMjMwMjI4MTkwNTE2WjCByjELMAkGA1UEBhMCVVMxEzAR
    405 # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
    406 # Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg
    407 # T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046OEE4Mi1FMzRGLTlE
    408 # REExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0G
    409 # CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC4E/lXXKMsy9rVa2a8bRb0Ar/Pj4+b
    410 # KiAgMgKayvCMFn3ddGof8eWFgJWp5JdKjWjrnmW1r9tHpcP2kFpjXp2Udrj55jt5
    411 # NYi1MERcoIo+E29XuCwFAMJftGdvsWea/OTQPIFsZEWqEteXdRncyVwct5xFzBIC
    412 # 1JWCdmfc7R59RMIyvgWjIz8356mweowkOstN1fe53KIJ8flrYILIQWsNRMOT3znA
    413 # GwIb9kyL54C6jZjFxOSusGYmVQ+Gr/qZQELw1ipx9s5jNP1LSpOpfTEBFu+y9KLN
    414 # BmMBARkSPpTFkGEyGSwGGgSdOi6BU6FPK+6urZ830jrRemK4JkIJ9tQhlGcIhAjh
    415 # cqZStn+38lRjVvrfbBI5EpI2NwlVIK2ibGW7sWeTAz/yNPNISUbQhGAJse/OgGj/
    416 # 1qz/Ha9mqfYZ8BHchNxn08nWkqyrjrKicQyxuD8mCatTrVSbOJYfQyZdHR9a4vgy
    417 # GeZEXBYQNAlIuB37QCOAgs/VeDU8M4dc/IlrTyC0uV1SS4Gk8zV+5X5eRu+XORN8
    418 # FWqzI6k/9y6cWwOWMK6aUN1XqLcaF/sm9rX84eKW2lhDc3C31WLjp8UOfOHZfPuy
    419 # y54xfilnhhCPy4QKJ9jggoqqeeEhCEfgDYjy+PByV/e5HDB2xHdtlL93wltAkI3a
    420 # Cxo84kVPBCa0OwIDAQABo4IBNjCCATIwHQYDVR0OBBYEFI26Vrg+nGWvrvIh0dQP
    421 # EonENR0QMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRY
    422 # MFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p
    423 # Y3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEF
    424 # BQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
    425 # a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAo
    426 # MSkuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgwDQYJKoZI
    427 # hvcNAQELBQADggIBAHGzWh29ibBNro3ns8E3EOHGsLB1Gzk90SFYUKBilIu4jDbR
    428 # 7qbvXNd8nnl/z5D9LKgw3T81jqy5tMiWp+p4jYBBk3PRx1ySqLUfhF5ZMWolRzW+
    429 # cQZGXV38iSmdAUG0CpR5x1rMdPIrTczVUFsOYGqmkoUQ/dRiVL4iAXJLCNTj4x3Y
    430 # wIQcCPt0ijJVinPIMAYzA8f99BbeiskyI0BHGAd0kGUX2I2/puYnlyS8toBnANjh
    431 # 21xgvEuaZ2dvRqvWk/i1XIlO67au/XCeMTvXhPOIUmq80U32Tifw3SSiBKTyir7m
    432 # oWH1i7H2q5QAnrBxuyy//ZsDfARDV/Atmj5jr6ATfRHDdUanQpeoBS+iylNU6RAR
    433 # u8g+TMCu/ZndZmrs9w+8galUIGg+GmlNk07fXJ58Oc+qFqgNAsNkMi+dSzKkWGA4
    434 # /klJFn0XichXL8+t7KOayXKGzQja6CdtCjisnyS8hbv4PKhaeMtf68wJWKKOs0tt
    435 # 2AJfYC5vSbH9ck8BGj2e/yQXEZEu88L5/fHK5XUk/IKXx3zaLkxXTSZ43Ea/WKXV
    436 # BzMasHZ3Pmny0moEekAXx1UhLNNYv4Vum33VirxSB6r/GKQxFSHu7yFfrWQpYyyD
    437 # H119TmhAedS8T1VabqdtO5ZP2E14TK82Vyxy3xEPelOo4dRIlhm7XY6k9B68MIIH
    438 # cTCCBVmgAwIBAgITMwAAABXF52ueAptJmQAAAAAAFTANBgkqhkiG9w0BAQsFADCB
    439 # iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl
    440 # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMp
    441 # TWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMTAwHhcNMjEw
    442 # OTMwMTgyMjI1WhcNMzAwOTMwMTgzMjI1WjB8MQswCQYDVQQGEwJVUzETMBEGA1UE
    443 # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
    444 # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ
    445 # Q0EgMjAxMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAOThpkzntHIh
    446 # C3miy9ckeb0O1YLT/e6cBwfSqWxOdcjKNVf2AX9sSuDivbk+F2Az/1xPx2b3lVNx
    447 # WuJ+Slr+uDZnhUYjDLWNE893MsAQGOhgfWpSg0S3po5GawcU88V29YZQ3MFEyHFc
    448 # UTE3oAo4bo3t1w/YJlN8OWECesSq/XJprx2rrPY2vjUmZNqYO7oaezOtgFt+jBAc
    449 # nVL+tuhiJdxqD89d9P6OU8/W7IVWTe/dvI2k45GPsjksUZzpcGkNyjYtcI4xyDUo
    450 # veO0hyTD4MmPfrVUj9z6BVWYbWg7mka97aSueik3rMvrg0XnRm7KMtXAhjBcTyzi
    451 # YrLNueKNiOSWrAFKu75xqRdbZ2De+JKRHh09/SDPc31BmkZ1zcRfNN0Sidb9pSB9
    452 # fvzZnkXftnIv231fgLrbqn427DZM9ituqBJR6L8FA6PRc6ZNN3SUHDSCD/AQ8rdH
    453 # GO2n6Jl8P0zbr17C89XYcz1DTsEzOUyOArxCaC4Q6oRRRuLRvWoYWmEBc8pnol7X
    454 # KHYC4jMYctenIPDC+hIK12NvDMk2ZItboKaDIV1fMHSRlJTYuVD5C4lh8zYGNRiE
    455 # R9vcG9H9stQcxWv2XFJRXRLbJbqvUAV6bMURHXLvjflSxIUXk8A8FdsaN8cIFRg/
    456 # eKtFtvUeh17aj54WcmnGrnu3tz5q4i6tAgMBAAGjggHdMIIB2TASBgkrBgEEAYI3
    457 # FQEEBQIDAQABMCMGCSsGAQQBgjcVAgQWBBQqp1L+ZMSavoKRPEY1Kc8Q/y8E7jAd
    458 # BgNVHQ4EFgQUn6cVXQBeYl2D9OXSZacbUzUZ6XIwXAYDVR0gBFUwUzBRBgwrBgEE
    459 # AYI3TIN9AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t
    460 # L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMI
    461 # MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMB
    462 # Af8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1Ud
    463 # HwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3By
    464 # b2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQRO
    465 # MEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2Vy
    466 # dHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MA0GCSqGSIb3DQEBCwUAA4IC
    467 # AQCdVX38Kq3hLB9nATEkW+Geckv8qW/qXBS2Pk5HZHixBpOXPTEztTnXwnE2P9pk
    468 # bHzQdTltuw8x5MKP+2zRoZQYIu7pZmc6U03dmLq2HnjYNi6cqYJWAAOwBb6J6Gng
    469 # ugnue99qb74py27YP0h1AdkY3m2CDPVtI1TkeFN1JFe53Z/zjj3G82jfZfakVqr3
    470 # lbYoVSfQJL1AoL8ZthISEV09J+BAljis9/kpicO8F7BUhUKz/AyeixmJ5/ALaoHC
    471 # gRlCGVJ1ijbCHcNhcy4sa3tuPywJeBTpkbKpW99Jo3QMvOyRgNI95ko+ZjtPu4b6
    472 # MhrZlvSP9pEB9s7GdP32THJvEKt1MMU0sHrYUP4KWN1APMdUbZ1jdEgssU5HLcEU
    473 # BHG/ZPkkvnNtyo4JvbMBV0lUZNlz138eW0QBjloZkWsNn6Qo3GcZKCS6OEuabvsh
    474 # VGtqRRFHqfG3rsjoiV5PndLQTHa1V1QJsWkBRH58oWFsc/4Ku+xBZj1p/cvBQUl+
    475 # fpO+y/g75LcVv7TOPqUxUYS8vwLBgqJ7Fx0ViY1w/ue10CgaiQuPNtq6TPmb/wrp
    476 # NPgkNWcr4A245oyZ1uEi6vAnQj0llOZ0dFtq0Z4+7X6gMTN9vMvpe784cETRkPHI
    477 # qzqKOghif9lwY1NNje6CbaUFEMFxBmoQtB1VM1izoXBm8qGCAs4wggI3AgEBMIH4
    478 # oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G
    479 # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUw
    480 # IwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMSYwJAYDVQQLEx1U
    481 # aGFsZXMgVFNTIEVTTjo4QTgyLUUzNEYtOUREQTElMCMGA1UEAxMcTWljcm9zb2Z0
    482 # IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsOAwIaAxUAku/zYujnqapN6BJ9
    483 # MJ5jtgDrlOuggYMwgYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu
    484 # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv
    485 # cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAN
    486 # BgkqhkiG9w0BAQUFAAIFAOZpNz0wIhgPMjAyMjA3MDExNzA1MDFaGA8yMDIyMDcw
    487 # MjE3MDUwMVowdzA9BgorBgEEAYRZCgQBMS8wLTAKAgUA5mk3PQIBADAKAgEAAgIR
    488 # FQIB/zAHAgEAAgIRszAKAgUA5mqIvQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgor
    489 # BgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBBQUA
    490 # A4GBAFPnj5aYeiMxAJhCBC3XyLLyNYf/OubzwI5EX68hNX+TC87/MMvxocAgfMk1
    491 # zLkJek8rPLlWGWf2oeGQYwyOQ0OMjD5YU4LnkVjN0l027+vwT2Rafc6RIWFiQbIG
    492 # RRBFfXDFgyuM97dVEf8ICSKsRlCCgFAV8JMNdND7JtN+xEb6MYIEDTCCBAkCAQEw
    493 # gZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT
    494 # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE
    495 # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAGZyI+vrbZ9vosA
    496 # AQAAAZkwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG9w0B
    497 # CRABBDAvBgkqhkiG9w0BCQQxIgQgkB6lWYhfhU1/DxjvSurvGL3RL89ss6hg4476
    498 # tkRKHTwwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBmfWn58qKN7WWpBTYO
    499 # rUO1BSCSnKPLC/G7wCOIc2JsfjCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMwEQYD
    500 # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
    501 # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
    502 # IFBDQSAyMDEwAhMzAAABmciPr622fb6LAAEAAAGZMCIEILRj7rb7JnV73e8wLbPq
    503 # CULQreKtMxdbry8TgOxho5edMA0GCSqGSIb3DQEBCwUABIICAKDNJpuPLp51vjon
    504 # QG0U01L3EGiaTgFCweFx7+x4vL5mVQ8JQBPaYJoy+34wnXF2U+0FwXW0SiTzzIHb
    505 # 0lFXKRkSMqCPnpW/1Oz474m9w95SvR86JgRC/kuJWtyD+TZg++zCafJeaLAXnuj3
    506 # LbpJlbNp7P6jW5Kz05J8xrz/Q+5g16VQ7RqqHImBKubLqAHEWrRcZiOXZZuIyDT4
    507 # 2L1vyDMMVHjGZfghQO5on6LsAmBmS2Ne7VteWUQxVWI/0yl1e81xjLzPFmiU0PrL
    508 # oWwI+fYVuKCYo5bwYQEhlVb5iVhNYYeNo0Voyh5Nnl75ClP/Xp/jeRb4hI9w6cdf
    509 # rlHWIhrKmNDb2Hmu7fVOF+A4O2j32EXG7sJPMNmboMFOeQf8eTcohw0LImS/eay/
    510 # 6vAcPeJw7jhHpJG20zDfusn4HDR1nD4oKTENvK7EIMSheRvsxAR1KS90sQLoPkyc
    511 # k5rkNTr8MHhvE4Nz5eeNfO7FIw2xPxwRST4p/hLes9xUw4H59TdSe9H0N92q118J
    512 # NNo/xo7e5d6lSLoonrL/TIYbvuoqM5PGw8HPS8ve09kV00MXTAGcnxpr2j1CzMAv
    513 # Y4i7KMGesQfOB5ounL187ZV/e+bhhHfLA0mgSnehHjXtQP/MNOvQ9/EXIK3/xcXg
    514 # mr4TmGPRZkuxUnXFoqN0pPOr9NOY
    515 # SIG # End signature block