Private/app-service.ps1
function GetCertMasterAppServiceName ($CertMasterResourceGroup, $SCEPmanAppServiceName) { # Criteria: # - Configuration value AppConfig:SCEPman:URL must be present, then it must be a CertMaster # - In a default installation, the URL must contain SCEPman's app service name. We require this. $strangeCertMasterFound = $false $rgwebapps = Convert-LinesToObject -lines $(az graph query -q "Resources | where type == 'microsoft.web/sites' and resourceGroup == '$CertMasterResourceGroup' and name !~ '$SCEPmanAppServiceName' | project name") Write-Information "$($rgwebapps.count) web apps found in the resource group $CertMasterResourceGroup (excluding SCEPman). We are finding if the CertMaster app is already created" if($rgwebapps.count -gt 0) { ForEach($potentialcmwebapp in $rgwebapps.data) { $scepmanUrl = ReadAppSetting -AppServiceName $potentialcmwebapp.name -ResourceGroup $CertMasterResourceGroup -SettingName 'AppConfig:SCEPman:URL' if($null -eq $scepmanUrl) { Write-Verbose "Web app $($potentialcmwebapp.name) is not a Certificate Master, continuing search ..." } else { $hascorrectscepmanurl = $scepmanUrl.ToUpperInvariant().Contains($SCEPmanAppServiceName.ToUpperInvariant()) # this works for deployment slots, too if($hascorrectscepmanurl -eq $true) { Write-Information "Certificate Master web app $($potentialcmwebapp.name) found." return $potentialcmwebapp.name } else { Write-Information "Certificate Master web app $($potentialcmwebapp.name) found, but its setting AppConfig:SCEPman:URL is $scepmanURL, which we could not identify with the SCEPman app service. It may or may not be the correct Certificate Master and we ignore it." $strangeCertMasterFound = $true } } } } if ($strangeCertMasterFound) { Write-Warning "There is at least one Certificate Master App Service in resource group $CertMasterResourceGroup, but we are not sure whether it belongs to SCEPman $SCEPmanAppServiceName." } Write-Warning "Unable to determine the Certificate Master app service name" return $null } function SelectBestDotNetRuntime ($ForLinux = $false) { if ($ForLinux) { return "DOTNETCORE:8.0" # Linux does not include auto-updating runtimes. Therefore we must select a specific one. } try { $runtimes = ExecuteAzCommandRobustly -azCommand "az webapp list-runtimes --os windows" | Convert-LinesToObject [String []]$WindowsDotnetRuntimes = $runtimes | Where-Object { $_.ToLower().startswith("dotnet:") } return $WindowsDotnetRuntimes[0] } catch { return "dotnet:6" } } function CreateCertMasterAppService ($TenantId, $SCEPmanResourceGroup, $SCEPmanAppServiceName, $CertMasterResourceGroup, $CertMasterAppServiceName, $DeploymentSlotName, $UpdateChannel = "prod") { if ([String]::IsNullOrWhiteSpace($CertMasterAppServiceName)) { $CertMasterAppServiceName = GetCertMasterAppServiceName -CertMasterResourceGroup $CertMasterResourceGroup -SCEPmanAppServiceName $SCEPmanAppServiceName $ShallCreateCertMasterAppService = $null -eq $CertMasterAppServiceName } else { # Check whether a cert master app service with the passed in name exists $CertMasterWebApps = Convert-LinesToObject -lines $(az graph query -q "Resources | where type == 'microsoft.web/sites' and resourceGroup == '$CertMasterResourceGroup' and name =~ '$CertMasterAppServiceName' | project name") $ShallCreateCertMasterAppService = 0 -eq $CertMasterWebApps.count } $scwebapp = Convert-LinesToObject -lines $(az graph query -q "Resources | where type == 'microsoft.web/sites' and resourceGroup == '$SCEPmanResourceGroup' and name =~ '$SCEPmanAppServiceName'") if($null -eq $CertMasterAppServiceName) { $CertMasterAppServiceName = $scwebapp.data.name if ($CertMasterAppServiceName.Length -gt 57) { $CertMasterAppServiceName = $CertMasterAppServiceName.Substring(0,57) } $CertMasterAppServiceName += "-cm" $potentialCertMasterAppServiceName = Read-Host "CertMaster web app not found. Please hit enter now if you want to create the app with name $CertMasterAppServiceName or enter the name of your choice, and then hit enter" if($potentialCertMasterAppServiceName) { $CertMasterAppServiceName = $potentialCertMasterAppServiceName } } if ($true -eq $ShallCreateCertMasterAppService) { Write-Information "User selected to create the app with the name $CertMasterAppServiceName" $isLinuxAppService = IsAppServiceLinux -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup $runtime = SelectBestDotNetRuntime -ForLinux $isLinuxAppService $null = az webapp create --resource-group $CertMasterResourceGroup --plan $scwebapp.data.properties.serverFarmId --name $CertMasterAppServiceName --assign-identity [system] --runtime $runtime Write-Information "CertMaster web app $CertMasterAppServiceName created" # Do all the configuration that the ARM template does normally $SCEPmanHostname = $scwebapp.data.properties.defaultHostName if ($null -ne $DeploymentSlotName) { $selectedSlot = Convert-LinesToObject -lines $(az graph query -q "Resources | where type == 'microsoft.web/sites/slots' and resourceGroup == '$SCEPmanResourceGroup' and name =~ '$SCEPmanAppServiceName/$DeploymentSlotName'") $SCEPmanHostname = $selectedSlot.data.properties.defaultHostName } $CertmasterAppSettingsTable = @{ WEBSITE_RUN_FROM_PACKAGE = $Artifacts_Certmaster[$UpdateChannel]; "AppConfig:AuthConfig:TenantId" = $TenantId; "AppConfig:SCEPman:URL" = "https://$SCEPmanHostname/"; } $isCertMasterLinux = IsAppServiceLinux -AppServiceName $CertMasterAppServiceName -ResourceGroup $CertMasterResourceGroup $CertMasterAppSettingsJson = AppSettingsHashTable2AzJson -psHashTable $CertmasterAppSettingsTable -convertForLinux $isCertMasterLinux Write-Verbose 'Configuring CertMaster web app settings' $null = az webapp config set --name $CertMasterAppServiceName --resource-group $CertMasterResourceGroup --use-32bit-worker-process $false --ftps-state 'Disabled' --always-on $true $null = az webapp update --name $CertMasterAppServiceName --resource-group $CertMasterResourceGroup --https-only $true $null = az webapp config appsettings set --name $CertMasterAppServiceName --resource-group $CertMasterResourceGroup --settings $CertMasterAppSettingsJson } return $CertMasterAppServiceName } function CreateSCEPmanAppService ( $SCEPmanResourceGroup, $SCEPmanAppServiceName, $AppServicePlanId) { # Find out which OS the App Service Plan uses $aspInfo = ExecuteAzCommandRobustly -azCommand "az appservice plan show --id $AppServicePlanId" | Convert-LinesToObject if ($null -eq $aspInfo) { throw "App Service Plan $AppServicePlanId not found" } $isLinuxAsp = $aspInfo.kind -eq "linux" $runtime = SelectBestDotNetRuntime -ForLinux $isLinuxAsp $null = ExecuteAzCommandRobustly -azCommand "az webapp create --resource-group $SCEPmanResourceGroup --plan $AppServicePlanId --name $SCEPmanAppServiceName --assign-identity [system] --runtime $runtime" Write-Information "SCEPman web app $SCEPmanAppServiceName created" Write-Verbose 'Configuring SCEPman General web app settings' $null = ExecuteAzCommandRobustly -azCommand "az webapp config set --name $SCEPmanAppServiceName --resource-group $SCEPmanResourceGroup --use-32bit-worker-process false --ftps-state 'Disabled' --always-on true" $null = ExecuteAzCommandRobustly -azCommand "az webapp update --name $SCEPmanAppServiceName --resource-group $SCEPmanResourceGroup --client-affinity-enabled false" } function GetAppServicePlan ( $AppServicePlanName, $ResourceGroup, $SubscriptionId) { $asp = ExecuteAzCommandRobustly -azCommand "az appservice plan list -g $ResourceGroup --query `"[?name=='$AppServicePlanName']`" --subscription $SubscriptionId" | Convert-LinesToObject return $asp } New-Variable -Name "DictAppServiceKinds" -Value @{} -Scope "Script" -Option ReadOnly function IsAppServiceLinux ($AppServiceName, $ResourceGroup) { if ($DictAppServiceKinds.ContainsKey("$AppServiceName $ResourceGroup")) { $kind = $DictAppServiceKinds["$AppServiceName $ResourceGroup"] } else { $appService = ExecuteAzCommandRobustly -azCommand "az webapp show --name $AppServiceName --resource-group $ResourceGroup" | Convert-LinesToObject $kind = $appService.kind $DictAppServiceKinds["$AppServiceName $ResourceGroup"] = $kind } return $kind -eq "app,linux" } function GetAppServiceHostNames ($SCEPmanResourceGroup, $AppServiceName, $DeploymentSlotName = $null) { if ($null -eq $DeploymentSlotName) { return ExecuteAzCommandRobustly -azCommand "az webapp config hostname list --webapp-name $AppServiceName --resource-group $SCEPmanResourceGroup --query `"[].name`" --output tsv" } else { return ExecuteAzCommandRobustly -azCommand "az webapp config hostname list --webapp-name $AppServiceName --resource-group $SCEPmanResourceGroup --slot $DeploymentSlotName --query `"[].name`" --output tsv" } } function CreateSCEPmanDeploymentSlot ($SCEPmanResourceGroup, $SCEPmanAppServiceName, $DeploymentSlotName) { $existingHostnameConfiguration = ReadAppSetting -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -SettingName "AppConfig:AuthConfig:ManagedIdentityEnabledForWebsiteHostname" if([string]::IsNullOrEmpty($existingHostnameConfiguration)) { SetAppSettings -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -Settings @(@{name="AppConfig:AuthConfig:ManagedIdentityEnabledForWebsiteHostname"; value=$SCEPmanSlotHostName}) Write-Information "Specified Production Slot Activation as such via AppConfig:AuthConfig:ManagedIdentityEnabledForWebsiteHostname" } $azOutput = az webapp deployment slot create --name $SCEPmanAppServiceName --resource-group $SCEPmanResourceGroup --slot $DeploymentSlotName --configuration-source $SCEPmanAppServiceName $null = CheckAzOutput -azOutput $azOutput -fThrowOnError $true Write-Information "Created SCEPman Deployment Slot $DeploymentSlotName" return Convert-LinesToObject -lines $(az webapp identity assign --name $SCEPmanAppServiceName --resource-group $SCEPmanResourceGroup --slot $DeploymentSlotName --identities [system]) } function GetDeploymentSlots($appServiceName, $resourceGroup) { $deploymentSlots = ExecuteAzCommandRobustly -azCommand "az webapp deployment slot list --name $appServiceName --resource-group $resourceGroup --query '[].name'" | Convert-LinesToObject if ($null -eq $deploymentSlots) { return @() } else { return $deploymentSlots } } function MarkDeploymentSlotAsConfigured($SCEPmanResourceGroup, $SCEPmanAppServiceName, $DeploymentSlotName = $null) { # Add a setting to tell the Deployment slot that it has been configured $SCEPmanSlotHostNames = GetAppServiceHostNames -SCEPmanResourceGroup $SCEPmanResourceGroup -AppServiceName $SCEPmanAppServiceName -DeploymentSlotName $DeploymentSlotName if ($SCEPmanSlotHostNames -is [array]) { $SCEPmanSlotHostName = $SCEPmanSlotHostNames[0] } else { $SCEPmanSlotHostName = $SCEPmanSlotHostNames } $managedIdentityEnabledOn = ([DateTimeOffset]::UtcNow).ToUnixTimeSeconds() Write-Verbose "[$SCEPmanAppServiceName-$DeploymentSlotName] Marking SCEPman App Service as configured (timestamp $managedIdentityEnabledOn)" $MarkAsConfiguredSettings = @( @{name="AppConfig:AuthConfig:ManagedIdentityEnabledOnUnixTime"; value=$managedIdentityEnabledOn}, @{name="AppConfig:AuthConfig:ManagedIdentityEnabledForWebsiteHostname"; value=$SCEPmanSlotHostName}, @{name="AppConfig:AuthConfig:ManagedIdentityPermissionLevel"; value=2} ) SetAppSettings -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -Settings $MarkAsConfiguredSettings -Slot $DeploymentSlotName } $RegExGuid = "[({]?[a-fA-F0-9]{8}[-]?([a-fA-F0-9]{4}[-]?){3}[a-fA-F0-9]{12}[})]?" function ConfigureSCEPmanInstance ($SCEPmanResourceGroup, $SCEPmanAppServiceName, $ScepManAppSettings, $AppRoleAssignmentsFinished, $SCEPmanAppId, $DeploymentSlotName = $null) { $existingApplicationId = ReadAppSetting -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -SettingName "AppConfig:AuthConfig:ApplicationId" -Slot $DeploymentSlotName Write-Debug "Existing Application Id is set to $existingApplicationId in slot $DeploymentSlotName. The new ID shall be $SCEPmanAppId." if ($null -ne $existingApplicationId) { $existingApplicationId = $existingApplicationId.Trim('"') } Write-Debug "The new ID is different to the existing ID? $($existingApplicationId -ne $SCEPmanAppId)" if(![string]::IsNullOrEmpty($existingApplicationId) -and $existingApplicationId -ne $SCEPmanAppId) { if ($existingApplicationId -notmatch $RegExGuid) { Write-Debug "Existing SCEPman Application ID is not a Guid. IsNullOrEmpty? $([string]::IsNullOrEmpty($existingApplicationId)); Is it different than the new one? $($existingApplicationId -ne $SCEPmanAppId); New ID: $SCEPmanAppId; Existing ID: $existingApplicationId" throw "SCEPman Application ID $existingApplicationId (Setting AppConfig:AuthConfig:ApplicationId) is not a GUID (Deployment Slot: $DeploymentSlotName). Aborting on unexpected setting." } Write-Debug "Creating backup of existing ApplicationId $existingApplicationId in slot $DeploymentSlotName" SetAppSettings -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -Settings @(@{name="BackUp:AppConfig:AuthConfig:ApplicationId"; value=$existingApplicationId}) -Slot $DeploymentSlotName Write-Verbose "[$SCEPmanAppServiceName-$DeploymentSlotName] Backed up ApplicationId" } SetAppSettings -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -Settings $ScepManAppSettings -Slot $DeploymentSlotName # The following setting AppConfig:AuthConfig:ApplicationKey is a secret, but we make sure it doesn't appear in the logs. Not even through az's echoes. Therefore we can ignore the leakage warning $existingApplicationKeySc = ReadAppSetting -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -SettingName "AppConfig:AuthConfig:ApplicationKey" -Slot $DeploymentSlotName Write-Verbose "[$SCEPmanAppServiceName-$DeploymentSlotName] Wrote SCEPman application settings" if(![string]::IsNullOrEmpty($existingApplicationKeySc)) { if ($existingApplicationKeySc.Contains("'")) { throw "SCEPman Application Key contains at least one single-quote character ('), which is unexpected. Aborting on unexpected setting" } SetAppSettings -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup -Settings @(@{name="BackUp:AppConfig:AuthConfig:ApplicationKey"; value=$existingApplicationKeySc}) -Slot $DeploymentSlotName $isScepmanLinux = IsAppServiceLinux -AppServiceName $SCEPmanAppServiceName -ResourceGroup $SCEPmanResourceGroup $applicationKeyKey = "AppConfig:AuthConfig:ApplicationKey" if ($isScepmanLinux) { $applicationKeyKey = $applicationKeyKey.Replace(':', '__') } $azCommand = @("webapp", "config", "appsettings", "delete", "--name", $SCEPmanAppServiceName, "--resource-group", $SCEPmanResourceGroup, "--setting-names", $applicationKeyKey) if ($null -eq $DeploymentSlotName) { $azCommand += @("--slot", $DeploymentSlotName) } $null = ExecuteAzCommandRobustly -callAzNatively -azCommand $azCommand Write-Verbose "[$SCEPmanAppServiceName-$DeploymentSlotName] Backed up ApplicationKey" } if ($AppRoleAssignmentsFinished) { MarkDeploymentSlotAsConfigured -SCEPmanResourceGroup $SCEPmanResourceGroup -SCEPmanAppServiceName $SCEPmanAppServiceName -DeploymentSlotName $DeploymentSlotName } } function ConfigureScepManAppServices($SCEPmanResourceGroup, $SCEPmanAppServiceName, $DeploymentSlotName, $CertMasterBaseURL, $SCEPmanAppId, $AppRoleAssignmentsFinished, $DeploymentSlots) { Write-Information "Configuring SCEPman, SCEPman's deployment slots (if any), and Certificate Master web app settings" # Add ApplicationId and some additional defaults in SCEPman web app settings $ScepManAppSettings = @( @{ name='AppConfig:AuthConfig:ApplicationId'; value=$SCEPmanAppID }, @{ name='AppConfig:IntuneValidation:DeviceDirectory'; value='AADAndIntune'} ) if (-not [string]::IsNullOrEmpty($CertMasterBaseURL)) { $ScepManAppSettings += @{ name='AppConfig:CertMaster:URL'; value=$CertMasterBaseURL } $ScepManAppSettings += @{ name='AppConfig:DirectCSRValidation:Enabled'; value='true' } } if ($null -eq $DeploymentSlotName) { ConfigureSCEPmanInstance -SCEPmanResourceGroup $SCEPmanResourceGroup -SCEPmanAppServiceName $SCEPmanAppServiceName -ScepManAppSettings $ScepManAppSettings -AppRoleAssignmentsFinished $AppRoleAssignmentsFinished -SCEPmanAppId $SCEPmanAppID } ForEach($tempDeploymentSlot in $DeploymentSlots) { ConfigureSCEPmanInstance -SCEPmanResourceGroup $SCEPmanResourceGroup -SCEPmanAppServiceName $SCEPmanAppServiceName -ScepManAppSettings $ScepManAppSettings -DeploymentSlotName $tempDeploymentSlot -AppRoleAssignmentsFinished $AppRoleAssignmentsFinished -SCEPmanAppId $SCEPmanAppID } } function ConfigureCertMasterAppService($CertMasterResourceGroup, $CertMasterAppServiceName, $SCEPmanAppId, $CertMasterAppId, $AppRoleAssignmentsFinished) { Write-Verbose "Setting Certificate Master configuration" $managedIdentityEnabledOn = ([DateTimeOffset]::UtcNow).ToUnixTimeSeconds() # Add ApplicationId and SCEPman API scope in certmaster web app settings $CertmasterAppSettings = @{ 'AppConfig:AuthConfig:ApplicationId' = $CertMasterAppId 'AppConfig:AuthConfig:SCEPmanAPIScope' = "api://$SCEPmanAppId" } if ($AppRoleAssignmentsFinished) { $CertmasterAppSettings['AppConfig:AuthConfig:ManagedIdentityEnabledOnUnixTime'] = "$managedIdentityEnabledOn" $CertmasterAppSettings['AppConfig:AuthConfig:ManagedIdentityPermissionLevel'] = 2 } $isCertMasterLinux = IsAppServiceLinux -AppServiceName $CertMasterAppServiceName -ResourceGroup $CertMasterResourceGroup $CertmasterAppSettingsJson = AppSettingsHashTable2AzJson -psHashTable $CertmasterAppSettings -convertForLinux $isCertMasterLinux $null = ExecuteAzCommandRobustly -azCommand "az webapp config appsettings set --name $CertMasterAppServiceName --resource-group $CertMasterResourceGroup --settings '$CertmasterAppSettingsJson'" } function SwitchToConfiguredChannel($AppServiceName, $ResourceGroup, $ChannelArtifacts) { $intendedChannel = ExecuteAzCommandRobustly -azCommand @("webapp", "config", "appsettings", "list", "--name", $AppServiceName, "--resource-group", $ResourceGroup, "--query", "[?name=='Update_Channel'].value | [0]", "--output", "tsv") -callAzNatively -noSecretLeakageWarning if (-not [string]::IsNullOrWhiteSpace($intendedChannel) -and "none" -ne $intendedChannel) { Write-Information "Switching app $AppServiceName to update channel $intendedChannel" $ArtifactsUrl = $ChannelArtifacts[$intendedChannel] if ([string]::IsNullOrWhiteSpace($ArtifactsUrl)) { Write-Warning "Could not find Artifacts URL for Channel $intendedChannel of App Service $AppServiceName. Available values: $(Join-String -Separator ',' -InputObject $ChannelArtifacts.Keys)" } else { Write-Verbose "Artifacts URL is $ArtifactsUrl" $null = ExecuteAzCommandRobustly -azCommand @("webapp", "config", "appsettings", "set", "--name", $AppServiceName, "--resource-group", $ResourceGroup, "--settings", "WEBSITE_RUN_FROM_PACKAGE=$ArtifactsUrl") -callAzNatively $null = ExecuteAzCommandRobustly -azCommand "az webapp config appsettings delete --name $AppServiceName --resource-group $ResourceGroup --setting-names ""Update_Channel""" } } } function SetAppSettings($AppServiceName, $ResourceGroup, $Settings, $Slot = $null) { foreach ($oneSetting in $Settings) { $settingName = $oneSetting.name $settingValueEscaped = $oneSetting.value.ToString().Replace('"','\"') if ($settingName.Contains("=")) { Write-Warning "Setting name $settingName contains at least one equal sign (=), which is unsupported. Skipping this setting." continue } $isAppServiceLinux = IsAppServiceLinux -AppServiceName $AppServiceName -ResourceGroup $ResourceGroup if ($isAppServiceLinux) { $settingName = $settingName.Replace(":", "__") } Write-Verbose "Setting app setting $settingName of app $AppServiceName in slot [$Slot]" Write-Debug "Setting $settingName to $settingValueEscaped" # there could be cases where this is a secret, so we do not use Write-Verbose if ($PSVersionTable.PSVersion.Major -eq 5 -or -not $PSVersionTable.OS.StartsWith("Microsoft Windows")) { $settingAssignment = "$settingName=$settingValueEscaped" } else { $settingAssignment = "`"$settingName`"=`"$settingValueEscaped`"" } $command = @('webapp', 'config', 'appsettings', 'set', '--name', $AppServiceName, '--resource-group', $ResourceGroup, '--settings', $settingAssignment) if ($null -ne $Slot) { $command += @('--slot', $Slot) } $null = ExecuteAzCommandRobustly -callAzNatively -azCommand $command } # The following does not work, as equal signs split this into incomprehensible gibberish: #$null = az webapp config appsettings set --name $AppServiceName --resource-group $ResourceGroup --settings (ConvertTo-Json($Settings) -Compress).Replace('"','\"') } function ReadAppSettings($AppServiceName, $ResourceGroup) { $slotSettings = ExecuteAzCommandRobustly -azCommand "az webapp config appsettings list --name $AppServiceName --resource-group $ResourceGroup --query `"[?slotSetting]`"" | Convert-LinesToObject $unboundSettings = ExecuteAzCommandRobustly -azCommand "az webapp config appsettings list --name $AppServiceName --resource-group $ResourceGroup --query `"[?!slotSetting]`"" | Convert-LinesToObject Write-Information "Read $($slotSettings.Count) slot settings and $($unboundSettings.Count) other settings from app $AppServiceName" return @{ slotSettings = $slotSettings settings = $unboundSettings } } function ReadAppSetting($AppServiceName, $ResourceGroup, $SettingName, $Slot = $null) { $isAppServiceLinux = IsAppServiceLinux -AppServiceName $AppServiceName -ResourceGroup $ResourceGroup if ($isAppServiceLinux) { $SettingName = $SettingName.Replace(":", "__") } $azCommand = @("webapp", "config", "appsettings", "list", "--name", $AppServiceName, "--resource-group", $ResourceGroup, "--query", "[?name=='$SettingName'].value | [0]") if ($null -ne $Slot) { $azCommand += @("--slot", $Slot) } $settingValue = ExecuteAzCommandRobustly -callAzNatively -azCommand $azCommand -noSecretLeakageWarning if(![string]::IsNullOrEmpty($settingValue)) { return $settingValue.Trim('"') } else { return $settingValue } } # SIG # Begin signature block # MIIvUgYJKoZIhvcNAQcCoIIvQzCCLz8CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB0MEFXlPmArvj1 # lQrCz+BMeUUmgSo73STeDC3DGhtAZaCCFDUwggWQMIIDeKADAgECAhAFmxtXno4h # MuI5B72nd3VcMA0GCSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0xMzA4MDExMjAwMDBaFw0z # ODAxMTUxMjAwMDBaMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/z # G6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZ # anMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7s # Wxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL # 2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfb # BHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3 # JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3c # AORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqx # YxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0 # viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aL # T8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjQjBAMA8GA1Ud # EwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgGGMB0GA1UdDgQWBBTs1+OC0nFdZEzf # Lmc/57qYrhwPTzANBgkqhkiG9w0BAQwFAAOCAgEAu2HZfalsvhfEkRvDoaIAjeNk # aA9Wz3eucPn9mkqZucl4XAwMX+TmFClWCzZJXURj4K2clhhmGyMNPXnpbWvWVPjS # PMFDQK4dUPVS/JA7u5iZaWvHwaeoaKQn3J35J64whbn2Z006Po9ZOSJTROvIXQPK # 7VB6fWIhCoDIc2bRoAVgX+iltKevqPdtNZx8WorWojiZ83iL9E3SIAveBO6Mm0eB # cg3AFDLvMFkuruBx8lbkapdvklBtlo1oepqyNhR6BvIkuQkRUNcIsbiJeoQjYUIp # 5aPNoiBB19GcZNnqJqGLFNdMGbJQQXE9P01wI4YMStyB0swylIQNCAmXHE/A7msg # dDDS4Dk0EIUhFQEI6FUy3nFJ2SgXUE3mvk3RdazQyvtBuEOlqtPDBURPLDab4vri # RbgjU2wGb2dVf0a1TD9uKFp5JtKkqGKX0h7i7UqLvBv9R0oN32dmfrJbQdA75PQ7 # 9ARj6e/CVABRoIoqyc54zNXqhwQYs86vSYiv85KZtrPmYQ/ShQDnUBrkG5WdGaG5 # nLGbsQAe79APT0JsyQq87kP6OnGlyE0mpTX9iV28hWIdMtKgK1TtmlfB2/oQzxm3 # i0objwG2J5VT6LaJbVu8aNQj6ItRolb58KaAoNYes7wPD1N1KarqE3fk3oyBIa0H # EEcRrYc9B9F1vM/zZn4wggawMIIEmKADAgECAhAIrUCyYNKcTJ9ezam9k67ZMA0G # CSqGSIb3DQEBDAUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ # bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0 # IFRydXN0ZWQgUm9vdCBHNDAeFw0yMTA0MjkwMDAwMDBaFw0zNjA0MjgyMzU5NTla # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDVtC9C # 0CiteLdd1TlZG7GIQvUzjOs9gZdwxbvEhSYwn6SOaNhc9es0JAfhS0/TeEP0F9ce # 2vnS1WcaUk8OoVf8iJnBkcyBAz5NcCRks43iCH00fUyAVxJrQ5qZ8sU7H/Lvy0da # E6ZMswEgJfMQ04uy+wjwiuCdCcBlp/qYgEk1hz1RGeiQIXhFLqGfLOEYwhrMxe6T # SXBCMo/7xuoc82VokaJNTIIRSFJo3hC9FFdd6BgTZcV/sk+FLEikVoQ11vkunKoA # FdE3/hoGlMJ8yOobMubKwvSnowMOdKWvObarYBLj6Na59zHh3K3kGKDYwSNHR7Oh # D26jq22YBoMbt2pnLdK9RBqSEIGPsDsJ18ebMlrC/2pgVItJwZPt4bRc4G/rJvmM # 1bL5OBDm6s6R9b7T+2+TYTRcvJNFKIM2KmYoX7BzzosmJQayg9Rc9hUZTO1i4F4z # 8ujo7AqnsAMrkbI2eb73rQgedaZlzLvjSFDzd5Ea/ttQokbIYViY9XwCFjyDKK05 # huzUtw1T0PhH5nUwjewwk3YUpltLXXRhTT8SkXbev1jLchApQfDVxW0mdmgRQRNY # mtwmKwH0iU1Z23jPgUo+QEdfyYFQc4UQIyFZYIpkVMHMIRroOBl8ZhzNeDhFMJlP # /2NPTLuqDQhTQXxYPUez+rbsjDIJAsxsPAxWEQIDAQABo4IBWTCCAVUwEgYDVR0T # AQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQUaDfg67Y7+F8Rhvv+YXsIiGX0TkIwHwYD # VR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMG # A1UdJQQMMAoGCCsGAQUFBwMDMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYY # aHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2Fj # ZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNV # HR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRU # cnVzdGVkUm9vdEc0LmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEEATAN # BgkqhkiG9w0BAQwFAAOCAgEAOiNEPY0Idu6PvDqZ01bgAhql+Eg08yy25nRm95Ry # sQDKr2wwJxMSnpBEn0v9nqN8JtU3vDpdSG2V1T9J9Ce7FoFFUP2cvbaF4HZ+N3HL # IvdaqpDP9ZNq4+sg0dVQeYiaiorBtr2hSBh+3NiAGhEZGM1hmYFW9snjdufE5Btf # Q/g+lP92OT2e1JnPSt0o618moZVYSNUa/tcnP/2Q0XaG3RywYFzzDaju4ImhvTnh # OE7abrs2nfvlIVNaw8rpavGiPttDuDPITzgUkpn13c5UbdldAhQfQDN8A+KVssIh # dXNSy0bYxDQcoqVLjc1vdjcshT8azibpGL6QB7BDf5WIIIJw8MzK7/0pNVwfiThV # 9zeKiwmhywvpMRr/LhlcOXHhvpynCgbWJme3kuZOX956rEnPLqR0kq3bPKSchh/j # wVYbKyP/j7XqiHtwa+aguv06P0WmxOgWkVKLQcBIhEuWTatEQOON8BUozu3xGFYH # Ki8QxAwIZDwzj64ojDzLj4gLDb879M4ee47vtevLt/B3E+bnKD+sEq6lLyJsQfmC # XBVmzGwOysWGw/YmMwwHS6DTBwJqakAwSEs0qFEgu60bhQjiWQ1tygVQK+pKHJ6l # /aCnHwZ05/LWUpD9r4VIIflXO7ScA+2GRfS0YW6/aOImYIbqyK+p/pQd52MbOoZW # eE4wggfpMIIF0aADAgECAhAE0w/ewLw2E3KQ6RwmFyT5MA0GCSqGSIb3DQEBCwUA # MGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjFBMD8GA1UE # AxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBDb2RlIFNpZ25pbmcgUlNBNDA5NiBTSEEz # ODQgMjAyMSBDQTEwHhcNMjMxMTE2MDAwMDAwWhcNMjYxMTE1MjM1OTU5WjCB8TET # MBEGCysGAQQBgjc8AgEDEwJERTEXMBUGCysGAQQBgjc8AgECEwZIZXNzZW4xIjAg # BgsrBgEEAYI3PAIBARMRT2ZmZW5iYWNoIGFtIE1haW4xHTAbBgNVBA8MFFByaXZh # dGUgT3JnYW5pemF0aW9uMRIwEAYDVQQFEwlIUkIgMTIzODExCzAJBgNVBAYTAkRF # MQ8wDQYDVQQIEwZIZXNzZW4xGjAYBgNVBAcTEU9mZmVuYmFjaCBhbSBNYWluMRcw # FQYDVQQKEw5nbHVlY2trYW5qYSBBRzEXMBUGA1UEAxMOZ2x1ZWNra2FuamEgQUcw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDOkzyWiAT0dzoCrdo4dTaE # UjIJKcht/Gvb3OOJ/WpNQYJius0XbgOcyBu+7+yGANG0SKDbGxuy8gl6FDMkMKXS # g4ukpw2GLeMNATJ+MBd5FL3MwTSyZS0SljlAbIdyo7ydBeCNrCqKsJoBLARTdxSu # fsxRtgsEOM3AqkT51Z+oSb3fOpAvG3E6fj6ViQP2C37m3t9LvCzNJO6TQ94ylKFg # WxOLmHlBnvBEK6wLsL3FRWl0avXTNvheH7XmY7vI9Othb469+V+FJVBbmD7SE0f5 # miAND4wpNGObz76r2TsHFcgTHah8EGKTJeo0+m3AM158ILT2cN35v8z7X4RbJ7L5 # k4eMFNoWKwPc72UPZKdlo0OQuutL5ehtFhopnB7WUUFCNV4+KQGYo9cKEeufGqV0 # xrIcdH409ejAuMleNZ4CLyU5LE5qVkYxLgdjDdCdxbk2ADSTOwQtpLJExnhf/jkc # 9sRTys9i6NtpE+hb6xbAJ7p4vQt3iLMDQHy6l98HNJNlmY3Phvk0ViUIzRC7qgv7 # Fe+5bE6FkFc/J4rrx6AUTJek/WvkhbvJp39IvspHUxTYC34l9y8Dcnxk3XU2TASn # JR6yKElD+OetRKE0rS9VcuL7kJrTY9det5Kv1hzoZj3zPqd5X+cqqV5hzE3aI3TP # 1v0zICGYf5ayeA1zg9aCkQIDAQABo4ICAjCCAf4wHwYDVR0jBBgwFoAUaDfg67Y7 # +F8Rhvv+YXsIiGX0TkIwHQYDVR0OBBYEFOTb7LJoGHhU5+5fcQSNJKUzQX0kMD0G # A1UdIAQ2MDQwMgYFZ4EMAQMwKTAnBggrBgEFBQcCARYbaHR0cDovL3d3dy5kaWdp # Y2VydC5jb20vQ1BTMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcD # AzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRwOi8vY3JsMy5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0Ex # LmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1 # c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hBMzg0MjAyMUNBMS5jcmwwgZQGCCsG # AQUFBwEBBIGHMIGEMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5j # b20wXAYIKwYBBQUHMAKGUGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRHNENvZGVTaWduaW5nUlNBNDA5NlNIQTM4NDIwMjFDQTEuY3J0 # MAkGA1UdEwQCMAAwDQYJKoZIhvcNAQELBQADggIBAMkcpd3bsp6QPtw6hZFySq8n # 50F0KYvrGH0MnQipkz7lV5RvFjl/cBf5gRSrebMIV1rvQMttrFxC06Y3zTbU6t4E # z1nDX76GZV7bmomreROITlH43UvsYacedTmiPp+SFDF5hjDz71XHaATzaSSL5puE # GRrGCyEh2Y/tw823jtk7jDLZrjb74kbGIB21/uUkjOWkhNGN55rDa933sjJuoZx2 # /pVSSmHxo+Bvc3td67EY4ylZj4CsBHmr6afeGKtZFT/QtnilYq+5nARiCDVKSHP0 # svNpmOCDZJg+aaq+TBAtvu6ddAogZ4FHtpOFQ+NQZeO9jWNn/9bYDdBlwejQKPqZ # 0p3oO+25FyYe8dxr1j82TyefL4mC486nVbSSk3XCu+LUKRmMkOh8cSKXyIP06RIz # LWQSpS1zenI+DREJ6VJHI/pBhRZGr9i6gwOIVaKva2t/AnaCkI4ulJd8iq6/lI+z # DvuLPjRqQOv2+Zf+1jbNV2I0BttmiFfXGDeAOCEaiF82lak6CcwkrGj3Hbt7YjuF # Zd7qCJWHG4pVrpJhwEScp+1+kDLpWGlupiPJv4XDhKUEqJPQ2KGhMzE0JDd8V7Si # 4gXvAoEZAPb1sjLcatDHYJX1acsAHEoYD2Um1Lx0pARy4LcHsTPrETz4EiiGg/iE # qeoXQDjtJraR++BTJXQyMYIaczCCGm8CAQEwfTBpMQswCQYDVQQGEwJVUzEXMBUG # A1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQg # RzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEgQ0ExAhAE0w/ewLw2 # E3KQ6RwmFyT5MA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAIoAKA # AKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIF5y/3qXrVfmqogAvhyQljB+ # 9qqhEWeu4BgxwoFUvr40MA0GCSqGSIb3DQEBAQUABIICAJPYMDrfJMxIQtvEgEMd # ojdAugdfa6mesrcUBgYmZgVQS6PcusNxdsPhZY70LUJ4v24+N2G53FPlLzC6nGtL # 9CgqvqAhmU0NiY6fk1o3R7O72fn2Go11kUizghq1OE9d5MqL+xRdq1dRZiqDP84K # AOHExG3UTuq8Mw2ZKtTMXKy2aj3wjamATksKSDBLerxW0I8nUePvlLcV3GXuTgvS # +bn2spzvUlQlM4QJ0FgbHbHmSOUyotQ80aoOZ9BZWVx/7nbicv3viGTnUw0WBZqL # xOdYX6CUCwy+NkvclMMN+MRrPgZB/1KRWkdCG0kmFaHBc3NfkMDBHDeasxxjy/GE # 6jE1gI30EzB278F+tK67euoGOOztKwp5qdaAtPxjQdkrbMUCp+DdNUwahg49p1RG # QJx1XYOcj6f3IGVFc5gBxThxh+fPDpa5x0VApAXr6lmdJ7H1dk0sBwTMtZ+9PuQs # oyOUz9q4nYRlOE/45O8Pqu1SGVSmOV7Gy+PmIWlLsEEQqiRuvzv2+3YGMGkZo39R # X/mwvr1lt+IMx2IxXe07Ond3rxyrYwOolic00EAuqNbFSM2UgtZ2rKQMQKoUL8/z # DBvJiV+sB/0P+/o3SM0yzXzNuGjwYM97axEp/KtIREGlWKEhFmyDVohh7F5qNelk # o7Ikxgi8il0zKOuM3c5TUZuKoYIXQDCCFzwGCisGAQQBgjcDAwExghcsMIIXKAYJ # KoZIhvcNAQcCoIIXGTCCFxUCAQMxDzANBglghkgBZQMEAgEFADB4BgsqhkiG9w0B # CRABBKBpBGcwZQIBAQYJYIZIAYb9bAcBMDEwDQYJYIZIAWUDBAIBBQAEIJyUwXZJ # 7RK6uHM29hovAy2wMBDXtJfkx5nreRqnJOB5AhEAl03Z445QN6xS9yr2/vNu4BgP # MjAyNDAzMTIxMjU0NTdaoIITCTCCBsIwggSqoAMCAQICEAVEr/OUnQg5pr/bP1/l # YRYwDQYJKoZIhvcNAQELBQAwYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD # ZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYg # U0hBMjU2IFRpbWVTdGFtcGluZyBDQTAeFw0yMzA3MTQwMDAwMDBaFw0zNDEwMTMy # MzU5NTlaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEg # MB4GA1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjMwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQCjU0WHHYOOW6w+VLMj4M+f1+XS512hDgncL0ijl3o7 # Kpxn3GIVWMGpkxGnzaqyat0QKYoeYmNp01icNXG/OpfrlFCPHCDqx5o7L5Zm42nn # af5bw9YrIBzBl5S0pVCB8s/LB6YwaMqDQtr8fwkklKSCGtpqutg7yl3eGRiF+0Xq # DWFsnf5xXsQGmjzwxS55DxtmUuPI1j5f2kPThPXQx/ZILV5FdZZ1/t0QoRuDwbjm # UpW1R9d4KTlr4HhZl+NEK0rVlc7vCBfqgmRN/yPjyobutKQhZHDr1eWg2mOzLukF # 7qr2JPUdvJscsrdf3/Dudn0xmWVHVZ1KJC+sK5e+n+T9e3M+Mu5SNPvUu+vUoCw0 # m+PebmQZBzcBkQ8ctVHNqkxmg4hoYru8QRt4GW3k2Q/gWEH72LEs4VGvtK0VBhTq # YggT02kefGRNnQ/fztFejKqrUBXJs8q818Q7aESjpTtC/XN97t0K/3k0EH6mXApY # TAA+hWl1x4Nk1nXNjxJ2VqUk+tfEayG66B80mC866msBsPf7Kobse1I4qZgJoXGy # bHGvPrhvltXhEBP+YUcKjP7wtsfVx95sJPC/QoLKoHE9nJKTBLRpcCcNT7e1NtHJ # XwikcKPsCvERLmTgyyIryvEoEyFJUX4GZtM7vvrrkTjYUQfKlLfiUKHzOtOKg8tA # ewIDAQABo4IBizCCAYcwDgYDVR0PAQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYD # VR0lAQH/BAwwCgYIKwYBBQUHAwgwIAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZI # AYb9bAcBMB8GA1UdIwQYMBaAFLoW2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQW # BBSltu8T5+/N0GSh1VapZTGj3tXjSTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8v # Y3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2 # VGltZVN0YW1waW5nQ0EuY3JsMIGQBggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcw # AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8v # Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hB # MjU2VGltZVN0YW1waW5nQ0EuY3J0MA0GCSqGSIb3DQEBCwUAA4ICAQCBGtbeoKm1 # mBe8cI1PijxonNgl/8ss5M3qXSKS7IwiAqm4z4Co2efjxe0mgopxLxjdTrbebNfh # YJwr7e09SI64a7p8Xb3CYTdoSXej65CqEtcnhfOOHpLawkA4n13IoC4leCWdKgV6 # hCmYtld5j9smViuw86e9NwzYmHZPVrlSwradOKmB521BXIxp0bkrxMZ7z5z6eOKT # GnaiaXXTUOREEr4gDZ6pRND45Ul3CFohxbTPmJUaVLq5vMFpGbrPFvKDNzRusEEm # 3d5al08zjdSNd311RaGlWCZqA0Xe2VC1UIyvVr1MxeFGxSjTredDAHDezJieGYkD # 6tSRN+9NUvPJYCHEVkft2hFLjDLDiOZY4rbbPvlfsELWj+MXkdGqwFXjhr+sJyxB # 0JozSqg21Llyln6XeThIX8rC3D0y33XWNmdaifj2p8flTzU8AL2+nCpseQHc2kTm # Ot44OwdeOVj0fHMxVaCAEcsUDH6uvP6k63llqmjWIso765qCNVcoFstp8jKastLY # OrixRoZruhf9xHdsFWyuq69zOuhJRrfVf8y2OMDY7Bz1tqG4QyzfTkx9HmhwwHcK # 1ALgXGC7KP845VJa1qwXIiNO9OzTF/tQa/8Hdx9xl0RBybhG02wyfFgvZ0dl5Rtz # tpn5aywGRu9BHvDwX+Db2a2QgESvgBBBijCCBq4wggSWoAMCAQICEAc2N7ckVHzY # R6z9KGYqXlswDQYJKoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoT # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UE # AxMYRGlnaUNlcnQgVHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3 # MDMyMjIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2 # IFRpbWVTdGFtcGluZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # AMaGNQZJs8E9cklRVcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjz # aPp985yJC3+dH54PMx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3E # F3+rGSs+QtxnjupRPfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYnc # fGpXevA3eZ9drMvohGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8O # pWNs5KbFHc02DVzV5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROp # VymWJy71h6aPTnYVVSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4i # FNmCKseSv6De4z6ic/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmif # tkaznTqj1QPgv/CiPMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0 # UfM2SU2LINIsVzV5K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9Ne # S3YSUZPJjAw7W4oiqMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCj # WAkBKAAOhFTuzuldyF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTAS # BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57I # bzAfBgNVHSMEGDAWgBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMC # AYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0 # MEMGA1UdHwQ8MDowOKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp # Q2VydFRydXN0ZWRSb290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCG # SAGG/WwHATANBgkqhkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAY # LhBNE88wU86/GPvHUF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQx # Z822EpZvxFBMYh0MCIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf # 7WC2qk+RZp4snuCKrOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDV # inF2ZdrM8HKjI/rAJ4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7 # +6adcq/Ex8HBanHZxhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJ # D5TNOXrd/yVjmScsPT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvk # OHOrpgFPvT87eK1MrfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJG # nXUsHicsJttvFXseGYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimG # sJigK+2VQbc61RWYMbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38A # C+R2AibZ8GV2QqYphwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d # 2zc4GqEr9u3WfPwwggWNMIIEdaADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqG # SIb3DQEBDAUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFz # c3VyZWQgSUQgUm9vdCBDQTAeFw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTla # MGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsT # EHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9v # dCBHNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8 # MCIwaTPswqclLskhPfKK2FnC4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauy # efLKEdLkX9YFPFIPUh/GnhWlfr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34Lz # B4TmdDttceItDBvuINXJIB1jKS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+x # embud8hIqGZXV59UWI4MK7dPpzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhA # kHnDeMe2scS1ahg4AxCN2NQ3pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1Lyu # GwN1XXhm2ToxRJozQL8I11pJpMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2 # PVldQnaHiZdpekjw4KISG2aadMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37A # lLTSYW3rM9nF30sEAMx9HJXDj/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD7 # 6GSmM9GJB+G9t+ZDpBi4pncB4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ # ybzTQRESW+UQUOsxxcpyFiIJ33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXA # j6KxfgommfXkaS+YHS312amyHeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTAD # AQH/MB0GA1UdDgQWBBTs1+OC0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF # 66Kv9JLLgjEtUYunpyGd823IDzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEE # bTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB # BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3Vy # ZWRJRFJvb3RDQS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGln # aWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAI # MAYGBFUdIAAwDQYJKoZIhvcNAQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979X # B72arKGHLOyFXqkauyL4hxppVCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4k # vFIDyE7QKt76LVbP+fT3rDB6mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU # 53/oWajwvy8LpunyNDzs9wPHh6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pc # VIxv76FQPfx2CWiEn2/K2yCNNWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5v # Iy30fnFqI2si/xK4VC0nftg62fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQxggN2 # MIIDcgIBATB3MGMxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5j # LjE7MDkGA1UEAxMyRGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBU # aW1lU3RhbXBpbmcgQ0ECEAVEr/OUnQg5pr/bP1/lYRYwDQYJYIZIAWUDBAIBBQCg # gdEwGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0y # NDAzMTIxMjU0NTdaMCsGCyqGSIb3DQEJEAIMMRwwGjAYMBYEFGbwKzLCwskPgl3O # qorJxk8ZnM9AMC8GCSqGSIb3DQEJBDEiBCDE3/7V5DSpwDXKRqf3xOTBy7vjey9G # D0pI4E6rwmXIaDA3BgsqhkiG9w0BCRACLzEoMCYwJDAiBCDS9uRt7XQizNHUQFdo # QTZvgoraVZquMxavTRqa1Ax4KDANBgkqhkiG9w0BAQEFAASCAgAh+mqxg5DOUEA8 # PXA1YCrPBbfs9wxWqxUpT/7NhYhwtIesq6dKQYE3SpCt67NSwzUBiJxMyLON/9HR # jQTuvQX2R2g+PB4HxpzHGbt0S6ycKXM1+pjJ7wRtlarKCScKACiU9WfQKKpyqqv1 # PDQYBj4hruofo7JrfpbCWtDfYF5xHAb17YU1Rh7jVt2UxCIezPU4BshaNrHuaRF+ # qesQOYdK9qRxOjGAE/UBmIipD2UcL3bcKujmvm2XXM8ZNEjR0RhLtKlXHaQj9u2y # Q1wAvQ7B5SEzlnWgQ/HJDhzbQCqMvRNvVS3/6DyMUVwf5NXuoR2dJ2jDJfYNFvSi # A0p0iVBqWNbDpC0Wwq9ij0g3sNndCL4sR8wrdIIslNe5tF70cax2NIe+oHkjzE9c # zohJJcRtu92gC+ixZNejOW4gpQv0d7jWLab8DMzin1VIsssdxdHdubctt+kdAg0u # 5t1/4DPjuGmUkMdWCu0A834ARZcX+ox6aPEPL5RfnH6WZJIyzKGtYDitiHAMVVuN # ey86Al9SrXzy+K+a2QOW1DZxbC2lN1X5F+7thvdgv+WRroeyjZ2GUys2LicT1Joj # QxnH92nFqgV+c9jE+JGDsKL7yg8sZfk2rKK+W+YMRGXz3Kjezpdwegb+E6NL+/Xe # K3Lno4Ru/jM+XMuXOn+gXR4tYrZQ8g== # SIG # End signature block |