DSCResources/VE_XD7Common/VE_XD7Common.psm1
Import-LocalizedData -BindingVariable localized -FileName VE_XD7Common.Resources.psd1; #region Private Functions function AddInvokeScriptBlockCredentials { <# .SYNOPSIS Adds the required Invoke-Command parameters for loopback processing with CredSSP. #> [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory)] [System.Collections.Hashtable] $Hashtable, [Parameter(Mandatory)] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential ) process { $Hashtable['ComputerName'] = $env:COMPUTERNAME; $Hashtable['Credential'] = $Credential; $Hashtable['Authentication'] = 'Credssp'; } } #end function AddInvokeScriptBlockCredentials function GetHostname { [CmdletBinding()] [OutputType([System.String])] param ( ) process { $globalIpProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties(); if ($globalIpProperties.DomainName) { return '{0}.{1}' -f $globalIpProperties.HostName, $globalIpProperties.DomainName; } else { return $globalIpProperties.HostName; } } #end process } #end function GetHostname function GetRegistryValue { <# .SYNOPSIS Returns a registry string value. .NOTES This is an internal function and shouldn't be called from outside. This function enables registry calls to be unit tested. #> [CmdletBinding(SupportsShouldProcess)] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSShouldProcess', '')] [OutputType([System.String])] param ( # Registry key name/path to query. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [Alias('Path')] [System.String] $Key, # Registry value to return. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $Name ) process { $itemProperty = Get-ItemProperty -Path $Key -Name $Name -ErrorAction SilentlyContinue; if ($itemProperty.$Name) { return $itemProperty.$Name; } return ''; } } #end function GetRegistryValue function StartWaitProcess { <# .SYNOPSIS Starts and waits for a process to exit. .NOTES This is an internal function and shouldn't be called from outside. #> [CmdletBinding(SupportsShouldProcess)] [OutputType([System.Int32])] param ( # Path to process to start. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $FilePath, # Arguments (if any) to apply to the process. [Parameter()] [AllowNull()] [System.String[]] $ArgumentList, # Credential to start the process as. [Parameter()] [AllowNull()] [System.Management.Automation.PSCredential] [System.Management.Automation.CredentialAttribute()] $Credential, # Working directory [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $WorkingDirectory = (Split-Path -Path $FilePath -Parent) ) process { $startProcessParams = @{ FilePath = $FilePath; WorkingDirectory = $WorkingDirectory; NoNewWindow = $true; PassThru = $true; }; $displayParams = '<None>'; if ($ArgumentList) { $displayParams = [System.String]::Join(' ', $ArgumentList); $startProcessParams['ArgumentList'] = $ArgumentList; } Write-Verbose ($localized.StartingProcess -f $FilePath, $displayParams); if ($Credential) { Write-Verbose ($localized.StartingProcessAs -f $Credential.UserName); $startProcessParams['Credential'] = $Credential; } if ($PSCmdlet.ShouldProcess($FilePath, 'Start Process')) { $process = Start-Process @startProcessParams -ErrorAction Stop; } if ($PSCmdlet.ShouldProcess($FilePath, 'Wait Process')) { Write-Verbose ($localized.ProcessLaunched -f $process.Id); Write-Verbose ($localized.WaitingForProcessToExit -f $process.Id); $process.WaitForExit(); $exitCode = [System.Convert]::ToInt32($process.ExitCode); Write-Verbose ($localized.ProcessExited -f $process.Id, $exitCode); } return $exitCode; } #end process } #end function StartWaitProcess function FindXDModule { <# .SYNOPSIS Locates a module's manifest (.psd1) file. #> [CmdletBinding()] [OutputType([System.String])] param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Name = 'Citrix.XenDesktop.Admin', [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Path = 'C:\Program Files\Citrix\XenDesktopPoshSdk\Module\Citrix.XenDesktop.Admin.V1' ) process { if (Test-Path -Path $Path) { $module = Get-ChildItem -Path $Path -Include "$Name.psd1" -File -Recurse if (-not $module) { # If we have no .psd1 file, search for a .psm1 (for StoreFront) $module = Get-ChildItem -Path $Path -Include "$Name.psm1" -File -Recurse } } if (-not $module -and (Test-Path -Path 'C:\Program Files\Citrix\PowerShellModules' -PathType Container)) { ## Try searching new (1912+) later module location (#48) $module = Get-ChildItem -Path 'C:\Program Files\Citrix\PowerShellModules' -Include "$Name.psd1" -File -Recurse } return $module.FullName } } function TestXDModule { <# .SYNOPSIS Tests whether Powershell modules or Snapin are available/registered. #> [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Name = 'Citrix.XenDesktop.Admin', [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Path = 'C:\Program Files\Citrix\XenDesktopPoshSdk\Module\Citrix.XenDesktop.Admin.V1', [Parameter()] [System.Management.Automation.SwitchParameter] $IsSnapin ) process { if ($IsSnapin) { if (Get-PSSnapin -Name $Name -Registered -ErrorAction SilentlyContinue) { return $true } } ## If testing a snap-in and it fails, try resolving it as a module (#18) if (FindXDModule -Name $Name -Path $Path) { return $true } return $false } } function AssertXDModule { <# .SYNOPSIS Asserts whether all the specified modules are present, throwing if not. #> [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String[]] $Name, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $Path = 'C:\Program Files\Citrix\XenDesktopPoshSdk\Module\Citrix.XenDesktop.Admin.V1', [Parameter()] [System.Management.Automation.SwitchParameter] $IsSnapin ) process { foreach ($moduleName in $Name) { if (-not (TestXDModule -Name $moduleName -Path $Path -IsSnapin:$IsSnapin)) { ThrowInvalidProgramException -ErrorId $moduleName -ErrorMessage $localized.XenDesktopSDKNotFoundError } } } } function AssertModule { <# .SYNOPSIS Asserts whether all the specified modules are present, throwing if not. #> [CmdletBinding()] param ( [Parameter()] [ValidateNotNullOrEmpty()] [System.String[]] $Name ) process { foreach ($moduleName in $Name) { if (-not (Get-Module -Name $moduleName -ListAvailable -ErrorAction SilentlyContinue)) { ThrowInvalidProgramException -ErrorId $moduleName -ErrorMessage $localized.XenDesktopModuleNotFoundError } } } } function Add-PSSnapin { <# .SYNOPSIS Proxy function to load Citrix PowerShell snapins within a module at the global scope. #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidOverwritingBuiltInCmdlets', '')] param ( [Parameter(Mandatory, ValueFromPipeline, ValueFromPipelineByPropertyName)] [System.String[]] $Name ) process { foreach ($snapinName in $Name) { $modulePath = Join-Path -Path $PSScriptRoot -ChildPath "$snapinName.psm1" Import-Module -Name $modulePath -Global -Verbose:$false } } } function GetXDBrokerMachine { <# .SYNOPSIS Searches for a registered Citrix XenDesktop machine by name. #> [CmdletBinding()] param ( [Parameter(Mandatory)] [System.String] $MachineName ) process { if ($MachineName.Contains('.')) { ## Attempt to locate the machine by FQDN $brokerMachine = Get-BrokerMachine -DNSName $MachineName -ErrorAction SilentlyContinue; } elseif ($MachineName.Contains('\')) { ## Otherwise attempt to locate the machine by DomainName\NetBIOSName $brokerMachine = Get-BrokerMachine -MachineName $MachineName -ErrorAction SilentlyContinue; } else { ## Failing all else, perform a wildcard search $brokerMachine = Get-BrokerMachine -MachineName "*\$MachineName" -ErrorAction SilentlyContinue; } if ($null -eq $brokerMachine) { Write-Error -ErrorId 'MachineNotFound' -Message ($localized.MachineNotFoundError -f $Machine); return; } elseif (($brokerMachine).Count -gt 1) { Write-Error -ErrorId 'AmbiguousMachineReference' -Message ($localized.AmbiguousMachineReferenceError -f $MachineName); return; } else { return $brokerMachine; } } #end process } #end function GetXDBrokerMachine function TestXDMachineIsExistingMember { <# .SYNOPSIS Tests whether a machine is an existing member of a list of FQDN machine members. #> [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory)] [System.String] $MachineName, [Parameter()] [System.String[]] $ExistingMembers ) process { if ((-not $MachineName.Contains('\')) -and (-not $MachineName.Contains('.'))) { Write-Warning -Message ($localized.MachineNameNotFullyQualifiedWarning -f $MachineName); $netBIOSName = $MachineName; } elseif ($MachineName.Contains('\')) { $netBIOSName = $MachineName.Split('\')[1]; } if ($ExistingMembers -contains $MachineName) { return $true; } elseif ($ExistingMembers -like '{0}.*' -f $netBIOSName) { return $true; } else { return $false; } } #end process } #end function TestXDMachine function TestXDMachineMembership { <# .SYNOPSIS Provides a centralised function to test whether machine membership of a Machine Catalog or Delivery Group are correct - evaluating FQDNs, DOMAINNAME\NETBIOS and NETBIOS name formats. #> [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory)] [System.String[]] $RequiredMembers, [Parameter(Mandatory)] [ValidateSet('Present','Absent')] [System.String] $Ensure, [Parameter()] [System.String[]] $ExistingMembers ) process { $isInCompliance = $true; foreach ($member in $RequiredMembers) { if (TestXDMachineIsExistingMember -MachineName $member -ExistingMembers $ExistingMembers) { if ($Ensure -eq 'Absent') { Write-Verbose ($localized.SurplusMachineReference -f $member); $isInCompliance = $false; } } else { if ($Ensure -eq 'Present') { Write-Verbose ($localized.MissingMachineReference -f $member); $isInCompliance = $false; } } } #end foreach member return $isInCompliance; } #end process } #end function TestXDMachineMembers function ResolveXDBrokerMachine { <# .SYNOPSIS Returns a machine machine from an existing collection of Citrix XenDesktop machines assigned to a Machine Catalog or Delivery Group #> [CmdletBinding()] [OutputType([System.String])] param ( [Parameter(Mandatory)] [System.String] $MachineName, [Parameter(Mandatory)] [AllowNull()] [System.Object[]] $BrokerMachines ) process { foreach ($machine in $brokerMachines) { ## Try matching on DNS name if (($machine.DNSName -eq $MachineName) -or ($machine.MachineName -eq $MachineName)) { return $machine; } elseif ((-not $MachineName.Contains('\')) -and ($machine.MachineName -match '^\S+\\{0}$' -f $MachineName)) { ## Try matching based on DOMAIN\NETBIOS name return $machine } } #end foreach machine return $null; } #end process } #end function ResolveXDBrokerMachine function ThrowInvalidOperationException { <# .SYNOPSIS Throws terminating error of category NotInstalled with specified errorId and errorMessage. #> [CmdletBinding()] param( [Parameter(Mandatory)] [System.String] $ErrorId, [Parameter(Mandatory)] [System.String] $ErrorMessage ) process { $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidArgument; $exception = New-Object -TypeName 'System.InvalidOperationException' -ArgumentList $ErrorMessage; $errorRecord = New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList $exception, $ErrorId, $errorCategory, $null; throw $errorRecord; } #end process } #end function ThrowInvalidOperationException function ThrowInvalidProgramException { <# .SYNOPSIS Throws terminating error of category NotInstalled with specified errorId and errorMessage. #> [CmdletBinding()] param( [Parameter(Mandatory)] [System.String] $ErrorId, [Parameter(Mandatory)] [System.String] $ErrorMessage ) process { $errorCategory = [System.Management.Automation.ErrorCategory]::NotInstalled; $exception = New-Object -TypeName 'System.InvalidProgramException' -ArgumentList $ErrorMessage; $errorRecord = New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList $exception, $ErrorId, $errorCategory, $null; throw $errorRecord; } #end process } #end function ThrowInvalidProgramException function ThrowOperationCanceledException { <# .SYNOPSIS Throws terminating error of category InvalidOperation with specified errorId and errorMessage. #> param( [Parameter(Mandatory)] [System.String] $ErrorId, [Parameter(Mandatory)] [System.String] $ErrorMessage ) process { $errorCategory = [System.Management.Automation.ErrorCategory]::InvalidOperation; $exception = New-Object -TypeName 'System.OperationCanceledException' -ArgumentList $ErrorMessage; $errorRecord = New-Object -TypeName 'System.Management.Automation.ErrorRecord' -ArgumentList $exception, $ErrorId, $errorCategory, $null; throw $errorRecord; } #end process } #end function ThrowOperationCanceledException function TestXDInstalledRole { <# .SYNOPSIS Tests whether a Citrix XenDesktop 7.x role is installed. #> [CmdletBinding()] [OutputType([System.Boolean])] param ( ## Citrix XenDesktop 7.x role to query. [Parameter(Mandatory)] [ValidateSet('Controller','Studio','Storefront','Licensing','Director','DesktopVDA','SessionVDA','FAS')] [System.String[]] $Role ) process { $installedRoles = GetXDInstalledRole -Role $Role; foreach ($r in $Role) { if ($installedRoles -notcontains $r) { return $false } } return $true } } function GetXDInstalledRole { <# .SYNOPSIS Returns installed Citrix XenDesktop 7.x installed products. #> [CmdletBinding()] [OutputType([System.String[]])] param ( ## Citrix XenDesktop 7.x role to query. [Parameter(Mandatory)] [ValidateSet('Controller','Studio','Storefront','Licensing','Director','DesktopVDA','SessionVDA','FAS')] [System.String[]] $Role ) process { $installedProducts = Get-ItemProperty 'HKLM:\SOFTWARE\Classes\Installer\Products\*' -ErrorAction SilentlyContinue | Where-Object { $_.ProductName -like '*Citrix*' -and $_.ProductName -notlike '*snap-in' } | Select-Object -ExpandProperty ProductName $installedRoles = @() foreach ($r in $Role) { switch ($r) { 'Controller' { $filter = 'Citrix Broker Service' } 'Studio' { $filter = 'Citrix Studio' } 'Storefront' { $filter = 'Citrix Storefront$' } 'Licensing' { $filter = 'Citrix Licensing' } 'Director' { $filter = 'Citrix Director(?!.VDA Plugin)' } 'DesktopVDA' { $filter = 'Citrix Virtual Desktop Agent' } 'SessionVDA' { $filter = 'Citrix Virtual Desktop Agent' } 'FAS' { $filter = 'Citrix Federated Authentication Service' } } $result = $installedProducts -match $filter if ([System.String]::IsNullOrEmpty($result)) { } elseif ($result) { $installedRoles += $r } } return $installedRoles } } function ResolveXDSetupMedia { <# .SYNOPSIS Resolve the correct installation media source for the local architecture depending on the role. #> [CmdletBinding()] [OutputType([System.String])] param ( ## Citrix XenDesktop 7.x role to install/uninstall. [Parameter(Mandatory)] [ValidateSet('Controller','Studio','Storefront','Licensing','Director','DesktopVDA','SessionVDA','FAS')] [System.String[]] $Role, ## Citrix XenDesktop 7.x installation media path. [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [System.String] $SourcePath ) process { $architecture = 'x86'; if ([System.Environment]::Is64BitOperatingSystem) { $architecture = 'x64' } if ($Role -contains 'DesktopVDA') { $installMedia = 'XenDesktopVdaSetup.exe' } elseif ($Role -contains 'SessionVDA') { $installMedia = 'XenDesktopVdaSetup.exe' } elseif ($Role -contains 'FAS') { $installMedia = 'XenDesktopUserCredentialServiceSetup.exe' } else { $installMedia = 'XenDesktopServerSetup.exe' } $sourceArchitecturePath = Join-Path -Path $SourcePath -ChildPath $architecture $installMediaPath = Get-ChildItem -Path $sourceArchitecturePath -Filter $installMedia -Recurse -File if (-not $installMediaPath) { throw ($localized.NoValidSetupMediaError -f $installMedia, $sourceArchitecturePath) } return $installMediaPath.FullName } } function ResolveXDServerSetupArguments { <# .SYNOPSIS Resolve the installation arguments for the associated XenDesktop role. #> [CmdletBinding()] [OutputType([System.String])] param ( ## Citrix XenDesktop 7.x role to install/uninstall. [Parameter(Mandatory)] [ValidateSet('Controller','Studio','Storefront','Licensing','Director','FAS')] [System.String[]] $Role, ## Citrix XenDesktop 7.x installation media path. [Parameter()] [ValidateNotNullOrEmpty()] [System.String] $LogPath = (Join-Path -Path $env:TMP -ChildPath '\Citrix\XenDesktop Installer'), ## Uninstall Citrix XenDesktop 7.x product. [Parameter()] [System.Management.Automation.SwitchParameter] $Uninstall, ## Ignore hardware check requirements/failures [Parameter()] [System.Boolean] $IgnoreHardwareCheckFailure ) process { $arguments = New-Object -TypeName System.Collections.ArrayList -ArgumentList @() $arguments.AddRange(@('/QUIET', '/LOGPATH', "`"$LogPath`"", '/NOREBOOT', '/COMPONENTS')) $components = @() foreach ($r in $Role) { switch ($r) { ## Install/uninstall component names by role 'Controller' { $components += 'CONTROLLER' } 'Studio' { $components += 'DESKTOPSTUDIO' } 'Storefront' { $components += 'STOREFRONT' } 'Licensing' { $components += 'LICENSESERVER' } 'Director' { $components += 'DESKTOPDIRECTOR' } 'FAS' { $components += 'USERCREDENTIALSERVICE' } } #end switch Role } $componentString = [System.String]::Join(',', $components) [ref] $null = $arguments.Add($componentString) ## Introduced in CVAD 1906 if (($Role -contains 'Controller') -and ($IgnoreHardwareCheckFailure -eq $true)) { [ref] $null = $arguments.Add('/IGNORE_HW_CHECK_FAILURE') } if ($Uninstall) { [ref] $null = $arguments.Add('/REMOVE') } else { ## Additional install parameters per role if ($Role -contains 'Controller') { [ref] $null = $arguments.Add('/NOSQL') } [ref] $null = $arguments.Add('/CONFIGURE_FIREWALL') } return [System.String]::Join(' ', $arguments.ToArray()) } } #endregion Private Functions # SIG # Begin signature block # MIIm9AYJKoZIhvcNAQcCoIIm5TCCJuECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQU0AVUVCNEmhBWfLTk1ALZ5nI0 # VzaggiCcMIIFjTCCBHWgAwIBAgIQDpsYjvnQLefv21DiCEAYWjANBgkqhkiG9w0B # AQwFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk # IElEIFJvb3QgQ0EwHhcNMjIwODAxMDAwMDAwWhcNMzExMTA5MjM1OTU5WjBiMQsw # CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu # ZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC/5pBzaN675F1KPDAiMGkz # 7MKnJS7JIT3yithZwuEppz1Yq3aaza57G4QNxDAf8xukOBbrVsaXbR2rsnnyyhHS # 5F/WBTxSD1Ifxp4VpX6+n6lXFllVcq9ok3DCsrp1mWpzMpTREEQQLt+C8weE5nQ7 # bXHiLQwb7iDVySAdYyktzuxeTsiT+CFhmzTrBcZe7FsavOvJz82sNEBfsXpm7nfI # SKhmV1efVFiODCu3T6cw2Vbuyntd463JT17lNecxy9qTXtyOj4DatpGYQJB5w3jH # trHEtWoYOAMQjdjUN6QuBX2I9YI+EJFwq1WCQTLX2wRzKm6RAXwhTNS8rhsDdV14 # Ztk6MUSaM0C/CNdaSaTC5qmgZ92kJ7yhTzm1EVgX9yRcRo9k98FpiHaYdj1ZXUJ2 # h4mXaXpI8OCiEhtmmnTK3kse5w5jrubU75KSOp493ADkRSWJtppEGSt+wJS00mFt # 6zPZxd9LBADMfRyVw4/3IbKyEbe7f/LVjHAsQWCqsWMYRJUadmJ+9oCw++hkpjPR # iQfhvbfmQ6QYuKZ3AeEPlAwhHbJUKSWJbOUOUlFHdL4mrLZBdd56rF+NP8m800ER # ElvlEFDrMcXKchYiCd98THU/Y+whX8QgUWtvsauGi0/C1kVfnSD8oR7FwI+isX4K # Jpn15GkvmB0t9dmpsh3lGwIDAQABo4IBOjCCATYwDwYDVR0TAQH/BAUwAwEB/zAd # BgNVHQ4EFgQU7NfjgtJxXWRM3y5nP+e6mK4cD08wHwYDVR0jBBgwFoAUReuir/SS # y4IxLVGLp6chnfNtyA8wDgYDVR0PAQH/BAQDAgGGMHkGCCsGAQUFBwEBBG0wazAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAC # hjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURS # b290Q0EuY3J0MEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwEQYDVR0gBAowCDAGBgRV # HSAAMA0GCSqGSIb3DQEBDAUAA4IBAQBwoL9DXFXnOF+go3QbPbYW1/e/Vwe9mqyh # hyzshV6pGrsi+IcaaVQi7aSId229GhT0E0p6Ly23OO/0/4C5+KH38nLeJLxSA8hO # 0Cre+i1Wz/n096wwepqLsl7Uz9FDRJtDIeuWcqFItJnLnU+nBgMTdydE1Od/6Fmo # 8L8vC6bp8jQ87PcDx4eo0kxAGTVGamlUsLihVo7spNU96LHc/RzY9HdaXFSMb++h # UD38dglohJ9vytsgjTVgHAIDyyCwrFigDkBjxZgiwbJZ9VVrzyerbHbObyMt9H5x # aiNrIv8SuFQtJ37YOtnwtoeW/VvRXKwYw02fc7cBqZ9Xql4o4rmUMIIGrjCCBJag # AwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG9w0BAQsFADBiMQswCQYDVQQG # EwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cuZGlnaWNl # cnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVkIFJvb3QgRzQwHhcNMjIw # MzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQswCQYDVQQGEwJVUzEXMBUGA1UE # ChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQg # UlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUDxPKRN6mXUaHW0oPRnkyibaCw # zIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1ATCyZzlm34V6gCff1DtITaEfFz # sbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW1OcoLevTsbV15x8GZY2UKdPZ # 7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS8nZH92GDGd1ftFQLIWhuNyG7 # QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jBZHRAp8ByxbpOH7G1WE15/teP # c5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCYJn+gGkcgQ+NDY4B7dW4nJZCY # OjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucfWmyU8lKVEStYdEAoq3NDzt9K # oRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLcGEh/FDTP0kyr75s9/g64ZCr6 # dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNFYLwjjVj33GHek/45wPmyMKVM # 1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI+RQQEgN9XyO7ZONj4KbhPvbC # dLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjASvUaetdN2udIOa5kM0jO0zbEC # AwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFLoW2W1N # hS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX44LScV1kTN8uZz/nupiuHA9P # MA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEFBQcDCDB3BggrBgEFBQcB # AQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBBBggr # BgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcmwwIAYDVR0gBBkwFzAI # BgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQB9WY7Ak7Zv # mKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJLKftwig2qKWn8acHPHQfpPmDI # 2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgWvalWzxVzjQEiJc6VaT9Hd/ty # dBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2MvGQmh2ySvZ180HAKfO+ovHVP # ulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSumScbqyQeJsG33irr9p6xeZmB # o1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJxLafzYeHJLtPo0m5d2aR8XKc # 6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un8WbDQc1PtkCbISFA0LcTJM3c # HXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SVe+0KXzM5h0F4ejjpnOHdI/0d # KNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4k9Tm8heZWcpw8De/mADfIBZP # J/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJDwq9gdkT/r+k0fNX2bwE+oLe # Mt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr5n8apIUP/JiW9lVUKx+A+sDy # Divl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBrAwggSYoAMCAQICEAitQLJg0pxM # n17Nqb2TrtkwDQYJKoZIhvcNAQEMBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoT # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UE # AxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIxMDQyOTAwMDAwMFoXDTM2 # MDQyODIzNTk1OVowaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2lnbmluZyBS # U0E0MDk2IFNIQTM4NCAyMDIxIENBMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC # AgoCggIBANW0L0LQKK14t13VOVkbsYhC9TOM6z2Bl3DFu8SFJjCfpI5o2Fz16zQk # B+FLT9N4Q/QX1x7a+dLVZxpSTw6hV/yImcGRzIEDPk1wJGSzjeIIfTR9TIBXEmtD # mpnyxTsf8u/LR1oTpkyzASAl8xDTi7L7CPCK4J0JwGWn+piASTWHPVEZ6JAheEUu # oZ8s4RjCGszF7pNJcEIyj/vG6hzzZWiRok1MghFIUmjeEL0UV13oGBNlxX+yT4Us # SKRWhDXW+S6cqgAV0Tf+GgaUwnzI6hsy5srC9KejAw50pa85tqtgEuPo1rn3MeHc # reQYoNjBI0dHs6EPbqOrbZgGgxu3amct0r1EGpIQgY+wOwnXx5syWsL/amBUi0nB # k+3htFzgb+sm+YzVsvk4EObqzpH1vtP7b5NhNFy8k0UogzYqZihfsHPOiyYlBrKD # 1Fz2FRlM7WLgXjPy6OjsCqewAyuRsjZ5vvetCB51pmXMu+NIUPN3kRr+21CiRshh # WJj1fAIWPIMorTmG7NS3DVPQ+EfmdTCN7DCTdhSmW0tddGFNPxKRdt6/WMtyEClB # 8NXFbSZ2aBFBE1ia3CYrAfSJTVnbeM+BSj5AR1/JgVBzhRAjIVlgimRUwcwhGug4 # GXxmHM14OEUwmU//Y09Mu6oNCFNBfFg9R7P6tuyMMgkCzGw8DFYRAgMBAAGjggFZ # MIIBVTASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBRoN+Drtjv4XxGG+/5h # ewiIZfROQjAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8B # Af8EBAMCAYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYIKwYBBQUHAQEEazBpMCQG # CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKG # NWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290 # RzQuY3J0MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3JsMBwGA1UdIAQVMBMwBwYFZ4EMAQMw # CAYGZ4EMAQQBMA0GCSqGSIb3DQEBDAUAA4ICAQA6I0Q9jQh27o+8OpnTVuACGqX4 # SDTzLLbmdGb3lHKxAMqvbDAnExKekESfS/2eo3wm1Te8Ol1IbZXVP0n0J7sWgUVQ # /Zy9toXgdn43ccsi91qqkM/1k2rj6yDR1VB5iJqKisG2vaFIGH7c2IAaERkYzWGZ # gVb2yeN258TkG19D+D6U/3Y5PZ7Umc9K3SjrXyahlVhI1Rr+1yc//ZDRdobdHLBg # XPMNqO7giaG9OeE4Ttpuuzad++UhU1rDyulq8aI+20O4M8hPOBSSmfXdzlRt2V0C # FB9AM3wD4pWywiF1c1LLRtjENByipUuNzW92NyyFPxrOJukYvpAHsEN/lYgggnDw # zMrv/Sk1XB+JOFX3N4qLCaHLC+kxGv8uGVw5ceG+nKcKBtYmZ7eS5k5f3nqsSc8u # pHSSrds8pJyGH+PBVhsrI/+PteqIe3Br5qC6/To/RabE6BaRUotBwEiES5ZNq0RA # 443wFSjO7fEYVgcqLxDEDAhkPDOPriiMPMuPiAsNvzv0zh57ju+168u38HcT5uco # P6wSrqUvImxB+YJcFWbMbA7KxYbD9iYzDAdLoNMHAmpqQDBISzSoUSC7rRuFCOJZ # DW3KBVAr6kocnqX9oKcfBnTn8tZSkP2vhUgh+Vc7tJwD7YZF9LRhbr9o4iZghurI # r6n+lB3nYxs6hlZ4TjCCBsIwggSqoAMCAQICEAVEr/OUnQg5pr/bP1/lYRYwDQYJ # KoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2 # IFRpbWVTdGFtcGluZyBDQTAeFw0yMzA3MTQwMDAwMDBaFw0zNDEwMTMyMzU5NTla # MEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4GA1UE # AxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjMwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQCjU0WHHYOOW6w+VLMj4M+f1+XS512hDgncL0ijl3o7Kpxn3GIV # WMGpkxGnzaqyat0QKYoeYmNp01icNXG/OpfrlFCPHCDqx5o7L5Zm42nnaf5bw9Yr # IBzBl5S0pVCB8s/LB6YwaMqDQtr8fwkklKSCGtpqutg7yl3eGRiF+0XqDWFsnf5x # XsQGmjzwxS55DxtmUuPI1j5f2kPThPXQx/ZILV5FdZZ1/t0QoRuDwbjmUpW1R9d4 # KTlr4HhZl+NEK0rVlc7vCBfqgmRN/yPjyobutKQhZHDr1eWg2mOzLukF7qr2JPUd # vJscsrdf3/Dudn0xmWVHVZ1KJC+sK5e+n+T9e3M+Mu5SNPvUu+vUoCw0m+PebmQZ # BzcBkQ8ctVHNqkxmg4hoYru8QRt4GW3k2Q/gWEH72LEs4VGvtK0VBhTqYggT02ke # fGRNnQ/fztFejKqrUBXJs8q818Q7aESjpTtC/XN97t0K/3k0EH6mXApYTAA+hWl1 # x4Nk1nXNjxJ2VqUk+tfEayG66B80mC866msBsPf7Kobse1I4qZgJoXGybHGvPrhv # ltXhEBP+YUcKjP7wtsfVx95sJPC/QoLKoHE9nJKTBLRpcCcNT7e1NtHJXwikcKPs # CvERLmTgyyIryvEoEyFJUX4GZtM7vvrrkTjYUQfKlLfiUKHzOtOKg8tAewIDAQAB # o4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/ # BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcB # MB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSltu8T # 5+/N0GSh1VapZTGj3tXjSTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5k # aWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0 # YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0 # cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0 # cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGlt # ZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCBGtbeoKm1mBe8cI1P # ijxonNgl/8ss5M3qXSKS7IwiAqm4z4Co2efjxe0mgopxLxjdTrbebNfhYJwr7e09 # SI64a7p8Xb3CYTdoSXej65CqEtcnhfOOHpLawkA4n13IoC4leCWdKgV6hCmYtld5 # j9smViuw86e9NwzYmHZPVrlSwradOKmB521BXIxp0bkrxMZ7z5z6eOKTGnaiaXXT # UOREEr4gDZ6pRND45Ul3CFohxbTPmJUaVLq5vMFpGbrPFvKDNzRusEEm3d5al08z # jdSNd311RaGlWCZqA0Xe2VC1UIyvVr1MxeFGxSjTredDAHDezJieGYkD6tSRN+9N # UvPJYCHEVkft2hFLjDLDiOZY4rbbPvlfsELWj+MXkdGqwFXjhr+sJyxB0JozSqg2 # 1Llyln6XeThIX8rC3D0y33XWNmdaifj2p8flTzU8AL2+nCpseQHc2kTmOt44Owde # OVj0fHMxVaCAEcsUDH6uvP6k63llqmjWIso765qCNVcoFstp8jKastLYOrixRoZr # uhf9xHdsFWyuq69zOuhJRrfVf8y2OMDY7Bz1tqG4QyzfTkx9HmhwwHcK1ALgXGC7 # KP845VJa1qwXIiNO9OzTF/tQa/8Hdx9xl0RBybhG02wyfFgvZ0dl5Rtztpn5aywG # Ru9BHvDwX+Db2a2QgESvgBBBijCCBtswggTDoAMCAQICEATKzAo8VGv2qBgLEa7N # zyYwDQYJKoZIhvcNAQELBQAwaTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2ln # bmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMTAeFw0yMTEwMTkwMDAwMDBaFw0y # MzExMDQyMzU5NTlaMGAxCzAJBgNVBAYTAkdCMQ8wDQYDVQQHEwZMb25kb24xHzAd # BgNVBAoTFlZpcnR1YWwgRW5naW5lIExpbWl0ZWQxHzAdBgNVBAMTFlZpcnR1YWwg # RW5naW5lIExpbWl0ZWQwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQC1 # ubejnuZBjG7SJ1KJ+GXJloNU7Rm7QGcZMVk61kuJsGi2CkqnsF7eT1YPIhs6JQdV # oVjsMbxovySukCuP7colHj1Tmktdx681RAUsvXymL2Vn57bD51wEB+4nfQnvrRW0 # 8PAADueYB9/d/2j60QHVmch5fOU9HIzPthlLjewN4B+3ynyMXOYzSNG231Jc3Epw # LSCdfoLHS/DgCTGYy2t5f8iC+PlVWrgzzUTzgJ59axT8imogvbjGnGXc47BnnfDO # f6s8DdP1uPQ9TIj/pW841QhEP8R84PG6tV1IN24sexFqDj5DfEW9mb9Y2qyvaoa/ # ssdPe4o+yO48GjUzP18z8B8/B0R8zfEn5jWsGpTGcOHBhL3sXDcszreVMqXds3hM # 4UQlfxg+ALTYni/NhIg/R/AEE/J3sy1uJfMW9KheeXQRCaMf6Th+M4LCfW2Bacjv # s0RPTkl3ToXc53nYif2ognkGG7jOUwURCATsk404jj8eX90HN82TIi0wxFw2I8kC # AwEAAaOCAgYwggICMB8GA1UdIwQYMBaAFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB0G # A1UdDgQWBBQSv6nVtbCtP7OXr5NeEdbP17Bi4DAOBgNVHQ8BAf8EBAMCB4AwEwYD # VR0lBAwwCgYIKwYBBQUHAwMwgbUGA1UdHwSBrTCBqjBToFGgT4ZNaHR0cDovL2Ny # bDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0 # MDk2U0hBMzg0MjAyMUNBMS5jcmwwU6BRoE+GTWh0dHA6Ly9jcmw0LmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIw # MjFDQTEuY3JsMD4GA1UdIAQ3MDUwMwYGZ4EMAQQBMCkwJwYIKwYBBQUHAgEWG2h0 # dHA6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzCBlAYIKwYBBQUHAQEEgYcwgYQwJAYI # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBcBggrBgEFBQcwAoZQ # aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29k # ZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcnQwDAYDVR0TAQH/BAIwADAN # BgkqhkiG9w0BAQsFAAOCAgEAHfkR7a+g8eOt0OUHzSShxbZmtVwo7n885yE86/Ev # V69c92hp7E0MLBfMz/oZdrhTVWFX4apt5D4kJkVdZuLJzGpcR+Ll/GPaxHN0XcIO # ii0WKrErV6rPZbzYpHkVfjktOxAyuDo7yQDadvZ4HGTpNZhS1L7eO11L+fAOn8H8 # D6iXQJoPnWGXOr1BjQ02TCxtn58qYjGKeoQUXqe1o6ZA1ZLQQ601AFh2V/Sk1OEG # 4/EQ2wO1ZFLnqmDep+Xf6SG1553ywWjJj/2DVKh9tzsMBCJi1OKSZ6QD6zlaQdjV # 7CJIX81xdI00w2Bu4CyLOgxD02Qn+8yGzz36E1R7pOWT1sV984/2iHnPoN/9ccmy # WE1jcPFZhBDG2rNmkCT/gYInwv2p14QO+26U+nenpWo0HFA+73wLjql9eAJfS8iJ # 5XLdFk6EcPYkLK1Y0VZckW+ijTdqRzJO6aKrb6Z7DoAvBcoq0V6gMd+fMORWxlE+ # pjj2AQJUqJ9jtntSy5/dIE4Hq3E6XMrXl4xHYQhGwFII9VkJ69T3PnUM/8Ytnr+Q # IMbqFy7qKx6chYDFbDXCIa/ocmlxrve6aZFihR4q01XyGDsi2U+Ka2uOOhP7RyIT # w6G6/kYMGorQYTiKQIhRnIWDvimmQdXir5iCFe+5uTAxJXvKYVEqGBwZAuUNc/45 # pVAxggXCMIIFvgIBATB9MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2Vy # dCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25p # bmcgUlNBNDA5NiBTSEEzODQgMjAyMSBDQTECEATKzAo8VGv2qBgLEa7NzyYwCQYF # Kw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAwGQYJKoZIhvcNAQkD # MQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwIwYJ # KoZIhvcNAQkEMRYEFMVTpX3YgUpFfzQZwZ8zTNTZkvyCMA0GCSqGSIb3DQEBAQUA # BIIBgLC/7YRdugCMH3SeMeZOK/PdWNDN0AI6PBD0QX73i5YabsAKIQhEuQA3CdUH # QGGp8JMXWnsSm+wspxgXgoszM/NsiSQSM2SCJKM913Tms9/7O8+LKjTRJlNYFPil # cMAa3tiTV45Vnt0MVDpe+Gbx4v3TNCLgXRCSRSJ5YT3zwzmFS47zBBZhp/pISXCx # 3GSJHIu+Yg2dHnv0RbnjB6FDtUHyGtLe5MHlI/TLf6xlenl45cakh+oEkhdS0cQ3 # wQyFtRik45I0GNufLdaRD6mYjZ5/fgCFzYRZ5d5tFA6C0NwmYRYBBbX4QzHDsU6e # fPhv/r8fdLLceBL+tmQH9eSHnf1kTcpIs8kTuo8xYrZgeglLGJ0r+kKQyPg6yZGE # RMWZj2Vb6qkLLNVzAUz3Z5KUzyapiEphkCDR8lhhQwcqYMV9TV/XFowDvDSMDBoG # 4aevOuHJyt/l2R+8nXUbirxUB7nPgNmfKOPlAnGN2pyU9ahfXmVIIsetCrgKzVKl # Qm4zsKGCAyAwggMcBgkqhkiG9w0BCQYxggMNMIIDCQIBATB3MGMxCzAJBgNVBAYT # AlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGlnaUNlcnQg # VHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0ECEAVEr/OU # nQg5pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCgaTAYBgkqhkiG9w0BCQMxCwYJKoZI # hvcNAQcBMBwGCSqGSIb3DQEJBTEPFw0yMzExMDQxNzA3MDBaMC8GCSqGSIb3DQEJ # BDEiBCByJJCAT/hbYtZjmaDSc/gIBu2/hBLtG49MIJDMYuXIVDANBgkqhkiG9w0B # AQEFAASCAgBmUgrwk6u545lLljMQ9GIpqtqOivJtFCc3F1jeYzi7nHKxjiRFycJ0 # ZAm4CpL3tm/HDbOFsr6y8IKZC31H+YSzO0JF6NsjNvGIV/I0vh1bwD25e7utaTv5 # ilGPePPgq5NxR2/hrEMY9G3Z9ReReGn5NdbevZflz9Uau8ZGCozTce0F1LrN2j+I # Z/GMVTrccGsR7TSD10ktJRG0AAx9FAAyjmxnRwibqqN0HHDdGOCl2p58cehym9jl # nyAyWAnBMvqCHgawFq4+ib08JPxhrdSeVPcPzw0Ng0R+DPE08W/cR5mEQXepwfkr # ET36a5R/CStzMXENC3JUhvVGvaTPDCLUX0N5PQpA6Pe0zskpx4z0sb1LHvYwzmGv # NadXeu9w7QEJC4HOFuA8qlsaEYyBMxOFNHNffUZByNRaEDWZXlf5BOCvGyikpL7c # 9eNwWX1fOiFnvUbHhTuGg/9iWoIoKP1TPbRCR8c+DxNItJHvvzMyNSN0iDIOqeZS # HxIwDZLeVElJ+pYWGyP5KCdMl/Y80gsJgzAcVF+HccDVPYtiNlx9opv/noC6+llh # xHvIGFf9Dm4eTTAy5soqSDWHwk5FVfzo0boOubI6Kerp2vaNxbAxWjCoLWJrH1gy # sTzeeYNXzkzL1vsBORMGRHuXDXiQ+JQBujZiwwFKCYDUQX1XG8MPqA== # SIG # End signature block |