UninstallMarvellQLogicFCPowerKit.psm1
#/************************************************************************ #* * #* NOTICE * #* * #* COPYRIGHT 2019-2023 Marvell Semiconductor, Inc * #* ALL RIGHTS RESERVED * #* * #* This computer program is CONFIDENTIAL and contains TRADE SECRETS of * #* Marvell Semiconductor, Inc. The receipt or possession of this * #* program does not convey any rights to reproduce or disclose its * #* contents, or to manufacture, use, or sell anything that it may * #* describe, in whole or in part, without the specific written consent * #* of Marvell Semiconductor, Inc. * #* Any reproduction of this program without the express written consent * #* of Marvell Semiconductor, Inc is a violation of the copyright laws * #* and may subject you to civil liability and criminal prosecution. * #* * #************************************************************************/ # Functions Function Test-IfNano { # Check if OS is Nano or Non-Nano $envInfo = [Environment]::OSVersion.Version $envInfoCimInst = Get-CimInstance Win32_OperatingSystem return ( ($envInfo.Major -eq 10) -and ($envInfo.Minor -eq 0) -and ($envInfoCimInst.ProductType -eq 3) -and ($envInfoCimInst.SuiteMask -eq 272) ) } Function Test-IfServerCore { # Check if OS is Server Core $regKey = 'hklm:/software/microsoft/windows nt/currentversion' return (Get-ItemProperty $regKey).InstallationType -eq 'Server Core' } Function Test-RegistryValue { Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $Path, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $Value ) try { Get-ItemProperty -Path $Path | Select-Object -ExpandProperty $Value -ErrorAction Stop 2>&1 | Out-Null return $true } catch { return $false } } Function Get-AppxPackageWrapper { Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $AppxName ) $numAttempts = 3 $numSecondsBetweenAttempts = 5 for ($i=0; $i -lt $numAttempts; $i++) { $appxPkg = Get-AppxPackage | Where-Object { $_.name -eq $AppxName } if ($appxPkg -ne $null) { break } Write-Host "Couldn't find Appx package. Trying again in $numSecondsBetweenAttempts seconds (attempt $($i+1) of $numAttempts) ..." -ForegroundColor DarkRed Start-Sleep -Seconds $numSecondsBetweenAttempts } if ($appxPkg -eq $null) { Write-Host 'Failed to find Appx package. Please try running this script again.' -ForegroundColor Red Exit } return $appxPkg } Function Remove-ProviderAppxProvisionedPackage { Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $AppxDisplayName ) if ($Script:isNano) { return } # Skip if Nano $appxProvPkg = Get-AppxProvisionedPackage -Online | Where-Object { $_.DisplayName -eq $AppxDisplayName } if ($appxProvPkg -ne $null) { Remove-AppxProvisionedPackage -Online -PackageName $appxProvPkg.PackageName 2>&1 | Out-Null Write-Host "Removed AppxProvisionedPackage $($appxProvPkg.PackageName)" } } Function Remove-ChangedCmdletsPathFromPSModulePath { # This function removes cmdlet module path(s) from system PSModulePath environment variable. #Remove-module -force MarvellQLogicFCCmdlets $cmdletPath = "C:\Program Files\WindowsPowerShell\Modules\MarvellQLogicFCCmdlets" if ($Script:isServerCore) { $appxCmdletsPath = "$env:ProgramFiles\Marvell_Semiconductor_Inc\FC_PowerKit\Cmdlets" } else { $appxCmdletsPath = (Get-AppxPackageWrapper -AppxName 'MRVLFCProvider').InstallLocation + '\Cmdlets' } if (Test-RegistryValue -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' -Value 'PSModulePath') { $currPSModulePathArr = ((Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment').PSModulePath).Split(';') $newPSModulePathArr = @() # Remove any paths containing 'MRVLFCProvider' from PSModulePath foreach ($path in $currPSModulePathArr) { if ((-not $path.Contains('MRVLFCProvider')) -or (-not $path.Contains($cmdletPath))) { $newPSModulePathArr += $path } else { Write-Host "Removed '$path' from PSModulePath." } } $newPSModulePathStr = $newPSModulePathArr -join ';' # Write PSModulePath to registry and set local session variable & setx /s $env:COMPUTERNAME PSModulePath $newPSModulePathStr /m 2>&1 | Out-Null $env:PSModulePath = $newPSModulePathStr } } Function Remove-CmdletsPathFromPSModulePath { # This function removes cmdlet module path(s) from system PSModulePath environment variable. Remove-module -force MarvellQLogicFCCmdlets 2>&1 | Out-NULL if ($Script:isServerCore) { $appxCmdletsPath = "$env:ProgramFiles\Marvell_Semiconductor_Inc\FC_PowerKit\Cmdlets" } else { #$appxCmdletsPath = (Get-AppxPackageWrapper -AppxName 'MRVLFCProvider').InstallLocation + '\Cmdlets' #$appxPkg = Get-AppxPackageWrapper -AppxName 'MRVLFCProvider' #$appxCmdletsPath = "$env:ProgramData\$($appxPkg.PackageFullName)" $appxCmdletsPath = "C:\ProgramData\MarvellQLogicFCCmdlets" } if (Test-RegistryValue -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment' -Value 'PSModulePath') { $currPSModulePathArr = ((Get-ItemProperty -Path 'HKLM:\System\CurrentControlSet\Control\Session Manager\Environment').PSModulePath).Split(';') $newPSModulePathArr = @() # Remove any paths containing 'MRVLFCProvider' from PSModulePath foreach ($path in $currPSModulePathArr) { if ((-not $path.Contains('MRVLFCProvider')) -and ($path -ne $appxCmdletsPath)) { $newPSModulePathArr += $path } else { Write-Host "Removed '$path' from PSModulePath." } } $newPSModulePathStr = $newPSModulePathArr -join ';' # Write PSModulePath to registry and set local session variable & setx /s $env:COMPUTERNAME PSModulePath $newPSModulePathStr /m 2>&1 | Out-Null $env:PSModulePath = $newPSModulePathStr } } Function Remove-CLSIDRegistryPaths { if (Test-Path -Path "Registry::HKCR\CLSID\$Script:CLSID") { Remove-Item -Path "Registry::HKCR\CLSID\$Script:CLSID" -Recurse Write-Host "Removed HKCR:\CLSID\$Script:CLSID from registry." } if (Test-Path -Path "HKLM:\Software\Classes\CLSID\$Script:CLSID") { Remove-Item -Path "HKLM:\Software\Classes\CLSID\$Script:CLSID" -Recurse Write-Host "Removed HKLM:\Software\Classes\CLSID\$Script:CLSID from registry." } } Function Uninstall-MofComp { # TODO - Determine if this function is always necessary if ($Script:isServerCore) { $mofCompFilePath = "$env:ProgramFiles\Marvell_Semiconductor_Inc\FC_PowerKit\MRVLFCProvider_Uninstall.mof" } else { $mofCompFilePath = (Get-AppxPackageWrapper -AppxName 'MRVLFCProvider').InstallLocation $mofCompFilePath += '\MRVLFCProvider_Uninstall.mof' } # $mofcompOutput = & mofcomp.exe -N:root\qlgcfc -class:forceupdate $appxPath\MRVLFCProvider_Uninstall.mof 2>&1 $mofcompOutput = & mofcomp.exe -N:root\qlgcfc $mofCompFilePath 2>&1 if ($mofcompOutput -match 'Error') { Write-Host "Failed to unregister `"$mofCompFilePath`": $($mofcompOutput -match 'Error')" -ForegroundColor Red } else { Write-Host "MRVLFCProvider unregistered." } if (Test-RegistryValue -Path 'HKLM:\Software\Microsoft\Wbem\CIMOM\SecuredHostProviders' -Value 'Root/qlgcfc:__Win32Provider.Name="MRVLFCProvider"') { Remove-ItemProperty -Path 'HKLM:\Software\Microsoft\Wbem\CIMOM\SecuredHostProviders' -Name 'Root/qlgcfc:__Win32Provider.Name="MRVLFCProvider"' } } Function Remove-CmdletsFromProgramData { # Remove any ProgramData directories containing 'MRVLFCProvider' $progDataPaths = (Get-ChildItem $env:ProgramData | Where-Object { ($_.Name).StartsWith('MRVLFCProvider_') }).FullName foreach ($path in $progDataPaths) { Remove-Item $path -Recurse -Force 2>&1 | Out-Null Write-Host "Cmdlets removed from `"$path`"." } if(Test-Path "C:\ProgramData\MarvellQLogicFCCmdlets") { $newProgramDataPath = (Get-ChildItem "C:\ProgramData\MarvellQLogicFCCmdlets").FullName foreach ($path in $newProgramDataPath) { Remove-Item $path -Recurse -Force 2>&1 | Out-Null } Remove-Item "C:\ProgramData\MarvellQLogicFCCmdlets" -Recurse -Force 2>&1 | Out-Null } } Function Remove-ChangedCmdletsFromWindowsPowerShellModule { # Remove any ProgramData directories containing 'MRVLFCProvider' $cmdletsDestPath = "C:\Program Files\WindowsPowerShell\Modules\MarvellQLogicFCCmdlets" if(Test-Path $cmdletsDestPath) { Remove-Item $cmdletsDestPath -Recurse -Force 2>&1 | Out-Null Write-Host "Cmdlets removed from `"$cmdletsDestPath`"." } } Function Remove-CmdletsFromProgramFiles { Remove-Item -Path "$env:ProgramFiles\Marvell_Semiconductor_Inc\FC_PowerKit" -Recurse -Force 2>&1 | Out-Null } Function Remove-RESTFilesFromProgramData { # Remove any ProgramData directories containing 'MRVLFCProvider' $progDataPaths = (Get-ChildItem $env:ProgramData | Where-Object { ($_.Name).StartsWith('MRVLFCProviderREST') }).FullName foreach ($path in $progDataPaths) { Remove-Item $path -Recurse -Force Write-Host "REST files removed from `"$path`"." } } Function Remove-AppxPackageWrapper { Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $AppxDisplayName ) $appxPkg = Get-AppxPackage | Where-Object { $_.Name -eq $AppxDisplayName } if ($appxPkg -ne $null) { $savedProgressPreference = $Global:ProgressPreference $Global:ProgressPreference = 'SilentlyContinue' Remove-AppxPackage -Package $appxPkg 2>&1 | Out-Null $Global:ProgressPreference = $savedProgressPreference Write-Host "Removed $AppxDisplayName AppxPackage." } } Function Remove-FromIIS { $appcmd = "$env:SystemRoot\system32\inetsrv\appcmd.exe" # Stop all sites $sites = (& $appcmd list site 2>&1) if ($sites -ne $null) { if ($sites.GetType() -eq [System.String]) { $siteName = $sites.Split('"')[1] $appcmdOutput = (& $appcmd stop site $siteName 2>&1) } else { foreach ($s in $sites) { $siteName = $s.Split('"')[1] $appcmdOutput = (& $appcmd stop site $siteName 2>&1) } } } # Stop DefaultAppPool and MOData apppool $appcmdOutput = (& $appcmd stop apppool /apppool.name:DefaultAppPool 2>&1) $appcmdOutput = (& $appcmd stop apppool /apppool.name:MOData 2>&1) # Delete MOData appool $appcmdOutput = (& $appcmd delete apppool /apppool.name:MOData 2>&1) # Delete MODataSvc app $appcmdOutput = (& $appcmd delete app MODataSvc/MODataSvc 2>&1) # Delete MODataSvc site $appcmdOutput = (& $appcmd delete site MODataSvc 2>&1) Remove-Item "$env:HOMEDRIVE\inetpub\wwwroot\MOData" -Recurse -Force # Start DefaultAppPool apppool $appcmdOutput = (& $appcmd start apppool /apppool.name:DefaultAppPool 2>&1) # Start all sites $sites = (& $appcmd list site 2>&1) if ($sites -ne $null) { if ($sites.GetType() -eq [System.String]) { $siteName = $sites.Split('"')[1] $appcmdOutput = (& $appcmd start site $siteName 2>&1) } else { foreach ($s in $sites) { $siteName = $s.Split('"')[1] $appcmdOutput = (& $appcmd start site $siteName 2>&1) } } } # Remove any existing firewall rules if ((Get-NetFirewallRule | Where-Object { ($_.DisplayName).StartsWith('MOData_IIS_Port') }) -ne $null) { Remove-NetFirewallRule -DisplayName 'MOData_IIS_Port' } Write-Host "Removed from IIS." } Function Test-LastExitCode { Param ( [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $ExitCode, [Parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] $Message, [Parameter(Mandatory=$false)] [AllowNull()] [Switch] $ExitScriptIfBadErrorCode ) if ($ExitCode -eq 0) { return; } if (-not $ExitScriptIfBadErrorCode) { Write-Host "WARNING: $Message" -ForegroundColor Yellow } else { Write-Host "ERROR: $Message" -ForegroundColor Red Exit } } Function Kill-WMI-Provider-Hosts-Processes { TASKKILL /F /IM "WmiPrvSE.exe" | Out-Null } Function UnInstall-FCPowerKit { #-------------------------------------------------------------------------------------------------- # Globals $Script:CLSID = '{A31B8A5E-8B6A-421C-8BB1-F85C9C34E659}' $Script:isNano = Test-IfNano $Script:isServerCore = Test-IfServerCore #-------------------------------------------------------------------------------------------------- # Script - Cmdlets Uninstall if (-not $UninstallRESTServerOnly) { Kill-WMI-Provider-Hosts-Processes if ($Script:isServerCore) { Remove-CmdletsPathFromPSModulePath Remove-CLSIDRegistryPaths Uninstall-MofComp Remove-CmdletsFromProgramFiles } else { Remove-ProviderAppxProvisionedPackage -AppxDisplayName 'MRVLFCProvider' Remove-CmdletsPathFromPSModulePath Remove-CLSIDRegistryPaths Uninstall-MofComp Remove-CmdletsFromProgramData Remove-AppxPackageWrapper -AppxDisplayName 'MRVLFCProvider' } Write-Host "Successfully uninstalled MarvellQLogicFCPowerKit.`n" -ForegroundColor Green Write-Host "Note: Restart the computer.`n" -ForegroundColor Yellow } } Export-ModuleMember -function UnInstall-FCPowerKit # SIG # Begin signature block # MIIp0gYJKoZIhvcNAQcCoIIpwzCCKb8CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUE6WoPXZG3gn43EDLevHmiPwq # CR2ggg6LMIIGsDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0B # AQwFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVk # IFJvb3QgRzQwHhcNMjEwNDI5MDAwMDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD # ZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEg # Q0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5 # WRuxiEL1M4zrPYGXcMW7xIUmMJ+kjmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJP # DqFX/IiZwZHMgQM+TXAkZLON4gh9NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXz # ENOLsvsI8IrgnQnAZaf6mIBJNYc9URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bq # HPNlaJGiTUyCEUhSaN4QvRRXXegYE2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTC # fMjqGzLmysL0p6MDDnSlrzm2q2AS4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaD # G7dqZy3SvUQakhCBj7A7CdfHmzJawv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urO # kfW+0/tvk2E0XLyTRSiDNipmKF+wc86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7AD # K5GyNnm+960IHnWmZcy740hQ83eRGv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4 # R+Z1MI3sMJN2FKZbS110YU0/EpF23r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlN # Wdt4z4FKPkBHX8mBUHOFECMhWWCKZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0I # U0F8WD1Hs/q27IwyCQLMbDwMVhECAwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYB # Af8CAQAwHQYDVR0OBBYEFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaA # FOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK # BggrBgEFBQcDAzB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v # Y3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4 # oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJv # b3RHNC5jcmwwHAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcN # AQEMBQADggIBADojRD2NCHbuj7w6mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcT # Ep6QRJ9L/Z6jfCbVN7w6XUhtldU/SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WT # auPrINHVUHmImoqKwba9oUgYftzYgBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9 # ntSZz0rdKOtfJqGVWEjVGv7XJz/9kNF2ht0csGBc8w2o7uCJob054ThO2m67Np37 # 5SFTWsPK6Wrxoj7bQ7gzyE84FJKZ9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0 # HKKlS43Nb3Y3LIU/Gs4m6Ri+kAewQ3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL # 6TEa/y4ZXDlx4b6cpwoG1iZnt5LmTl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+1 # 6oh7cGvmoLr9Oj9FpsToFpFSi0HASIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8 # M4+uKIw8y4+ICw2/O/TOHnuO77Xry7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrF # hsP2JjMMB0ug0wcCampAMEhLNKhRILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy # 1lKQ/a+FSCH5Vzu0nAPthkX0tGFuv2jiJmCG6sivqf6UHedjGzqGVnhOMIIH0zCC # BbugAwIBAgIQD5Of8cNhOFj7xs+otK1ttzANBgkqhkiG9w0BAQsFADBpMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD # ZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEg # Q0ExMB4XDTIxMDgwNjAwMDAwMFoXDTIzMDgwODIzNTk1OVowgbYxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRQwEgYDVQQHEwtTYW50YSBDbGFyYTEk # MCIGA1UEChMbTWFydmVsbCBTZW1pY29uZHVjdG9yLCBJbmMuMQswCQYDVQQLEwJJ # VDEkMCIGA1UEAxMbTWFydmVsbCBTZW1pY29uZHVjdG9yLCBJbmMuMSMwIQYJKoZI # hvcNAQkBFhRyb2dlcmxpdUBtYXJ2ZWxsLmNvbTCCAiIwDQYJKoZIhvcNAQEBBQAD # ggIPADCCAgoCggIBAK+G6bprBRoRahhuwYGrO2RLstJGnM1jyzOdDFKwUUcYKqZq # wWDFD4bJl7uz3bbT8BpXKext0OdJADxK2uJ3Hiyvr3PBmA/egbbblQMSYgbH6uQG # 3tYkeftWbSq3qrqTQg7ooWaU+ioQVvJ7xY+CGPvXotsISuMZHtvg7YrMh2t3v/IS # KKQbxtFaGZQ6w48WLUfmxWxmgkQiYJZAvEHDSMeEwVorqtoeDGdPJH6nqMwkSs/D # r+0AfbIvDqqz1+LbTxOrRcPavz9YxURUOIVSWD37jIL/Dh3XrDxTPTdu1VJd3GQL # w/JUA6gQ62OFvU1uDRKu+QoQovCWwvTmivjX6bLFNKNJBqSjyV3JjZKV1CywpX8g # +jMXIk+EAX8cdKfykjg+Q9m7K+U/LVTrQEVZdW1d28X8SV52mdvRC8FKuA0mt/I+ # PDLJxQnJL+tPzBlej+LQItJaJV/D77YMLaL+ysdyiXpgKpeVcyrEffaa1i0zaqhG # 1wTn5ZOvOLmndu4cuoI2kN7WkdbMxY8ctHNbjmL7k+DiYDBMyjBci9QBtHbITota # pzHXkh+Z3B6LWv4hqSHpUWcTD+47gj+hylXOIG17H623x4ejZWU2lSzBcS1SoDur # k4AjNpBw7LEV9tAVeYAD7JatFyaxN+0FqzvsxxPSTik+cJqwPz308cd0/vRVAgMB # AAGjggInMIICIzAfBgNVHSMEGDAWgBRoN+Drtjv4XxGG+/5hewiIZfROQjAdBgNV # HQ4EFgQUvrI1spn9zgGyR79ijHAnCb1z5VQwHwYDVR0RBBgwFoEUcm9nZXJsaXVA # bWFydmVsbC5jb20wDgYDVR0PAQH/BAQDAgeAMBMGA1UdJQQMMAoGCCsGAQUFBwMD # MIG1BgNVHR8Ega0wgaowU6BRoE+GTWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9E # aWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEu # Y3JsMFOgUaBPhk1odHRwOi8vY3JsNC5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVz # dGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDA+BgNVHSAE # NzA1MDMGBmeBDAEEATApMCcGCCsGAQUFBwIBFhtodHRwOi8vd3d3LmRpZ2ljZXJ0 # LmNvbS9DUFMwgZQGCCsGAQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8v # b2NzcC5kaWdpY2VydC5jb20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRp # Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNI # QTM4NDIwMjFDQTEuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # AG2VgABY1DAXHNlfMtPRGohJPSaymc2n94AzZPo1pBj4e18BohRaaPHQ0VL8NnON # P/iOyFmlK38/R8gmXK6nywDILrwFquvvA6xAQuLriS9fDbhru8uMhHWOLCpg1G/F # Oq3ZJk8iOPlIcQLCMPxLoNx51uAmDlHVpQ1nEErRCBiN87Gy81+fQs8pb5JqW/qx # iZtgp7uZ/HFrj3u2saneXSP/5Za+P/TnUsGrurxcGWegaiqQbTKzIoocSwo/EUG/ # bjzhw2uVEuTDgk25fZ15suysZh/aERjkuWVGHM/rHJ/CmNIchLL0ozbEZ1JAYQ6n # 2ApvaLvc6eAW69fApmGdk8Si5rlrF4k/JaflQEBfrJA472PG3zFHUA1OGlUF3XXA # ykf+QVCeJLG5XVVapahTZ9+BnuQ9OWDMd0uueFNu1f73Y3ayEyYkE98dpewEoeEc # aVLWOfRuAZ8dhy/6R3gnFo7I+g3TwVBeVCab3D05HoMHjs70bmGXX+yJ+JMOsaqm # nsU33q6KVIDPqh9qI2dfT59x+kVhsqLv/JlkCgo8X0D9gz3eCg+FZZPT+VduVR6R # /c/h/IQdF8bEx+EESui2x4Q8NvA990PSrAwgnbaGkwNqIWQzSpbOnQeihfWxA8bZ # GZSAIeohsb3GNQbP5R/EDyB8TlQls8oZT3qgPUMMQ0XIMYIasTCCGq0CAQEwfTBp # MQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMT # OERpZ2lDZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0 # IDIwMjEgQ0ExAhAPk5/xw2E4WPvGz6i0rW23MAkGBSsOAwIaBQCggdgwGQYJKoZI # hvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcC # ARUwIwYJKoZIhvcNAQkEMRYEFFLscXei6EJNAB+k7y0Coj/y18VcMHgGCisGAQQB # gjcCAQwxajBooEyASgBNAGEAcgB2AGUAbABsACAAUQBsAG8AZwBpAGMAIABGAGkA # YgByAGUAIABDAGgAYQBuAG4AZQBsACAAUABvAHcAZQByAEsAaQB0oRiAFmh0dHA6 # Ly93d3cubWFydmVsbC5jb20wDQYJKoZIhvcNAQEBBQAEggIAlNikQgvC836KhSEN # W/swNdD4eCPZxM8+ObGdI4Jeb+MKDzx4J2launjbXTqH7lA6Qhai48dX5FLC+Q8t # o07/V1B83zHxGujNYMIPeFS3lrYomf/NLBJ7n1Z7p9xSRBDx4gYMvwPzLJmksbsS # WDswb1u0K8yW+KHcykrftYhVniIKHwxCrXAyTf+iwRIQNIP6v5L0DyFQifnCpa5E # mF5y8qWPe/0IQjXSA+CVGF06QTk55oDKHqRQghfZ3TIi9c7IGRpGQS6OYGCvA9iI # nWkXPFevj4wS8dmH4n+VmAy9lzV1AXqMTAofC+HpuXmnv4Hr/12ITcKqmrcprhV+ # 47PSVGcq1oMSO5YrI2p6psu1qZCN6QWTWFKd4fK7uLeQOcwTf10uR8VgFiW6AV3e # CD2X8kSveykGiMYEaX19LVpqBettjaF53crwwpfRjBfnuQ1CHGB41TXoYMHFJrFn # x9VFZBSFHmMbUAF+CIg3t9gISym5l9osotYjJEWNi2IDGZ9cV+AIWsCDO1WQy2K1 # HriRsZgCuZtnSHp1dcRS3v7AIuug9MLzVt2Qp1gzRF5EAqwSi8E8Jh+4PtRD6rey # jPRxSBrsslXCTPTMe01Y285hzA9IJ0VnS9fuLmmiFW/lAc0B9/f7vDnG80IMSvC/ # Vsmf2+MN83/P7cDb8HHJ842OuQahghcuMIIXKgYKKwYBBAGCNwMDATGCFxowghcW # BgkqhkiG9w0BBwKgghcHMIIXAwIBAzEPMA0GCWCGSAFlAwQCAQUAMGgGCyqGSIb3 # DQEJEAEEoFkEVzBVAgEBBglghkgBhv1sBwEwITAJBgUrDgMCGgUABBQTqg/BPwiv # C90dV6tPpJHJHwux6AIRAP9Mp7A6R0yrjSeEQPzMaMEYDzIwMjMwNTEwMDg0ODMy # WqCCEwcwggbAMIIEqKADAgECAhAMTWlyS5T6PCpKPSkHgD1aMA0GCSqGSIb3DQEB # CwUAMGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkG # A1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3Rh # bXBpbmcgQ0EwHhcNMjIwOTIxMDAwMDAwWhcNMzMxMTIxMjM1OTU5WjBGMQswCQYD # VQQGEwJVUzERMA8GA1UEChMIRGlnaUNlcnQxJDAiBgNVBAMTG0RpZ2lDZXJ0IFRp # bWVzdGFtcCAyMDIyIC0gMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AM/spSY6xqnya7uNwQ2a26HoFIV0MxomrNAcVR4eNm28klUMYfSdCXc9FZYIL2tk # pP0GgxbXkZI4HDEClvtysZc6Va8z7GGK6aYo25BjXL2JU+A6LYyHQq4mpOS7eHi5 # ehbhVsbAumRTuyoW51BIu4hpDIjG8b7gL307scpTjUCDHufLckkoHkyAHoVW54Xt # 8mG8qjoHffarbuVm3eJc9S/tjdRNlYRo44DLannR0hCRRinrPibytIzNTLlmyLuq # UDgN5YyUXRlav/V7QG5vFqianJVHhoV5PgxeZowaCiS+nKrSnLb3T254xCg/oxwP # UAY3ugjZNaa1Htp4WB056PhMkRCWfk3h3cKtpX74LRsf7CtGGKMZ9jn39cFPcS6J # AxGiS7uYv/pP5Hs27wZE5FX/NurlfDHn88JSxOYWe1p+pSVz28BqmSEtY+VZ9U0v # kB8nt9KrFOU4ZodRCGv7U0M50GT6Vs/g9ArmFG1keLuY/ZTDcyHzL8IuINeBrNPx # B9ThvdldS24xlCmL5kGkZZTAWOXlLimQprdhZPrZIGwYUWC6poEPCSVT8b876asH # DmoHOWIZydaFfxPZjXnPYsXs4Xu5zGcTB5rBeO3GiMiwbjJ5xwtZg43G7vUsfHuO # y2SJ8bHEuOdTXl9V0n0ZKVkDTvpd6kVzHIR+187i1Dp3AgMBAAGjggGLMIIBhzAO # BgNVHQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEF # BQcDCDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgw # FoAUuhbZbU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFGKK3tBh/I8xFO2XC809 # KpQU31KcMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5j # cmwwgZAGCCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5k # aWdpY2VydC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0 # LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdD # QS5jcnQwDQYJKoZIhvcNAQELBQADggIBAFWqKhrzRvN4Vzcw/HXjT9aFI/H8+ZU5 # myXm93KKmMN31GT8Ffs2wklRLHiIY1UJRjkA/GnUypsp+6M/wMkAmxMdsJiJ3Hjy # zXyFzVOdr2LiYWajFCpFh0qYQitQ/Bu1nggwCfrkLdcJiXn5CeaIzn0buGqim8FT # YAnoo7id160fHLjsmEHw9g6A++T/350Qp+sAul9Kjxo6UrTqvwlJFTU2WZoPVNKy # G39+XgmtdlSKdG3K0gVnK3br/5iyJpU4GYhEFOUKWaJr5yI+RCHSPxzAm+18SLLY # kgyRTzxmlK9dAlPrnuKe5NMfhgFknADC6Vp0dQ094XmIvxwBl8kZI4DXNlpflhax # YwzGRkA7zl011Fk+Q5oYrsPJy8P7mxNfarXH4PMFw1nfJ2Ir3kHJU7n/NBBn9iYy # mHv+XEKUgZSCnawKi8ZLFUrTmJBFYDOA4CPe+AOk9kVH5c64A0JH6EE2cXet/aLo # l3ROLtoeHYxayB6a1cLwxiKoT5u92ByaUcQvmvZfpyeXupYuhVfAYOd4Vn9q78KV # mksRAsiCnMkaBXy6cbVOepls9Oie1FqYyJ+/jbsYXEP10Cro4mLueATbvdH7Wwqo # cH7wl4R44wgDXUcsY6glOJcB0j862uXl9uab3H4szP8XTE0AotjWAQ64i+7m4HJV # iSwnGWH2dwGMMIIGrjCCBJagAwIBAgIQBzY3tyRUfNhHrP0oZipeWzANBgkqhkiG # 9w0BAQsFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkw # FwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVz # dGVkIFJvb3QgRzQwHhcNMjIwMzIzMDAwMDAwWhcNMzcwMzIyMjM1OTU5WjBjMQsw # CQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRp # Z2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENB # MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAxoY1BkmzwT1ySVFVxyUD # xPKRN6mXUaHW0oPRnkyibaCwzIP5WvYRoUQVQl+kiPNo+n3znIkLf50fng8zH1AT # CyZzlm34V6gCff1DtITaEfFzsbPuK4CEiiIY3+vaPcQXf6sZKz5C3GeO6lE98NZW # 1OcoLevTsbV15x8GZY2UKdPZ7Gnf2ZCHRgB720RBidx8ald68Dd5n12sy+iEZLRS # 8nZH92GDGd1ftFQLIWhuNyG7QKxfst5Kfc71ORJn7w6lY2zkpsUdzTYNXNXmG6jB # ZHRAp8ByxbpOH7G1WE15/tePc5OsLDnipUjW8LAxE6lXKZYnLvWHpo9OdhVVJnCY # Jn+gGkcgQ+NDY4B7dW4nJZCYOjgRs/b2nuY7W+yB3iIU2YIqx5K/oN7jPqJz+ucf # WmyU8lKVEStYdEAoq3NDzt9KoRxrOMUp88qqlnNCaJ+2RrOdOqPVA+C/8KI8ykLc # GEh/FDTP0kyr75s9/g64ZCr6dSgkQe1CvwWcZklSUPRR8zZJTYsg0ixXNXkrqPNF # YLwjjVj33GHek/45wPmyMKVM1+mYSlg+0wOI/rOP015LdhJRk8mMDDtbiiKowSYI # +RQQEgN9XyO7ZONj4KbhPvbCdLI/Hgl27KtdRnXiYKNYCQEoAA6EVO7O6V3IXjAS # vUaetdN2udIOa5kM0jO0zbECAwEAAaOCAV0wggFZMBIGA1UdEwEB/wQIMAYBAf8C # AQAwHQYDVR0OBBYEFLoW2W1NhS9zKXaaL3WMaiCPnshvMB8GA1UdIwQYMBaAFOzX # 44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggr # BgEFBQcDCDB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3Nw # LmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGlnaWNl # cnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4oDag # NIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RH # NC5jcmwwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3 # DQEBCwUAA4ICAQB9WY7Ak7ZvmKlEIgF+ZtbYIULhsBguEE0TzzBTzr8Y+8dQXeJL # Kftwig2qKWn8acHPHQfpPmDI2AvlXFvXbYf6hCAlNDFnzbYSlm/EUExiHQwIgqgW # valWzxVzjQEiJc6VaT9Hd/tydBTX/6tPiix6q4XNQ1/tYLaqT5Fmniye4Iqs5f2M # vGQmh2ySvZ180HAKfO+ovHVPulr3qRCyXen/KFSJ8NWKcXZl2szwcqMj+sAngkSu # mScbqyQeJsG33irr9p6xeZmBo1aGqwpFyd/EjaDnmPv7pp1yr8THwcFqcdnGE4AJ # xLafzYeHJLtPo0m5d2aR8XKc6UsCUqc3fpNTrDsdCEkPlM05et3/JWOZJyw9P2un # 8WbDQc1PtkCbISFA0LcTJM3cHXg65J6t5TRxktcma+Q4c6umAU+9Pzt4rUyt+8SV # e+0KXzM5h0F4ejjpnOHdI/0dKNPH+ejxmF/7K9h+8kaddSweJywm228Vex4Ziza4 # k9Tm8heZWcpw8De/mADfIBZPJ/tgZxahZrrdVcA6KYawmKAr7ZVBtzrVFZgxtGIJ # Dwq9gdkT/r+k0fNX2bwE+oLeMt8EifAAzV3C+dAjfwAL5HYCJtnwZXZCpimHCUcr # 5n8apIUP/JiW9lVUKx+A+sDyDivl1vupL0QVSucTDh3bNzgaoSv27dZ8/DCCBY0w # ggR1oAMCAQICEA6bGI750C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkG # A1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRp # Z2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENB # MB4XDTIyMDgwMTAwMDAwMFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMx # FTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNv # bTEhMB8GA1UEAxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orY # WcLhKac9WKt2ms2uexuEDcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8ae # FaV+vp+pVxZZVXKvaJNwwrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckg # HWMpLc7sXk7Ik/ghYZs06wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwr # t0+nMNlW7sp7XeOtyU9e5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y # 1DekLgV9iPWCPhCRcKtVgkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjX # WkmkwuapoGfdpCe8oU85tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIb # Zpp0yt5LHucOY67m1O+SkjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0c # lcOP9yGyshG3u3/y1YxwLEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLim # dwHhD5QMIR2yVCkliWzlDlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIW # IgnffEx1P2PsIV/EIFFrb7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZ # qbId5RsCAwEAAaOCATowggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX # 44LScV1kTN8uZz/nupiuHA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3z # bcgPMA4GA1UdDwEB/wQEAwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGG # GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2Nh # Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBF # BgNVHR8EPjA8MDqgOKA2hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNl # cnRBc3N1cmVkSURSb290Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG # 9w0BAQwFAAOCAQEAcKC/Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviH # GmlUIu2kiHdtvRoU9BNKei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59Pes # MHqai7Je1M/RQ0SbQyHrlnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3 # A8eHqNJMQBk1RmppVLC4oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rb # II01YBwCA8sgsKxYoA5AY8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+ # 2DrZ8LaHlv1b0VysGMNNn3O3AamfV6peKOK5lDGCA3YwggNyAgEBMHcwYzELMAkG # A1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdp # Q2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQ # DE1pckuU+jwqSj0pB4A9WjANBglghkgBZQMEAgEFAKCB0TAaBgkqhkiG9w0BCQMx # DQYLKoZIhvcNAQkQAQQwHAYJKoZIhvcNAQkFMQ8XDTIzMDUxMDA4NDgzMlowKwYL # KoZIhvcNAQkQAgwxHDAaMBgwFgQU84ciTYYzgpI1qZS8vY+W6f4cfHMwLwYJKoZI # hvcNAQkEMSIEIA1uw0Vt7zp1uKZASwCYjwna9oAWEBbVM79XpgP5nOHyMDcGCyqG # SIb3DQEJEAIvMSgwJjAkMCIEIMf04b4yKIkgq+ImOr4axPxP5ngcLWTQTIB1V6Aj # tbb6MA0GCSqGSIb3DQEBAQUABIICAGuXWMKt1RF8mKIe5p7L2ovlif7NQoAGEK/C # gQXU1Nc/AoXFUV4gKu7l4CF9zq5anC0ibkDTQgPJhZBpCgMZHBGHDovMh6liU3e1 # lyqWcDpU0wgkFZcfSX778bWzSmc2v2b+xFW02/vMJzpbCrK2mAwbMm1ax6nC4Q5g # z6rtjbXXPcVUiDw36Tf+jWFKn9CJ1UHwCW3YXyXt+zeUIkRaZlizNSzSjwq9UjHT # adBNny1k98mAmp78A5p3rRHNJbaNvfbrte2pMnuKltY0y2P+ATCWudHi3ro0k4H1 # MYl4FpDC+vELjLkKT/WYiLhzMEJWFrY8XEBhfPNSnUaCifSKbO/cW8cNWSTjvn3b # qnrjoqSMdbcaJeJtNKpXHZDECDjmIhs3s5PaoEOIw8T2cnbtMb2mH5mi5d68vuKr # A3NZTFttu5cLTQKYOZ7NI9Mt3BmbWFq9qnp1PEYG1C0ZQL98OrKaUXPsj4gAWEcr # imZrlxvj7P61WG4CXlaGa+5yf9kT0d54bvYR7f7H/pAlRX/XK/naq8Ezf25d6wx+ # auyIZ+Z32QpM2rpTuIaZBUmFzGvOl13GgJFD+aMkIc8eWiPRF0bq+AHZj3ukqHvA # eoFO3Bl+HLPpb1x1oFe2awtmBTy8rQVx2OwO2h+7oLzCFGFEcLAq8GPMSwBaPC9C # BHuBCUo6 # SIG # End signature block |