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 } } 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 # MIInRgYJKoZIhvcNAQcCoIInNzCCJzMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDuBrUG34Hsva/t # 9F2L9HH8yMJddXTMkz5SQIBcLCkuXaCCDLowggX1MIID3aADAgECAhMzAAACHU0Z # yE7XD1dIAAAAAAIdMA0GCSqGSIb3DQEBCwUAMFcxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBD # b2RlIFNpZ25pbmcgUENBIDIwMjQwHhcNMjYwNDE2MTg1OTQzWhcNMjcwNDE1MTg1 # OTQzWjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYD # VQQDExVNaWNyb3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IB # DwAwggEKAoIBAQDQvewXxx9gZZFC6Ys1WBay8BJ8kGA4JQnH5CMafqOASlTpK9H8 # o5ZXTXt0caVQTNMUPt445wXYD+dFtaKWTwDn1I52oUSrC9vJin1Gsqt+zyKJL5Dg # 3eQXbQNR61DmMy20GLTIO3SFed9Rfi/ophgCLGFLDR3r0KvHjwMb/jYWS0celV/4 # Lz27LfAekm8v9E5IXaeiXbAUYZKK090n4CVl3JBtbN+9DtI9SNu/yjvozW52/u7R # X/Ttpa/KDlpuokZ+Zcbvmtd9ur9gFLvZzh41o9MsE/clQtdaFWGvuo6Jua/ntpgk # ey3E5/vBFe+MJPG6phdnuo6r57ZudCudiI1bAgMBAAGjggGbMIIBlzAOBgNVHQ8B # Af8EBAMCB4AwHwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0O # BBYEFH6QuMwqcPG0hQlQ6c5jCtTTLrVeMEUGA1UdEQQ+MDykOjA4MR4wHAYDVQQL # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xFjAUBgNVBAUTDTIzMDAxMis1MDc1NTkw # HwYDVR0jBBgwFoAUf1k/VCHarU/vBeXmo9ctBpQSCDEwYAYDVR0fBFkwVzBVoFOg # UYZPaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0 # JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNybDBtBggrBgEFBQcBAQRh # MF8wXQYIKwYBBQUHMAKGUWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # Y2VydHMvTWljcm9zb2Z0JTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDI0LmNy # dDAMBgNVHRMBAf8EAjAAMA0GCSqGSIb3DQEBCwUAA4ICAQBKTbYOjzwTG/DXGaz9 # s6+fQeaTtDcFmMY+5UyVFCyj7Pv+5i37qfX8lSL/tBIfYQfWsMuBQlfZurJD6r4H # VJ2CeH+1fgiq8dcHdVKoZ3Sa2qXoX3cq9iS8cVb06B7+5/XJ7I0OxHH9fDsvJ3T3 # w5V/ZtAIFmLrl+P0CtG+92uzRsn0nTbdFjOkLMLWPLAU3THohKRlSEMgFJpPkm5n # 5UAZ35xX6FWCrDLsSKb555bTifwa8mJBwdlof0bmfYidH+dxZ1FdDxvLnNl9zeKs # A4kejaaIqqIPguhwAti5Ql7BlTNoJNwxCvBmqW2MQLnCkYN/VVUsR3V2x/rcTNzo # Bf/Z/SpROvdaA2ZOOd1uioXJt3tdLQ7vHpqpib0KfWr/FWXW10q38VxfCnRQBqzb # SuztR7nEMuzX7Ck+B/XaPDXd1qh72+QYyB0Z2VzWmO9zsnb9Uq/dwu8LGeQqnyu6 # 7SDGACvnXii2fb9+US492VTnXSnFKyqwgzUyFMtZK1/sHYTv6bG4TtQUygQxTN+Z # V+aJIlKO2MqZ7bKrAnOzS9m6NgoTdWOq11bTOZwKlIEV/EhV9SWkDmdpR/hPPT2v # 6TEj4F8PT/zHjRezIU5c/DGlt/VhY/pK0XkJtEyMmmS1BMtjU/rqBZVMIm3dnxQs # /TBByr+Cf8Z1r7aifQVQ+WSqzjCCBr0wggSloAMCAQICEzMAAAA5O7Y3Gb8GHWcA # AAAAADkwDQYJKoZIhvcNAQEMBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRl # IEF1dGhvcml0eSAyMDExMB4XDTI0MDgwODIwNTQxOFoXDTM2MDMyMjIyMTMwNFow # VzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEo # MCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAyNDCCAiIwDQYJ # KoZIhvcNAQEBBQADggIPADCCAgoCggIBANgBnB7jOMeqlRYHNa265v4IY9fH8TKh # emHfPINe1gpLaV3dhg324WwH06LcHbpnsBukCDNitryo0dtS/EW6I/yEL/bLSY8h # KpbfQuWusBPr9qazYcDxCW/qnjb5JsI1s8bNOg3bVATvQVL4tcf03aTycsz8QeCd # M0l/yHRObJ9QqazM1r6VPEOJ7LL+uEEb73w6QCuhs89a1uv1zerOYMnsneRRwCbp # yW11IcggU0cRKDDq1pjVJzIbIF6+oiXXbReOsgeI8zu1FyQfK0fVkaya8SmVHQ/t # Of23mZ4W9k0Ri22QW9p3UgSC5OUDktKxxcCmGL6tXLfOGSWHIIV4YrTJTT6PNty5 # REojHJuZHArkF9VnHTERWoTjAzfI3kP+5b4alUdhgAZ7ttOu1bVnXfHaqPYl2rPs # 20ji03LOVWsh/radgE17es5hL+t6lV0eVHrVhsssROWJuz2MXMCt7iw7lFPG9LXK # Gjsmonn2gotGdHIuEg5JnJMJVmixd5LRlkmgYRZKzhxSCwyoGIq0PhaA7Y+VPct5 # pCHkijcIIDm0nlkK+0KyepolcqGm0T/GYQRMhHJlGOOmVQop36wUVUYklUy++vDW # eEgEo4s7hxN6mIbf2MSIQ/iIfMZgJxC69oukMUXCrOC3SkE/xIkgpfl22MM1itkZ # 35nNXkMolU1lAgMBAAGjggFOMIIBSjAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGC # NxUBBAMCAQAwHQYDVR0OBBYEFH9ZP1Qh2q1P7wXl5qPXLQaUEggxMBkGCSsGAQQB # gjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # ci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAwTgYIKwYBBQUHMAKGQmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2VyQXV0MjAx # MV8yMDExXzAzXzIyLmNydDANBgkqhkiG9w0BAQwFAAOCAgEAFJQfOChP7onn6fLI # MKrSlN1WYKwDFgAddymOUO3FrM8d7B/W/iQ6DxXsDn7D5W4wMwYeLystcEqfkjz4 # NURRgazyMu5yRzQh4LqjA4tStTcJh1opExo7nn5PuPBYnbu0+THSuVHTe0VTTPVh # ily/piFrDo3axQ9P4C+Ol5yet+2gTfekICS5xS+cYfSIvgn0JksVBVMYVI5QFu/q # hnLhsEFEUzG8fvv0hjgkO+lkpV9ty6GkN4vdnd7ya6Q6aR9y34aiM1qmxaxBi6OU # nyNl6fkuun/diTFnYDLTppOkr/mg5WSfCiDVMNCxtj4wPKC5OmHm1DQIt/MNokbb # H3UGsFP1QbzsLocuSqLCvH09Io3fDPTmscR9Y75G4qX7RTX8AdBPo0I6OEojf39z # uFZt0qOHm65YWQE69cZM2ueE1MB05dNNgHK9gTE7zKvK/fg8B2qjW88MT/WF5V5u # vZGtqa9FSL2RazArA+rDPuf6JGYz4HpgMZHB4S6szWSKYBv0VisCzfxgeU+dquXW # 9bd0auYlOB58DPcOYKdc3Se94g+xL4pcEhbB54JOgAkwYTu/9dLeH2pDqeJZAABV # DWRQCaXfO5LgyKwKCLYXpigrZYCjUSBcr+Ve8PFWMhVTQl0v4q8J/AUmQN5W4n10 # 1cY2L4A7GTQG1h32HHAvfQESWP0xghniMIIZ3gIBATBuMFcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jv # c29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMjQCEzMAAAIdTRnITtcPV0gAAAAAAh0w # DQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYK # KwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIDH2Qqzr # 7UxNCLvVaLL3NWJ2EqjlFug3aBhhocWDyb/SMEIGCisGAQQBgjcCAQwxNDAyoBSA # EgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20w # DQYJKoZIhvcNAQEBBQAEggEAx4Bayw9zs9A7d08kVrQynHgqStd8hb3sbTlRshdZ # gmPItDJRw3uD6dky+318yFKyTUuNiZ3585KJ3CQp10g9wlvl1TrrtSV13k2uCZf4 # 71n9TisEdPImf0mQ2nO0KCW/eKTJFIJ0MLG3S8eLZO1RCclrt1rl8LyxDiXDPSz4 # KNspalJ3QlSWI5HpPe81qf7nKLG4VihjvUw0oeM5wDuFPpP54gXgDYJzpXJctloy # 8h67e3JL9w1dlHQWpnsbiY+ELvzjleVpP1n79Njnlo/VBnZlZWVM1/m+Wwzh3k+M # tIoNDVYB0oBOq7gqW5+FV/KJ5r12kUpbL9gx6Oo4ddLYoaGCF5QwgheQBgorBgEE # AYI3AwMBMYIXgDCCF3wGCSqGSIb3DQEHAqCCF20wghdpAgEDMQ8wDQYJYIZIAWUD # BAIBBQAwggFSBgsqhkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGEWQoD # ATAxMA0GCWCGSAFlAwQCAQUABCCuR7HL24JsoJppqf0J6UeM/rXKT6punh0Y3Osp # QDK/ZgIGaegML70PGBMyMDI2MDQyOTEwMjE0Mi4xNTlaMASAAgH0oIHRpIHOMIHL # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxN # aWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRT # UyBFU046MzMwMy0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFNlcnZpY2WgghHqMIIHIDCCBQigAwIBAgITMwAAAiEzwDX70g8hpAABAAAC # ITANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGlu # Z3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAe # Fw0yNjAyMTkxOTM5NTRaFw0yNzA1MTcxOTM5NTRaMIHLMQswCQYDVQQGEwJVUzET # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV # TWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmlj # YSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046MzMwMy0wNUUw # LUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggIi # MA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDbcTACqU1YvRocyWL2PL9fyf/+ # ULs2qK7U1aZsRnDZSnlCr7K7jgA3eFCEJL5BZ7dUTC0DeZepf+ZC+7HEbB4IdzmJ # fQAUDFFerqY5VTHmQvP2XA3lWSFj740idcGUHglP5H/PbCJU7GAHWP2HdcCjdx1l # YAo0A+zLI7xwnTQeMyOXX212Eg4UmDPPJgxdTMw6WFVWsBPWRBi5gDixy2s+7R8A # Dk5lbBBFDB5h0CjrNWIN7uCAzF5g7trrL8nXIKp10mj9RxhcGQ+tlht6VIvdygRV # TUGdzFB2/nBvJqQ9kxxFltQST70fEdx4TyaKow/f5+BSh4z4/9f7NXIVVTLn/8kc # JAfRqFmRrrFt3IKby7VrzmYuoQWD0lmNFtGQ57BrJkPrPFAPek1ALtcbb7FH3nQp # vi8ngz/MFX/+cnmNFWFU29VVLmzB9XvLZxbYvkeett0mh5lfteeN2rEwUyrdrKuf # z9h2S6pbate+C2h02CrXwSka0x6ezpTmGkIJLFt25ub/UYXNLdHdsxGD6EfckOIo # JYsm4MS9F/vSqLNHK89I0vTLBngQEp6LIFkINanRT3PtNx3pNKRKJRALc6L6mhW4 # hL4aHL749qPfQ72t5qAMm5xiKYMgJ2WanidRLNuI251JIN7raaeA/2vb0XFkZcIb # TR1pfQGsco4U0g5tjwIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFOYjIs5qa6pfuquP # yyK1FTr5QDCnMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8GA1Ud # HwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3Js # L01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBsBggr # BgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUyMDIw # MTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgw # DgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4ICAQA4I/3bkdnTxD2rFum3 # MF8xVKdEkohAObbePrQ+0fr5bRimjz9sVkKT/7gcj4OMcClSYG+IdX6Mp3EYsLHW # fjvwfzFoeZE+yTbdBj/1VHZQRuCmw6QqeVCTbw2nnS7nBxnWd9oZXbPUpqEawH5D # qXQaWFgR9A4KWVK/IvXVDMj1PlPCES1P3JonNbdhkkkz49rJuKOm5b7e/BH8loqA # mXOXRc22yxWVTMWrEp4pslmv8eT7VoY8X/jdKYTPVEXsfmLbVFcqzMuB8vFGfUyW # sWROS8wgq7lQYfWcYqh7NymoATX+wWYK3zWG7aRciPGUAzznXdf+aHtIWnQLNa5H # FmSXkiak3fSuprWYZiHhuYjE16hroApcBHpm+8S/kNqhm9WjQX+2BxnYv+Jejy6l # qTi8fLBLS069WXVw/ptf5IV+FtYl34GvVoeg31UoUmVVZe1SDUJkm9dDXc8l/qBD # YiAIT2CCsPTyt9XA9JVuHxdP63n7ChvWAO/47QRuCDsUlFJoWwyBwl7jeYpaRVMt # Qt0iuJMGGjgEaJX1Q/2j8sXURvTceLHDD9ipWt092ZDWMQciDRmhHNFOX1dnjBvk # /k1UMcg997j5oYznAnSpJvlg/4BP3aVE0h/YH2KgsKbU4NXZHAjJXj2Slqo1C115 # CG6qBZaFkM8W6vPZCm5qnSezOjCCB3EwggVZoAMCAQICEzMAAAAVxedrngKbSZkA # AAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpX # YXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQg # Q29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRl # IEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIyNVow # fDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMd # TWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEBAQUA # A4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXIyjVX # 9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjoYH1q # UoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1yaa8d # q6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v3byN # pOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pGve2k # rnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viSkR4d # Pf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYrbqgS # Uei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlMjgK8 # QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSLW6Cm # gyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AFemzF # ER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIurQID # AQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIEFgQU # KqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWnG1M1 # GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0 # bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMA # QTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV9lbL # j+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1p # Y3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAxMC0w # Ni0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIz # LmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv6lwU # tj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZnOlNN # 3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1bSNU # 5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4rPf5 # KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU6ZGy # qVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDFNLB6 # 2FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/HltE # AY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdUCbFp # AUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKiexcd # FYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTmdHRb # atGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZqELQd # VTNYs6FwZvKhggNNMIICNQIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMxEzAR # BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p # Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg # T3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjMzMDMtMDVFMC1E # OTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMKAQEw # BwYFKw4DAhoDFQALbEgZZnyYHXJ1DGb5fGjplXptuaCBgzCBgKR+MHwxCzAJBgNV # BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m # dCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA7ZvECDAiGA8y # MDI2MDQyODIzNDA1NloYDzIwMjYwNDI5MjM0MDU2WjB0MDoGCisGAQQBhFkKBAEx # LDAqMAoCBQDtm8QIAgEAMAcCAQACAhVfMAcCAQACAhLIMAoCBQDtnRWIAgEAMDYG # CisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSChCjAIAgEA # AgMBhqAwDQYJKoZIhvcNAQELBQADggEBACwy1jEO0yzsN8ZqGHnbagjjDvt3Xv/I # EDFfz5VliLRx8X0iLOgWaWtqLgnOTHwJ4XJTnCEFTD4fbGLYPxrdws1ainjYUsKT # Z2xoGT4SHN3GWKtrcMKG+bePVmmroODa96EJp6/cwEz7XgADxUl1NYpt+qRedMKb # +DeltovhOsOTHb/vv+tx0V/AGZroUHiqJ6yPND656dL3TKOebszgRLZT8VsGg8ih # fyqpM32v6iUq4UB6TonNy0YlAmO5jN4Paa087smzwbhwA6VYd7j+hDtubSwXg3Bg # fHRQ/zww/EYVleryDzR+yEyghducboz86C3pXPCPtHtGqNin9P4TZQExggQNMIIE # CQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4G # A1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYw # JAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAiEzwDX7 # 0g8hpAABAAACITANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkDMQ0GCyqG # SIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCDgGyGMYfz2Mz+rae/N9NWi1//zA0qW # L4t14jNDI8vWzTCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIADvIQefFVUa # 4BJy8IZywMAvmGSKdUVqEmy9A++PCj1EMIGYMIGApH4wfDELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUt # U3RhbXAgUENBIDIwMTACEzMAAAIhM8A1+9IPIaQAAQAAAiEwIgQg+ryFtDqKZopj # yfNM1f5NsdkFFub/A/xhhdtmiLlE314wDQYJKoZIhvcNAQELBQAEggIABt5cxVZ7 # rZ+1wqgLeQctyFMDO/0IM7VL5TnVgf++N9WGCXZPPrEWGqHRkREfw9VF9uo/mnGQ # uCJv4P+lrHKK+nJ4VWsMNK1wbfULX1fSKn8ISKKhn6HCStxWZvqfkLNxcjRQJ5HG # EIvRpDJZFsSRh1C0pOQ8zRajXPl4xjqxAfW/F2v6s/VqcmWcTqTBZo9wVVetSkQz # +PVHvAzhl6BOCm24MsiSOUmQunzFlpQvvFdctKStEcMCaexCY7B+ffMi7NvhDih9 # 5sWKfbaf6FlWBfxVXQvGE3e5mlTSgznCzTsf1mwm9++WBmwnqOMKjRLLZ2aC7bRr # hql7XuVaMzwWwBbdIVbMQ9Ew+3PfBbeyxMhlrtWtaKBHAGxaj9iXyUJ0yF1z22mR # EsS8AK9uVoaaU9ryOL7XYSaZZECFH33JKIcSecLjCvr0fE6bdhOt2An68ck9o2fu # AhfLjc3o6F5Vnbo505iIWINg5v2hmCWhFkX7xbiLJeChwLC9GH0QzJXTllewMlZ4 # FMfCYYnwT3N2GPnOD95ZqxGII6lzX40zGRtRSFuNAL819kWhJdsWmBZsix1lY/wT # 6RNHX00BqmYczRSlZ0W/iGBJw6OmTmdUGdnOJiEPA3+VB4J/i+TGWlb5o8yAf3qc # ZzgnBoN3f6Q9sQv7Cs5fSKs7U+0ssXjmRc8= # SIG # End signature block |