# Copyright (c) 2025 SIOS Technology Corp. # # UpgradeCompatTool.ps1 <# .SYNOPSIS This script will check to verify that a system is compatable with DataKeeper v8.11.0 and v10.0.0 .DESCRIPTION This Powershell script creates a Windows form with two buttons - Check and Exit. The Check button will run a function that will verify whether the local system is compatible with DataKeeper versions 8.11.0 and 10.0.0. It will display a status message indicating whether the check is successful or not, and will set the exit code to 0 if the system is compatible, nonzero if it is not. .PARAMETER Console Runs the utility in just the console. .PARAMETER DryRun Runs a dry run without modifying any registry settings. .PARAMETER NoLog The script will not output any messages to the event logs #> param( [switch]$Console, [switch]$DryRun, [switch]$NoLog ) $script:DK_Version = "8.11.0 and 10.0.0" $script:app = "Application" $script:src_app = "UpgradeCompatTool" $script:INFO = "INFO" $script:WARN = "WARNING" $script:ContactSupport = "DO NOT proceed with the upgrade, and contact support to assist with remediation." $script:RunAdministrator = "Ensure you are running as an administrator." $script:SYS_COMPATIBLE = 0 $script:SYS_INCOMPATIBLE = 1 $global:ExitCode = $SYS_COMPATIBLE #### FUNCTIONS ####### function OutputStatus { param( [string]$Message, [switch]$Output, [switch]$Log, [int]$EventId, [string]$LogLevel ) # Output to the console or GUI if ($Output -and $Console) { Write-Host $Message } ElseIf ($Output) { $Status.Text = $Message $Status.Visible = $true } # Log the message if ($Log -and !$NoLog) { Write-EventLog -LogName $Script:app -Source $Script:src_app -EventId $EventId -EntryType $LogLevel -Message $Message } } # TestCompatibility: # # This is the action that occurs when the Check button is pressed. It will: # 1 - Attempt to open the ExtMirr driver key. If it does not exist, # set display a Success status message since it is not an upgrade. # If an error accessing the registry occurs, set the exit code to # Failed and display a status message with exception details. # 2 - Read the volume UpperFilters value. On any error, set the exit code # to failed and display an appropriate status message. # 3 - Loop through each entry in UpperFilters, adding any drivers to the # $NewUpperFilters string array but skipping ExtMirr. # 4 - If ExtMirr was not found, or it was not the last one in the list, # add it to the end of $NewUpperFilters and save $NewUpperFilters to # the volume UpperFilters value. If an error saving the registry value # occurs, set the exit code to failed (1) and display an appropriate # status message. # 5 - Checks if FixUpperFilters is enabled. If it is enabled, it disables # it and sets ChangedFixUpperFilters, as a record of the change, so it # can be reverted in future releases. # 6 - On success, display a Success status message. # function TestCompatibility { [string[]]$DryRunOutput = @() [string[]]$ChangesMade = @() # Add Event Log Source if not already present if (!$NoLog) { try { $SetupLogging = [System.Diagnostics.EventLog]::SourceExists($script:src_app) if (!($SetupLogging)) { New-EventLog -LogName $Script:app -Source $Script:src_app } } catch [System.Security.SecurityException] { OutputStatus -Message "Status: FAILED - Unable to establish event logging`r`n$RunAdministrator" -Output $global:ExitCode = $SYS_INCOMPATIBLE return } catch { OutputStatus -Message "Status: FAILED - Unable to establish event logging`r`n$ContactSupport`r`nError is: " + $($_.Exception.Message) -Output $global:ExitCode = $SYS_INCOMPATIBLE return } } OutputStatus -Message "Checking System Compatibility with DataKeeper v$DK_Version." -Log -EventId 1 -LogLevel $INFO # 1 - See if the ExtMirr key exists - if not then this is fresh install try { $ExtMirrKey = Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Services\ExtMirr' -ErrorAction Stop } # If not found we get an ItemNotFound exception catch [System.Management.Automation.ItemNotFoundException] { OutputStatus -Message "Status: Success - Fresh install of DataKeeper version $DK_Version is supported.`r`nPlease rerun utility after install, to disable FixUpperFilters feature." -Output -Log -EventId 3 -LogLevel $WARN return } # If any other error occurred print that catch { OutputStatus -Message "Status: FAILED - unexpected error`r`n$RunAdministrator`r`n$ContactSupport`r`nError is: $($_.Exception.Message)" -Output -Log -EventId 4 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } [string[]]$NewUpperFilters = @() # 2 - Read the volume UpperFilters value $RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Class\{71a27cdd-812a-11d0-bec7-08002be2092f}' $UpperFilters = Get-ItemProperty -Path $RegistryPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty UpperFilters -ErrorAction SilentlyContinue if($UpperFilters -eq $null) { OutputStatus -Message "Status: FAILED - unexpected error: failed to retrieve UpperFilters value`r`n$RunAdministrator`r`n$ContactSupport" -Output -Log -EventId 5 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } # 3 - Loop through UpperFilters values $foundExtMirr = $false $ExtMirrLast = $true # Append all filters to $NewUpperFilters, skipping ExtMirr foreach($FilterDriver in $UpperFilters) { if($FilterDriver -match 'ExtMirr') { $foundExtMirr = $true } else { $NewUpperFilters += $FilterDriver if($foundExtMirr) { $ExtMirrLast = $false } } } # 4 - If ExtMirr was not found, or if it was not last in the list # then append it to the list and save it to the UpperFilters. if(!$foundExtMirr -or ($foundExtMirr -and !$ExtMirrLast)) { $NewUpperFilters += 'ExtMirr' # Only make changes if we are not operating in dry run mode if ($DryRun) { OutputStatus -Message "Dry Run: UpperFilters order would be changed from '$UpperFilters' to '$NewUpperFilters'." -Log -EventId 12 -LogLevel $INFO $DryRunOutput += "UpperFilters order would be changed from '$UpperFilters' to '$NewUpperFilters'." } else { OutputStatus -Message "UpperFilters order will be changed from '$UpperFilters' to '$NewUpperFilters'." -Log -EventId 13 -LogLevel $INFO # Save the value - if not successful set Status string to FAILED try { Set-ItemProperty -Path $RegistryPath -Name UpperFilters -Value $NewUpperFilters -ErrorAction Stop } # Check for permission denied exception catch [System.Security.SecurityException] { OutputStatus -Message "Status: FAILED - Unable to save the UpperFilters value.`r`n$RunAdministrator`r`nError is: $($_.Exception.Message)" -Output -Log -EventId 9 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } # If any exception occurs, set status to failed and print it out catch { OutputStatus -Message "Status: FAILED - Unable to save the UpperFilters value.`r`n$ContactSupport`r`nError is: $($_.Exception.Message)" -Output -Log -EventId 6 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } $ChangesMade += "UpperFilters changed from '$UpperFilters' to '$NewUpperFilters'." } } # 5 - Check and update the FixUpperFilters setting $RegistryPath = 'HKLM:\SYSTEM\CurrentControlSet\Services\ExtMirr\Parameters' $FixUpperFilters = Get-ItemProperty -Path $RegistryPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty FixUpperFilters -ErrorAction SilentlyContinue $ExtMirrVersion = Get-ItemProperty -Path $RegistryPath -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Version -ErrorAction SilentlyContinue # Check DataKeeper version. If it is 8.9.1 or older, just set FixUpperFilters. $FixUpperFiltersVersions = @('8.9.2', '8.10.0', '8.10.1', '8.10.2', '8.11.0', '10.0.0') if($FixUpperFilters -eq $null -and !($FixUpperFiltersVersion -contains $ExtMirrVersion)) { OutputStatus -Message "DataKeeper Version predates FixUpperFilters feature. Preemptively creating value." -Log -EventId 11 -LogLevel $INFO # Set FixUpperFilters to 1, which will trigger the logic to set the actual registry value below. $FixUpperFilters = 1 $DryRunOutput += "FixUpperFilters key would need to be created." $ChangesMade += "FixUpperFilters key created." } # Check if we successfully collected the FixUpperFilters registry value elseif($FixUpperFilters -eq $null) { OutputStatus -Message "Status: FAILED - unexpected error: failed to retrieve FixUpperFilters value`r`n$RunAdministrator`r`n$ContactSupport" -Output -Log -EventId 7 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } # Check if FixUpperFilters is enabled. If so, disable it, and set ChangedUpperFilters as a record of the change. if($FixUpperFilters -eq 1) { # Only make changes if we are not operating in dry run mode if ($DryRun) { OutputStatus -Message "Dry Run: FixUpperFilters would be set to 0 and ChangedFixUpperFilters would be set to 1." -Log -EventId 14 -LogLevel $INFO $DryRunOutput += "FixUpperFilters would be set to 0 and ChangedFixUpperFilters would be set to 1." } else { OutputStatus -Message "FixUpperFilters will be set to 0 and ChangedFixUpperFilters will be set to 1." -Log -EventId 15 -LogLevel $INFO try { Set-ItemProperty -Path $RegistryPath -Name FixUpperFilters -Value 0 -ErrorAction Stop Set-ItemProperty -Path $RegistryPath -Name ChangedFixUpperFilters -Value 1 -ErrorAction Stop } # Check for permission denied exception catch [System.Security.SecurityException] { OutputStatus -Message "Status: FAILED - Unable to save the FixUpperFilters and/or ChangedFixUpperFilters value.`r`n$RunAdministrator`r`nError is: $($_.Exception.Message)" -Output -Log -EventId 10 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } # Catch all other errors catch { OutputStatus -Message "Status: FAILED - Unable to save the FixUpperFilters and/or ChangedFixUpperFilters value.`r`n$ContactSupport`r`nError is: $($_.Exception.Message)" -Output -Log -EventId 8 -LogLevel $WARN $global:ExitCode = $SYS_INCOMPATIBLE return } $ChangesMade += "FixUpperFilters set to 0 and ChangedFixUpperFilters set to 1." } } # 6 - Display a Status: Success message if we have gotten this far. Changes required if running in Dry Run mode. if ($DryRun) { if ($DryRunOutput.Count -eq 0) { OutputStatus -Message "Status: Success (Dry Run) - This system is compatible with an upgrade to DataKeeper version $DK_Version. No Changes required." -Output -Log -EventId 16 -LogLevel $WARN } else { OutputStatus -Message "Status: Changes Needed (Dry Run) - This system is NOT yet compatible with an upgrade to DataKeeper version $DK_Version. Changes Required:`r`n$($DryRunOutput -join "`r`n")" -Output -Log -EventId 17 -LogLevel $WARN } } elseif ($ChangesMade.Count -eq 0) { OutputStatus -Message "Status: Success - This system is compatible with an upgrade to DataKeeper version $DK_Version." -Output -Log -EventId 2 -LogLevel $WARN } else { OutputStatus -Message "Status: Success - This system is now compatible with an upgrade to DataKeeper version $DK_Version. Changes Made:`r`n$($ChangesMade -join "`r`n")" -Output -Log -EventId 18 -LogLevel $WARN } } function RunGui { Add-Type -AssemblyName System.Windows.Forms $FormObject = [System.Windows.Forms.Form] $LabelObject = [System.Windows.Forms.Label] $ButtonObject = [System.Windows.Forms.Button] $ToolForm = new-object $FormObject $ToolForm.ClientSize = '800,240' $ToolForm.Text = "DataKeeper Version $DK_Version Compatibility Test" $ToolForm.BackColor = '#EDF2FA' $Title = new-object $LabelObject $Title.Text = "Press the ''Check'' button to test your system for compatibility with DataKeeper version $DK_Version. `r`nThe status will be displayed upon completion" $Title.AutoSize = $true $Title.Font = 'Segoe UI,12' $Title.Location = new-object System.Drawing.Point(20, 20) $Status = new-object $LabelObject $Status.visible = $false $Status.AutoSize = $true $Status.Font = 'Segoe UI,12,style=bold' $Status.Location = new-object System.Drawing.Point(20, 80) $RunButton = new-object $ButtonObject $RunButton.Text = 'Check' $RunButton.ClientSize = '75,15' $RunButton.Location = new-object System.Drawing.Point(20,190) $RunButton.AutoSize = $true $RunButton.Font = 'Segoe UI,12' $RunButton.BackColor = '#f0f0f0' $ExitButton = new-object $ButtonObject $ExitButton.Text = 'Exit' $ExitButton.ClientSize = '35,15' $ExitButton.AutoSize = $true $ExitButton.Font = 'Segoe UI,12' $ExitButton.BackColor = '#f0f0f0' $ExitButton.Location = new-object System.Drawing.Point(105,190) #### BIND BUTTON FUNCTIONS ##### $RunButton.Add_Click({ $RunButton.Enabled = $false TestCompatibility $ExitButton.Enabled = $true }) $ExitButton.Add_Click({$ToolForm.Dispose()}) #### INITIALIZE AND RUN THE PROGRAM $ToolForm.Controls.AddRange(@($RunButton, $Title, $Status, $ExitButton)) $ToolForm.ShowDialog() | Out-Null $ToolForm.Dispose() } # Check whether to run in console mode or GUI mode if ($Console) { TestCompatibility } else { RunGui } exit $global:ExitCode # SIG # Begin signature block # MIIr5gYJKoZIhvcNAQcCoIIr1zCCK9MCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCD8uqiH8nx6GSSe # pDp23qSyfbmFPnZ3HUW7Q1K6FOxxnaCCJQMwggVvMIIEV6ADAgECAhBI/JO0YFWU # jTanyYqJ1pQWMA0GCSqGSIb3DQEBDAUAMHsxCzAJBgNVBAYTAkdCMRswGQYDVQQI # DBJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcMB1NhbGZvcmQxGjAYBgNVBAoM # EUNvbW9kbyBDQSBMaW1pdGVkMSEwHwYDVQQDDBhBQUEgQ2VydGlmaWNhdGUgU2Vy # dmljZXMwHhcNMjEwNTI1MDAwMDAwWhcNMjgxMjMxMjM1OTU5WjBWMQswCQYDVQQG # EwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMS0wKwYDVQQDEyRTZWN0aWdv # IFB1YmxpYyBDb2RlIFNpZ25pbmcgUm9vdCBSNDYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQCN55QSIgQkdC7/FiMCkoq2rjaFrEfUI5ErPtx94jGgUW+s # hJHjUoq14pbe0IdjJImK/+8Skzt9u7aKvb0Ffyeba2XTpQxpsbxJOZrxbW6q5KCD # J9qaDStQ6Utbs7hkNqR+Sj2pcaths3OzPAsM79szV+W+NDfjlxtd/R8SPYIDdub7 # P2bSlDFp+m2zNKzBenjcklDyZMeqLQSrw2rq4C+np9xu1+j/2iGrQL+57g2extme # me/G3h+pDHazJyCh1rr9gOcB0u/rgimVcI3/uxXP/tEPNqIuTzKQdEZrRzUTdwUz # T2MuuC3hv2WnBGsY2HH6zAjybYmZELGt2z4s5KoYsMYHAXVn3m3pY2MeNn9pib6q # RT5uWl+PoVvLnTCGMOgDs0DGDQ84zWeoU4j6uDBl+m/H5x2xg3RpPqzEaDux5mcz # mrYI4IAFSEDu9oJkRqj1c7AGlfJsZZ+/VVscnFcax3hGfHCqlBuCF6yH6bbJDoEc # QNYWFyn8XJwYK+pF9e+91WdPKF4F7pBMeufG9ND8+s0+MkYTIDaKBOq3qgdGnA2T # OglmmVhcKaO5DKYwODzQRjY1fJy67sPV+Qp2+n4FG0DKkjXp1XrRtX8ArqmQqsV/ # AZwQsRb8zG4Y3G9i/qZQp7h7uJ0VP/4gDHXIIloTlRmQAOka1cKG8eOO7F/05QID # AQABo4IBEjCCAQ4wHwYDVR0jBBgwFoAUoBEKIz6W8Qfs4q8p74Klf9AwpLQwHQYD # VR0OBBYEFDLrkpr/NZZILyhAQnAgNpFcF4XmMA4GA1UdDwEB/wQEAwIBhjAPBgNV # HRMBAf8EBTADAQH/MBMGA1UdJQQMMAoGCCsGAQUFBwMDMBsGA1UdIAQUMBIwBgYE # VR0gADAIBgZngQwBBAEwQwYDVR0fBDwwOjA4oDagNIYyaHR0cDovL2NybC5jb21v # ZG9jYS5jb20vQUFBQ2VydGlmaWNhdGVTZXJ2aWNlcy5jcmwwNAYIKwYBBQUHAQEE # KDAmMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI # hvcNAQEMBQADggEBABK/oe+LdJqYRLhpRrWrJAoMpIpnuDqBv0WKfVIHqI0fTiGF # OaNrXi0ghr8QuK55O1PNtPvYRL4G2VxjZ9RAFodEhnIq1jIV9RKDwvnhXRFAZ/ZC # J3LFI+ICOBpMIOLbAffNRk8monxmwFE2tokCVMf8WPtsAO7+mKYulaEMUykfb9gZ # pk+e96wJ6l2CxouvgKe9gUhShDHaMuwV5KZMPWw5c9QLhTkg4IUaaOGnSDip0TYl # d8GNGRbFiExmfS9jzpjoad+sPKhdnckcW67Y8y90z7h+9teDnRGWYpquRRPaf9xH # +9/DUp/mBlXpnYzyOmJRvOwkDynUWICE5EV7WtgwggYUMIID/KADAgECAhB6I67a # U2mWD5HIPlz0x+M/MA0GCSqGSIb3DQEBDAUAMFcxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxLjAsBgNVBAMTJVNlY3RpZ28gUHVibGljIFRp # bWUgU3RhbXBpbmcgUm9vdCBSNDYwHhcNMjEwMzIyMDAwMDAwWhcNMzYwMzIxMjM1 # OTU5WjBVMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSww # KgYDVQQDEyNTZWN0aWdvIFB1YmxpYyBUaW1lIFN0YW1waW5nIENBIFIzNjCCAaIw # DQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBAM2Y2ENBq26CK+z2M34mNOSJjNPv # IhKAVD7vJq+MDoGD46IiM+b83+3ecLvBhStSVjeYXIjfa3ajoW3cS3ElcJzkyZlB # nwDEJuHlzpbN4kMH2qRBVrjrGJgSlzzUqcGQBaCxpectRGhhnOSwcjPMI3G0hedv # 2eNmGiUbD12OeORN0ADzdpsQ4dDi6M4YhoGE9cbY11XxM2AVZn0GiOUC9+XE0wI7 # CQKfOUfigLDn7i/WeyxZ43XLj5GVo7LDBExSLnh+va8WxTlA+uBvq1KO8RSHUQLg # zb1gbL9Ihgzxmkdp2ZWNuLc+XyEmJNbD2OIIq/fWlwBp6KNL19zpHsODLIsgZ+WZ # 1AzCs1HEK6VWrxmnKyJJg2Lv23DlEdZlQSGdF+z+Gyn9/CRezKe7WNyxRf4e4bwU # trYE2F5Q+05yDD68clwnweckKtxRaF0VzN/w76kOLIaFVhf5sMM/caEZLtOYqYad # tn034ykSFaZuIBU9uCSrKRKTPJhWvXk4CllgrwIDAQABo4IBXDCCAVgwHwYDVR0j # BBgwFoAU9ndq3T/9ARP/FqFsggIv0Ao9FCUwHQYDVR0OBBYEFF9Y7UwxeqJhQo1S # gLqzYZcZojKbMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMBMG # A1UdJQQMMAoGCCsGAQUFBwMIMBEGA1UdIAQKMAgwBgYEVR0gADBMBgNVHR8ERTBD # MEGgP6A9hjtodHRwOi8vY3JsLnNlY3RpZ28uY29tL1NlY3RpZ29QdWJsaWNUaW1l # U3RhbXBpbmdSb290UjQ2LmNybDB8BggrBgEFBQcBAQRwMG4wRwYIKwYBBQUHMAKG # O2h0dHA6Ly9jcnQuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY1RpbWVTdGFtcGlu # Z1Jvb3RSNDYucDdjMCMGCCsGAQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNv # bTANBgkqhkiG9w0BAQwFAAOCAgEAEtd7IK0ONVgMnoEdJVj9TC1ndK/HYiYh9lVU # acahRoZ2W2hfiEOyQExnHk1jkvpIJzAMxmEc6ZvIyHI5UkPCbXKspioYMdbOnBWQ # Un733qMooBfIghpR/klUqNxx6/fDXqY0hSU1OSkkSivt51UlmJElUICZYBodzD3M # /SFjeCP59anwxs6hwj1mfvzG+b1coYGnqsSz2wSKr+nDO+Db8qNcTbJZRAiSazr7 # KyUJGo1c+MScGfG5QHV+bps8BX5Oyv9Ct36Y4Il6ajTqV2ifikkVtB3RNBUgwu/m # SiSUice/Jp/q8BMk/gN8+0rNIE+QqU63JoVMCMPY2752LmESsRVVoypJVt8/N3qQ # 1c6FibbcRabo3azZkcIdWGVSAdoLgAIxEKBeNh9AQO1gQrnh1TA8ldXuJzPSuALO # z1Ujb0PCyNVkWk7hkhVHfcvBfI8NtgWQupiaAeNHe0pWSGH2opXZYKYG4Lbukg7H # pNi/KqJhue2Keak6qH9A8CeEOB7Eob0Zf+fU+CCQaL0cJqlmnx9HCDxF+3BLbUuf # rV64EbTI40zqegPZdA+sXCmbcZy6okx/SjwsusWRItFA3DE8MORZeFb6BmzBtqKJ # 7l939bbKBy2jvxcJI98Va95Q5JnlKor3m0E7xpMeYRriWklUPsetMSf2NvUQa/E5 # vVyefQIwggYaMIIEAqADAgECAhBiHW0MUgGeO5B5FSCJIRwKMA0GCSqGSIb3DQEB # DAUAMFYxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLTAr # BgNVBAMTJFNlY3RpZ28gUHVibGljIENvZGUgU2lnbmluZyBSb290IFI0NjAeFw0y # MTAzMjIwMDAwMDBaFw0zNjAzMjEyMzU5NTlaMFQxCzAJBgNVBAYTAkdCMRgwFgYD # VQQKEw9TZWN0aWdvIExpbWl0ZWQxKzApBgNVBAMTIlNlY3RpZ28gUHVibGljIENv # ZGUgU2lnbmluZyBDQSBSMzYwggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIB # gQCbK51T+jU/jmAGQ2rAz/V/9shTUxjIztNsfvxYB5UXeWUzCxEeAEZGbEN4QMgC # sJLZUKhWThj/yPqy0iSZhXkZ6Pg2A2NVDgFigOMYzB2OKhdqfWGVoYW3haT29PST # ahYkwmMv0b/83nbeECbiMXhSOtbam+/36F09fy1tsB8je/RV0mIk8XL/tfCK6cPu # YHE215wzrK0h1SWHTxPbPuYkRdkP05ZwmRmTnAO5/arnY83jeNzhP06ShdnRqtZl # V59+8yv+KIhE5ILMqgOZYAENHNX9SJDm+qxp4VqpB3MV/h53yl41aHU5pledi9lC # BbH9JeIkNFICiVHNkRmq4TpxtwfvjsUedyz8rNyfQJy/aOs5b4s+ac7IH60B+Ja7 # TVM+EKv1WuTGwcLmoU3FpOFMbmPj8pz44MPZ1f9+YEQIQty/NQd/2yGgW+ufflcZ # /ZE9o1M7a5Jnqf2i2/uMSWymR8r2oQBMdlyh2n5HirY4jKnFH/9gRvd+QOfdRrJZ # b1sCAwEAAaOCAWQwggFgMB8GA1UdIwQYMBaAFDLrkpr/NZZILyhAQnAgNpFcF4Xm # MB0GA1UdDgQWBBQPKssghyi47G9IritUpimqF6TNDDAOBgNVHQ8BAf8EBAMCAYYw # EgYDVR0TAQH/BAgwBgEB/wIBADATBgNVHSUEDDAKBggrBgEFBQcDAzAbBgNVHSAE # FDASMAYGBFUdIAAwCAYGZ4EMAQQBMEsGA1UdHwREMEIwQKA+oDyGOmh0dHA6Ly9j # cmwuc2VjdGlnby5jb20vU2VjdGlnb1B1YmxpY0NvZGVTaWduaW5nUm9vdFI0Ni5j # cmwwewYIKwYBBQUHAQEEbzBtMEYGCCsGAQUFBzAChjpodHRwOi8vY3J0LnNlY3Rp # Z28uY29tL1NlY3RpZ29QdWJsaWNDb2RlU2lnbmluZ1Jvb3RSNDYucDdjMCMGCCsG # AQUFBzABhhdodHRwOi8vb2NzcC5zZWN0aWdvLmNvbTANBgkqhkiG9w0BAQwFAAOC # AgEABv+C4XdjNm57oRUgmxP/BP6YdURhw1aVcdGRP4Wh60BAscjW4HL9hcpkOTz5 # jUug2oeunbYAowbFC2AKK+cMcXIBD0ZdOaWTsyNyBBsMLHqafvIhrCymlaS98+Qp # oBCyKppP0OcxYEdU0hpsaqBBIZOtBajjcw5+w/KeFvPYfLF/ldYpmlG+vd0xqlqd # 099iChnyIMvY5HexjO2AmtsbpVn0OhNcWbWDRF/3sBp6fWXhz7DcML4iTAWS+MVX # eNLj1lJziVKEoroGs9Mlizg0bUMbOalOhOfCipnx8CaLZeVme5yELg09Jlo8BMe8 # 0jO37PU8ejfkP9/uPak7VLwELKxAMcJszkyeiaerlphwoKx1uHRzNyE6bxuSKcut # isqmKL5OTunAvtONEoteSiabkPVSZ2z76mKnzAfZxCl/3dq3dUNw4rg3sTCggkHS # RqTqlLMS7gjrhTqBmzu1L90Y1KWN/Y5JKdGvspbOrTfOXyXvmPL6E52z1NZJ6ctu # MFBQZH3pwWvqURR8AgQdULUvrxjUYbHHj95Ejza63zdrEcxWLDX6xWls/GDnVNue # KjWUH3fTv1Y8Wdho698YADR7TNx8X8z2Bev6SivBBOHY+uqiirZtg0y9ShQoPzmC # cn63Syatatvx157YK9hlcPmVoa1oDE5/L9Uo2bC5a4CH2RwwggZiMIIEyqADAgEC # AhEApCk7bh7d16c0CIetek63JDANBgkqhkiG9w0BAQwFADBVMQswCQYDVQQGEwJH # QjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSwwKgYDVQQDEyNTZWN0aWdvIFB1 # YmxpYyBUaW1lIFN0YW1waW5nIENBIFIzNjAeFw0yNTAzMjcwMDAwMDBaFw0zNjAz # MjEyMzU5NTlaMHIxCzAJBgNVBAYTAkdCMRcwFQYDVQQIEw5XZXN0IFlvcmtzaGly # ZTEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMTAwLgYDVQQDEydTZWN0aWdvIFB1 # YmxpYyBUaW1lIFN0YW1waW5nIFNpZ25lciBSMzYwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQDThJX0bqRTePI9EEt4Egc83JSBU2dhrJ+wY7JgReuff5KQ # NhMuzVytzD+iXazATVPMHZpH/kkiMo1/vlAGFrYN2P7g0Q8oPEcR3h0SftFNYxxM # h+bj3ZNbbYjwt8f4DsSHPT+xp9zoFuw0HOMdO3sWeA1+F8mhg6uS6BJpPwXQjNSH # pVTCgd1gOmKWf12HSfSbnjl3kDm0kP3aIUAhsodBYZsJA1imWqkAVqwcGfvs6pbf # s/0GE4BJ2aOnciKNiIV1wDRZAh7rS/O+uTQcb6JVzBVmPP63k5xcZNzGo4DOTV+s # M1nVrDycWEYS8bSS0lCSeclkTcPjQah9Xs7xbOBoCdmahSfg8Km8ffq8PhdoAXYK # OI+wlaJj+PbEuwm6rHcm24jhqQfQyYbOUFTKWFe901VdyMC4gRwRAq04FH2VTjBd # CkhKts5Py7H73obMGrxN1uGgVyZho4FkqXA8/uk6nkzPH9QyHIED3c9CGIJ098hU # 4Ig2xRjhTbengoncXUeo/cfpKXDeUcAKcuKUYRNdGDlf8WnwbyqUblj4zj1kQZSn # Zud5EtmjIdPLKce8UhKl5+EEJXQp1Fkc9y5Ivk4AZacGMCVG0e+wwGsjcAADRO7W # ga89r/jJ56IDK773LdIsL3yANVvJKdeeS6OOEiH6hpq2yT+jJ/lHa9zEdqFqMwID # AQABo4IBjjCCAYowHwYDVR0jBBgwFoAUX1jtTDF6omFCjVKAurNhlxmiMpswHQYD # VR0OBBYEFIhhjKEqN2SBKGChmzHQjP0sAs5PMA4GA1UdDwEB/wQEAwIGwDAMBgNV # HRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMEoGA1UdIARDMEEwNQYM # KwYBBAGyMQECAQMIMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20v # Q1BTMAgGBmeBDAEEAjBKBgNVHR8EQzBBMD+gPaA7hjlodHRwOi8vY3JsLnNlY3Rp # Z28uY29tL1NlY3RpZ29QdWJsaWNUaW1lU3RhbXBpbmdDQVIzNi5jcmwwegYIKwYB # BQUHAQEEbjBsMEUGCCsGAQUFBzAChjlodHRwOi8vY3J0LnNlY3RpZ28uY29tL1Nl # Y3RpZ29QdWJsaWNUaW1lU3RhbXBpbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0 # dHA6Ly9vY3NwLnNlY3RpZ28uY29tMA0GCSqGSIb3DQEBDAUAA4IBgQACgT6khnJR # IfllqS49Uorh5ZvMSxNEk4SNsi7qvu+bNdcuknHgXIaZyqcVmhrV3PHcmtQKt0bl # v/8t8DE4bL0+H0m2tgKElpUeu6wOH02BjCIYM6HLInbNHLf6R2qHC1SUsJ02MWNq # RNIT6GQL0Xm3LW7E6hDZmR8jlYzhZcDdkdw0cHhXjbOLsmTeS0SeRJ1WJXEzqt25 # dbSOaaK7vVmkEVkOHsp16ez49Bc+Ayq/Oh2BAkSTFog43ldEKgHEDBbCIyba2E8O # 5lPNan+BQXOLuLMKYS3ikTcp/Qw63dxyDCfgqXYUhxBpXnmeSO/WA4NwdwP35lWN # hmjIpNVZvhWoxDL+PxDdpph3+M5DroWGTc1ZuDa1iXmOFAK4iwTnlWDg3QNRsRa9 # cnG3FBBpVHnHOEQj4GMkrOHdNDTbonEeGvZ+4nSZXrwCW4Wv2qyGDBLlKk3kUW1p # IScDCpm/chL6aUbnSsrtbepdtbCLiGanKVR/KC1gsR0tC6Q0RfWOI4owggZqMIIE # 0qADAgECAhEAiJxIJtUiUSzO6zVz2TfmTjANBgkqhkiG9w0BAQwFADBUMQswCQYD # VQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1pdGVkMSswKQYDVQQDEyJTZWN0 # aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2MB4XDTI1MDYyMDAwMDAwMFoX # DTI4MDYxOTIzNTk1OVowYDELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3Ju # aWExHTAbBgNVBAoMFFNJT1MgVGVjaG5vbG9neSBDb3JwMR0wGwYDVQQDDBRTSU9T # IFRlY2hub2xvZ3kgQ29ycDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AJyn8lb10fa0d/PWBz1eHhzKaRfqdeY5stBowFAKruau5s4/9ic2NuqKlpoUmXey # 2KQOL6+bmrICD4034goesGa5VQZF8Xy+NeZNiyRst22QRJvVGiM126S2oQc2+lzt # gVq1/tvHv0zqfg02xlFvuNx/K/oJRsCMKLqSXqYgDyJhDd0kgtKhwcGF7jMOvDDF # WqG5CQdODV/VtHI4oZY13J+JmGigDvkpGReIVS6QknYv0/QrfKQts6tNeC7L5G88 # LKmLc3zAkQb+m/jrHXA+O8XGTUr4tunZIrjLE1b1ROsziLKtFDPZCIHGRmN268qx # o+JAazKf/t4On7h5VIlrhrf0nlj5LPQNaPbP7WH4JnWpZm5AwsPU5tCLmPe2vt+i # dIta3V2bbZ+fD470zTW7+MeebRoX/KTwrUgwTrZ8L7BuZacDjKcg/1/u32qp3fXl # puFY4G7cPQ7GgRbmZmnwP38N+kPNITfIGSsWAidG5QTa9LoNrQA6MPB7ftmOvIy3 # PR4SsVCNR80XB5Ljy9EZcwS9/yiS5S6UJ629FIqyYq1nFtRIXrq/iOF5l3lRVfJ0 # UMixylnPu02fjxvizBwoXlEM2myouRzJvh7xjJsLOO881hb0FeV4E+q6oi/t2yjL # 6qyX6Z7LSMROzKnVqdfzrK7qbSOjMFong+uVjESiFDppAgMBAAGjggGpMIIBpTAf # BgNVHSMEGDAWgBQPKssghyi47G9IritUpimqF6TNDDAdBgNVHQ4EFgQU8qARTdPy # KrgyEPQyxbpmSyHR2I4wDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYD # VR0lBAwwCgYIKwYBBQUHAwMwSgYDVR0gBEMwQTA1BgwrBgEEAbIxAQIBAwIwJTAj # BggrBgEFBQcCARYXaHR0cHM6Ly9zZWN0aWdvLmNvbS9DUFMwCAYGZ4EMAQQBMEkG # A1UdHwRCMEAwPqA8oDqGOGh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGlnb1B1 # YmxpY0NvZGVTaWduaW5nQ0FSMzYuY3JsMHkGCCsGAQUFBwEBBG0wazBEBggrBgEF # BQcwAoY4aHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUHVibGljQ29kZVNp # Z25pbmdDQVIzNi5jcnQwIwYIKwYBBQUHMAGGF2h0dHA6Ly9vY3NwLnNlY3RpZ28u # Y29tMB4GA1UdEQQXMBWBE3N1cHBvcnRAdXMuc2lvcy5jb20wDQYJKoZIhvcNAQEM # BQADggGBACpViTDGtLnGP600JxhGK8j6oBURlhSK51B8yrsZpgtoBzjshVO59rzL # jjPMoaLwOnMD5G4hcU656MFgQ+sf8y3P+iAmhKHtImK/Ox6EE8AjoU9W9uQP9S9m # pR3hS3+wFrUxyiUO3s5BUPh87UgQtcOp7a61d31sSJTtoUSqRBcl931czxXhNwGd # r+VTYig8lEDgG44emWc9U0j1GK+vjzln/LGm7UobX4e68PZhGdQiK9y6sVkwxDxl # voLTcf+5iICUvrqvXSkr+d7TvkdxPOstURaWX2nvhh8wESQCctxaRM+S2BXO7iEb # lcYVdHyJBhIqrBaX5BV4SqVgP5F53EQQtj38dVFhx7WryjJ7B/mm3w1GiaeEKLy7 # LJMrcU4yO/2GS8AG80YQOmySOrQtihpgfKngDTkddx3i8+GC6tP9HrvhkVNgKtn2 # tr9lk3gV6/Kel8Hu2uWrOoPRY33mTWXyHiairlMoWYyhHrCls08wl2/KSlBQFqbd # Js9x09M11zCCBoIwggRqoAMCAQICEDbCsL18Gzrno7PdNsvJdWgwDQYJKoZIhvcN # AQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpOZXcgSmVyc2V5MRQwEgYD # VQQHEwtKZXJzZXkgQ2l0eTEeMBwGA1UEChMVVGhlIFVTRVJUUlVTVCBOZXR3b3Jr # MS4wLAYDVQQDEyVVU0VSVHJ1c3QgUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5 # MB4XDTIxMDMyMjAwMDAwMFoXDTM4MDExODIzNTk1OVowVzELMAkGA1UEBhMCR0Ix # GDAWBgNVBAoTD1NlY3RpZ28gTGltaXRlZDEuMCwGA1UEAxMlU2VjdGlnbyBQdWJs # aWMgVGltZSBTdGFtcGluZyBSb290IFI0NjCCAiIwDQYJKoZIhvcNAQEBBQADggIP # ADCCAgoCggIBAIid2LlFZ50d3ei5JoGaVFTAfEkFm8xaFQ/ZlBBEtEFAgXcUmanU # 5HYsyAhTXiDQkiUvpVdYqZ1uYoZEMgtHES1l1Cc6HaqZzEbOOp6YiTx63ywTon43 # 4aXVydmhx7Dx4IBrAou7hNGsKioIBPy5GMN7KmgYmuu4f92sKKjbxqohUSfjk1mJ # lAjthgF7Hjx4vvyVDQGsd5KarLW5d73E3ThobSkob2SL48LpUR/O627pDchxll+b # TSv1gASn/hp6IuHJorEu6EopoB1CNFp/+HpTXeNARXUmdRMKbnXWflq+/g36NJXB # 35ZvxQw6zid61qmrlD/IbKJA6COw/8lFSPQwBP1ityZdwuCysCKZ9ZjczMqbUcLF # yq6KdOpuzVDR3ZUwxDKL1wCAxgL2Mpz7eZbrb/JWXiOcNzDpQsmwGQ6Stw8tTCqP # umhLRPb7YkzM8/6NnWH3T9ClmcGSF22LEyJYNWCHrQqYubNeKolzqUbCqhSqmr/U # dUeb49zYHr7ALL8bAJyPDmubNqMtuaobKASBqP84uhqcRY/pjnYd+V5/dcu9ieER # jiRKKsxCG1t6tG9oj7liwPddXEcYGOUiWLm742st50jGwTzxbMpepmOP1mLnJskv # ZaN5e45NuzAHteORlsSuDt5t4BBRCJL+5EZnnw0ezntk9R8QJyAkL6/bAgMBAAGj # ggEWMIIBEjAfBgNVHSMEGDAWgBRTeb9aqitKz1SA4dibwJ3ysgNmyzAdBgNVHQ4E # FgQU9ndq3T/9ARP/FqFsggIv0Ao9FCUwDgYDVR0PAQH/BAQDAgGGMA8GA1UdEwEB # /wQFMAMBAf8wEwYDVR0lBAwwCgYIKwYBBQUHAwgwEQYDVR0gBAowCDAGBgRVHSAA # MFAGA1UdHwRJMEcwRaBDoEGGP2h0dHA6Ly9jcmwudXNlcnRydXN0LmNvbS9VU0VS # VHJ1c3RSU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDA1BggrBgEFBQcBAQQp # MCcwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZI # hvcNAQEMBQADggIBAA6+ZUHtaES45aHF1BGH5Lc7JYzrftrIF5Ht2PFDxKKFOct/ # awAEWgHQMVHol9ZLSyd/pYMbaC0IZ+XBW9xhdkkmUV/KbUOiL7g98M/yzRyqUOZ1 # /IY7Ay0YbMniIibJrPcgFp73WDnRDKtVutShPSZQZAdtFwXnuiWl8eFARK3PmLqE # m9UsVX+55DbVIz33Mbhba0HUTEYv3yJ1fwKGxPBsP/MgTECimh7eXomvMm0/GPxX # 2uhwCcs/YLxDnBdVVlxvDjHjO1cuwbOpkiJGHmLXXVNbsdXUC2xBrq9fLrfe8IBs # A4hopwsCj8hTuwKXJlSTrZcPRVSccP5i9U28gZ7OMzoJGlxZ5384OKm0r568Mo9T # YrqzKeKZgFo0fj2/0iHbj55hc20jfxvK3mQi+H7xpbzxZOFGm/yVQkpo+ffv5gdh # p+hv1GDsvJOtJinJmgGbBFZIThbqI+MHvAmMmkfb3fTxmSkop2mSJL1Y2x/955S2 # 9Gu0gSJIkc3z30vU/iXrMpWx2tS7UVfVP+5tKuzGtgkP7d/doqDrLF1u6Ci3TpjA # ZdeLLlRQZm867eVeXED58LXd1Dk6UvaAhvmWYXoiLz4JA5gPBcz7J311uahxCweN # xE+xxxR3kT0WKzASo5G/PyDez6NHdIUKBeE3jDPs2ACc6CkJ1Sji4PKWVT0/MYIG # OTCCBjUCAQEwaTBUMQswCQYDVQQGEwJHQjEYMBYGA1UEChMPU2VjdGlnbyBMaW1p # dGVkMSswKQYDVQQDEyJTZWN0aWdvIFB1YmxpYyBDb2RlIFNpZ25pbmcgQ0EgUjM2 # AhEAiJxIJtUiUSzO6zVz2TfmTjANBglghkgBZQMEAgEFAKB8MBAGCisGAQQBgjcC # AQwxAjAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsx # DjAMBgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCAgTpPhSRSJNuyXAc3B52Fr # M8VYm6cwhFV/w9oWkgtgZjANBgkqhkiG9w0BAQEFAASCAgADXPeYhyKtRcHmGcJz # 2yg+eot3WElatv0W4VH5sWoiOJPkOMaPG+Q9BZijm5nzHh5syQQ6fhc9Nrij0bbQ # P6aXKV3FsSjrwpRgzhfBzhHNpa7w4x3HK7EPuCEy3BkXU466Y3l1JJn35UxUi+QP # 4y0+r1/hk/FSTSL7V/kn6z6RqSOzb3AT/N+LH1b4Hw4C7aBlAMOq0RCn3sEmlaPZ # fmxIdZMM4Kw1M65L0ARdM9axlv+KqU/nNQYlqjX8vougcOeZOCz0q1tyuhUIFEMO # 251bA+yKE0XE3HuGrZ01thJcB67m83h5SLI97dGOXlrYL+JL/3y494ruNb3/N61y # rBtoVV6FQizJgBKKizsucjpnjqFcsqcAEhGwU8Jf6UqxbeTrskytv8S9n7g74Rjm # F0A042Dg+4oI9wwu7UWF4FF/NcrMBAyfJtRCL+lRX5RKyt28cxgWViNQQCDYq/U2 # HmJDzPgQ7n3iIwa4Ak17F1q9Hzg1bvbWD5h+dr9U3bf2APrN+UUChCXtctxNdr7l # B2DNAlwVLOrIwbXYB7/zIQ+p0+i0nlnWIP/+EzWJoTIgnikLdmIpSa9yPFJRbv89 # GLLRQSDTdgarZxaSC2+ePT458YM5gfFtXoXtDWOMxSADOZDXo3YfnQGVDdj/9+wJ # eG5TfFFduVUltgRqzCDtTV/nqaGCAyMwggMfBgkqhkiG9w0BCQYxggMQMIIDDAIB # ATBqMFUxCzAJBgNVBAYTAkdCMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxLDAq # BgNVBAMTI1NlY3RpZ28gUHVibGljIFRpbWUgU3RhbXBpbmcgQ0EgUjM2AhEApCk7 # bh7d16c0CIetek63JDANBglghkgBZQMEAgIFAKB5MBgGCSqGSIb3DQEJAzELBgkq # hkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI2MDEyMDE3MjkwNFowPwYJKoZIhvcN # AQkEMTIEMLSfyMpFwcZ33n6X0RTU3q03uo9ef4leZDrl+c0+wWd6stMfhEzgpkBE # 1+Et5figYTANBgkqhkiG9w0BAQEFAASCAgAPZU7FfhpDSI0hHRHye7GuM7vdWUqh # zR7PimMEBYdIW1u9wSzlhtKHpW4etAPfMdCxeWo1nOIL0zj4mSJ/8WNu/rRy25uA # usrQz6zAEUuIfborIllkMWuOJfyL15cu8npqOXOB4RciMWQG0MLaqUPXYUHDvm5u # TkWjlL1lbmfEg+zGmsRsnMUCGangeGjpxUq7ftKmqRsXp3Icngaamtlh7XBXSeCR # b5Nr3rlEZ3f2wp+k2ecjuy0LhkpCTYG5F52uUKn56EpiE+iGJudLRNOYPIviukyu # 3nirCcNDVneB+ZURzr7F1OT5xAZXUhmO3QvUOaJGWXjRqx7hT37lG7we0K9UbPDY # iMan0BTqy4CpsOrqgTJdy8QBrxYxPYG4pxul9O9UXxvfYm8QAzHgnyE77wLV9hne # Iiga3aULk35+kcWC3cvLDE0keOpZsplGz9kN7nVBoNXnfVLkVUDlsXT7aY7lJq4Q # qS04ZEOJjlRg1VOC8OfiBIYnvW5bDOCUtTGBHp3LUbFdStFsPdqoxVBGmAKWcR/v # n237/Kfo6mfBcPYF8+wLnuURuWsPOKZepsbbl4KviYGK4HuDhvR1Dxa+uVSpnmBl # lZVkYSmmd9AgQ/bJ8qIYKnjWHLPIIu7iIzHiLaKUDV9/Gx1JkE3WbXckHsySN7PK # Y9JLZHHwHmJscw== # SIG # End signature block