Git.psm1
|
function Add-GitTag { [CmdletBinding()] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string] $Version ) $tagName = "v$Version" $sha = Start-NativeExecution git rev-parse HEAD $shortSha = $shortSha = $sha.Substring(0, 8) $commitMessage = "Added tag $tagName for changeset $shortSha" Log info $commitMessage Start-NativeExecution git tag -a $tagName -m $commitMessage } function Clear-GitBranches { [CmdletBinding()] param( [switch] $IncludeGoneRemoteBranches ) $currentBranch = Start-NativeExecution git rev-parse --abbrev-ref HEAD if ($LASTEXITCODE -ne 0) { Log warning 'Error on getting the current branch. Are you outside of a Git repository?' Log trace "$currentBranch" return } Log info "Searching for branches which already merged into '$currentBranch'..." $branches = @{ } # 1. Try the default way (no remote rebased branches can be detected) $mergedBranches = Get-GitMergedBranches $mergedBranches | ForEach-Object { Log trace "Branch found with Git default logic: '$_'" } if ($mergedBranches) { $branches.Add('default logic', $mergedBranches) > $null } # 2. Try the custom way (check each hash, also remote rebased branches can be detected) $mergedOrRebasedBranches = Get-GitMergedOrRebasedBranches $mergedOrRebasedBranches | ForEach-Object { Log trace "Branch found with Git deeper logic: '$_'" } if ($mergedOrRebasedBranches) { $branches.Add('deep logic', $mergedOrRebasedBranches) > $null } # 3. Try also the rebased and squashed logic (check for branches which are already contained in the current branch, even if they were rebased or squashed) $rebasedAndSquashedBranches = Get-RebasedAndSquashedBranches $rebasedAndSquashedBranches | ForEach-Object { Log trace "Branch found with Git rebased and squashed logic: '$_'" } if ($rebasedAndSquashedBranches) { $branches.Add('rebased and squashed logic', $rebasedAndSquashedBranches) > $null } # 4. Try also the remote gone logic (check for branches which are removed on remote, but still exist locally) if ($IncludeGoneRemoteBranches) { # 3. Get also remote gone branches $remoteGoneBranches = Get-GitRemoteGoneBranches $remoteGoneBranches | ForEach-Object { Log trace "Branch found with Git remote gone logic: '$_'" } if ($remoteGoneBranches) { $branches.Add('gone logic', $remoteGoneBranches) > $null } } # Filter out duplicates $uniqueMergedBranches = Get-Distincted @($mergedBranches, $mergedOrRebasedBranches, $rebasedAndSquashedBranches, $remoteGoneBranches) | Sort-Object if (-not $uniqueMergedBranches) { Log info 'No merged branches were found' return } $sb = [System.Text.StringBuilder]::new() $prefix = 'Merged branch:' $logicColumn = ($uniqueMergedBranches | Sort-Object Length -Descending | Select-Object -First 1).Length + 2 foreach ($branch in $uniqueMergedBranches) { $logics = Get-Logics -groupedBranches $branches -branchName $branch $sb.Clear() > $null $sb.Append(("$prefix {0,-$logicColumn} {1}" -f "'$($branch)'", "[detected by: $($logics -join ', ')]")) > $null Log info $sb.ToString() } $title = 'Delete merged branches' $message = 'Do you want to delete the already-merged local branches displayed above?' $yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Delete the remote branches listed.' $no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Leave the branches alone.' $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) $result = $Host.UI.PromptForChoice($title, $message, $options, 1) if ($result -eq 1) { return } $uniqueMergedBranches | ForEach-Object { Start-NativeExecution git branch -D $_ | Log info } } function Get-GitMergedBranches() { $mergedBranches = [System.Collections.ArrayList]@() $branches = Start-NativeExecution git branch --merged if ($LASTEXITCODE -ne 0) { Log trace "Error on getting merged branches: $branches" return } $filteredBranches = $branches | ForEach-Object { $_.Trim() } | Where-Object { $_ -notmatch '^\* (master|main)$' } | Where-Object { $_ -notmatch '^(master|main)$' } | Where-Object { $_ -notmatch '^\* .*$' } foreach ($branch in $filteredBranches) { Log trace "Branch already merged '$branch'" $mergedBranches.Add($branch) > $null } return $mergedBranches } function Get-GitMergedOrRebasedBranches() { $currentBranch = Start-NativeExecution git rev-parse --abbrev-ref HEAD if ($LASTEXITCODE -ne 0) { Log trace "Error on getting merged or rebased branches: $currentBranch" return } Log trace "currentBranch: '$currentBranch'" $currentLocalBranch = Start-NativeExecution git symbolic-ref -q HEAD if ($LASTEXITCODE -ne 0) { Log trace "Error on getting merged or rebased branches: $currentLocalBranch" return } Log trace "currentLocalBranch: '$currentLocalBranch'" $currentRemoteBranch = Start-NativeExecution git for-each-ref '--format="%(upstream:short)"' $currentLocalBranch if ($LASTEXITCODE -ne 0) { Log trace "Error on getting merged or rebased branches: $currentRemoteBranch" return } Log trace "currentRemoteBranch: '$currentRemoteBranch'" $mergedbranches = [System.Collections.ArrayList]@() if (-not $currentRemoteBranch) { return $mergedbranches } $localBranches = Start-NativeExecution git for-each-ref refs/heads '--format="%(refname:short)"' | Where-Object { $_ -notmatch '(master|main)' } | Where-Object { $_ -notmatch $currentBranch } if ($LASTEXITCODE -ne 0) { Log trace "Error on getting merged or rebased branches: $localBranches" return } foreach ($localBranch in $localBranches) { $notMergedHashFound = $false Log trace "Check local branch '$localBranch'..." $results = Start-NativeExecution git cherry $currentRemoteBranch $localBranch if ($LASTEXITCODE -ne 0) { Log trace "Get merged hashes failed: '$results'" break } foreach ($result in $results) { if ($result -match '^\-') { Log trace "Hash merged '$result'" continue } if ($result -match '^\+') { Log trace "Hash was not merged '$result'" } else { Log trace "No hash '$result'" } $notMergedHashFound = $true break } if (-not $notMergedHashFound) { Log trace "Branch already merged '$localBranch'" $mergedbranches.Add($localBranch) > $null } } return $mergedbranches } function Get-RebasedAndSquashedBranches { <# .SYNOPSIS Finds local branches whose changes are already contained in the current branch. .DESCRIPTION Iterates over all local branches (except the current one) and uses a test merge to check whether the branch's content is already present in the current branch. Detects squash and rebase merges where commit SHAs no longer match. .PARAMETER ExcludeBranches Branch names to skip (e.g. 'develop', 'release/*'). The current branch is skipped automatically. .EXAMPLE Get-RebasedAndSquashedBranches .EXAMPLE Get-RebasedAndSquashedBranches -ExcludeBranches 'develop','staging' #> [CmdletBinding()] param( [string[]]$ExcludeBranches = @() ) # Make sure we are inside a Git repository git rev-parse --is-inside-work-tree 2>$null | Out-Null if ($LASTEXITCODE -ne 0) { Write-Error 'Not a Git repository in the current directory.' return } # Make sure the working directory is clean - otherwise the test merge could go wrong $status = git status --porcelain if ($status) { Write-Error 'Working directory is not clean. Please commit or stash first.' return } # Determine the current branch (this is the target branch for comparison) $currentBranch = git rev-parse --abbrev-ref HEAD if ($currentBranch -eq 'HEAD') { Write-Error 'Detached HEAD - please check out a branch first.' return } Write-Verbose "Checking branches against '$currentBranch'..." # Get all local branches, filter out the current one and excluded ones $allBranches = git branch --format='%(refname:short)' | Where-Object { $_ -ne $currentBranch -and $_ -notin $ExcludeBranches } if (-not $allBranches) { Write-Verbose 'No branches to check.' return } $mergedBranches = @() foreach ($branch in $allBranches) { Write-Verbose "Checking '$branch'..." # Run a test merge without committing, suppress stderr git merge --no-commit --no-ff $branch 2>&1 | Out-Null $mergeExitCode = $LASTEXITCODE if ($mergeExitCode -ne 0) { # Merge conflict - branch definitely contains its own changes Write-Verbose " '$branch' has conflicts - skipping." git merge --abort 2>&1 | Out-Null continue } # Check whether the merge produced any actual content changes $diff = git diff --cached --stat # Always abort the merge afterwards # On "Already up to date" there is no active merge -> --abort would fail $mergeHead = git rev-parse --verify --quiet MERGE_HEAD 2>$null if ($mergeHead) { git merge --abort 2>&1 | Out-Null } if (-not $diff) { # No changes -> branch content is already included Write-Verbose " '$branch' is already included." $mergedBranches += $branch } else { Write-Verbose " '$branch' still has open changes." } } return $mergedBranches } function Get-GitRemoteGoneBranches() { $goneBranches = [System.Collections.ArrayList]@() $branches = Start-NativeExecution git branch -v if ($LASTEXITCODE -ne 0) { Log trace "Error on getting remote gone branches: $branches" return } $filteredBranches = $branches | ForEach-Object { $_.Trim() } | Where-Object { $_ -notmatch '^\* (master|main)' } | Where-Object { $_ -notmatch '^(master|main)' } | Where-Object { $_ -notmatch '^\* .*' } | Where-Object { $_ -match '^.*\[gone\].*' } if (-not $filteredBranches) { Log trace 'No remote gone branches found' return } $filteredBranchNames = $filteredBranches | ForEach-Object { $_.Split(' ', [System.StringSplitOptions]::RemoveEmptyEntries)[0] } foreach ($branchName in $filteredBranchNames) { Log trace "Branch is removed on remote '$branchName'" $goneBranches.Add($branchName) > $null } return $goneBranches } function Get-Distincted { param( [Parameter()] [object[][]] $Items ) $hashSet = [System.Collections.Generic.HashSet[System.Object]]::new() foreach ($item in $Items) { foreach ($entry in $item) { $hashSet.Add($entry) > $null } } $distinctedList = [System.Collections.ArrayList]@() foreach ($value in $hashSet) { $distinctedList.Add($value) > $null } return $distinctedList } function Get-Logics([hashtable] $groupedBranches, [string] $branchName) { $logics = [System.Collections.ArrayList]@() foreach ($logic in $groupedBranches.GetEnumerator()) { [object[]] $values = $logic.Value if ($values.Contains($branchName)) { $logics.Add($logic.Name) > $null } } return $logics } function Invoke-GitkAll() { Invoke-Gitk -All @args } function Invoke-Gitk() { param( [switch] $All ) $command = 'gitk' $arguments = [System.Collections.ArrayList]@() if ($All) { $arguments.Add('--all') > $null } $arguments += $args Start-NativeExecution $command @arguments } function Merge-GitAllRemoteBranches($RemoteRefs = $null, $Strategie = 'recursive', [switch] $UseTheirs = $false, [switch] $UseOurs = $false) { if ($null -eq $RemoteRefs) { $RemoteRefs = 'origin/' } $currentBranch = (git rev-parse --abbrev-ref HEAD).Trim() git fetch --all git branch -r | ForEach-Object { $localBranch = $_ $localBranch = $localBranch.Trim().Replace($RemoteRefs, '').Trim() $localBranch = $localBranch.Trim().Replace('*', '').Trim() $remoteBranch = $_.Trim().Replace('*', '').Trim() if ($remoteBranch.StartsWith($RemoteRefs) -and -not $remoteBranch.StartsWith($RemoteRefs + 'HEAD')) { Log info "Processing branch '${localBranch}'..." git checkout $localBranch if ($UseTheirs) { git merge $remoteBranch -s $Strategie -X theirs } elseif ($UseOurs) { git merge $remoteBranch -s $Strategie -X ours } else { git merge $remoteBranch } } } git checkout $currentBranch } function Merge-GitBranchUseTheirs($SourceBranchName, $DestinationBranchName) { if (($null -eq $SourceBranchName) -or ($null -eq $DestinationBranchName)) { return } $currentBranch = (git rev-parse --abbrev-ref HEAD).Trim() $tempHash = Get-Checksum -Value ([System.Guid]::NewGuid()) -Algorithm SHA1 $tempBranchName = "merge-use-theirs-${tempHash}" $commitMessage = "Merge branch '${SourceBranchName}' into '${DestinationBranchName}'" git checkout -b $tempBranchName $SourceBranchName git merge --strategy=ours $DestinationBranchName git checkout $DestinationBranchName git merge --no-ff $tempBranchName -m $commitMessage git branch -D $tempBranchName git checkout $currentBranch } function Push-GitAllTrackedBranches($RemoteRefs) { if ($null -eq $RemoteRefs) { $RemoteRefs = 'origin/' } $currentBranch = (git rev-parse --abbrev-ref HEAD).Trim() git branch | ForEach-Object { $localBranch = $_ $localBranch = $localBranch.Trim().Replace('*', '').Trim() $trackingRefs = git config branch.$localBranch.merge if ($trackingRefs -and ($trackingRefs.Trim().StartsWith('refs/heads/' + $RemoteRefs))) { Log info "Processing branch '${localBranch}'..." git checkout $localBranch git push } } git checkout $currentBranch } function Remove-GitAllBranches($RemoteRefs, [switch] $ForceAll = $false) { if ($null -eq $RemoteRefs) { $RemoteRefs = 'origin/' } $currentBranch = (git rev-parse --abbrev-ref HEAD).Trim() $tempHash = Get-Checksum -Value ([System.Guid]::NewGuid()) -Algorithm SHA1 $tempBranchName = "remove-all-${tempHash}" git checkout -f -b $tempBranchName git branch | ForEach-Object { $localBranch = $_ $localBranch = $localBranch.Trim().Replace('*', '').Trim() $trackingRefs = git config branch.$localBranch.merge if ($trackingRefs -and ($localBranch -ne $tempBranchName) -and (($ForceAll) -or ($null -ne $trackingRefs))) { if (($ForceAll) -or ($trackingRefs.Trim().StartsWith('refs/remotes/' + $RemoteRefs)) -or ($trackingRefs.Trim().StartsWith('refs/heads/' + $RemoteRefs))) { Log info "Delete local branch '${localBranch}'..." git branch -D $localBranch } } } if ($ForceAll) { git checkout master } else { git checkout $currentBranch } git branch -D $tempBranchName } function Reset-GitAllBranches($RemoteRefs) { Remove-GitAllBranches $RemoteRefs Set-GitTrackAllRemoteBranches $RemoteRefs Merge-GitAllRemoteBranches $RemoteRefs } function Set-GitTrackAllRemoteBranches($RemoteRefs) { if ($null -eq $RemoteRefs) { $RemoteRefs = 'origin/' } $localBranches = git branch | ForEach-Object { $_.Trim().Replace('*', '').Trim() } $notTrackedLocalBranches = @() git for-each-ref --format='%(refname:short) <- %(upstream:short)' 'refs/heads' | ForEach-Object { $row = $_ -split '<-' $localBranch = $row[0].Trim() $remoteBranch = $row[1].Trim() $query = "branch.${localBranch}.remote" $configRemote = git config --get $query if (-not $remoteBranch -and -not $configRemote) { $notTrackedLocalBranches += $localBranch } } git branch -r | ForEach-Object { $localBranch = $_ $localBranch = $localBranch.Trim().Replace($remoteRefs, '').Trim() $localBranch = $localBranch.Trim().Replace('*', '').Trim() $remoteBranch = $_.Trim().Replace('*', '').Trim() if ($remoteBranch.StartsWith($remoteRefs + 'HEAD') -or -not ($remoteBranch.StartsWith($remoteRefs))) { return } if (-not ($notTrackedLocalBranches -contains $localBranch) -and -not ($localBranches -contains $localBranch)) { git branch -t $localBranch $remoteBranch } elseif ($notTrackedLocalBranches -contains $localBranch) { git branch -u $remoteBranch $localBranch } } } function Set-GitTrackMatchedRemoteBranches($RemoteRefs) { if ($null -eq $RemoteRefs) { $RemoteRefs = 'origin/' } $notTrackedLocalBranches = @() git for-each-ref --format='%(refname:short) <- %(upstream:short)' 'refs/heads' | ForEach-Object { $row = $_ -split '<-' $localBranch = $row[0].Trim() $remoteBranch = $row[1].Trim() $query = "branch.${localBranch}.remote" $configRemote = git config --get $query if (-not $remoteBranch -and -not $configRemote) { $notTrackedLocalBranches += $localBranch } } $remotes = git branch -r | ForEach-Object { $_.Trim().Replace('*', '').Trim() } $notTrackedLocalBranches | ForEach-Object { $localBranch = $_ $remotes | ForEach-Object { $remoteBranch = $_ if ($remoteBranch -eq ($RemoteRefs + $localBranch)) { git branch -u $remoteBranch $localBranch return } } } } function Update-GitAllBranches() { $currentBranch = git rev-parse --abbrev-ref HEAD git fetch --all $branchPairs = git for-each-ref --format='%(refname:short) <- %(upstream:short)' 'refs/heads' $branchPairs | ForEach-Object { $pair = $_ -split ' <- ' $localBranch = $pair[0] $remoteBranch = $pair[1] if ($localBranch -and $remoteBranch) { Log info "Processing branch '${localBranch}'..." git checkout $localBranch git rebase $remoteBranch } } git checkout $currentBranch } function Update-GitBranch() { git fetch --all $localBranch = git rev-parse --abbrev-ref HEAD $remoteBranch = git rev-parse --abbrev-ref --symbolic-full-name '@{upstream}' if (-not $remoteBranch) { Print-Warning "No upstream configured for branch '${localBranch}'" return } $remoteBranches = git for-each-ref --format='%(upstream:short)' 'refs/heads' foreach ($branch in $remoteBranches) { if ( $branch -eq $remoteBranch) { Log info "Rebase branch '${remoteBranch}' into '${localBranch}'..." git rebase $remoteBranch break } } } function Add-AssumedUnchanged { [CmdletBinding()] param( [Parameter(Mandatory = $true)] [string] $Path ) $files = Get-Item $Path | Select-Object -ExpandProperty FullName $files | Log info $title = 'Add assume-unchanged flag' $message = 'Do you want to add the assume-unchanged flag for the files displayed above?' $yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Add the assume-unchanged flag for each file at the Git index.' $no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Does not make any changes.' $options = [System.Management.Automation.Host.ChoiceDescription[]] @($yes, $no) $choice = $Host.UI.PromptForChoice($title, $message, $options, 1) switch ($choice) { 0 { foreach ($file in $files) { git update-index --assume-unchanged -- $file } Log info 'Add assumed-unchanged.' } 1 { Log info 'Nothing changed.' } } } function Remove-AssumedUnchanged { [CmdletBinding()] param( [Parameter(Mandatory)] [string] $Path ) $files = Get-Item $Path | Select-Object -ExpandProperty FullName $files | Log info $title = 'Remove assume-unchanged flag' $message = 'Do you want to remove the assume-unchanged flag for the files displayed above?' $yes = New-Object System.Management.Automation.Host.ChoiceDescription '&Yes', 'Remove the assume-unchanged flag for each file at the Git index.' $no = New-Object System.Management.Automation.Host.ChoiceDescription '&No', 'Does not make any changes.' $options = [System.Management.Automation.Host.ChoiceDescription[]] @($yes, $no) $choice = $Host.UI.PromptForChoice($title, $message, $options, 1) switch ($choice) { 0 { foreach ($file in $files) { git update-index --no-assume-unchanged -- $file } Log info 'Removed assumed-unchanged.' } 1 { Log info 'Nothing changed.' } } } New-Alias agt Add-GitTag New-Alias cgb Clear-GitBranches New-Alias gk Invoke-Gitk New-Alias gka Invoke-GitkAll New-Alias pgst Push-GitAllTrackedBranches New-Alias ugab Update-GitAllBranches New-Alias ugb Update-GitBranch # SIG # Begin signature block # MIIn8gYJKoZIhvcNAQcCoIIn4zCCJ98CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCxUP2Z8Drb5RZk # iYh2eSyGO5M0v4DIRn8o2KiAI7a0AaCCIP4wggWNMIIEdaADAgECAhAOmxiO+dAt # 5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNV # BAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBa # Fw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2Vy # dCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lD # ZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3E # MB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKy # unWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsF # xl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU1 # 5zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJB # MtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObUR # WBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6 # nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxB # YKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5S # UUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+x # q4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIB # NjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwP # TzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMC # AYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdp # Y2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0 # aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENB # LmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0Nc # Vec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnov # Lbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65Zy # oUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFW # juyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPF # mCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9z # twGpn1eqXijiuZQwggahMIIEiaADAgECAhAHhD2tAcEVwnTuQacoIkZ5MA0GCSqG # SIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRy # dXN0ZWQgUm9vdCBHNDAeFw0yMjA2MjMwMDAwMDBaFw0zMjA2MjIyMzU5NTlaMFox # CzAJBgNVBAYTAkxWMRkwFwYDVQQKExBFblZlcnMgR3JvdXAgU0lBMTAwLgYDVQQD # EydHb0dldFNTTCBHNCBDUyBSU0E0MDk2IFNIQTI1NiAyMDIyIENBLTEwggIiMA0G # CSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCtHvQHskNmiqJndyWVCqX4FtYp5FfJ # LO9Sh0BuwXuvBeNYt21xf8h/pLJ/7YzeKcNq9z4zEhecqtD0xhbvSB8ksBAfWBMZ # O0NLfOT0j7WyNuD7rv+ZFza+mxIQ79s1dCiwUMwGonaoDK7mqZfDpKEExR6UyKBh # 3aatT73U2Imx/x+fYTmQFq+N8FrLs6Fh6YEGWJTgsxyw1fAChCfgtEcZkdtcgK7q # uqskHtW6PJ9l5VNJ7T3WXpznsOOxrz3qx0CzWjwK8+3Kv2X6piWvd8YRfAOycSrT # 4/PM0cHLFc5xs/4m/ek4FCnYSem43doFftBxZBQkHKoPW3Bt6VIrhVIwvO7hrUjh # chJJZYdSld3bANDviJ5/ToP7ENv97U9MtKFvmC5dzd1p4HxFR0p5wWmYQbW+y3RF # m0np6H9m57MUMNp0ysmdJjb0f7+dVLX3OEBUb6H+r1LRLZT/xEOTuwOxGg2S4w25 # KGL9SCBUW4nkBljPHeJToU+THt0P8ZQf4B9IFlGxtLK0g3uOAnwSFgKtmNjhkTl8 # caLAQwbgEINCqrhc0b6k2Z8+QwgVAL0nIuzM9ckKP8xtIcWg85L3/l0cTkHQde+j # KGDG2CdxBHtflLIUtwqD7JA2uCxWlIzRNgwT0kH2en0+QV8KziSGaqO2r06kwboq # 2/xy4e98CEfSYwIDAQABo4IBWTCCAVUwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNV # HQ4EFgQUyfwQ71DIy2t/vQhE7zpik+1bXpowHwYDVR0jBBgwFoAU7NfjgtJxXWRM # 3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMD # MHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl # cnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRw # Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAc # BgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATANBgkqhkiG9w0BAQsFAAOCAgEA # C9sK17IdmKTCUatEs7+yewhJnJ4tyrLwNEnfl6HrG8Pm7HZ0b+5Jc+GGqJT8kRc7 # mihuVrdsYNHdicueDL9imhtCusI/rUmjwhtflp+XgLkmgLGrmsEho1b+lGiRp7LC # /10di8SAOilDkHj5Zx142xRvBrrWj9eOdSGHwYubAsEd6CDojwcaVz9pfXMzYO3k # c0O6PXg1TkcgkYlCUAuDHuk/sZx68W0FVj1P2iMh+VUq9lL1puroAydoeWVUh/+c # MXeqfgpBqlAW+r8ma5F6yKL0stVQH8vYb1ES0mJSIPyIfkIjC1V0pbZS3p0QWsKa # afEor8fLfLNfSxntVI/ugut0+6ekluPWRpEXH+JAiNdRjbLbZchCREe3/Xl0Ylwk # A+eQVJfM0A7XiuFtY/mOpK2AN+E25t5mQYFhpdxZX5LTDKWgDnb+A6QnEt4iNyuk # cLaJuS8IPgPz0E2ALZLt3Rqs+lXifK/GwnNIWQNbf7FmLDB9ph8i8dvsR1hsjc2K # PEW4bAsbvLcz8hN1zE1/QbOV92vDGoFjwZOi2koQ+UyEh0e8jDFHAKJeTI+p8EPE # /mqvojLFAnt31yXIA2tjt0ERtsjkhBNmZY6SEOfnIoOwvyqavLPya1Ut3/2cOFLu # NQ8Ql6HaZsNQErnnzn+ZEAaUTkPZaeVyoHIkODECLzkwgga0MIIEnKADAgECAhAN # x6xXBf8hmS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUw # EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x # ITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcwMDAw # MDBaFw0zODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp # Q2VydCwgSW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3Rh # bXBpbmcgUlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0ZodLRRF51NrY0NlLWZloMs # VO1DahGPNRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi6wuim5bap+0lgloM2zX4 # kftn5B1IpYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNgxVBdJkf77S2uPoCj7GH8 # BLuxBG5AvftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQSku2 # Ws3IfDReb6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJm/s80FiocSk1VYLZlDwF # t+cVFBURJg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+8y9o # HRaQT/aofEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1ZlAeSpQl92QOMeRxykvq # 6gbylsXQskBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9MmeOreGPRdtBx3yGOP+r # x3rKWDEJlIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7Yk/ehb//Wx+5kMqIMRvU # BDx6z1ev+7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm1UUl # 9VnePs6BaaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6X5uAiynM7Bu2ayBjUwID # AQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU729TSunk # Bnx6yuKQVvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08w # DgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEB # BGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsG # AQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz # dGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgG # BmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBABfO+xaAHP4H # PRF2cTC9vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQM2qE # JPe36zwbSI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt6vJy # 9lMDPjTLxLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0F8HABBgr0UdqirZ7bowe # 9Vj2AIMD8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmSNq1U # H410ANVko43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKfZxAvBAKqMVuqte69M9J6 # A47OvgRaPs+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzEwlvzZiiyfTPjLbnFRsjs # Yg39OlV8cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmMThi0 # vw9vODRzW6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOXgpIUsWTjd6xpR6oaQf/D # Jbg3s6KCLPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx9yHb # xtl5TPau1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3/BAP # vIXKUjPSxyZsq8WhbaM2tszWkPZPubdcMIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC # 0cR2p5V0aDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMO # RGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGlt # ZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAw # MFoXDTM2MDkwMzIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1l # c3RhbXAgUmVzcG9uZGVyIDIwMjUgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCC # AgoCggIBANBGrC0Sxp7Q6q5gVrMrV7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA # 69HFTBdwbHwBSOeLpvPnZ8ZN+vo8dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6w # W2R6kSu9RJt/4QhguSssp3qome7MrxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00 # Cll8pjrUcCV3K3E0zz09ldQ//nBZZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOM # A3CoB/iUSROUINDT98oksouTMYFOnHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmot # uQhcg9tw2YD3w6ySSSu+3qU8DD+nigNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1O # pbybpMe46YceNA0LfNsnqcnpJeItK/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeH # VZlc4seAO+6d2sC26/PQPdP51ho1zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1r # oSrgHjSHlq8xymLnjCbSLZ49kPmk8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSURO # wnu7zER6EaJ+AliL7ojTdS5PWPsWeupWs7NpChUk555K096V1hE0yZIXe+giAwW0 # 0aHzrDchIc2bQhpp0IoKRR7YufAkprxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGV # MIIBkTAMBgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM # 6DAfBgNVHSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMC # B4AwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQG # CCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKG # UWh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRp # bWVTdGFtcGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSg # UqBQhk5odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRU # aW1lU3RhbXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAI # BgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcE # ua5gQezRCESeY0ByIfjk9iJP2zWLpQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/Ym # RDfxT7C0k8FUFqNh+tshgb4O6Lgjg8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8 # AQ/UdKFOtj7YMTmqPO9mzskgiC3QYIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/E # ABgfZXLWU0ziTN6R3ygQBHMUBaB5bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQ # VTeLni2nHkX/QqvXnNb+YkDFkxUGtMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gV # utDojBIFeRlqAcuEVT0cKsb+zJNEsuEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85 # EE8LUkqRhoS3Y50OHgaY7T/lwd6UArb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hg # gt8l2Yv7roancJIFcbojBcxlRcGG0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJ # gKf47CdxVRd/ndUlQ05oxYy2zRWVFjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLv # UxxVZE/rptb7IRE2lskKPIJgbaP5t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7P # OGT75qaL6vdCvHlshtjdNXOCIUjsarfNZzCCBxswggUDoAMCAQICEAYFIuuX3jJX # cLz8AeYyZmYwDQYJKoZIhvcNAQELBQAwWjELMAkGA1UEBhMCTFYxGTAXBgNVBAoT # EEVuVmVycyBHcm91cCBTSUExMDAuBgNVBAMTJ0dvR2V0U1NMIEc0IENTIFJTQTQw # OTYgU0hBMjU2IDIwMjIgQ0EtMTAeFw0yNTEyMjkwMDAwMDBaFw0yNjEyMjgyMzU5 # NTlaMGExCzAJBgNVBAYTAkRFMQ8wDQYDVQQIEwZCYXllcm4xETAPBgNVBAcTCEZh # cmNoYW50MRYwFAYDVQQKEw1NYW51ZWwgVGFuemVyMRYwFAYDVQQDEw1NYW51ZWwg # VGFuemVyMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAuxv/b0+nhaEE # 94ewtCEHJFhCdgrwn6iF1lZ41Y40alX0LnSGBniZxw480yw+F9o6qhhprIpKvEoW # WW1q+KNMxjdbLgKPlMcudU8DTfUVxKRxlVuqSMdizawGlQgwtwrj5RDsWEE2k0nq # guNejIRWrWDn6JblBaj/WIx8DZ9YuYl6egi/KtJF5lYC6StOgymjFdZQ6WKs5v9Q # IZMCvMw0BqpthVkFUXEQ07J49/h50bkl1dfNAnT2K8V2QeVGuJ5YOSs3GFMXiAxZ # g6LJTHT0poTL5I5XD62X9xQ56LMRa9IDmFx6x4sMDrkn5oNVSGw7Vmx7cnI/5u1C # 1pEymuN8vTa3DeMcVOngt7k9wRLyA+OTzdlobO+o+Hfr2S9zFVh+7PVDC0wUzrTd # W7u1c63IK89HPHnTc37lnGFQUGPXYKXIooN6UhIbHRDTUFVO/sH2LysKLRyFWEs8 # qdOsszmx2zL+WNKmjrBmQBvPzrV7IimT6rpmpCYxEnoY/bFvXsmK5avv/Osj+efn # GkCc9hm7oLxy494MFy3u5S1XqkB0jweBCJo750sGG3N8QapKAicVYobSXBdeLxsm # H82yzsczRNPRAdyAGbFIe5vVpl43OSwclH9gRpREbdE63Bb8Uvyn+8FqECSb1f7N # uLXsMwue6nHTf7Lc/u48srSd6yRnY70CAwEAAaOCAdQwggHQMB8GA1UdIwQYMBaA # FMn8EO9QyMtrf70IRO86YpPtW16aMB0GA1UdDgQWBBREAaQBaa2AQTUPKUUkMbf9 # S5f5sDA+BgNVHSAENzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8v # d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoG # CCsGAQUFBwMDMIGXBgNVHR8EgY8wgYwwRKBCoECGPmh0dHA6Ly9jcmwzLmRpZ2lj # ZXJ0LmNvbS9Hb0dldFNTTEc0Q1NSU0E0MDk2U0hBMjU2MjAyMkNBLTEuY3JsMESg # QqBAhj5odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vR29HZXRTU0xHNENTUlNBNDA5 # NlNIQTI1NjIwMjJDQS0xLmNybDCBgwYIKwYBBQUHAQEEdzB1MCQGCCsGAQUFBzAB # hhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wTQYIKwYBBQUHMAKGQWh0dHA6Ly9j # YWNlcnRzLmRpZ2ljZXJ0LmNvbS9Hb0dldFNTTEc0Q1NSU0E0MDk2U0hBMjU2MjAy # MkNBLTEuY3J0MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBABqpRiImY/Bk # WSYmqNEZsmjcqPNRBEp9bYFMylajgTFR7dOLqF9sCStkO+cs/X64RKHkZtlaCrQa # ecZp6j/Dpq1fnkp2NfwuAaX2Osp/h6tMKnjaun3gvTdmI/j2iyJv6YJRxZ7daee7 # q9bkPzCTINwNc7AqWHbZ3Whlg+MmhLXaFHpoasR5JO9Vh+A8z8Y593G1bc7/Wjp2 # JWBNrCLjSUuz83YcDtf7yaURHuoJ96NDrHpbggaYU1s75sMhfBwAMTuYN2HmQe6/ # ShmDwGPtNzja0OtUdL0siHUp3Gouuqiux+ii7sjK0BDqvW3cbIQhCY41HkrJt4YF # e+KAUzZXeger2mTb9StmWLTLuqTKvUnCpzsVlqEO1I6NwsXgV2u46/0EYqk42vBT # e1vwXXj2Eawp5g4sSHQqbcxTAr/H5wZDIMp32tSyDMqV7zXhT6UWvxy5xua9Zkvf # j7bn7CzUWgX/+GMyP8KlgXEDG5rCY1uSxleFBvn0ACZjWRp+kWl17WbdrIL22Kkl # 2s1px/g9dfRbhHwNVAX1Mx2S7uCreeRs5qAA1cEjct2ulpNIbuPAEDDKenUHDTfN # k0osUL9uaOjSx6HiVkcwPHgFzyMyu+SCVOUTpBhwBXIH+/r77s6XVnQWmjUHcZUY # Y6KuwZiQ+E7joeAaZ0JGyW+LWx8WPfg7MYIGSjCCBkYCAQEwbjBaMQswCQYDVQQG # EwJMVjEZMBcGA1UEChMQRW5WZXJzIEdyb3VwIFNJQTEwMC4GA1UEAxMnR29HZXRT # U0wgRzQgQ1MgUlNBNDA5NiBTSEEyNTYgMjAyMiBDQS0xAhAGBSLrl94yV3C8/AHm # MmZmMA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAw # GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG # AQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIJrDkVh1NqHsnBE2PZjFy7nR8apv+X6u # v/jV0GbOdYLAMA0GCSqGSIb3DQEBAQUABIICAGY2Rs6oFTtDQ5GO+iFiX+G5k1jH # 2bak5DdSM4BKOGWAAsyYaoxoPhZXyE1MWMUKtunhExYfUbKM+efvbYx0qLj/eY/r # bYNk7YyJyz1PKo71BTMipDp3Ozsf9GWHkJxSq4RRG6PkVhB0qtLd4VT+kcfqAr5a # Ikrp9AYrLYx6HNiIRcmgeQJwmBf2fkwUyjUZW6knUrMMKD3A2nw8wox9ULXBgGYz # NPrnZ8ibCEBneWxPLjNIiVEQTUiKJSNcNPO17LVAdTiykWEgm/W0j9wKJqcOxsG0 # k1XQmN5XdZPJDzxBe3HEnkC+6rRwFuALG1BhhKuK0p8sTWLxd1K1gm4Hc9dGE7j6 # P15nVlii6sBrx1/RW+m2LZNABkxUHoxh6jCocFcPH73RKic8wl1rwU7nIRmktUwG # 7V4QvqMvOu2teHl6G4UZ7MjvHOnX5bNGWGHCqmBD1XrJ0CJm5yw6ozPrhmgXuLIs # kd3VI8pyWROu37lvV3Ab3jFn7yF7xohD2YJXDUTFdh773s5/Z6Fkomf8I0iSPsVJ # TC3yzkN7kzzc/JeHMQ+2D9NiLBg/xPlAtFy/vk1/VIBYM0HPRWV3DMjDGomBtOmd # MRHqlpRukpkLHe0ourLOVo9b2TpL1shEpqOiHTZHZ8aGPyw2it9Qyg1ovyyZZ4m1 # VYLeLRsSuELrXPSVoYIDJjCCAyIGCSqGSIb3DQEJBjGCAxMwggMPAgEBMH0waTEL # MAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMUEwPwYDVQQDEzhE # aWdpQ2VydCBUcnVzdGVkIEc0IFRpbWVTdGFtcGluZyBSU0E0MDk2IFNIQTI1NiAy # MDI1IENBMQIQCoDvGEuN8QWC0cR2p5V0aDANBglghkgBZQMEAgEFAKBpMBgGCSqG # SIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI2MDQyNTE2NTgy # OVowLwYJKoZIhvcNAQkEMSIEINBSMnJIhFKHsCWx0r8lgCllFO9KlBIheWZ62bPD # M+e4MA0GCSqGSIb3DQEBAQUABIICAIJfLKjiDu9OHJQ9Yk0EzFNtEQEVnojsoaaR # c3OuINweewc/mhREmcOyHBSGiPXBsZUWzhqzc4joCNlL8sueUFmh+ODSgOW4R+ub # H/AIy60ifTN9Tns/kiIdOyoMbidhqqKLTo7qXVrY9HI9PcWyP2yTCgpmq8KyUKGf # 1aJjTpNgovX5khbFb6G0LeZTm5rtjqRC6i62PIAJlMBf/msFthHH7fp8J+oz2O0D # GaDV68MxRoUVvLn4MwgIphvyx+W7x7gpKC+lCcJDq3W+ALR5ot3QdCwJePOTrGRn # 1CzCVZKCsQ9v+CsYzM1QJcYLvJHxdLfMmtx79o3eWjNLWTERQ7jhHI0pvDNH20sQ # CaNnKUwij1ED2ImLGiZK8UckzRhG1Uqglvwsw8khuRmX1aCN6M+rzOGzEUsKHiYO # gdRDPsLLd/ichZnfZUdoMR6m/9xooN4jowjMg4k8NoSRuOjSy812yQ0t4RHV+fQE # vXwvixWo+dsfFBZGLAl8AZ71JS66bwJ91h+w/Hm5k/bRmDMxBhSFhHz3pJZh10GZ # FUJSKNiNbXsHBEXV8l1X5Gld/hEgLJWV09+ZwZQNvXXNZNUHRBZ9Kf1yasy3vUzs # GkE5lbq8lq4D3wGVTAFqPe/2oujrVWRwGgtQu0gEFaSwhd0zYEX4PP0/8XtSiOxj # DQ2ZB8J/ # SIG # End signature block |