PureStorage.AzureNative.Tools.psm1
. $PSScriptRoot/PureStorage.AzureNative.Util.ps1 # AVS resource ID for the dev environment $AvsResourceIdDev = "/subscriptions/96798833-9949-4913-a555-b0f2de70a444/resourceGroups/rg-krypton-sddc-network-dev-eastus/providers/Microsoft.AVS/privateClouds/krypton-private-cloud-dev" $AvsResourceIdQA = "/subscriptions/de8f0119-1ff4-4aa1-b5ee-7be650f2d750/resourceGroups/rg-krypton-avs-qa-eastus/providers/Microsoft.AVS/privateClouds/krypton-avs-qa-eastus" # Time window for the request (set to 60 minutes for now, can be adjusted as discussed) $TimeWindowInMinutes = 60 Function Get-SSLThumbprintFromCertString { param ( [String]$CertString ) $CertString = $CertString -replace '-----BEGIN CERTIFICATE-----', '' $CertString = $CertString -replace '-----END CERTIFICATE-----', '' $CertString = $CertString -replace '\s', '' $certificate = [Security.Cryptography.X509Certificates.X509Certificate2]::new([Convert]::FromBase64String($CertString)) $thumbprint = $certificate.Thumbprint $thumbprint = $thumbprint -replace '(.{2})', '$1:' $thumbprint = $thumbprint.TrimEnd(':') return $thumbprint } Function Register-RemotePlugin { param( [parameter(Mandatory = $true)] [VMware.Vim.ExtensionManager]$ExtensionMgr, [parameter(Mandatory = $true)] [String]$RegistrationUrl, [parameter(Mandatory = $true)] [String]$PluginVersion, [parameter(Mandatory = $true)] [String]$PluginThumbprint, [parameter(Mandatory = $false)] [String]$PluginCertificate ) #build extension to register. Will pull the SSL thumprint from the target address $description = New-Object VMware.Vim.Description $description.label = "Pure Storage Manager" $description.summary = "Pure Storage Management Plugin for the vSphere Client" $extensionClientInfo = New-Object VMware.Vim.ExtensionClientInfo $extensionClientInfo.Company = "Pure Storage, Inc." $extensionClientInfo.Description = $description $extensionClientInfo.Type = "vsphere-client-remote" $extensionClientInfo.Version = $PluginVersion $extensionClientInfo.Url = $RegistrationUrl $extensionServerInfo = New-Object VMware.Vim.ExtensionServerInfo $extensionServerInfo.AdminEmail = "noreply@purestorage.com" $extensionServerInfo.Company = "Pure Storage, Inc." $extensionServerInfo.Description = $description $extensionServerInfo.Url = $RegistrationUrl $extensionServerInfo.Type = "HTTPS" $extensionServerInfo.ServerThumbprint = $PluginThumbprint if ($PluginCertificate) { $extensionServerInfo.ServerCertificate = $PluginCertificate } $extensionSpec = New-Object VMware.Vim.Extension $extensionSpec.key = "com.purestorage.integrations.vmware.pureplugin" $extensionSpec.version = $PluginVersion $extensionSpec.Description = $description $extensionSpec.Client += $extensionClientInfo $extensionSpec.Server += $extensionServerInfo $extensionSpec.LastHeartbeatTime = get-date PrintLog "Registering new plugin" VERBOSE $ExtensionMgr.RegisterExtension($extensionSpec) } <# .SYNOPSIS This function unregisters the vSphere remote plugin extension from AVS .EXAMPLE Unregister-PureStorageAvsRemotePlugin .INPUTS No inputs are required .OUTPUTS None #> Function Unregister-PureStorageAvsRemotePlugin { [CmdletBinding()] [AVSAttribute(10, UpdatesSDDC = $false, AutomationOnly = $true)] param() $services = Get-View 'ServiceInstance' $extensionMgr = Get-View $services.Content.ExtensionManager $extensionMgr.UnregisterExtension("com.purestorage.integrations.vmware.pureplugin") PrintLog "PureStorage Remote Plugin un-registered successfully" INFO } <# .SYNOPSIS This function registers the vSphere remote plugin extension with AVS .PARAMETER RegistrationUrl vSphere remote plugin registration URL .PARAMETER PluginVersion The version of the plugin that is being registered .PARAMETER PluginCertificate The full SSL certificate of the vSphere remote plugin being registered, in pem format. i.e. -----BEGIN CERTIFICATE----- Base64–encoded certificate -----END CERTIFICATE----- .EXAMPLE Register-PureStorageAvsRemotePlugin -PluginHost 'https://10.20.30.40/plugin-manifest-location.zip' -PluginVersion '1.0.0' -PluginCertificate @" -----BEGIN CERTIFICATE----- Base64–encoded certificate -----END CERTIFICATE----- "@ .INPUTS vSphere remote plugin registration URL, version, and SSL certificate .OUTPUTS None #> Function Register-PureStorageAvsRemotePlugin { [CmdletBinding()] [AVSAttribute(10, UpdatesSDDC = $false, AutomationOnly = $true)] param( [Parameter( Mandatory = $true, HelpMessage = 'vSphere remote plugin registration URL')] [ValidateNotNull()] [String]$RegistrationUrl, [Parameter( Mandatory = $true, HelpMessage = 'version of the vSphere remote plugin being registered')] [ValidateNotNull()] [String]$PluginVersion, [Parameter( Mandatory = $true, HelpMessage = 'full SSL certificate of the vSphere remote plugin being registered')] [ValidateNotNull()] [String]$PluginCertificate ) $services = Get-View 'ServiceInstance' $extensionMgr = Get-View $services.Content.ExtensionManager $serverVersion = $services.Content.About.Version $CERT_SUPPORTED_VCENTER_VERSION = "8.0.2"; $thumbprint = Get-SSLThumbprintFromCertString -CertString $PluginCertificate if ([System.Version]$ServerVersion -ge [System.Version]$CERT_SUPPORTED_VCENTER_VERSION) { PrintLog "Host Version $serverVersion, registering using Remote Plugin public certificate" INFO Register-RemotePlugin -ExtensionMgr $extensionMgr -RegistrationUrl $RegistrationUrl -PluginVersion $PluginVersion -PluginThumbprint $thumbprint -PluginCertificate $PluginCertificate } else { PrintLog "Host Version $serverVersion, registering using Remote Plugin thumbprint" INFO Register-RemotePlugin -ExtensionMgr $extensionMgr -RegistrationUrl $RegistrationUrl -PluginVersion $PluginVersion -PluginThumbprint $thumbprint } PrintLog "PureStorage Remote Plugin (Version: $PluginVersion) registered successfully" INFO } <# .SYNOPSIS This function get the version of vSphere remote plugin extension with AVS .EXAMPLE Get-PureStorageAvsRemotePluginVersion .INPUTS No inputs are required .OUTPUTS Named Plugin Version stored under Key "PureStorageAvsPluginVersion" in NamedOutput if Plugin is registered #> Function Get-PureStorageAvsRemotePluginVersion { [CmdletBinding()] [AVSAttribute(10, UpdatesSDDC = $false, AutomationOnly = $true)] param() $services = Get-View 'ServiceInstance' $extensionMgr = Get-View $services.Content.ExtensionManager $version = ($extensionMgr.FindExtension("com.purestorage.integrations.vmware.pureplugin")).version if ($null -eq $version) { PrintLog "No Pure Storage Avs Remote Plugin Installed" WARNING } else { PrintLog "Pure Storage Avs Remote Plugin Version $version is currently installed" INFO } $NamedOutputs = @{} $NamedOutputs["PureStorageAvsPluginVersion"] = $version Set-Variable -Name NamedOutputs -Value $NamedOutputs -Scope Global } <# .SYNOPSIS Creates a new service account and assigns it a role with specific privileges. .DESCRIPTION The New-AvsServiceAccount function creates a new service account with the specified name and password. It then creates a role named 'PureStorageService' if it doesn't already exist, and assigns the role to the service account. The function also adds permissions for the service account on all VM hosts. .PARAMETER InitializationHandle The InitializationHandle is a base64 encoded JSON object that contains the following fields: { "data": "<Base64 encoded InitializationHandle>", "signature": "<Signature>" } .EXAMPLE $InitializationDataEnc = New-AvsServiceAccount -InitializationHandle "eyJkYXRh" This example decodes the InitializationHandle and validates the signature first. It then creates a new service account with the name defined in data.serviceAccountUsername wiht random password. It assigns the 'PureStorageService' role to the service account and adds permissions for the service account on all VM hosts. It returns an encrypted initialization data which is base64 encoded that contains the service account username, password and vSphere IP. #> function New-AvsServiceAccount { [CmdletBinding()] [AVSAttribute(10, UpdatesSDDC = $false, AutomationOnly = $true)] param( [Parameter(Mandatory = $true)] [string]$InitializationHandle ) # TODO: this function will be deprecated once we move to OBO fully. # Convert the InitializationHandle to a JSON object $DecodedInitializationHandle = ConvertFrom-Base64 -Base64Text $InitializationHandle | ConvertFrom-Json $Data = $DecodedInitializationHandle.data $Signature = $DecodedInitializationHandle.signature # Convert the data to a JSON object $DecodedData = ConvertFrom-Base64 -Base64Text $Data | ConvertFrom-Json # The data is a JSON object with the following structure: # { # "sddcResourceId": "string", # "requestDatetime": "string", # "ephemeralPublicKey": "string", # "serviceAccountUserame": "string" # } $SddcResourceId = $DecodedData.sddcResourceId $RequestDatetime = $DecodedData.requestDatetime $EphemeralPublicKey = $DecodedData.ephemeralPublicKey $AccountName = $DecodedData.serviceAccountUsername # Validate the prefix of the account name if (-not $AccountName.StartsWith($AccountNamePrefix)) { throw "The account name must start with '$AccountNamePrefix'" } # Make sure user doesn't try to use the data with a different SDDC if ($env:SddcResourceId -and $env:SddcResourceId -ne $SddcResourceId) { throw "The SDDC resource ID in the request does not match the current SDDC resource ID" } # Determine which keys to use based on the SDDC resource ID and test signature validity $keysToTest = @() if ($SddcResourceId -eq $AvsResourceIdDev -or $SddcResourceId -eq $AvsResourceIdQA) { $keysToTest += "$PSScriptRoot/avs_public_key_dev.pem" } if (-not [string]::IsNullOrEmpty($SddcResourceId)) { $keysToTest += "$PSScriptRoot/avs_public_key_prod.pem" } else { # Default to local test environment when AVS is not set $keysToTest += "$PSScriptRoot/avs_public_key_test.pem" } # Test signature validity with each key in the list $isValidSignature = $false foreach ($keyPath in $keysToTest) { $publicKey = Get-Content $keyPath -Raw $isValidSignature = Test-TextSignarure -Text $Data -Signature $Signature -PublicKey $publicKey if ($isValidSignature) { break } } if (-not $IsValidSignature) { throw "The data signature is not valid" } # Make sure the request date is in UTC if ($RequestDatetime.Kind -ne [System.DateTimeKind]::Utc) { throw "Request datetime must be in UTC" } # Validate the request datetime is within the time window Test-RequestDatetimeInUTC -RequestDatetime $RequestDatetime -TimeWindowInMinutes $TimeWindowInMinutes # Generate a random password for the service account $AccountPassword = New-RandomPassword # If the user already exists, update the password $User = Get-SsoPersonUser -Domain 'vsphere.local' | Where-Object { $_.Name -eq $AccountName } if ($User) { Write-Warning "User $AccountName already exists, updating the password" Set-SsoPersonUser -User $User -NewPassword $AccountPassword -ErrorAction Stop } else { $User = New-SsoPersonUser -UserName $AccountName -Password $AccountPassword -Description "Pure Storage Service Account" -ErrorAction Stop } # Create Role and assign Role to user $Role = Get-VIRole -Name $RoleName -ErrorAction SilentlyContinue if ($Role) { Write-Warning "Role $RoleName already exists, checking the role privileges against the required privileges" CompareAndUpdate-Privileges -Role $Role -RequiredPrivileges $PluginPrivileges } else { $Privileges = @() foreach ($priv in $PluginPrivileges) { Write-Debug "Adding privilege: $priv" $Privileges += Get-VIPrivilege -Id $priv } $Role = New-VIRole -Name $RoleName -Privilege $Privileges } $Account = Get-VIAccount -Domain $User.Domain | Where-Object { $_.Id -eq $AccountName } if (-not $Account) { throw "Failed to create account for user $User" } $RootFolder = Get-Folder -NoRecursion if (-not $RootFolder) { throw "Failed to retrieve root folder" } Write-Host "Adding permissions for Account $AccountName on $($RootFolder.Name) with Role $RoleName" New-VIPermission -Entity $RootFolder -Principal $Account -Role $Role -Propagate $true $vSphereIp = $Account.Server.ServiceUri.Host $InitializationData= @{ "serviceAccountUsername" = $AccountName "serviceAccountPassword" = $AccountPassword "vSphereIp" = $vSphereIp } | ConvertTo-Json try { $InitializationDataEnc = ConvertTo-EncryptedText -Text $InitializationData -PublicKey $EphemeralPublicKey } catch { throw "Failed to encrypt the initialization data with error: $_" } $NamedOutputs = @{} $NamedOutputs["InitializationDataEnc"] = $InitializationDataEnc Set-Variable -Name NamedOutputs -Value $NamedOutputs -Scope Global } <# .SYNOPSIS Removes a service account and the role assigned to it. .DESCRIPTION The Remove-AvsServiceAccount function removes the service account with "psserviceaccount" as the name prefix and an optional suffix in dev enviroment. It removes the account only when it has the "PureStorageService" role assigned to it. It also removes the role "PureStorageService" after the removal of the account. .PARAMETER Suffix The suffix of the account name which is only needed in dev enviroment and is empty in production. .EXAMPLE Remove-AvsServiceAccount -Suffix "1234" This example tries to remove a service account named "psserviceaccount1234". It checks if the account has the "PureStorageService" role assigned to it and removes the account and the role if it does. #> function Remove-AvsServiceAccount { [CmdletBinding()] [AVSAttribute(10, UpdatesSDDC = $false, AutomationOnly = $true)] param( [Parameter(Mandatory = $false)] [string]$Suffix ) # TODO: this function will be deprecated once we move to OBO fully. $AccountName = $AccountNamePrefix + $Suffix $User = Get-SsoPersonUser -Domain 'vsphere.local' | Where-Object { $_.Name -eq $AccountName } if ($User) { # Get the roles assigned to the user $name = "VSPHERE.LOCAL\" + $User.Name $accountPermissions = Get-VIPermission -Principal $name # Check if the user has the PureStorageService role $hasRole = $false foreach ($permission in $accountPermissions) { if ($permission.Role -eq $RoleName) { $hasRole = $true break } } if ($hasRole) { Write-Host "Removing user $AccountName" try { Remove-SsoPersonUser -User $User # Removes the permission (user and role association) Remove-VIPermission -Permission $accountPermissions -Confirm:$false Write-Output "Removed user $name from the role $RoleName." } catch { throw "Failed to remove user $AccountName with error: $_" } $Role = Get-VIRole -Name $RoleName if ($Role) { # Filter permissions by role name $Permissions = Get-VIPermission $accountWithRole = $Permissions | Where-Object { $_.Role -eq $RoleName } # Remove the PureStorageService role if there is no account assigned to it if ($accountWithRole.Count -eq 0) { Write-Host "Removing role $Role " try { Remove-VIRole -Role $Role -Force -Confirm:$false } catch { throw "Failed to remove role $Role with error: $_" } } else { Write-Warning "Role $RoleName still has other accounts assigned to it" } } else { Write-Warning "Failed to find role $Role" } } else { Write-Warning "This command is only supposed to remove the account with the role $RoleName" } } else { Write-Warning "Failed to find user $AccountName" } } <# .SYNOPSIS Establish or re-establish the Storagepool-AVS connection. .DESCRIPTION This function automates the end-to-end process of integrating an Azure Storage Pool with Azure VMware Solution (AVS). It performs a series of steps to securely enable the AVS connection, provision required service accounts, and finalize the integration. .PARAMETER StoragePoolResourceId The resource ID of the storage pool to call enable, finalize and get avs connection endpoint. .PARAMETER CorrelationId Optional. The Pure Storage Cloud correlation ID for the AVS connection. It's generated by Azure and used to track the request. .PARAMETER PureStorageBlockApiVersion Optional. The API version for the PureStorage.Block endpoint. (default: '2024-10-01-preview') .EXAMPLE Connect-StoragepoolToAvs -StoragePoolResourceId "1234" -CorrelationId "5678" -PureStorageBlockApiVersion "2024-10-01-preview" .INPUTS Storagepool resource Id, Pure Storage Cloud correlation ID, PureStorage.Block API version .OUTPUTS None #> function Connect-StoragepoolToAvs { [CmdletBinding()] [AVSAttribute(30, UpdatesSDDC = $false, AutomationOnly = $false)] param( [Parameter(Mandatory = $true)] [string]$StoragePoolResourceId, [Parameter(Mandatory = $false)] [string]$CorrelationId, [Parameter(Mandatory = $false)] [string]$PureStorageBlockApiVersion = '2024-10-01-preview' ) # STEP 1. Enable AVS Connection PrintLog "STEP 1: Enabling AVS connection" INFO if ($err = Invoke-EnableAvsConnection -StoragePoolResourceId $StoragePoolResourceId -CorrelationId $CorrelationId -PureStorageBlockApiVersion $PureStorageBlockApiVersion) { throw $err } $res = Get-AvsConnection -StoragePoolResourceId $StoragePoolResourceId ` -CorrelationId $CorrelationId ` -PureStorageBlockApiVersion $PureStorageBlockApiVersion $initializationHandle = $res.serviceInitializationHandle if ($null -ne $initializationHandle.sddcResourceId -and $null -ne $initializationHandle.serviceAccountUsername) { PrintLog "AVS connection initialization is completed" INFO } else { throw "Failed to enable AVS connection" } # STEP 2. Call Create Service Account Run Command $errorMessageSA = $null $errorReportingCodeSA = "error" $initializationData = @{} PrintLog "STEP 2: Creating a new AVS service account" INFO try { $initializationHandleJson = $initializationHandle | ConvertTo-Json -Depth 10 $initializationData = _New-AvsServiceAccount -InitializationHandle $initializationHandleJson } catch { $errorMessageSA = "AVS service account creation failed: $($_.Exception.Message)" PrintLog $errorMessageSA ERROR } if ($errorMessageSA) { $initializationData = @{ "serviceAccountUsername" = "" "serviceAccountPassword" = "" "vSphereIp" = $errorReportingCodeSA "vSphereCertificate" = $errorMessageSA } PrintLog "STEP 3: Handling error via '/finalizeAvsConnection' endpoint" INFO } else { # STEP 3. Finalize AVS Connection PrintLog "STEP 3: Finalizing Avs Connection" INFO } $err = Invoke-FinalizeAvsConnection -ServiceInitializationData $initializationData ` -StoragePoolResourceId $StoragePoolResourceId ` -CorrelationId $CorrelationId ` -PureStorageBlockApiVersion $PureStorageBlockApiVersion if ($err) { $msg = "Failed to finalize AVS connection with error: $err" throw $msg } PrintLog "AVS connection is established successfully" INFO } <# .SYNOPSIS Disable or remove an existing Storagepool–AVS connection in a controlled manner. .DESCRIPTION This function automates the end-to-end process of removing an Azure Storage Pool from Azure VMware Solution (AVS). It securely disables the AVS connection by calling the liftr API. .PARAMETER StoragePoolResourceId The resource ID of the storage pool to call disable avs connection endpoint. .PARAMETER CorrelationId Optional. The Pure Storage Cloud correlation ID for the AVS connection. It's generated by Azure and used to track the request. .PARAMETER PureStorageBlockApiVersion Optional. The API version for the PureStorage.Block endpoint. (default: '2024-10-01-preview') .EXAMPLE Disconnect-StoragepoolFromAvs -StoragePoolResourceId "1234" -CorrelationId "5678" -PureStorageBlockApiVersion "2024-10-01-preview" .INPUTS Storagepool resource Id, Pure Storage Cloud correlation ID, PureStorage.Block API version .OUTPUTS None #> Function Disconnect-StoragepoolFromAvs { [CmdletBinding()] [AVSAttribute(30, UpdatesSDDC = $false, AutomationOnly = $false)] param( [Parameter(Mandatory = $true)] [string]$StoragePoolResourceId, [Parameter(Mandatory = $false)] [string]$CorrelationId, [Parameter(Mandatory = $false)] [string]$PureStorageBlockApiVersion = '2024-10-01-preview' ) # Disable AVS Connection PrintLog "STEP: Disabling AVS connection" INFO $err = Invoke-DisableAvsConnection -StoragePoolResourceId $StoragePoolResourceId -CorrelationId $CorrelationId -PureStorageBlockApiVersion $PureStorageBlockApiVersion if ($err) { $msg = "Failed to disable AVS connection with error: $err" throw $msg } PrintLog "Storage pool is disconnected from AVS successfully" INFO } # SIG # Begin signature block # MIIuvwYJKoZIhvcNAQcCoIIusDCCLqwCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBl386gICU0Ap7m # WWwOxpq82ToA4QkhaOcc+SWTkTw5UKCCE2gwggVyMIIDWqADAgECAhB2U/6sdUZI # k/Xl10pIOk74MA0GCSqGSIb3DQEBDAUAMFMxCzAJBgNVBAYTAkJFMRkwFwYDVQQK # ExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENvZGUgU2ln # bmluZyBSb290IFI0NTAeFw0yMDAzMTgwMDAwMDBaFw00NTAzMTgwMDAwMDBaMFMx # CzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQD # EyBHbG9iYWxTaWduIENvZGUgU2lnbmluZyBSb290IFI0NTCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBALYtxTDdeuirkD0DcrA6S5kWYbLl/6VnHTcc5X7s # k4OqhPWjQ5uYRYq4Y1ddmwCIBCXp+GiSS4LYS8lKA/Oof2qPimEnvaFE0P31PyLC # o0+RjbMFsiiCkV37WYgFC5cGwpj4LKczJO5QOkHM8KCwex1N0qhYOJbp3/kbkbuL # ECzSx0Mdogl0oYCve+YzCgxZa4689Ktal3t/rlX7hPCA/oRM1+K6vcR1oW+9YRB0 # RLKYB+J0q/9o3GwmPukf5eAEh60w0wyNA3xVuBZwXCR4ICXrZ2eIq7pONJhrcBHe # OMrUvqHAnOHfHgIB2DvhZ0OEts/8dLcvhKO/ugk3PWdssUVcGWGrQYP1rB3rdw1G # R3POv72Vle2dK4gQ/vpY6KdX4bPPqFrpByWbEsSegHI9k9yMlN87ROYmgPzSwwPw # jAzSRdYu54+YnuYE7kJuZ35CFnFi5wT5YMZkobacgSFOK8ZtaJSGxpl0c2cxepHy # 1Ix5bnymu35Gb03FhRIrz5oiRAiohTfOB2FXBhcSJMDEMXOhmDVXR34QOkXZLaRR # kJipoAc3xGUaqhxrFnf3p5fsPxkwmW8x++pAsufSxPrJ0PBQdnRZ+o1tFzK++Ol+ # A/Tnh3Wa1EqRLIUDEwIrQoDyiWo2z8hMoM6e+MuNrRan097VmxinxpI68YJj8S4O # JGTfAgMBAAGjQjBAMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G # A1UdDgQWBBQfAL9GgAr8eDm3pbRD2VZQu86WOzANBgkqhkiG9w0BAQwFAAOCAgEA # Xiu6dJc0RF92SChAhJPuAW7pobPWgCXme+S8CZE9D/x2rdfUMCC7j2DQkdYc8pzv # eBorlDICwSSWUlIC0PPR/PKbOW6Z4R+OQ0F9mh5byV2ahPwm5ofzdHImraQb2T07 # alKgPAkeLx57szO0Rcf3rLGvk2Ctdq64shV464Nq6//bRqsk5e4C+pAfWcAvXda3 # XaRcELdyU/hBTsz6eBolSsr+hWJDYcO0N6qB0vTWOg+9jVl+MEfeK2vnIVAzX9Rn # m9S4Z588J5kD/4VDjnMSyiDN6GHVsWbcF9Y5bQ/bzyM3oYKJThxrP9agzaoHnT5C # JqrXDO76R78aUn7RdYHTyYpiF21PiKAhoCY+r23ZYjAf6Zgorm6N1Y5McmaTgI0q # 41XHYGeQQlZcIlEPs9xOOe5N3dkdeBBUO27Ql28DtR6yI3PGErKaZND8lYUkqP/f # obDckUCu3wkzq7ndkrfxzJF0O2nrZ5cbkL/nx6BvcbtXv7ePWu16QGoWzYCELS/h # AtQklEOzFfwMKxv9cW/8y7x1Fzpeg9LJsy8b1ZyNf1T+fn7kVqOHp53hWVKUQY9t # W76GlZr/GnbdQNJRSnC0HzNjI3c/7CceWeQIh+00gkoPP/6gHcH1Z3NFhnj0qinp # J4fGGdvGExTDOUmHTaCX4GUT9Z13Vunas1jHOvLAzYIwggbmMIIEzqADAgECAhB3 # vQ4DobcI+FSrBnIQ2QRHMA0GCSqGSIb3DQEBCwUAMFMxCzAJBgNVBAYTAkJFMRkw # FwYDVQQKExBHbG9iYWxTaWduIG52LXNhMSkwJwYDVQQDEyBHbG9iYWxTaWduIENv # ZGUgU2lnbmluZyBSb290IFI0NTAeFw0yMDA3MjgwMDAwMDBaFw0zMDA3MjgwMDAw # MDBaMFkxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxTaWduIG52LXNhMS8w # LQYDVQQDEyZHbG9iYWxTaWduIEdDQyBSNDUgQ29kZVNpZ25pbmcgQ0EgMjAyMDCC # AiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANZCTfnjT8Yj9GwdgaYw90g9 # z9DljeUgIpYHRDVdBs8PHXBg5iZU+lMjYAKoXwIC947Jbj2peAW9jvVPGSSZfM8R # Fpsfe2vSo3toZXer2LEsP9NyBjJcW6xQZywlTVYGNvzBYkx9fYYWlZpdVLpQ0LB/ # okQZ6dZubD4Twp8R1F80W1FoMWMK+FvQ3rpZXzGviWg4QD4I6FNnTmO2IY7v3Y2F # QVWeHLw33JWgxHGnHxulSW4KIFl+iaNYFZcAJWnf3sJqUGVOU/troZ8YHooOX1Re # veBbz/IMBNLeCKEQJvey83ouwo6WwT/Opdr0WSiMN2WhMZYLjqR2dxVJhGaCJedD # CndSsZlRQv+hst2c0twY2cGGqUAdQZdihryo/6LHYxcG/WZ6NpQBIIl4H5D0e6lS # TmpPVAYqgK+ex1BC+mUK4wH0sW6sDqjjgRmoOMieAyiGpHSnR5V+cloqexVqHMRp # 5rC+QBmZy9J9VU4inBDgoVvDsy56i8Te8UsfjCh5MEV/bBO2PSz/LUqKKuwoDy3K # 1JyYikptWjYsL9+6y+JBSgh3GIitNWGUEvOkcuvuNp6nUSeRPPeiGsz8h+WX4VGH # aekizIPAtw9FbAfhQ0/UjErOz2OxtaQQevkNDCiwazT+IWgnb+z4+iaEW3VCzYkm # eVmda6tjcWKQJQ0IIPH/AgMBAAGjggGuMIIBqjAOBgNVHQ8BAf8EBAMCAYYwEwYD # VR0lBAwwCgYIKwYBBQUHAwMwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU # 2rONwCSQo2t30wygWd0hZ2R2C3gwHwYDVR0jBBgwFoAUHwC/RoAK/Hg5t6W0Q9lW # ULvOljswgZMGCCsGAQUFBwEBBIGGMIGDMDkGCCsGAQUFBzABhi1odHRwOi8vb2Nz # cC5nbG9iYWxzaWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUwRgYIKwYBBQUHMAKG # Omh0dHA6Ly9zZWN1cmUuZ2xvYmFsc2lnbi5jb20vY2FjZXJ0L2NvZGVzaWduaW5n # cm9vdHI0NS5jcnQwQQYDVR0fBDowODA2oDSgMoYwaHR0cDovL2NybC5nbG9iYWxz # aWduLmNvbS9jb2Rlc2lnbmluZ3Jvb3RyNDUuY3JsMFYGA1UdIARPME0wQQYJKwYB # BAGgMgEyMDQwMgYIKwYBBQUHAgEWJmh0dHBzOi8vd3d3Lmdsb2JhbHNpZ24uY29t # L3JlcG9zaXRvcnkvMAgGBmeBDAEEATANBgkqhkiG9w0BAQsFAAOCAgEACIhyJsav # +qxfBsCqjJDa0LLAopf/bhMyFlT9PvQwEZ+PmPmbUt3yohbu2XiVppp8YbgEtfjr # y/RhETP2ZSW3EUKL2Glux/+VtIFDqX6uv4LWTcwRo4NxahBeGQWn52x/VvSoXMNO # Ca1Za7j5fqUuuPzeDsKg+7AE1BMbxyepuaotMTvPRkyd60zsvC6c8YejfzhpX0FA # Z/ZTfepB7449+6nUEThG3zzr9s0ivRPN8OHm5TOgvjzkeNUbzCDyMHOwIhz2hNab # XAAC4ShSS/8SS0Dq7rAaBgaehObn8NuERvtz2StCtslXNMcWwKbrIbmqDvf+28rr # vBfLuGfr4z5P26mUhmRVyQkKwNkEcUoRS1pkw7x4eK1MRyZlB5nVzTZgoTNTs/Z7 # KtWJQDxxpav4mVn945uSS90FvQsMeAYrz1PYvRKaWyeGhT+RvuB4gHNU36cdZytq # tq5NiYAkCFJwUPMB/0SuL5rg4UkI4eFb1zjRngqKnZQnm8qjudviNmrjb7lYYuA2 # eDYB+sGniXomU6Ncu9Ky64rLYwgv/h7zViniNZvY/+mlvW1LWSyJLC9Su7UpkNpD # R7xy3bzZv4DB3LCrtEsdWDY3ZOub4YUXmimi/eYI0pL/oPh84emn0TCOXyZQK8ei # 4pd3iu/YTT4m65lAYPM8Zwy2CHIpNVOBNNwwggcEMIIE7KADAgECAgxcuW61kTkv # +4t8zgQwDQYJKoZIhvcNAQELBQAwWTELMAkGA1UEBhMCQkUxGTAXBgNVBAoTEEds # b2JhbFNpZ24gbnYtc2ExLzAtBgNVBAMTJkdsb2JhbFNpZ24gR0NDIFI0NSBDb2Rl # U2lnbmluZyBDQSAyMDIwMB4XDTI0MDMxMTE0MDQxMloXDTI3MDMxMjE0MDQxMlow # cjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC1Nh # bnRhIENsYXJhMRswGQYDVQQKExJQdXJlIFN0b3JhZ2UsIEluYy4xGzAZBgNVBAMT # ElB1cmUgU3RvcmFnZSwgSW5jLjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAMCQrioSn48IvHpTg5dofsUYj/pNTDidwjYUrcxVu78NoyhSweG8FhcxDi/S # I40+8Fccl3D5ZoqpjkFnGhzSwmpxU3J4AP7+fdTZht9eWD1I5qKY07esYwdPDV4y # g+csPfdGPqI2XjRfT5UC3YkXQeUrX8KQZldD4KqvgxzpYcuBwsgHbTb/eArpi68Y # gFR2jgZGyZigfy8RuJMrL1thcBOe/VWjUyK21wVT8cuunBYFaStLHhsRBRMDcZBD # uTSGC4evE6oaCqlQbdMl9YFJ64mDQsKlCxrr7rmLVtcVzKGwmjp4b2xRwE+RmTh6 # JtrUL9Wx/3a3UzgAnDNimfwp85zoL48kyLtHqQ3FI8tVKGm+aBOgBZfmURoy7fbp # 4zKhGgqFbpOmILO16i4f999YsEEJQgIF3CtyH1R60/ZZWlDmoeeEgjAGrnd14muU # 5Hk3Cksr43uPUAg+fV78Y0fDV85ibm42ZwwPuz6MI4HhYNUlGzRwIQ31vjaGuAMW # HNqFKkcO0JuIeHQ/gFKPnYIxnGC9H9R4Kw/uMezqtnYJwGU2epB/ABl/w7U4NgU2 # ZOxWB5BFy4frZ3f+hNgbjFUjMaXnVFotOJxXntzjdSl4znw8DaKiC5ooChteZMIT # G9p078p/TUsOJQbUtFADSY1hsfCfB7t+gJSNt5peS9GOZIMVAgMBAAGjggGxMIIB # rTAOBgNVHQ8BAf8EBAMCB4AwgZsGCCsGAQUFBwEBBIGOMIGLMEoGCCsGAQUFBzAC # hj5odHRwOi8vc2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc2djY3I0NWNv # ZGVzaWduY2EyMDIwLmNydDA9BggrBgEFBQcwAYYxaHR0cDovL29jc3AuZ2xvYmFs # c2lnbi5jb20vZ3NnY2NyNDVjb2Rlc2lnbmNhMjAyMDBWBgNVHSAETzBNMEEGCSsG # AQQBoDIBMjA0MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNv # bS9yZXBvc2l0b3J5LzAIBgZngQwBBAEwCQYDVR0TBAIwADBFBgNVHR8EPjA8MDqg # OKA2hjRodHRwOi8vY3JsLmdsb2JhbHNpZ24uY29tL2dzZ2NjcjQ1Y29kZXNpZ25j # YTIwMjAuY3JsMBMGA1UdJQQMMAoGCCsGAQUFBwMDMB8GA1UdIwQYMBaAFNqzjcAk # kKNrd9MMoFndIWdkdgt4MB0GA1UdDgQWBBSzJ9KiDCa3UBiAajy+Iioj5kQjzDAN # BgkqhkiG9w0BAQsFAAOCAgEAHsFQixeQEcoHurq9NWSUt4S39Q+UGP6crmVq3Wwy # 9g23YbdWg+SgMxoLUqdoDfA4k4B6Dyoo0jEQzn2kxnsnT9lNHKrcZHH88dv0hjfi # H2qAiQWazPjS3LhK2J6nhpyipJPpyRaSQG4x4aG0NB2D4WUfUz9CGAYsERJGww/w # kTaaxMipttKDTaI1C49u1igDfRzIO+Q8vuyyBFLiYTno/df97xtjNC+KxxFhDhl/ # 4tawK6kwxaVzCMAfj48I67Wbo4DMH6pM1s19as7c3qp92i3MylGKsB6+u+o7UkbS # dLNkS4ALI33CJOUc+GoK3Nt5IXXCFJTQFHBXkBdAur3gmlXEm8vlNG/1Sbxr0H7T # 1e7ABGH/48o/+PeMLuCc72EeK5dJ4cX9NEQ3QnTsZHwGnYzjEOvOvP0s1c7yNsDb # cUHoIqQvb5xS5aqMU5G+8sdPQ1nwpPf7gGaEEbAVW4w51Pam42qeN9HIPa+ZinXn # sN02Kk1Qw0QwUqzaQy9W/gIquI0KOjw0LmoW9M/8S0lrjpEq2eEeUw9WQLhhUEIi # rFxGPtjqiCLiiS9CZ+kf2vWLJKUspkYv+OHT3q805Zg1dJsBFAzEYUFLb1mhmigD # EO9bsMorjECIL2ijE5zHtbGkalrrsPWu8tiDT/B7P9GSYzKfOOy4PoOIfWSK0Ixl # S7IxghqtMIIaqQIBATBpMFkxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9iYWxT # aWduIG52LXNhMS8wLQYDVQQDEyZHbG9iYWxTaWduIEdDQyBSNDUgQ29kZVNpZ25p # bmcgQ0EgMjAyMAIMXLlutZE5L/uLfM4EMA0GCWCGSAFlAwQCAQUAoIGcMBkGCSqG # SIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3 # AgEVMC8GCSqGSIb3DQEJBDEiBCCu0Ojqdlr8RmrjG21DZ9XERNz+vHpiqphQkjnM # 2PtoyjAwBgorBgEEAYI3AgEMMSIwIKACgAChGoAYaHR0cHM6Ly9wdXJlc3RvcmFn # ZS5jb20gMA0GCSqGSIb3DQEBAQUABIICADfOImxd660mTMEb9gTu8bsJZnocMkuu # FLjDt0RokVQ1vyEx69QV+bd64nb+AFXKBdMXd5uQo5FbQC02ZtmBdghcErEgtp7h # GkmY1lzTVrwj3W8+u1kk4NkLL/p8gjhWFz4TnJQlTR1GrcJLWpKup8kHxdRqpuDu # Z0+vYjV+8IsN5qXXbyqFL+6rgKcq3C68CVPjPRfj4rr/2DTswKlt7TcLHiWWKelG # G27pkFigm6j6DkQ2i9st4mxqmx+K83OrWSAMFA9llvji0yjgzYf/oUuPTxrYPPxo # 6jlHPkvi6fqHJgSjpkYagPTmVr5yEN322Ld6E9sZg8Yypamz5iu9SKGu37uqiZuP # bncAOOR31j1idAbf7s+wqLWqqZ46TOaJedyNpYhpfleqpexLg7/wa0i+uYOT9rTW # xNb/3GmMn3EARjoR4ryI3r2vkD6SMd87GRrKQDwW1GWlYKmC6TVf4GX/etaR4LpB # QE7h73Jwg+9s1lIQIb19EuwTqO1Lfnwns9vEPmjgZn8ej4A9byPl1yHdYLO+NjIZ # q2RFp0jxPbWRBxH9poQMsxcRneqCTBMFykbOCBoX9+L4bhwtm/EZcyMALMoD5naN # KOSZvQwN4SQ5ZeMD7a8gKhWQB0+Y2mQrBlnE4YZhdzppDYK1TRzE6YywagVvOAv0 # mZ2C/fr7B04QoYIXdjCCF3IGCisGAQQBgjcDAwExghdiMIIXXgYJKoZIhvcNAQcC # oIIXTzCCF0sCAQMxDzANBglghkgBZQMEAgEFADB3BgsqhkiG9w0BCRABBKBoBGYw # ZAIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIJBuktfAgp2fpZtJpvZI # pI6/0CcaDU8Eqq3PtnFo/LGeAhAfP5Ck469sooRrIz+oJABCGA8yMDI1MDYxMjE5 # MjkyN1qgghM6MIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC0cR2p5V0aDANBgkqhkiG # 9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4x # QTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQw # OTYgU0hBMjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAwMFoXDTM2MDkwMzIzNTk1 # OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYD # VQQDEzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1lc3RhbXAgUmVzcG9uZGVy # IDIwMjUgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANBGrC0Sxp7Q # 6q5gVrMrV7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA69HFTBdwbHwBSOeLpvPn # Z8ZN+vo8dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6wW2R6kSu9RJt/4QhguSss # p3qome7MrxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00Cll8pjrUcCV3K3E0zz09 # ldQ//nBZZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOMA3CoB/iUSROUINDT98ok # souTMYFOnHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmotuQhcg9tw2YD3w6ySSSu+ # 3qU8DD+nigNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1OpbybpMe46YceNA0LfNsn # qcnpJeItK/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeHVZlc4seAO+6d2sC26/PQ # PdP51ho1zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1roSrgHjSHlq8xymLnjCbS # LZ49kPmk8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSUROwnu7zER6EaJ+AliL7ojT # dS5PWPsWeupWs7NpChUk555K096V1hE0yZIXe+giAwW00aHzrDchIc2bQhpp0IoK # RR7YufAkprxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGVMIIBkTAMBgNVHRMBAf8E # AjAAMB0GA1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM6DAfBgNVHSMEGDAWgBTv # b1NK6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH/BAww # CgYIKwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQGCCsGAQUFBzABhhhodHRw # Oi8vb2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKGUWh0dHA6Ly9jYWNlcnRz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFtcGluZ1JTQTQw # OTZTSEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vY3Js # My5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3RhbXBpbmdSU0E0 # MDk2U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZI # AYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcEua5gQezRCESeY0ByIfjk # 9iJP2zWLpQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/YmRDfxT7C0k8FUFqNh+tsh # gb4O6Lgjg8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8AQ/UdKFOtj7YMTmqPO9m # zskgiC3QYIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/EABgfZXLWU0ziTN6R3ygQ # BHMUBaB5bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQVTeLni2nHkX/QqvXnNb+ # YkDFkxUGtMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gVutDojBIFeRlqAcuEVT0c # Ksb+zJNEsuEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85EE8LUkqRhoS3Y50OHgaY # 7T/lwd6UArb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hggt8l2Yv7roancJIFcboj # BcxlRcGG0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJgKf47CdxVRd/ndUlQ05o # xYy2zRWVFjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLvUxxVZE/rptb7IRE2lskK # PIJgbaP5t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7POGT75qaL6vdCvHlshtjd # NXOCIUjsarfNZzCCBrQwggScoAMCAQICEA3HrFcF/yGZLkBDIgw6SYYwDQYJKoZI # hvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZ # MBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1 # c3RlZCBSb290IEc0MB4XDTI1MDUwNzAwMDAwMFoXDTM4MDExNDIzNTk1OVowaTEL # MAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhE # aWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAy # MDI1IENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALR4MdMKmEFy # vjxGwBysddujRmh0tFEXnU2tjQ2UtZmWgyxU7UNqEY81FzJsQqr5G7A6c+Gh/qm8 # Xi4aPCOo2N8S9SLrC6Kbltqn7SWCWgzbNfiR+2fkHUiljNOqnIVD/gG3SYDEAd4d # g2dDGpeZGKe+42DFUF0mR/vtLa4+gKPsYfwEu7EEbkC9+0F2w4QJLVSTEG8yAR2C # QWIM1iI5PHg62IVwxKSpO0XaF9DPfNBKS7Zazch8NF5vp7eaZ2CVNxpqumzTCNSO # xm+SAWSuIr21Qomb+zzQWKhxKTVVgtmUPAW35xUUFREmDrMxSNlr/NsJyUXzdtFU # Ut4aS4CEeIY8y9IaaGBpPNXKFifinT7zL2gdFpBP9qh8SdLnEut/GcalNeJQ55Iu # wnKCgs+nrpuQNfVmUB5KlCX3ZA4x5HHKS+rqBvKWxdCyQEEGcbLe1b8Aw4wJkhU1 # JrPsFfxW1gaou30yZ46t4Y9F20HHfIY4/6vHespYMQmUiote8ladjS/nJ0+k6Mvq # zfpzPDOy5y6gqztiT96Fv/9bH7mQyogxG9QEPHrPV6/7umw052AkyiLA6tQbZl1K # hBtTasySkuJDpsZGKdlsjg4u70EwgWbVRSX1Wd4+zoFpp4Ra+MlKM2baoD6x0VR4 # RjSpWM8o5a6D8bpfm4CLKczsG7ZrIGNTAgMBAAGjggFdMIIBWTASBgNVHRMBAf8E # CDAGAQH/AgEAMB0GA1UdDgQWBBTvb1NK6eQGfHrK4pBW9i/USezLTjAfBgNVHSME # GDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0l # BAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRw # Oi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8 # MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0 # ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATAN # BgkqhkiG9w0BAQsFAAOCAgEAF877FoAc/gc9EXZxML2+C8i1NKZ/zdCHxYgaMH9P # w5tcBnPw6O6FTGNpoV2V4wzSUGvI9NAzaoQk97frPBtIj+ZLzdp+yXdhOP4hCFAT # uNT+ReOPK0mCefSG+tXqGpYZ3essBS3q8nL2UwM+NMvEuBd/2vmdYxDCvwzJv2sR # UoKEfJ+nN57mQfQXwcAEGCvRR2qKtntujB71WPYAgwPyWLKu6RnaID/B0ba2H3LU # iwDRAXx1Neq9ydOal95CHfmTnM4I+ZI2rVQfjXQA1WSjjf4J2a7jLzWGNqNX+DF0 # SQzHU0pTi4dBwp9nEC8EAqoxW6q17r0z0noDjs6+BFo+z7bKSBwZXTRNivYuve3L # 2oiKNqetRHdqfMTCW/NmKLJ9M+MtucVGyOxiDf06VXxyKkOirv6o02OoXN4bFzK0 # vlNMsvhlqgF2puE6FndlENSmE+9JGYxOGLS/D284NHNboDGcmWXfwXRy4kbu4QFh # Om0xJuF2EZAOk5eCkhSxZON3rGlHqhpB/8MluDezooIs8CVnrpHMiD2wL40mm53+ # /j7tFaxYKIqL0Q4ssd8xHZnIn/7GELH3IdvG2XlM9q7WP/UwgOkw/HQtyRN62JK4 # S1C8uw3PdBunvAZapsiI5YKdvlarEvf8EA+8hcpSM9LHJmyrxaFtoza2zNaQ9k+5 # t1wwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUA # MGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT # EHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQg # Um9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNV # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp # Y2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIw # DQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqcl # LskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YF # PFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceIt # DBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZX # V59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1 # ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2Tox # RJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdp # ekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF # 30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9 # t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQ # UOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXk # aS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1Ud # DgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEt # UYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsG # AQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0 # dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD # QS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29t # L0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAw # DQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979XB72arKGHLOyF # XqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4kvFIDyE7QKt76 # LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8L # punyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2 # CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si # /xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN8MIIDeAIBATB9 # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcgUlNBNDA5NiBTSEEy # NTYgMjAyNSBDQTECEAqA7xhLjfEFgtHEdqeVdGgwDQYJYIZIAWUDBAIBBQCggdEw # GgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNTA2 # MTIxOTI5MjdaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFN1iMKyGCi0wa9o4sWh5 # UjAH+0F+MC8GCSqGSIb3DQEJBDEiBCCZkGk96NF1wRxnx1jAalap1LAgV7nNXQbw # yoFZ/u9OSTA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCBKoD+iLNdchMVck4+Cjmdr # nK7Ksz/jbSaaozTxRhEKMzANBgkqhkiG9w0BAQEFAASCAgAYnTtHEQdo/YqTi90m # B3VK8F6aJYrc37V8v9TUcJ5jb+aru3B2bctn6JbIM7uO5E0LmsLQSvXtVpGV+iUk # lHUDvyKBDRULdtaTUeY4PfLxxJR6ZcuEDVMLyyyzBr2v0TcyTmy1LpoEz6ns4kHt # IRQ3zgwBl3P3UF7fCRO3Y454dC9TKkPJiPfD0/bPAdULUWFIGDZJgI2T+/r9kI+t # BEucv/9pvXqgGsSIlyys5v9VenaerX+CnSecFcNUsJvPLDrAx7Uo3tRFanpwO6WV # L52G1bZiScYkVrHQ7ypGH3Hh4VUTfFUFx26k/eb/NSXH2hR2uMubuFC1J86NKj8h # bZTB6R7CsVBj8/8MvrbtVT69wZE5lRUTc4mpUjO4VIuQsIFrNulky8GWkxDQD4rL # NURwOS1b2914wbodTZzdqdcFqG38XA26ItHmyNMm3x12Pc6BBDrSgL332AC6ntB2 # eDV4one1uNMIIU8eW56N1QSNP74KS7S6JMpOAgIbhBkjSkwVs94358TjkP5cX9rB # EWRSU+cBGsF4CnfBtLl7cC/+Qv8RQalPbwUQ01jkmY6C1Z87e46e1Onj2Wx/Gr8M # tUpSBHC7B3D7hlFw9TTe76umijMcz+pOtdEZianMfDin5I/+X+41iei4A7onMtIy # vWYQULaYWVzuXn03SIg7iEuDHQ== # SIG # End signature block |