Policy.Autorest/custom/Helpers.ps1
|
# ---------------------------------------------------------------------------------- # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # Code generated by Microsoft (R) AutoRest Code Generator.Changes may cause incorrect behavior and will be lost if the code # is regenerated. # ---------------------------------------------------------------------------------- using namespace System.Management.Automation.Language # split policy ids into usable parts function ParsePolicyId { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] # the resource Id of a policy definition param($resourceId, $policyType) # validate args if (!$resourceId) { throw 'ParsePolicyId(resourceId, policyType) argument error: resourceId must be provided.' } if (!$policyType) { # extract policyType $temp = $resourceId -split '/providers/Microsoft.Authorization/' if ($temp.Length -lt 2) { throw 'parsePolicy(resourceId, policyType) argument error: resourceId is not a Microsoft.Authorization resource type' } $policyType = ($temp[1] -split '/')[0] } if (!$policyType) { throw 'ParsePolicyId(resourceId, policyType) argument error: unable to find type name.' } $mark = "/providers/Microsoft.Authorization/$($policyType)/" $parts = $resourceId -split $mark $scope = $parts[0] $name = '' if ($parts.Length -gt 1) { $parts = $parts[1] -split '/' $name = $parts[0] if (($parts.Length -gt 2) -and ($parts[1] -eq 'versions')) { $parsedVersion = ParsePolicyVersion $parts[2] } } $scopeType = 'none' $subId = '' $mgName = '' $rgName = '' $resource = '' $resNamespace = '' $resType = '' $resName = '' if (!$scope) { $scopeType = 'builtin' } elseif ($scope -like '/providers/Microsoft.Management/managementGroups/*') { $scopeType = 'mgname' $mgName = ($scope -split '/providers/Microsoft.Management/managementGroups/')[1] } elseif ($scope -like '/subscriptions/*/resourceGroups/*/*') { $scopeType = 'resource' $temp = ($scope -split '/subscriptions/')[1] $temp = ($temp -split '/resourceGroups/') $subId = $temp[0] $temp = ($temp[1] -split '/providers/') $rgName = $temp[0] $temp = $temp[1] -split '/' if ($temp.Length -gt 2) { $resNamespace = $temp[0] $resType = $temp[1..($temp.Length-2)] -join '/' $resName = $temp[$temp.Length-1] } $resource = $scope } elseif ($scope -like '/subscriptions/*/resourceGroups/*') { $scopeType = 'rgname' $temp = ($scope -split '/subscriptions/')[1] $temp = ($temp -split '/resourceGroups/') $subId = $temp[0] $rgName = $temp[1] } elseif ($scope -like '/subscriptions/*') { $scopeType = 'subId' $subId = ($scope -split '/subscriptions/')[1] } $artifactRef = '' $artifact = $scope + $mark + $name if ($parsedVersion.VersionRef) { $artifactRef = "$artifact/versions/$($parsedVersion.VersionRef)" } return @{ PolicyType = $policyType Scope = $scope ScopeType = $scopeType SubscriptionId = $subId ManagementGroupName = $mgName ResourceGroupName = $rgName Resource = $resource ResourceNamespace = $resNamespace ResourceType = $resType ResourceName = $resName Name = $name Artifact = $artifact ArtifactRef = $artifactRef Version = $parsedVersion.Version Major = $parsedVersion.Major Minor = $parsedVersion.Minor Patch = $parsedVersion.Patch Suffix = $parsedVersion.Suffix VersionRef = $parsedVersion.VersionRef VersionMajorRef = $parsedVersion.VersionMajorRef VersionMinorRef = $parsedVersion.VersionMinorRef } } # parse policy version with format: (ddd|*).(ddd|*).(ddd|*)[-suffix] function ParsePolicyVersion { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] # the resource Id of a policy definition param($version) $parts = $version -split '\.' $major = $parts[0] $minor = '' if ($parts.Length -gt 1) { $minor = $parts[1] } $patch = '' $suffix = '' if ($parts.Length -gt 2) { $parts = $parts[2] -split '-' $patch = $parts[0] if ($parts.Length -gt 1) { $suffix = $parts[1] } } $versionMinorRef = '' $versionMajorRef = @($major,'*','*') -join '.' if ($minor -ne '*') { $versionMinorRef = @($major,$minor,'*') -join '.' } if ($suffix) { if ($versionMinorRef) { $versionMinorRef = $versionMinorRef + '-' + $suffix } $versionMajorRef = $versionMajorRef + '-' + $suffix } $versionRef = '' if ($versionMinorRef) { $versionRef = $versionMinorRef } else { $versionRef = $versionMajorRef } return @{ Version = $version Major = $major Minor = $minor Patch = $patch Suffix = $suffix VersionRef = $versionRef VersionMajorRef = $versionMajorRef VersionMinorRef = $versionMinorRef } } # split policy definition resourceId into its parts (used externally) function ParsePolicyDefinitionId { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] # the resource Id of a policy definition param($ResourceId) ParsePolicyId $ResourceId 'policyDefinitions' } # split policy set definition resourceId into its parts function ParsePolicySetDefinitionId { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] # the resource Id of a policy set definition param($ResourceId) ParsePolicyId $ResourceId 'policySetDefinitions' } # split policy assignment resourceId into its parts function ParsePolicyAssignmentId { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] # the resource Id of a policy set definition param($ResourceId) ParsePolicyId $ResourceId 'policyAssignments' } # split policy assignment resourceId into its parts function ParsePolicyExemptionId { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] # the resource Id of a policy set definition param($resourceId) ParsePolicyId $ResourceId 'policyExemptions' } # Wrapper for JSON -> PSObject conversion that works on both Core and Desktop editions function ConvertFrom-JsonSafe { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [Parameter(ValueFromPipeline)] $InputObject, [switch]$AsHashtable = $false ) if ($PSVersionTable.PSEdition -eq 'Core') { ConvertFrom-Json $InputObject -AsHashtable:$AsHashtable } elseif ($AsHashtable) { # ConvertFrom-Json on Windows Powershell doesn't support -AsHashtable parameter $converted = ConvertParameterInput ($InputObject | ConvertFrom-Json) if (($converted -is [array]) -and ($converted.Count -eq 1)) { return $converted[0] } else { return $converted } } else { ConvertFrom-Json $InputObject } } # convert the parameter object (could be either hashtable or PSCustomObject) to policy-formatted hashtable suitable for autorest serializers function ConvertParameterObject { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param ($InputObject) $returnValue = @{} if ($InputObject -is [hashtable]) { foreach ($key in $InputObject.Keys) { $returnValue[$key] = @{ value = (ConvertParameterInput -InputObject $InputObject[$key]) } } } else { foreach ($property in $InputObject.PSObject.Properties) { $returnValue[$property.Name] = @{ value = (ConvertParameterInput -InputObject $InputObject.PSObject.Properties[$property.Name]) } } } return $returnValue } # Convert input parameter value to hashtable type expected by the autorest serializers function ConvertParameterArray { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param ($InputObject) if ($InputObject -is [array]) { $collection = @( foreach ($object in $InputObject) { ConvertParameterArray $object } ) Write-Output -NoEnumerate $collection } elseif ($InputObject -is [hashtable]) { return $InputObject } elseif ($InputObject -is [PSObject]) { $hash = @{} foreach ($property in $InputObject.PSObject.Properties) { $hash[$property.Name] = (ConvertParameterArray $property.Value).PSObject.BaseObject } $hash } else { return $InputObject } } # convert various parameter input formats to policy-formatted hashtable suitable for autorest serializers function ConvertParameterInput { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param ($InputObject) # traverse collections to ensure nested values are all processed if ($InputObject -is [hashtable]) { $returnValue = @{} foreach ($key in $InputObject.Keys) { $returnValue[$key] = (ConvertParameterInput $InputObject[$key]) } return $returnValue } elseif ($InputObject -is [array]) { $returnValue = @() foreach ($object in $InputObject) { $returnValue += (ConvertParameterInput $object) } return ,$returnValue } elseif ($InputObject -is [PSObject]) { $returnValue = @{} foreach ($property in $InputObject.PSObject.Properties) { $returnValue[$property.Name] = (ConvertParameterInput $property.Value) } return $returnValue } else { return $InputObject } } # Convert output hashtable object output by autorest serializers to PSCustomObject format for legacy support function ConvertObjectToPSObject { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param($InputObject) if ($null -eq $InputObject) { return [PSCustomObject]$null } if ($InputObject -is [array]) { return ,@(foreach ($obj in $InputObject) { ConvertObjectToPSObject $obj }) } if (!$InputObject.ToJsonString) { return [PSCustomObject]$InputObject } $jsonString = $InputObject.ToJsonString() if ($jsonString -is [array]) { $jsonString = "[$([System.String]::Join(',', $jsonString))]" } ConvertFrom-JsonSafe $jsonString } # Recursive conversion function for common AST blocks from parsing function Convert-AstLiteral { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param([Ast] $Node) # ensure Node isn't null before checking type in switch if ($null -eq $Node) { return $null } switch ($Node) { # Numbers, $true/$false/$null { $_.GetType() -eq [ConstantExpressionAst] } { return $_.Value } # Strings like "text" or 'text' { $_.GetType() -eq [StringConstantExpressionAst] } { return $_.Value } { $_.GetType() -eq [ExpandableStringExpressionAst] } { return $_.Value } # This node type is essentially a wrapper node for an array { $_.GetType() -eq [ArrayExpressionAst] } { $arr = @() foreach ($e in $_.SubExpression.Statements) { $arr += Convert-AstLiteral $e } return $arr } # Arrays: @( ... ) { $_.GetType() -eq [ArrayLiteralAst] } { $arr = @() foreach ($e in $_.Elements) { $arr += Convert-AstLiteral $e } return $arr } # Nested hashtables { $_.GetType() -eq [HashtableAst] } { $h = @{} foreach ($kv in $_.KeyValuePairs) { $k = $kv.Item1.Value $h[$k] = Convert-AstLiteral $kv.Item2 } return $h } # Case where a literal is wrapped in a pipeline { $_.GetType() -eq [PipelineAst] } { if ($_.PipelineElements.Count -eq 1) { return Convert-AstLiteral $_.PipelineElements[0].Expression } else { throw "Pipeline contains multiple elements, expected a single literal expression when parsing PSCustomObject." } } # Handles variables such as $null, $true, $false { $_.GetType() -eq [VariableExpressionAst] } { if ($_.VariablePath.IsVariable) { return $_.VariablePath.UserPath } else { throw "Unsupported variable path for safe conversion: $($_.VariablePath.ToString()). Unable to parse PSCustomObject." } } # Handles the case where a literal gets tokenized as a MemberExpressionAst - returns the string representation of the token { $_.GetType() -eq [MemberExpressionAst] } { return $_.Extent.Text } default { # Anything else is not allowed throw "Unsupported AST node for safe conversion: $($_.GetType().Name). Value: $($_.ToString()). Unable to parse PSCustomObject." } } } # Safely converts a string representation of a hashtable or PSCustomObject into a hashtable function ConvertTo-HashtableSafely { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [Parameter(Mandatory)] [string] $InputObject ) # Adding quotes to unquoted strings, datetimes, etc. to avoid parsing errors $fixedInput = $InputObject -replace '(?m)(=\s*)([a-zA-Z_][\w\-\.:/]*|\d{1,2}:\d{2}:\d{2}|\d{4}-\d{2}-\d{2}(?:[T ]\d{2}:\d{2}:\d{2}Z?)?|\d{1,2}/\d{1,2}/\d{4}(?:\s+\d{1,2}:\d{2}:\d{2})?|\d{4}/\d{2}/\d{2}(?:\s+\d{1,2}:\d{2}:\d{2})?)(\s*[\r\n;}]|$)', '$1"$2"$3' $tokens = $null; $errors = $null $ast = [Parser]::ParseInput($fixedInput, [ref]$tokens, [ref]$errors) if ($errors -and $errors.Count -gt 0) { throw "Invalid PSCustomObject or hashtable literal: $($errors[0].Message)" } # Find the first expression in the script $expr = $ast.EndBlock.Statements | ForEach-Object { $_.PipelineElements | ForEach-Object { $_.Expression } } | Select-Object -First 1 if (-not ($expr -is [HashtableAst])) { throw "Top-level expression is not a hashtable. It is of type: $($expr.GetType())" } return Convert-AstLiteral $expr } function GetPSObjectProperty { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param ( [PSObject]$PropertyObject, [string]$PropertyPath ) $propertyNames = $PropertyPath.Split('.') $tmpObject = $PropertyObject foreach ($propertyName in $propertyNames) { $propertyInfo = $tmpObject.PSObject.Properties[$propertyName] if ($propertyInfo) { if ($propertyInfo.Value -is [PSObject]) { $tmpObject = [PSObject]$propertyInfo.Value continue } return $propertyInfo.Value } } return $tmpObject } # tests whether the given string is a Uri function Test-Uri { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param([string]$Value) $uri = '' [System.Uri]::TryCreate($Value, [System.UriKind]::Absolute, [ref]$uri) } # issues a GET to the given address and returns the contents function Get-UriContent { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param([string]$UriAddress) $response = Invoke-WebRequest $UriAddress -DisableKeepAlive -Method Get if ($response.StatusCode -eq 200) { return $response.Content } } # if the given string is a file path or URI, returns the contents of the file or web page # otherwise returns the original string function GetFileUriOrStringParameterValue { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param([string]$parameterValue) # Test-Path can throw on bad input, but we just want to move to the next check if it does try { if (Test-Path $parameterValue) { return Get-Content $parameterValue | Out-String } } catch { # if error, want to handle exactly same as path not being valid by continuing } if (Test-Uri $parameterValue) { return Get-UriContent $parameterValue } else { return $parameterValue } } function ResolvePolicyParameter { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [string]$ParameterName, [string]$ParameterValue, [bool]$Debug = $false ) $policy = GetFileUriOrStringParameterValue $ParameterValue if ($debug) { Write-Host -ForegroundColor Cyan "Parameter ${ParameterName}:" $policy } $policyParameter = ConvertFrom-JsonSafe -AsHashtable $policy if ($policyParameter.properties) { return $policyParameter.properties } else { return $policyParameter } } function ResolvePolicyMetadataParameter { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( $MetadataValue, [bool]$Debug = $false ) if ($MetadataValue -is [hashtable]) { return $MetadataValue } if ([System.String]::IsNullOrEmpty($MetadataValue)) { return $MetadataValue } # This function will usually be passed a string, but can have an issue if passed a PSCustomObject that isn't converted to string if ($MetadataValue -isnot [string]) { $MetadataValue = $MetadataValue | ConvertTo-Json -Depth 30 } $metadata = (GetFileUriOrStringParameterValue $MetadataValue).Trim() if ($debug) { Write-Host -ForegroundColor Cyan Metadata: $metadata } if ($metadata -like '@{*') { # probably a PSCustomObject, try converting to hashtable return ConvertTo-HashtableSafely $metadata } # otherwise it should be a JSON string if ($metadata -like '{*}') { return $metadata | ConvertFrom-JsonSafe -AsHashtable } throw "Unrecognized metadata format - value: [$($metadataValue)], type: [$($metadataValue.GetType())]" } # construct the full Id of a resource given the various parts (only used internally in this file) function resolvePolicyArtifact { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [string]$name, [string]$subscriptionId, [string]$managementGroupName, [string]$id, [string]$policyType ) $scope = '' $scopeType = 'none' $scopeName = '' $resourceId = '<invalid>' if ($id -and !$subscriptionId -and !$managementGroupName) { $resolved = ParsePolicyId $id $policyType $scope = $resolved.Scope $scopeType = $resolved.ScopeType switch ($scopeType) { 'subId' { $subscriptionId = $resolved.SubscriptionId $scopeName = "subscription $($subscriptionId)" } 'mgName' { $managementGroupName = $resolved.ManagementGroupName $scopeName = "management group $($managementGroupName)" } 'rgname' { $subscriptionId = $resolved.SubscriptionId $scopeName = "resource group $($resolved.ResourceGroupName) (subId: $($subscriptionId))" } 'resource' { $subscriptionId = $resolved.SubscriptionId $scopeName = "resource id $($resolved.Resource)" } 'none' { $scopeName = "scope $($scope)" } } $name = $resolved.Name $resourceId = $id } else { if ($name) { if ($managementGroupName) { $scopeType = 'mgName' $scopeName = "management group $($managementGroupName)" $scope = "/providers/Microsoft.Management/managementGroups/$($managementGroupName)" } else { if (!$subscriptionId) { $subscriptionId = (Get-SubscriptionId) } $scopeType = 'subId' $scopeName = "subscription $($subscriptionId)" $scope = "/subscriptions/$($subscriptionId)" } $resourceId = "$($scope)/providers/Microsoft.Authorization/$($policyType)/$($name)" } } return @{ Scope = $scope ScopeType = $scopeType ScopeName = $scopeName Name = $name SubscriptionId = $subscriptionId ManagementGroupName = $managementGroupName ResourceId = $resourceId ResourceGroupName = $resolved.ResourceGroupName ResourceNamespace = $resolved.ResourceNamespace ResourceType = $resolved.ResourceType ResourceName = $resolved.ResourceName Artifact = $resolved.Artifact Version = $resolved.Version } } function ResolvePolicyDefinition { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [string]$Name, [string]$SubscriptionId, [string]$ManagementGroupName, [string]$Id ) resolvePolicyArtifact $Name $SubscriptionId $ManagementGroupName $Id 'policyDefinitions' } function ResolvePolicySetDefinition { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [string]$Name, [string]$SubscriptionId, [string]$ManagementGroupName, [string]$Id ) resolvePolicyArtifact $Name $SubscriptionId $ManagementGroupName $Id 'policySetDefinitions' } function ResolvePolicyAssignment { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [string]$Name, [string]$Scope, [string]$Id ) if ($Id) { $resourceId = $Id } elseif ($Scope) { $resourceId = "$($Scope)/providers/Microsoft.Authorization/policyAssignments/$($Name)" } else { $resourceId = "/subscriptions/$($(Get-SubscriptionId))/providers/Microsoft.Authorization/policyAssignments/$($Name)" } resolvePolicyArtifact $null $null $null $resourceId 'policyAssignments' } function ResolvePolicyExemption { [Microsoft.Azure.PowerShell.Cmdlets.Policy.DoNotExportAttribute()] param( [string]$Name, [string]$Scope, [string]$Id ) if ($Id) { $resourceId = $Id } elseif ($Scope) { $resourceId = "$($Scope)/providers/Microsoft.Authorization/policyExemptions/$($Name)" } else { $resourceId = "/subscriptions/$($(Get-SubscriptionId))/providers/Microsoft.Authorization/policyExemptions/$($Name)" } resolvePolicyArtifact $null $null $null $resourceId 'policyExemptions' } function LocationCompleter( $commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameter ) { if ($global:AzPSPolicyCachedLocations.Count -le 0) { $response = Invoke-AzRestMethod -Uri "https://management.azure.com/subscriptions/$($(Get-SubscriptionId))/locations?api-version=2022-12-01" -Method GET $global:AzPSPolicyCachedLocations = ($response.Content | ConvertFrom-JsonSafe).value | Sort-Object -Property name | Select-Object -ExpandProperty name } # If you see the following error, it means your context access has expired # The given key 'AzureAttestationServiceEndpointSuffix' was not present in the dictionary. $global:AzPSPolicyCachedLocations | Where-Object { $_ -like "$wordToComplete*" } } function Get-SubscriptionId { $script = Resolve-Path "$PSScriptRoot/../utils/Get-SubscriptionIdTestSafe.ps1" return . $script } function Get-ExtraParameters ( $DefaultProfile, $Break, $HttpPipelineAppend, $HttpPipelinePrepend, $Proxy, $ProxyCredential, $ProxyUseDefaultCredentials ) { $parms = @{} if ($PSBoundParameters['DefaultProfile']) { $parms['DefaultProfile'] = $PSBoundParameters['DefaultProfile'] } if ($PSBoundParameters['Break']) { $parms['Break'] = $PSBoundParameters['Break'] } if ($PSBoundParameters['HttpPipelineAppend']) { $parms['HttpPipelineAppend'] = $PSBoundParameters['HttpPipelineAppend'] } if ($PSBoundParameters['HttpPipelinePrepend']) { $parms['HttpPipelinePrepend'] = $PSBoundParameters['HttpPipelinePrepend'] } if ($PSBoundParameters['Proxy']) { $parms['Proxy'] = $PSBoundParameters['Proxy'] } if ($PSBoundParameters['ProxyCredential']) { $parms['ProxyCredential'] = $PSBoundParameters['ProxyCredential'] } if ($PSBoundParameters['ProxyUseDefaultCredentials']) { $parms['ProxyUseDefaultCredentials'] = $PSBoundParameters['ProxyUseDefaultCredentials'] } return $parms } # register the location completer for New-AzPolicyAssignment Register-ArgumentCompleter -CommandName New-AzPolicyAssignment -ParameterName Location -ScriptBlock ${function:LocationCompleter} # cache Azure locations to be used by the location completer (Get-AzLocation is not available in this context, need to use REST) $global:AzPSPolicyCachedLocations = @() # SIG # Begin signature block # MIInbQYJKoZIhvcNAQcCoIInXjCCJ1oCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCB97cRrvC0xIYWR # KS2GaOXaXAEjWZeDD28ZRO/nU9zM9KCCDMkwggYEMIID7KADAgECAhMzAAACHPrN # xZvoL37EAAAAAAIcMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQxWhcNMjcwNDE1MTg1 # OTQxWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDVsZfgOKmM31HPfoWOoNEiw0SlCiIxUMC0I9NMWbucKOw/e9lP # oAoehQVu6SG65V4EPzrYsnBnFPNoi4/HoOdjhz1qkrEt4I6tEcxXU6oOeY9zGveC # /3iBeuhLYxM3M/PkcUoebF+Nednm8OkdSPoDu8imViHPQq/8CQUu0WRR4rE+dMRf # rpVqfmNi2qWCX94T4MsepijGVkwE//tJg0ryAiYdHT34LSnlG/RSBZmQRGWZ5g8j # qnKjRParSqMft1gvjuUTVgtWNZfgcLFSK5Wa0myrq8OPcgTGGsRgun+tnSS+IxDT # xVsAPH1OzvPjwomguByhUe/OcvUN0D5Wmp7xAgMBAAGjggGqMIIBpjAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFNoH7a2YDjOSwpkp6DHcmUS7J+0yMFQGA1UdEQRNMEukSTBHMS0wKwYDVQQL # EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxFjAUBgNVBAUT # DTIzMDAxMis1MDc1NjkwHwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEw # YAYDVR0fBFkwVzBVoFOgUYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w # cy9jcmwvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # bDBtBggrBgEFBQcBAQRhMF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmcl # MjBQQ0ElMjAyMDI0LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4IC # AQAUnEqhaRXe0T3hIJjvdQErEkrA/7bByjn6t5IArODkkRjzkYwtKMc2yYj2quaN # rLutWw2YZcngKPy1b71YyDJQTy4NDRwaSh9Tw5thrk3NmcPrAHia5vtcBJ1CgtKK # 7mQbIcQ22d/N3813ayCDDFewu1+jsZmX+r/aTEqaOM4TVxVtRSkuCy8nAXKuChOK # Li/zA4XuH8iEYqIsj2YoNaeSxVmeGiERXpKdo3dDmYi0kO5w2D8VS4c3+9h6gElY # BaAAg/dYErBg27qT3vv0zRDJhJufvCNylA8S7/+8H5E/PV5cng6na9VV/w9OV3qu # uND6zdGa2EX38Glp50F9AIQk3p2xXmcvorDeM4XJ7UlWYBi6g80J1SSOQnInCYFE # msfUNn3+1AaTJKSJL83quKArTac2pKhu0Yzzzrzo6HrsRiQKzpnRBb1/dMa6P3hz # 75XbMRBctNsFhZC07WCmjExdLg2eHW5uV0TY8D5+6wozJf7vF3+WHkYPO85Z+BC6 # U4FkNbYNycZ9cE4j1tXRdyDCfml6c0HWPHjNVDObrv9lKt3qUqFpX38VCqVCyNOO # 1UcXfQiVjJw32U2WUKZjt/neJKHEBsm9kFsLuWzkQ53+qcaSaytmsCnk2gOglrlD # 5d3kKyvvAw+rzm0lT8K38P6PLxfZQHhu4W8dV7Av8N2ZmDCCBr0wggSloAMCAQIC # EzMAAAA5O7Y3Gb8GHWcAAAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBS # b290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoX # DTM2MDMyMjIyMTMwNFowVzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQ # Q0EgMjAyNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeq # lRYHNa265v4IY9fH8TKhemHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo # 0dtS/EW6I/yEL/bLSY8hKpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATv # QVL4tcf03aTycsz8QeCdM0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a # 1uv1zerOYMnsneRRwCbpyW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1 # FyQfK0fVkaya8SmVHQ/tOf23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfO # GSWHIIV4YrTJTT6PNty5REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7 # ttOu1bVnXfHaqPYl2rPs20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJ # uz2MXMCt7iw7lFPG9LXKGjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxS # CwyoGIq0PhaA7Y+VPct5pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOm # VQop36wUVUYklUy++vDWeEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3 # SkE/xIkgpfl22MM1itkZ35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8E # BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPX # LQaUEggxMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMB # Af8wHwYDVR0jBBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBP # oE2gS4ZJaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAw # TgYIKwYBBQUHMAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMv # TWljUm9vQ2VyQXV0MjAxMV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOC # AgEAFJQfOChP7onn6fLIMKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D # 5W4wMwYeLystcEqfkjz4NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBY # nbu0+THSuVHTe0VTTPVhily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSI # vgn0JksVBVMYVI5QFu/qhnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6 # aR9y34aiM1qmxaxBi6OUnyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4w # PKC5OmHm1DQIt/MNokbbH3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7 # RTX8AdBPo0I6OEojf39zuFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK # /fg8B2qjW88MT/WF5V5uvZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSK # YBv0VisCzfxgeU+dquXW9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkw # YTu/9dLeH2pDqeJZAABVDWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVT # Ql0v4q8J/AUmQN5W4n101cY2L4A7GTQG1h32HHAvfQESWP0xghn6MIIZ9gIBATBu # MFcxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # KDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIc # +s3Fm+gvfsQAAAAAAhwwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwG # CisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZI # hvcNAQkEMSIEIEhpObXBLjQ7QUagQMJxLzSLz++xWqZ1eAdIPlEbxeBsMEIGCisG # AQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEBBQAEggEATIqtiWQDaapKnHAMP96W # 2i2YlTc7hTFHwetXZX52D52U7LdDh4o7ywfYi48/mocF5iH14xDoXL3yz6AUxPUq # hhV7/fTgN7FY0LoghEs3cvMw9hYwEvpBO29ry1lnfl6AfOuG9zT0l7cTo5ijo1FO # S1dCkiHjmT9qPNt6gVTZ8PL9yAyzYf93pLwBHLAHGg9BFSg6nsn22+4Yed/tZcvk # fKe7HvpFHc2UAEaaVxx+zSBstDZznuH25Ipxp2XEiiLWWHxRAgysAlF/44QfHftG # lDBuWXhsnx1EfwKLUmK8+BptpFwwI9NmuHHub8LYiVvY22KSTo9GkjF5K9H4eJ5s # pKGCF6wwgheoBgorBgEEAYI3AwMBMYIXmDCCF5QGCSqGSIb3DQEHAqCCF4UwgheB # AgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFZBgsqhkiG9w0BCRABBKCCAUgEggFEMIIB # QAIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFlAwQCAQUABCCmwyCTm7SzYkIZdDH6 # VFBfopC00rwKydAA36gx5a1myAIGahGSvnqOGBIyMDI2MDUyNzEwMjI1OC4wMVow # BIACAfSggdmkgdYwgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRl # ZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYD # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloIIR+zCCBygwggUQoAMC # AQICEzMAAAIVGAPTgQcmfFMAAQAAAhUwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMjUwODE0MTg0ODIwWhcNMjYxMTEzMTg0 # ODIwWjCB0zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsG # A1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMScwJQYD # VQQLEx5uU2hpZWxkIFRTUyBFU046NjUxQS0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1p # Y3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIiMA0GCSqGSIb3DQEBAQUAA4IC # DwAwggIKAoICAQDDcdXeFXEvSURg9XTdd40pnnXtUhuB7GGUM92lfANLQFi3E/CL # hdillHWV3S7pyvZeO66B2DnQNTHlYcvRCFjZ32+QlKTTasT/vmFwq33WbYiHbztB # HFEyYW7cEXrjrqTyqnm5e197q5yKrj1hpLyn53O/e5NqsPiFDxRPstr3mk4mJGrH # F3So4YsQK8csRc9eKg1LH2nKHOGbqW3t7MvEl4VVi3FKGRq8+hk3R04KJh6HgqCg # qjJqDMy5KIsKIxRbhR7hCybrnwUk0ZM2HtXmpdhUDqTnGPDlZ5Z0o7PSL0DmMFxt # j19U6j9wDyLVvK3NwNPFvedy1yXLz85h42y2Rpv8iyrcLF7W+r3p8gcTX5kaYmOR # rWyh3Co/JxWn/a1v4GO6U8vkPquBRdM8XzhTzZEsodXntsHx8dGmCeNxYFC5c+BV # 5JekRFaKa3Q0XaUI4vOqCu9L+9ip17kuf1iUoqEBn/EMTRMsgivr4j/YlO1c/fid # +NMQ1WowEhJZxqQjEDAZvdEHnIcLHKcgU1Utx8oCwR0LlTZ6bR8C+ZW/Syieqe/X # ty5piLZ4ItaGgrUhzzkPDuz+WFxesGljif9GXmXfAfOzi84iG7zsMjLlBRoS6kSz # JjQ1aqAjgFaXq/XCCx76XwNYV5Reh+FS4KBVO5Mc3cryJ2gxufxDd51QgQIDAQAB # o4IBSTCCAUUwHQYDVR0OBBYEFIkhd/FyoDAWoaP2N3BC11Kpp2PXMB8GA1UdIwQY # MBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1UdHwRYMFYwVKBSoFCGTmh0dHA6 # Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFRpbWUt # U3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggrBgEFBQcBAQRgMF4wXAYIKwYB # BQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj # cm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIwMTAoMSkuY3J0MAwGA1UdEwEB # /wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeAMA0G # CSqGSIb3DQEBCwUAA4ICAQB3jYe1X6QZu/HMsFMLk7u+QIgE/L8HCmMLN4vneECI # Q55un5V02fCb0ZUJ9ircox+uPhS8pBNQBpLlmTB7WC9neWNJKcI7JLk7A2712mDf # DD5BbZ45xIuTJUBYWsufoiKDdML/NYy9WGpe10WEbYonWVJs3bbZyxjcTf8GsaW4 # CW8RP2CbFXLLE3Ln3/skXnMgZwmJvJ3Gz3gkvUG0+Bck59nND7/eJNzp4O2ZpZPo # Mp2cmhynzCRcpY8iwER+QPqTVCK3C+3SYes5FqHvlKN5w4q3ihZrJUuQ9OGjXZ7S # ieASDVyN7l/FJka2GsytYq8jhHscQLuTyZof148DdWIfQJVJI559o9MYzMiEcKjm # neMblIxzI7d4D24RphAkhMmUsbcHDAabKljsL/z+ePVI6GDHUeAnTLA4kv3F8/gA # 5xaYJ9uyqAZsJoLtYfmwg13N8xqvxXtg0WqRsIZQqFzwakjIT4wqfJWffeOy5oYC # U1GDt1VFRKhgsnG9SzD0Y7DIGkHBsT2yo4ub4ew7TSgXbc8yKjtYVdwVNkCOne6O # KEEB8utcgKAY4c92RnTja7Utmo5yeWvdfO+Ax76Y8/Jqxbx/Su3MmPdXkT8QqLJC # U/GP0x+rbH2GKaeVdYZkJU94QFE6s1sNgF9rNPIs0I5OxG2Sw5JXcUG0+elC0s3v # njCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkAAAAAABUwDQYJKoZIhvcNAQEL # BQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV # BAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4X # DTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVowfDELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3Rh # bXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDk4aZM # 57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX9gF/bErg4r25PhdgM/9cT8dm # 95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1qUoNEt6aORmsHFPPFdvWGUNzB # RMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8dq6z2Nr41JmTamDu6GnszrYBb # fowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byNpOORj7I5LFGc6XBpDco2LXCO # Mcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2krnopN6zL64NF50ZuyjLVwIYw # XE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4dPf0gz3N9QZpGdc3EXzTdEonW # /aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgSUei/BQOj0XOmTTd0lBw0gg/w # EPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8QmguEOqEUUbi0b1qGFphAXPK # Z6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6CmgyFdXzB0kZSU2LlQ+QuJYfM2 # BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzFER1y7435UsSFF5PAPBXbGjfH # CBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQIDAQABo4IB3TCCAdkwEgYJKwYB # BAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQUKqdS/mTEmr6CkTxGNSnPEP8v # BO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMFwGA1UdIARVMFMwUQYM # KwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggrBgEF # BQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBW # BgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUH # AQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # L2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNydDANBgkqhkiG9w0BAQsF # AAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwUtj5OR2R4sQaTlz0xM7U518Jx # Nj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN3Zi6th542DYunKmCVgADsAW+ # iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU5HhTdSRXud2f8449xvNo32X2 # pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5KYnDvBewVIVCs/wMnosZiefw # C2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGyqVvfSaN0DLzskYDSPeZKPmY7 # T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB62FD+CljdQDzHVG2dY3RILLFO # Ry3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltEAY5aGZFrDZ+kKNxnGSgkujhL # mm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFpAUR+fKFhbHP+CrvsQWY9af3L # wUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcdFYmNcP7ntdAoGokLjzbaukz5 # m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRbatGePu1+oDEzfbzL6Xu/OHBE # 0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQdVTNYs6FwZvKhggNWMIICPgIB # ATCCAQGhgdmkgdYwgdMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRl # ZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjY1MUEtMDVFMC1EOTQ3MSUwIwYD # VQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEwBwYFKw4DAhoD # FQCPp5N6Nu5gTUh+Nt+u3q1d68JRIKCBgzCBgKR+MHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA7cCuLTAiGA8yMDI2MDUyNjIz # NDEzM1oYDzIwMjYwNTI3MjM0MTMzWjB0MDoGCisGAQQBhFkKBAExLDAqMAoCBQDt # wK4tAgEAMAcCAQACAhHhMAcCAQACAhPLMAoCBQDtwf+tAgEAMDYGCisGAQQBhFkK # BAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEAAgMBhqAwDQYJ # KoZIhvcNAQELBQADggEBAHJNg2pE5M7bE5HUqa0uDttGdSaEW5PR3IUWlu4rH8qi # jmfBliXzJaN9b/9chhlWQaGcHXLZ0NHjrJfwgMjk8kT33EU1l+NYtKhDDXOAcV+q # 96UeEqcP1DIfLkgwLON4fwqHeD+8ZQSzRoO/hHQEcAB/RKsBHyX0IxeFEGdWjDtW # d8ukzDaaxZxT6FbqAcT707w4auaGo4i5qN55V9SJeTZt57+i8cx4fkAy/gfn3opH # QvteVMNLIwbzTGTpV3fJXgXJHAQbMziaM//daeuCX+1aK4eHE2JXbv1/koB0SiJ6 # UZOuxvqEmO02F4eP5loB1Ipn2rhNKwP5vQFq69Y/ZY0xggQNMIIECQIBATCBkzB8 # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N # aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAhUYA9OBByZ8UwABAAAC # FTANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE # MC8GCSqGSIb3DQEJBDEiBCCemhxSAjhoMxVX7vRuGKQw3ZTgyVe+7A+Wg+f7f/Uy # 5zCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIHAQ9HY8OtMUtyu1CwqtSLuj # Pkk1EIX8pEcyKFI17uyKMIGYMIGApH4wfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTACEzMAAAIVGAPTgQcmfFMAAQAAAhUwIgQgOfYeb5O3tPtUQ44cIl2KGDkq # oaJM0rUpYbD+QhDXfr4wDQYJKoZIhvcNAQELBQAEggIAQkDvYY9UiZOoRCoz8Rzm # VpKPdt9dwC7Jy5eDNSNKB5MJjBhTNnG0XTkBvezMoTb5J/aBVVBHF5Odn/yyXiMt # rmOHUkmXAMojWLSo8FODy3TzJUQRM5fUdpbEvQOf87jQQQvMiaah91YPjuZ2QVT2 # LqWBNcfIwRjUjG6E9CPTb5fz8XYPzZ8pJksqnyw1Ft/j+zfsfB4Majv6gFx5yn9l # Syr+VFIiWKPRxIL8n9Wh1Nyl/bMR3RBZKwJryNjtC+ktK2h5nGDTAb40evkGYNED # cfr0prQCsEjEAVyrfCsZNVN7mTbTVzMNBf7wzPPOZDNkGkjAECP1fJ28fgK4BQ2D # yua5VjvQerpHm7SKFjEFmJ+lP3zu18DxsJCdkDLlgWTd1UTAmLQT5qvvzsPecADZ # 7lO+PJ/EvT/6qQaggJL4P/xWH/YcoP8JKV29g2rI5VRKb+CLVq2/DbmsIXPJAanB # Exx7V3a2HORpQ5f94fWnoH42tSBCsspXmLqJQxXkfVCbY9esM3sCFLaPTXqx/7xO # A7Dm6vbgPIrN/EhfXQQEHI7odQpf1k27HBv8vynwRPD9belNnUidU0Ed65EIGWpI # qQlXxX3soonVM7ag9QPpv91c9kgHeQKF5GyCKAjEMHQvdpKMhID9hHhyK0Yb1UpQ # wgp8kO9HPCMAhKC/nV3igos= # SIG # End signature block |