modules/AzStack.Insights/remediations/RemoveUnreferencedGhostCsvMountPoints.ps1
|
<#
.SYNOPSIS Removes unreferenced ghost Cluster Shared Volume mount points (C:\ClusterStorage.00X). .DESCRIPTION Removes leftover numbered CSV roots ONLY when nothing on the cluster still references them. The gate is deliberately strict and is re-evaluated immediately before any deletion, because deleting a referenced ghost root can take virtual machines or Arc Resource Bridge offline. The remediation refuses to act when any of the following is true: * an ACTIVE Cluster Shared Volume is mounted under a numbered root * a cluster resource parameter references a numbered root * a virtual machine disk, configuration, checkpoint, or paging path references a numbered root * an SMB client has a file open under a numbered root * any child of a ghost root is a reparse point, meaning it still redirects to a live volume * a ghost root contains live platform working data (a MocArb or ImageStore directory, WorkingDirectory content, or any virtual hard disk); this is a hard blocker even with no other reference, because deleting it destroys live state A lone Infrastructure_<n> directory (an orchestrator breadcrumb with no other platform content) does not block by itself; it is only treated as a blocker when the root is otherwise referenced. See the TSG for the full procedure: https://github.com/Azure/AzureLocal-Supportability/blob/main/TSG/Storage/Troubleshoot-Storage-GhostCsvMountPoints.md .PARAMETER Force If specified, the remediation proceeds without prompting for confirmation. The safety gate above still applies and is never bypassed. .PARAMETER SkipEnvironmentCheck If specified, the remediation proceeds even if environment requirements are not met. Use with caution. #> [CmdletBinding()] [Diagnostics.CodeAnalysis.SuppressMessageAttribute( 'PSUseUsingScopeModifierInNewRunspaces', '', Justification = 'The remote scriptblock declares param($Pattern, $RootNamePattern, $PlatformContentPattern) and the values are supplied with -ArgumentList through Invoke-AzsSupportCommand. That form is transport-agnostic across WinRM, PowerShell Direct, and local runspaces, whereas $using: is remoting-scope-fragile. This is a known analyzer false positive for param plus -ArgumentList.')] param( [Parameter(Mandatory = $false, Position = 0)] [switch]$Force, [Parameter(Mandatory = $false, Position = 1)] [switch]$SkipEnvironmentCheck ) Import-LocalizedData -BindingVariable 'localizedData' -BaseDirectory "$PSScriptRoot\locale" -UICulture $PSUICulture $remediationObject = Initialize-RemediationObject -Properties $localizedData.Remediation -SkipEnvironmentCheck:$SkipEnvironmentCheck if ($remediationObject.Status -eq [RemediationStatus]::NOT_APPLICABLE) { return $remediationObject } if (-not $Force) { if (-not (Confirm-RemediationAction -Properties $localizedData.Remediation)) { $remediationObject.Status = [RemediationStatus]::USER_CANCELLED return $remediationObject } } $changesApplied = $false try { <# START REPAIR LOGIC #> # Pattern and root discovery come from AzStack.Common, shared with the # analyzer, so this delete gate can never drift narrower than the # classification that decided a root was safe to remove. $ghostPathPattern = Get-AzsGhostCsvPathPattern $ghostRootNamePattern = Get-AzsGhostCsvRootNamePattern $platformContentPattern = Get-AzsGhostCsvPlatformContentPattern $blockers = New-Object -TypeName System.Collections.Generic.List[string] $ghostRoots = @(Get-AzsGhostCsvRoot) if ($ghostRoots.Count -eq 0) { Write-AzsSupportLog -Level 'Informational' -Message "No ghost CSV roots found on $env:COMPUTERNAME." $remediationObject.ChangesApplied = $false $remediationObject.Status = [RemediationStatus]::NO_CHANGE_APPLIED Write-AzsSupportLog -Level 'Informational' -Message $localizedData.ChangesNotApplied return $remediationObject } # Gate 1: an active CSV under a numbered root is the live namespace, not a ghost. # This query is safety critical, so a failure to run it is a hard stop rather # than a silent zero, matching the per-node gate below: a check that could not # run must fail the remediation, never silently contribute zero blockers. try { foreach ($csv in (Get-ClusterSharedVolume -ErrorAction Stop)) { if ($csv.SharedVolumeInfo.FriendlyVolumeName -match $ghostPathPattern) { $blockers.Add("ActiveCsvUnderNumberedRoot: $($csv.Name) -> $($csv.SharedVolumeInfo.FriendlyVolumeName)") } } } catch { Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove ghost CSV roots: the active-CSV safety check (Get-ClusterSharedVolume) could not run: $($_.Exception.Message)" $remediationObject.ChangesApplied = $false $remediationObject.ScriptStackTrace = Get-FormattedException -Exception $_ $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f "the active-CSV safety check could not run ($($_.Exception.Message)), so it is not safe to confirm the roots are unreferenced." $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } # Gate 2: cluster-wide resource parameters. Catches VMs owned by other nodes. # Enumerating the resources is safety critical and therefore terminating: a # failure to enumerate is a hard stop, for the same reason as Gate 1. try { $clusterResources = @(Get-ClusterResource -ErrorAction Stop) } catch { Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove ghost CSV roots: the cluster-resource safety check (Get-ClusterResource) could not run: $($_.Exception.Message)" $remediationObject.ChangesApplied = $false $remediationObject.ScriptStackTrace = Get-FormattedException -Exception $_ $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f "the cluster-resource safety check could not run ($($_.Exception.Message)), so it is not safe to confirm the roots are unreferenced." $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } # Reading each resource's parameters is safety critical too, so a failure here # is a hard stop rather than a swallowed error. # # The earlier tolerance was based on a false premise. A resource type that does # not expose parameters does NOT throw: Get-ClusterParameter returns an EMPTY # collection for it. Measured read-only across three live clusters (195 cluster # resources over 14 resource types): zero throws, and the two types that have no # parameters, Storage QoS Policy Manager and User Manager, both returned an empty # collection without raising. So swallowing exceptions here bought nothing and # only hid real failures, such as a cluster RPC or access error after enumeration # succeeded, which would silently contribute zero blockers and permit deletion. try { foreach ($resource in $clusterResources) { foreach ($parameter in (Get-ClusterParameter -InputObject $resource -ErrorAction Stop)) { if (($parameter.Value -is [string]) -and ($parameter.Value -match $ghostPathPattern)) { $blockers.Add("ClusterResource: $($resource.Name).$($parameter.Name) -> $($parameter.Value)") } } } } catch { Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove ghost CSV roots: the cluster-resource parameter safety check (Get-ClusterParameter) could not run: $($_.Exception.Message)" $remediationObject.ChangesApplied = $false $remediationObject.ScriptStackTrace = Get-FormattedException -Exception $_ $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f "the cluster-resource parameter safety check could not run ($($_.Exception.Message)), so it is not safe to confirm the roots are unreferenced." $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } # Gate 3: per-node references across every cluster node. # # Enumeration is terminating for the same reason as Gates 1 and 2. $clusterNodes = $null try { $clusterNodes = @(Get-ClusterNode -ErrorAction Stop) } catch { # A standalone (non-clustered) host has no cluster nodes to enumerate; fall # back to checking just this machine. Any OTHER failure is a hard stop. if ($_.Exception -is [System.Management.Automation.CommandNotFoundException]) { $clusterNodes = @() } else { Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove ghost CSV roots: the cluster-node safety check (Get-ClusterNode) could not run: $($_.Exception.Message)" $remediationObject.ChangesApplied = $false $remediationObject.ScriptStackTrace = Get-FormattedException -Exception $_ $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f "the cluster-node safety check could not run ($($_.Exception.Message)), so it is not safe to confirm the roots are unreferenced." $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } } # A node that is not Up cannot be queried, so it must be counted as a BLOCKER # rather than filtered away. Filtering first meant a Down or Paused node was # never queried AND never counted as unqueryable, so a root still referenced on # that node passed the gate and was deleted. That silently broke the stated # contract that any node which cannot be queried is a hard stop. foreach ($offline in @($clusterNodes | Where-Object { $_.State -ne 'Up' })) { $blockers.Add("NodeNotQueryable: $($offline.Name) is $($offline.State), so its references could not be checked") } # Where-Object on an empty pipeline yields nothing, but @( (<nothing>).Name ) # is Count 1 containing $null, not Count 0, so the local-node fallback never # fired and the refusal message read "1 node(s) could not be queried ()". # Projecting names explicitly and dropping empties makes the count honest. $nodes = @($clusterNodes | Where-Object { $_.State -eq 'Up' } | ForEach-Object { $_.Name } | Where-Object { -not [string]::IsNullOrWhiteSpace($_) }) if ($nodes.Count -eq 0) { $localNode = $env:COMPUTERNAME if ([string]::IsNullOrWhiteSpace($localNode)) { # Defensive: without a name there is nothing to query, and proceeding # would mean deleting with the per-node gate never actually run. Write-AzsSupportLog -Level 'Warning' -Message 'Refusing to remove ghost CSV roots: no cluster node is Up and the local computer name could not be resolved, so the per-node safety check cannot run.' $remediationObject.ChangesApplied = $false $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f 'no cluster node is Up and the local computer name could not be resolved, so the per-node safety check could not run.' $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } $nodes = @($localNode) } # Query each node INDIVIDUALLY rather than in one fan-out call. A single # Invoke-Command against every node drops an unreachable node's results as a # non-terminating error, and this gate authorises a PERMANENT delete: the # node we failed to ask may be the one still referencing the root. So any # node that cannot be queried is a hard stop, never a silent gap. # # Invoke-AzsSupportCommand is the sanctioned wrapper and executes the local # node directly rather than over WinRM. $unreachableNodes = New-Object -TypeName System.Collections.Generic.List[string] foreach ($node in $nodes) { try { $nodeResult = Invoke-AzsSupportCommand -ComputerName $node -ErrorAction Stop ` -ArgumentList @($ghostPathPattern, $ghostRootNamePattern, $platformContentPattern) -ScriptBlock { param($Pattern, $RootNamePattern, $PlatformContentPattern) $hits = New-Object -TypeName System.Collections.Generic.List[string] $orphans = New-Object -TypeName System.Collections.Generic.List[string] # Every query below is safety critical and therefore TERMINATING. # With -ErrorAction SilentlyContinue a failed query returns nothing # and the loop simply iterates zero times, which is indistinguishable # from "this node is clean". Since this gate authorises a permanent # delete, a check that could not run must fail the node rather than # silently contribute zero references. foreach ($vm in (Get-VM -ErrorAction Stop)) { foreach ($disk in ($vm | Get-VMHardDiskDrive -ErrorAction Stop)) { if ($disk.Path -match $Pattern) { $hits.Add("VMHardDisk: $($vm.Name) -> $($disk.Path)") } # Walk the parent chain. A checkpoint or differencing PARENT can # still live on a ghost root while the attached child sits on a # healthy CSV, so testing only $disk.Path lets the gate pass and # the delete then breaks the chain, leaving the child unusable. # An unreadable link fails CLOSED at every depth: if the chain # cannot be read, its cleanliness cannot be proven. $parent = $disk.Path $depth = 0 while ($parent) { # Bound checked BEFORE each hop; checking after the loop # reported a fully-walked chain of exactly the limit as too # deep, turning a valid chain into a false refusal. if ($depth -ge 50) { $hits.Add("VMDiskChainTooDeep: $($vm.Name) exceeded 50 links and was not fully walked") break } # A disk file that does not EXIST ends the chain rather than # blocking. An orphaned VM still pointing at a deleted VHDX is # ordinary in the field, and a file that is not there cannot # hold a parent link to a ghost root. The attached path is # already matched directly above. if (-not (Test-Path -LiteralPath $parent -ErrorAction Stop)) { # Orphaned VM: the disk no longer exists. Informational, # never a blocker. Test-Path is TERMINATING so an access or # provider error refuses the node via the outer catch rather # than reading as "missing"; the orphan is carried back # separately from $hits so it never blocks the delete. $orphans.Add("VM '$($vm.Name)' is configured with a disk that no longer exists ($parent).") break } # An existing file that cannot be READ is genuinely unknown # coverage, so that still blocks. $vhd = Get-VHD -Path $parent -ErrorAction SilentlyContinue if (-not $vhd) { $hits.Add("VMDiskChainUnreadable: $($vm.Name) -> could not read '$parent' at depth $depth") break } $parent = $vhd.ParentPath if ($parent -and ($parent -match $Pattern)) { $hits.Add("VMDiskParent: $($vm.Name) -> $parent") } $depth++ } } foreach ($property in 'ConfigurationLocation', 'SnapshotFileLocation', 'SmartPagingFilePath') { $value = $vm.$property if ($value -and ($value -match $Pattern)) { $hits.Add("VMConfig: $($vm.Name).$property -> $value") } } } foreach ($openFile in (Get-SmbOpenFile -ErrorAction Stop)) { if ($openFile.Path -match $Pattern) { $hits.Add("SmbOpenFile: $($openFile.Path)") } } # The patterns are passed in rather than restated here, so the # remote leg shares the same source of truth as the local one. # It cannot call the shared helper directly because AzStack.Common # is not guaranteed to be loaded in the remote session. foreach ($root in (Get-ChildItem -Path 'C:\' -Filter 'ClusterStorage.*' -ErrorAction Stop | Where-Object { $_.PSIsContainer -and $_.Name -match $RootNamePattern })) { # Recursive, because the delete is recursive. A reparse point nested # below the first level redirects to live storage just as much as one # at the top, and checking only immediate children left that blind. foreach ($child in (Get-ChildItem -LiteralPath $root.FullName -Force -Recurse -ErrorAction Stop)) { if ($child.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { $hits.Add("ReparsePoint: $($child.FullName)") } # Live platform WORKING DATA (ARB/MOC directories, the image # store, any VHD). Deleting this destroys live state, so it is a # hard blocker with or without a reference. This was missing # entirely: the gate only looked for Infrastructure_<n>, so a # root holding MocArb or ImageStore was deleted outright. if ($child.Name -match $PlatformContentPattern) { $hits.Add("PlatformContent: $($child.FullName)") } } foreach ($child in (Get-ChildItem -LiteralPath $root.FullName -Force -ErrorAction Stop)) { # An Infrastructure_<n> directory on its own is usually an # orchestrator breadcrumb of a few hundred bytes with nothing # pointing at it. Reported as a SOFT signal so it only blocks # when the root is also referenced, matching the analyzer. Held # unconditionally, it made the guarded cleanup refuse on the most # common case in the field and pushed the operator to delete by # hand instead, which is the riskier path. if ($child.Name -match '^Infrastructure_\d+$') { $hits.Add("PlatformBreadcrumb: $($child.FullName)") } } } # Always emit a result object, even with zero hits, so that a null # return is unambiguously a FAILED query and not a clean node. [PSCustomObject]@{ Node = $env:COMPUTERNAME; Hits = @($hits); Orphans = @($orphans) } } $nodeResult = @($nodeResult | Where-Object { $null -ne $_ }) if ($nodeResult.Count -eq 0) { throw "No result was returned from $node." } foreach ($result in $nodeResult) { foreach ($hit in @($result.Hits)) { $blockers.Add("[$($result.Node)] $hit") } foreach ($orphan in @($result.Orphans)) { Write-AzsSupportLog -Level 'Informational' -Message "[$($result.Node)] Also seen while checking ghost CSV mount points: $orphan" } } } catch { $unreachableNodes.Add($node) Write-AzsSupportLog -Level 'Warning' -Message "Could not query node $node for ghost CSV references: $($_.Exception.Message)" } } # Refuse rather than delete on incomplete evidence. if ($unreachableNodes.Count -gt 0) { $unreachableList = $unreachableNodes -join ', ' Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove ghost CSV roots: $($unreachableNodes.Count) node(s) could not be queried ($unreachableList). A node that cannot be checked may still reference a ghost root." $remediationObject.ChangesApplied = $false $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f "$($unreachableNodes.Count) node(s) could not be queried ($unreachableList), so it is not safe to confirm the roots are unreferenced." $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } # An Infrastructure_<n> breadcrumb is a SOFT signal: on its own it does not block, # because it is the ordinary leftover the TSG routes to the safe cleanup path, and # blocking on it made this remediation refuse on the most common case in the field. # It escalates only when the root is genuinely referenced, which is exactly the # analyzer's rule ($hasPlatformContent -and $rootReferences.Count -gt 0). Every # other blocker, including live platform working data and reparse points, is hard. $hardBlockers = @($blockers | Where-Object { $_ -notmatch '^\[[^\]]+\] PlatformBreadcrumb:' }) $softBlockers = @($blockers | Where-Object { $_ -match '^\[[^\]]+\] PlatformBreadcrumb:' }) if ($hardBlockers.Count -gt 0) { Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove ghost CSV roots. $($hardBlockers.Count) blocker(s) found:" foreach ($blocker in $hardBlockers) { Write-AzsSupportLog -Level 'Warning' -Message " $blocker" } foreach ($blocker in $softBlockers) { Write-AzsSupportLog -Level 'Warning' -Message " (also present) $blocker" } $remediationObject.ChangesApplied = $false $remediationObject.Status = [RemediationStatus]::NO_CHANGE_APPLIED Write-AzsSupportLog -Level 'Informational' -Message $localizedData.ChangesNotApplied return $remediationObject } foreach ($blocker in $softBlockers) { Write-AzsSupportLog -Level 'Informational' -Message "Proceeding despite an orchestrator breadcrumb, because nothing references the root: $blocker" } # Gate passed. Record an inventory, then remove. # Use the framework working directory rather than $env:TEMP: it is where the # support tooling collects artifacts, and $env:TEMP is not defined on every # host the module runs under. $stamp = Get-Date -Format 'yyyyMMdd-HHmmss' $backupPath = Join-Path -Path (Get-AzsSupportWorkingDirectory) -ChildPath "GhostCsvInventory-$stamp" New-Item -ItemType Directory -Path $backupPath -Force | Out-Null foreach ($root in $ghostRoots) { Get-ChildItem -LiteralPath $root.FullName -Recurse -Force -ErrorAction SilentlyContinue | Select-Object -Property FullName, Length, LastWriteTime | Export-Csv -Path (Join-Path -Path $backupPath -ChildPath "$($root.Name)-inventory.csv") -NoTypeInformation } Write-AzsSupportLog -Level 'Informational' -Message "Inventory of ghost CSV roots written to $backupPath" foreach ($root in $ghostRoots) { # Re-validate the FULL blocker set for THIS root immediately before removing it, # not just reparse points. During the inventory pass (which walks every root # recursively) a reparse point, a VM disk, a VM config/checkpoint/paging path, an # SMB open file, an active CSV, or platform content can appear on the node, and # deleting a now-referenced root would break it. Any blocker that reappears aborts # the delete. Cluster-wide references were proven absent by the gate above; this # closes the local window the inventory walk opens. $lateBlockers = New-Object -TypeName System.Collections.Generic.List[string] foreach ($child in (Get-ChildItem -LiteralPath $root.FullName -Force -Recurse -ErrorAction Stop)) { if ($child.Attributes -band [System.IO.FileAttributes]::ReparsePoint) { $lateBlockers.Add("ReparsePoint: $($child.FullName)") } if ($child.Name -match $platformContentPattern) { $lateBlockers.Add("PlatformContent: $($child.FullName)") } } foreach ($vm in (Get-VM -ErrorAction Stop)) { foreach ($disk in ($vm | Get-VMHardDiskDrive -ErrorAction Stop)) { if ($disk.Path -match $ghostPathPattern) { $lateBlockers.Add("VMHardDisk: $($vm.Name) -> $($disk.Path)") } } foreach ($property in 'ConfigurationLocation', 'SnapshotFileLocation', 'SmartPagingFilePath') { if ($vm.$property -and ($vm.$property -match $ghostPathPattern)) { $lateBlockers.Add("VMConfig: $($vm.Name).$property -> $($vm.$property)") } } } foreach ($openFile in (Get-SmbOpenFile -ErrorAction Stop)) { if ($openFile.Path -match $ghostPathPattern) { $lateBlockers.Add("SmbOpenFile: $($openFile.Path)") } } foreach ($csv in (Get-ClusterSharedVolume -ErrorAction Stop)) { if ($csv.SharedVolumeInfo.FriendlyVolumeName -match $ghostPathPattern) { $lateBlockers.Add("ActiveCsvUnderNumberedRoot: $($csv.Name) -> $($csv.SharedVolumeInfo.FriendlyVolumeName)") } } if ($lateBlockers.Count -gt 0) { Write-AzsSupportLog -Level 'Warning' -Message "Refusing to remove $($root.FullName): $($lateBlockers.Count) reference(s) appeared after the safety gate ran ($($lateBlockers[0]))." $remediationObject.ChangesApplied = $changesApplied $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f "a reference appeared under $($root.FullName) after the safety gate ran, so the root is no longer safe to remove." $remediationObject.Status = [RemediationStatus]::FAILURE return $remediationObject } Write-AzsSupportLog -Level 'Informational' -Message "Removing ghost CSV root $($root.FullName)" Remove-Item -LiteralPath $root.FullName -Recurse -Force -ErrorAction Stop $changesApplied = $true } <# END REPAIR LOGIC #> if ($changesApplied) { $remediationObject.ChangesApplied = $true $remediationObject.Status = [RemediationStatus]::SUCCESS Write-AzsSupportLog -Level 'Informational' -Message $localizedData.ChangesApplied } else { $remediationObject.ChangesApplied = $false $remediationObject.Status = [RemediationStatus]::NO_CHANGE_APPLIED Write-AzsSupportLog -Level 'Informational' -Message $localizedData.ChangesNotApplied } } catch { $_ | Write-AzsSupportLog -Level 'Exception' # Report what was actually done. If one ghost root was removed and a later one # threw, the caller must still learn that a permanent deletion happened. $remediationObject.ChangesApplied = $changesApplied $remediationObject.ScriptStackTrace = Get-FormattedException -Exception $_ $remediationObject.ExceptionMessage = $localizedData.ChangesFailed -f $_.Exception.Message $remediationObject.Status = [RemediationStatus]::FAILURE } return $remediationObject # SIG # Begin signature block # MIInRAYJKoZIhvcNAQcCoIInNTCCJzECAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD5iHQ5XzeKLp79 # /zNnPKBK+wbBl+olGXhcTwr/v1MWaqCCDLowggX1MIID3aADAgECAhMzAAACHU0Z # yE7XD1dIAAAAAAIdMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQzWhcNMjcwNDE1MTg1 # OTQzWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDQvewXxx9gZZFC6Ys1WBay8BJ8kGA4JQnH5CMafqOASlTpK9H8 # o5ZXTXt0caVQTNMUPt445wXYD+dFtaKWTwDn1I52oUSrC9vJin1Gsqt+zyKJL5Dg # 3eQXbQNR61DmMy20GLTIO3SFed9Rfi/ophgCLGFLDR3r0KvHjwMb/jYWS0celV/4 # Lz27LfAekm8v9E5IXaeiXbAUYZKK090n4CVl3JBtbN+9DtI9SNu/yjvozW52/u7R # X/Ttpa/KDlpuokZ+Zcbvmtd9ur9gFLvZzh41o9MsE/clQtdaFWGvuo6Jua/ntpgk # ey3E5/vBFe+MJPG6phdnuo6r57ZudCudiI1bAgMBAAGjggGbMIIBlzAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFH6QuMwqcPG0hQlQ6c5jCtTTLrVeMEUGA1UdEQQ+MDykOjA4MR4wHAYDVQQL # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xFjAUBgNVBAUTDTIzMDAxMis1MDc1NTkw # HwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEwYAYDVR0fBFkwVzBVoFOg # UYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0 # JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNybDBtBggrBgEFBQcBAQRh # MF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # Y2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # dDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQBKTbYOjzwTG/DXGaz9 # s6+fQeaTtDcFmMY+5UyVFCyj7Pv+5i37qfX8lSL/tBIfYQfWsMuBQlfZurJD6r4H # VJ2CeH+1fgiq8dcHdVKoZ3Sa2qXoX3cq9iS8cVb06B7+5/XJ7I0OxHH9fDsvJ3T3 # w5V/ZtAIFmLrl+P0CtG+92uzRsn0nTbdFjOkLMLWPLAU3THohKRlSEMgFJpPkm5n # 5UAZ35xX6FWCrDLsSKb555bTifwa8mJBwdlof0bmfYidH+dxZ1FdDxvLnNl9zeKs # A4kejaaIqqIPguhwAti5Ql7BlTNoJNwxCvBmqW2MQLnCkYN/VVUsR3V2x/rcTNzo # Bf/Z/SpROvdaA2ZOOd1uioXJt3tdLQ7vHpqpib0KfWr/FWXW10q38VxfCnRQBqzb # SuztR7nEMuzX7Ck+B/XaPDXd1qh72+QYyB0Z2VzWmO9zsnb9Uq/dwu8LGeQqnyu6 # 7SDGACvnXii2fb9+US492VTnXSnFKyqwgzUyFMtZK1/sHYTv6bG4TtQUygQxTN+Z # V+aJIlKO2MqZ7bKrAnOzS9m6NgoTdWOq11bTOZwKlIEV/EhV9SWkDmdpR/hPPT2v # 6TEj4F8PT/zHjRezIU5c/DGlt/VhY/pK0XkJtEyMmmS1BMtjU/rqBZVMIm3dnxQs # /TBByr+Cf8Z1r7aifQVQ+WSqzjCCBr0wggSloAMCAQICEzMAAAA5O7Y3Gb8GHWcA # AAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRl # IEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoXDTM2MDMyMjIyMTMwNFow # VzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEo # MCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAyNDCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeqlRYHNa265v4IY9fH8TKh # emHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo0dtS/EW6I/yEL/bLSY8h # KpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATvQVL4tcf03aTycsz8QeCd # M0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a1uv1zerOYMnsneRRwCbp # yW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1FyQfK0fVkaya8SmVHQ/t # Of23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfOGSWHIIV4YrTJTT6PNty5 # REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7ttOu1bVnXfHaqPYl2rPs # 20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJuz2MXMCt7iw7lFPG9LXK # Gjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxSCwyoGIq0PhaA7Y+VPct5 # pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOmVQop36wUVUYklUy++vDW # eEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3SkE/xIkgpfl22MM1itkZ # 35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGC # NxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPXLQaUEggxMBkGCSsGAQQB # gjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # ci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAwTgYIKwYBBQUHMAKGQmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAFJQfOChP7onn6fLI # MKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D5W4wMwYeLystcEqfkjz4 # NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBYnbu0+THSuVHTe0VTTPVh # ily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSIvgn0JksVBVMYVI5QFu/q # hnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6aR9y34aiM1qmxaxBi6OU # nyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4wPKC5OmHm1DQIt/MNokbb # H3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7RTX8AdBPo0I6OEojf39z # uFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK/fg8B2qjW88MT/WF5V5u # vZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSKYBv0VisCzfxgeU+dquXW # 9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkwYTu/9dLeH2pDqeJZAABV # DWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVTQl0v4q8J/AUmQN5W4n10 # 1cY2L4A7GTQG1h32HHAvfQESWP0xghngMIIZ3AIBATBuMFcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jv # c29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIdTRnITtcPV0gAAAAAAh0w # DQYJYIZIAWUDBAIBBQCggZAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwLwYJ # KoZIhvcNAQkEMSIEILUdMEEe4x9XoyYmouHRF0GWX2Pza4/GAidD1H84Cr/JMEIG # CisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEAGW2Q+lOebxW5dv/R # kT/a/W/SW4ak8HxlCaqZC6vaSU9lZhIIpKIbt535SQPwxA3tZ7Ufe9B9VxTmxdlk # rspJz3ObRvvxwtJJHCQvmWbq1nz8oc506HI7Ip0VQuXiE+xlVovitZw9sTnT+Z9F # SJ4kSct72xgLu2g01S9PcVduxNAYaKsn40/BLuYgVOPzDBOx+kBWq0sOYXV/R7hn # B8kbvbOgz8fJIm/NQjt3LIEsxO6MfxK7pIHLXEjkLI826WIzfL10VGE7t9niXKSU # XdSp1WZ+M+RzYJuF1bNs43ou0CQEQrQy7Y63ZRReuFjjn9JmGjYDKD6IGzIH3vrt # qzphbKGCF7AwghesBgorBgEEAYI3AwMBMYIXnDCCF5gGCSqGSIb3DQEHAqCCF4kw # gheFAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsqhkiG9w0BCRABBKCCAUkEggFF # MIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCAdoGexKJsMrWOD # lOCjTQ2bJ/jjqxEjE5EzSn+O3hwttAIGaonmeGrxGBMyMDI2MDkwMjE1MjY1Mi40 # MDRaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExp # bWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo2NTFBLTA1RTAtRDk0NzEl # MCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaCCEf4wggcoMIIF # EKADAgECAhMzAAACFRgD04EHJnxTAAEAAAIVMA0GCSqGSIb3DQEBCwUAMHwxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv # c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI1MDgxNDE4NDgyMFoXDTI2MTEx # MzE4NDgyMFowgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # LTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEn # MCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYDVQQD # ExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIICIjANBgkqhkiG9w0BAQEF # AAOCAg8AMIICCgKCAgEAw3HV3hVxL0lEYPV03XeNKZ517VIbgexhlDPdpXwDS0BY # txPwi4XYpZR1ld0u6cr2Xjuugdg50DUx5WHL0QhY2d9vkJSk02rE/75hcKt91m2I # h287QRxRMmFu3BF6466k8qp5uXtfe6uciq49YaS8p+dzv3uTarD4hQ8UT7La95pO # JiRqxxd0qOGLECvHLEXPXioNSx9pyhzhm6lt7ezLxJeFVYtxShkavPoZN0dOCiYe # h4KgoKoyagzMuSiLCiMUW4Ue4Qsm658FJNGTNh7V5qXYVA6k5xjw5WeWdKOz0i9A # 5jBcbY9fVOo/cA8i1bytzcDTxb3nctcly8/OYeNstkab/Isq3Cxe1vq96fIHE1+Z # GmJjka1sodwqPycVp/2tb+BjulPL5D6rgUXTPF84U82RLKHV57bB8fHRpgnjcWBQ # uXPgVeSXpERWimt0NF2lCOLzqgrvS/vYqde5Ln9YlKKhAZ/xDE0TLIIr6+I/2JTt # XP34nfjTENVqMBISWcakIxAwGb3RB5yHCxynIFNVLcfKAsEdC5U2em0fAvmVv0so # nqnv17cuaYi2eCLWhoK1Ic85Dw7s/lhcXrBpY4n/Rl5l3wHzs4vOIhu87DIy5QUa # EupEsyY0NWqgI4BWl6v1wgse+l8DWFeUXofhUuCgVTuTHN3K8idoMbn8Q3edUIEC # AwEAAaOCAUkwggFFMB0GA1UdDgQWBBSJIXfxcqAwFqGj9jdwQtdSqadj1zAfBgNV # HSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBfBgNVHR8EWDBWMFSgUqBQhk5o # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBU # aW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmwwbAYIKwYBBQUHAQEEYDBeMFwG # CCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRz # L01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNydDAMBgNV # HRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMA4GA1UdDwEB/wQEAwIH # gDANBgkqhkiG9w0BAQsFAAOCAgEAd42HtV+kGbvxzLBTC5O7vkCIBPy/BwpjCzeL # 53hAiEOebp+VdNnwm9GVCfYq3KMfrj4UvKQTUAaS5Zkwe1gvZ3ljSSnCOyS5OwNu # 9dpg3ww+QW2eOcSLkyVAWFrLn6Iig3TC/zWMvVhqXtdFhG2KJ1lSbN222csY3E3/ # BrGluAlvET9gmxVyyxNy59/7JF5zIGcJibydxs94JL1BtPgXJOfZzQ+/3iTc6eDt # maWT6DKdnJocp8wkXKWPIsBEfkD6k1Qitwvt0mHrORah75SjecOKt4oWayVLkPTh # o12e0ongEg1cje5fxSZGthrMrWKvI4R7HEC7k8maH9ePA3ViH0CVSSOefaPTGMzI # hHCo5p3jG5SMcyO3eA9uEaYQJITJlLG3BwwGmypY7C/8/nj1SOhgx1HgJ0ywOJL9 # xfP4AOcWmCfbsqgGbCaC7WH5sINdzfMar8V7YNFqkbCGUKhc8GpIyE+MKnyVn33j # suaGAlNRg7dVRUSoYLJxvUsw9GOwyBpBwbE9sqOLm+HsO00oF23PMio7WFXcFTZA # jp3ujihBAfLrXICgGOHPdkZ042u1LZqOcnlr3XzvgMe+mPPyasW8f0rtzJj3V5E/ # EKiyQlPxj9Mfq2x9himnlXWGZCVPeEBROrNbDYBfazTyLNCOTsRtksOSV3FBtPnp # QtLN754wggdxMIIFWaADAgECAhMzAAAAFcXna54Cm0mZAAAAAAAVMA0GCSqGSIb3 # DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIw # MAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAx # MDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMyMjVaMHwxCzAJBgNVBAYTAlVT # MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1l # LVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA # 5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51yMo1V/YBf2xK4OK9uT4XYDP/ # XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY6GB9alKDRLemjkZrBxTzxXb1 # hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9cmmvHaus9ja+NSZk2pg7uhp7 # M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN7928jaTjkY+yOSxRnOlwaQ3K # Ni1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDuaRr3tpK56KTesy+uDRedGbsoy # 1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74kpEeHT39IM9zfUGaRnXNxF80 # 3RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2K26oElHovwUDo9Fzpk03dJQc # NIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5TI4CvEJoLhDqhFFG4tG9ahha # YQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZki1ugpoMhXV8wdJGUlNi5UPkL # iWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9QBXpsxREdcu+N+VLEhReTwDwV # 2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3PmriLq0CAwEAAaOCAd0wggHZMBIG # CSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUCBBYEFCqnUv5kxJq+gpE8RjUp # zxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJlpxtTNRnpcjBcBgNVHSAEVTBT # MFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jv # c29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYDVR0lBAwwCgYI # KwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGG # MA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186a # GMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3Br # aS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsG # AQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwDQYJKoZIhvcN # AQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/ypb+pcFLY+TkdkeLEGk5c9MTO1 # OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulmZzpTTd2YurYeeNg2LpypglYA # A7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM9W0jVOR4U3UkV7ndn/OOPcbz # aN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECWOKz3+SmJw7wXsFSFQrP8DJ6L # GYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4FOmRsqlb30mjdAy87JGA0j3m # Sj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3UwxTSwethQ/gpY3UA8x1RtnWN0 # SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPXfx5bRAGOWhmRaw2fpCjcZxko # JLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVXVAmxaQFEfnyhYWxz/gq77EFm # PWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGConsXHRWJjXD+57XQKBqJC482 # 2rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU5nR0W2rRnj7tfqAxM328y+l7 # vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEGahC0HVUzWLOhcGbyoYIDWTCC # AkECAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExp # bWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo2NTFBLTA1RTAtRDk0NzEl # MCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcGBSsO # AwIaAxUAj6eTejbuYE1Ifjbfrt6tXevCUSCggYMwgYCkfjB8MQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGlt # ZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsFAAIFAO5CO5UwIhgPMjAyNjA5 # MDIwNjA3MTdaGA8yMDI2MDkwMzA2MDcxN1owdzA9BgorBgEEAYRZCgQBMS8wLTAK # AgUA7kI7lQIBADAKAgEAAgIv5AIB/zAHAgEAAgITJTAKAgUA7kONFQIBADA2Bgor # BgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIBAAID # AYagMA0GCSqGSIb3DQEBCwUAA4IBAQAKrFIVIIKaLxILivOKk/x00B14YtWY6N0Q # 8uRLiOU3mc81ddYc4v/YizA497bKwdoqCpIWSAeyI6u2S0xkbBER5XzT0ez9TmbF # j0tTOsL0il2NZ0KdPALH2ydpi38FQgtmsVCLS3RI+wLixM3fCDTnr/eegWjHzTry # BtX3DqPQg/giT5LFWClliGK+Y5AKTgF93Vg6Kp/1YVS4K7c/YgL0oE/km7S2mctW # vNe7ZuROLVRf7KcfG8CAd0bXdojfYTXI6FMSR4ImPk89TBROx7F/xAX5cIjvDnhw # dtIxVa/ZwsqfKcq3HFs2iP+Q/lfzAi8KfTsytBM7z3vrmwX1yeJuMYIEDTCCBAkC # AQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG # A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAIVGAPTgQcm # fFMAAQAAAhUwDQYJYIZIAWUDBAIBBQCgggFKMBoGCSqGSIb3DQEJAzENBgsqhkiG # 9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgzkbqD5jIbF02A2JdtvsyuoceGWlK13jR # y78WwyTCrgkwgfoGCyqGSIb3DQEJEAIvMYHqMIHnMIHkMIG9BCBwEPR2PDrTFLcr # tQsKrUi7oz5JNRCF/KRHMihSNe7sijCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwAhMzAAACFRgD04EHJnxTAAEAAAIVMCIEIE2KOSuZqUulWLSQ # gwgABa/YxOiW0sjgx4gD1U68YApYMA0GCSqGSIb3DQEBCwUABIICAICxkLNyd21V # wxrmWAH7iVltxg10Ro4xGc79ULewo7QM7aychAZwL5OwfBkEwSkV5OQDUw+0NoB8 # rnRbGcJgutYqum444BIKZxz3mBT6gIzvnoIJ/6XTZcmglw7bTN8gF4EAVrsvhqnm # t2KshbKG9m2NZTWMsxR7tUKhyOllKxezOBDox0qffgOcxv2C/fVO5YUHoo0bWAd7 # WORhwLXZI1EbXaQ3xEHSxlnwoYigNSNr+DYWXShOZSbqOJiElFyAnHBYlheCzIFw # VcB1behWHpVyHolJoKJR/kuOwtHNTx/gcyHWUZys1KHi1nuC4symGlAse06E/1T6 # oW2XTJaaiKjya7wVLomSwfICwth16vEdFw63dvpnv6R2BoRqTtdNx+7AsESdavua # 7kUjiDkj8QlxWBK1S2xZQvKgNWLnMQpvc0OdK1O9d1gXh55IJHWlof7nJJg9jIW9 # GwhcH7oIIEWnaW+qAUeT/SWLVVmYS4lQyGcowg/Rg/yCwNZnsfcXReqWqQg33/y3 # AporrhV9rvYMXppgnHfONO2a0AvPQ4ChBr2aHMJ6ldyTcUNaiJ1jdNXefA1mG+R7 # eahBebUVY+D4cLGGwH/EDVHP7LJwUDgPb2yBtK9LXDVaKKu/RZPWwQncf1WrPQ1u # 3mQPeTGJpAQ6AdEYuxx6Emb/QkYsAvvh # SIG # End signature block |