rules/Azure.Template.Rule.ps1
# Copyright (c) Microsoft Corporation. # Licensed under the MIT License. # # Validation rules for Azure template and parameter files # #region Template # Synopsis: Use ARM template file structure. Rule 'Azure.Template.TemplateFile' -Ref 'AZR-000212' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_06' } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $Assert.HasFields($jsonObject, @('$schema', 'contentVersion', 'resources')); $jsonObject.PSObject.Properties | Within 'Name' '$schema', 'contentVersion', 'metadata', 'parameters', 'functions', 'variables', 'resources', 'outputs'; } # Synopsis: Use a more recent version of the Azure template schema. Rule 'Azure.Template.TemplateSchema' -Ref 'AZR-000213' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $Assert.HasJsonSchema($jsonObject, @( 'https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json' 'https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json' 'https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json' 'https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json' ), $True); } # Synopsis: Use a Azure template schema with the https scheme. Rule 'Azure.Template.TemplateScheme' -Ref 'AZR-000214' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $Assert.StartsWith($jsonObject, '$schema', 'https://'); } # Synopsis: Use template parameter descriptions. Rule 'Azure.Template.ParameterMetadata' -Ref 'AZR-000215' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } { $parameters = @(GetTemplateParameters); if ($parameters.Length -eq 0) { return $Assert.Pass(); } foreach ($parameter in $parameters) { $Assert.HasFieldValue($parameter.value, 'metadata.description'). Reason($LocalizedData.TemplateParameterDescription, $parameter.name); } } # Synopsis: ARM templates should include at least one resource. Rule 'Azure.Template.Resources' -Ref 'AZR-000216' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } { $jsonObject = $PSRule.GetContent($TargetObject)[0]; $Assert.GreaterOrEqual($jsonObject, 'resources', 1); } # Synopsis: ARM template parameters should be used at least once. Rule 'Azure.Template.UseParameters' -Ref 'AZR-000217' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } { $jsonContent = Get-Content -Path $TargetObject.FullName -Raw; $parameters = @(GetTemplateParameters); if ($parameters.Length -eq 0) { return $Assert.Pass(); } foreach ($parameter in $parameters) { $Assert.Match($jsonContent, '.', "\`"\[[\s\S]*parameters\(\s{0,}'$($parameter.name.Replace('$', '\$'))'\s{0,}\)[\s\S]*\]\`""). Reason($LocalizedData.ParameterNotFound, $parameter.name); } } # Synopsis: Each Azure Resource Manager (ARM) template file should contain a minimal number of parameters. Rule 'Azure.Template.DefineParameters' -Ref 'AZR-000218' -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { $parameters = @(GetTemplateParameters); $Assert.GreaterOrEqual($parameters, '.', 1); } # Synopsis: ARM template variables should be used at least once. Rule 'Azure.Template.UseVariables' -Ref 'AZR-000219' -Type '.json' -If { (IsTemplateFile) } -Tag @{ release = 'GA'; ruleSet = '2020_09' } { $jsonObject = $PSRule.GetContent($TargetObject)[0]; $jsonContent = Get-Content -Path $TargetObject.FullName -Raw; $variableNames = @($jsonObject.variables.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' } | ForEach-Object { $variable = $_; if ($variable.name -eq 'copy') { $variable.value | ForEach-Object { $_.name; } } else { $variable.name; } }); if ($variableNames.Length -eq 0) { return $Assert.Pass(); } foreach ($variableName in $variableNames) { $Assert.Match($jsonContent, '.', "\`"\[[\s\S]*variables\(\s{0,}'$([System.Text.RegularExpressions.Regex]::Escape($variableName))'\s{0,}\)[\s\S]*\]\`""). Reason($LocalizedData.VariableNotFound, $variableName); } } # Synopsis: Set the default value for location parameters within ARM template to the default value to `[resourceGroup().location]`. Rule 'Azure.Template.LocationDefault' -Ref 'AZR-000220' -Type '.json' -If { (HasLocationParameter) } -Tag @{ release = 'GA'; ruleSet = '2021_03' } { # https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 $parameters = @(GetTemplateParameters -Name 'location'); foreach ($parameter in $parameters) { if ($Assert.HasFieldValue($parameter.Value, 'defaultValue', 'global').Result) { $Assert.Pass(); } else { $defaultValue = [PSRule.Rules.Azure.Runtime.Helper]::CompressExpression($parameter.Value.defaultValue); $Assert.HasFieldValue($defaultValue, '.', '[resourceGroup().location]'). Reason($LocalizedData.ParameterInvalidDefaultValue, $parameter.Name, $parameter.Value.defaultValue); } } } # Synopsis: Location parameters should use a string value. Rule 'Azure.Template.LocationType' -Ref 'AZR-000221' -Type '.json' -If { (HasLocationParameter) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { # https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Location-Should-Not-Be-Hardcoded.test.ps1 $parameters = @(GetTemplateParameters -Name 'location'); foreach ($parameter in $parameters) { $Assert.HasFieldValue($parameter.Value, 'type', 'string'); } } # Synopsis: Template resource location should be an expression or `global`. Rule 'Azure.Template.ResourceLocation' -Ref 'AZR-000222' -Type '.json' -If { (HasTemplateResources) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { # https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Resources-Should-Have-Location.test.ps1 $resources = @(GetTemplateResources); if ($resources.Length -eq 0) { return $Assert.Pass(); } foreach ($resource in $resources) { AnyOf { $Assert.NotHasField($resource, 'location'); $Assert.HasFieldValue($resource, 'location', 'global'); $Assert.Match($resource, 'location', '^\[.*\]$'); } } } # Synopsis: Template should reference a location parameter to specify resource location. Rule 'Azure.Template.UseLocationParameter' -Ref 'AZR-000223' -Level Warning -Type '.json' -If { (IsTemplateFile -Suffix '/deploymentTemplate.json') -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { $jsonObject = $PSRule.GetContent($TargetObject)[0]; if ($Assert.HasField($jsonObject, 'parameters.location').Result) { $jsonObject.parameters.PSObject.Properties.Remove('location') } $content = $jsonObject | ConvertTo-Json -Depth 100; $Assert.NotMatch($content, '.', 'resourceGroup\(\s{0,}\)\.location'). Reason($LocalizedData.ExpressionInTemplate, 'resourceGroup().location'); } # Synopsis: Template parameters `minValue` and `maxValue` constraints must be valid. Rule 'Azure.Template.ParameterMinMaxValue' -Ref 'AZR-000224' -Type '.json' -If { (HasTemplateParameters) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { # https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Min-And-Max-Value-Are-Numbers.test.ps1 # Get parameters with either minValue or maxValue $parameters = @(GetTemplateParameters | Where-Object { $Assert.HasField($_.Value, @('minValue', 'maxValue')).Result }); if ($parameters.Length -eq 0) { return $Assert.Pass(); } foreach ($parameter in $parameters) { $Assert.HasFieldValue($parameter.Value, 'type', 'int'); if ($Assert.HasField($parameter.Value, 'minValue').Result) { $Assert.IsInteger($parameter.Value, 'minValue'). Reason($LocalizedData.ParameterTypeMismatch, 'minValue', $parameter.Name, 'int'); } if ($Assert.HasField($parameter.Value, 'maxValue').Result) { $Assert.IsInteger($parameter.Value, 'maxValue'). Reason($LocalizedData.ParameterTypeMismatch, 'maxValue', $parameter.Name, 'int'); } } } # Synopsis: Use default deployment detail level for nested deployments. Rule 'Azure.Template.DebugDeployment' -Ref 'AZR-000225' -Type '.json' -If { (HasTemplateResources) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { # https://github.com/Azure/arm-ttk/blob/master/arm-ttk/testcases/deploymentTemplate/Deployment-Resources-Must-Not-Be-Debug.test.ps1 # Get deployments $resources = @($PSRule.GetContent($TargetObject)[0].resources | Where-Object { $Assert.HasFieldValue($_, 'type', 'Microsoft.Resources/deployments').Result }); if ($resources.Length -eq 0) { return $Assert.Pass(); } foreach ($resource in $resources) { $Assert.HasDefaultValue($resource, 'properties.debugSetting.detailLevel', 'None'); } } # Synopsis: Set the parameter default value to a value of the same type. Rule 'Azure.Template.ParameterDataTypes' -Ref 'AZR-000226' -Type '.json' -If { (HasTemplateParameters) } -Tag @{ release = 'GA'; ruleSet = '2021_03'; } { $jsonObject = $PSRule.GetContent($TargetObject)[0]; $parameters = @($jsonObject.parameters.PSObject.Properties); if ($parameters.Length -eq 0) { return $Assert.Pass(); } foreach ($parameter in $parameters) { if (!$Assert.HasField($parameter.Value, 'defaultValue').Result) { # No defaultValue $Assert.Pass(); } elseif ($parameter.Value.defaultValue -is [string] -and $parameter.Value.defaultValue.StartsWith('[') -and $parameter.Value.defaultValue.EndsWith(']')) { # Is function $Assert.Pass(); } elseif ($Null -eq $parameter.Value.defaultValue) { # defaultValue is null $Assert.Pass(); } elseif ($parameter.Value.type -eq 'bool') { $Assert.IsBoolean($parameter.Value, 'defaultValue'). Reason($LocalizedData.ParameterTypeMismatch, 'defaultValue', $parameter.Name, $parameter.Value.type); } elseif ($parameter.Value.type -eq 'int') { $Assert.IsInteger($parameter.Value, 'defaultValue'). Reason($LocalizedData.ParameterTypeMismatch, 'defaultValue', $parameter.Name, $parameter.Value.type); } elseif ($parameter.Value.type -eq 'array') { $Assert.IsArray($parameter.Value, 'defaultValue'). Reason($LocalizedData.ParameterTypeMismatch, 'defaultValue', $parameter.Name, $parameter.Value.type); } elseif ($parameter.Value.type -eq 'string' -or $parameter.Value.type -eq 'secureString') { $Assert.IsString($parameter.Value, 'defaultValue'). Reason($LocalizedData.ParameterTypeMismatch, 'defaultValue', $parameter.Name, $parameter.Value.type); } elseif ($parameter.Value.type -eq 'object' -or $parameter.Value.type -eq 'secureObject') { $Assert.TypeOf($parameter.Value, 'defaultValue', [PSObject]). Reason($LocalizedData.ParameterTypeMismatch, 'defaultValue', $parameter.Name, $parameter.Value.type); } } } # Synopsis: Set the parameter value to a value that matches the specified strong type. Rule 'Azure.Template.ParameterStrongType' -Ref 'AZR-000227' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } { $Assert.Create($PSRule.Issue.Get('PSRule.Rules.Azure.Template.ParameterStrongType')); } # Synopsis: Template expressions should not exceed the maximum length. Rule 'Azure.Template.ExpressionLength' -Ref 'AZR-000228' -Type 'Microsoft.Resources/deployments' -Tag @{ release = 'GA'; ruleSet = '2021_12'; } { $Assert.Create($PSRule.Issue.Get('PSRule.Rules.Azure.Template.ExpressionLength')); } #endregion Template #region Parameters # Synopsis: Use ARM parameter file structure. Rule 'Azure.Template.ParameterFile' -Ref 'AZR-000229' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2020_06' } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $Assert.HasFields($jsonObject, @('$schema', 'contentVersion', 'parameters')); $jsonObject.PSObject.Properties | Within 'Name' '$schema', 'contentVersion', 'metadata', 'parameters'; } # Synopsis: Use a Azure template parameter schema with the https scheme. Rule 'Azure.Template.ParameterScheme' -Ref 'AZR-000230' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $Assert.StartsWith($jsonObject, '$schema', 'https://'); } # Synopsis: Configure a metadata link for each parameter file. Rule 'Azure.Template.MetadataLink' -Ref 'AZR-000231' -Type '.json' -If { $Configuration.AZURE_PARAMETER_FILE_METADATA_LINK -eq $True -and (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09' } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $field = $Assert.HasFieldValue($jsonObject, 'metadata.template'); if (!$field.Result) { return $field; } $path = [PSRule.Rules.Azure.Runtime.Helper]::GetMetadataLinkPath($TargetObject.FullName, $jsonObject.metadata.template) $Assert.FilePath($path, '.'); $Assert.WithinPath($path, '.', @($PWD)); } # Synopsis: Specify a value for each parameter in template parameter files. Rule 'Azure.Template.ParameterValue' -Ref 'AZR-000232' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $parameters = @($jsonObject.parameters.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' }); if ($parameters.Length -eq 0) { return $Assert.Pass(); } foreach ($parameter in $parameters) { if ($Assert.HasField($parameter.Value, 'value').Result -or $Assert.HasFieldValue($parameter.Value, 'reference').Result) { $Assert.Pass(); } else { $Assert.Fail($LocalizedData.ParameterValueNotSet, $parameter.Name); } } } # Synopsis: Use a valid secret reference within parameter files. Rule 'Azure.Template.ValidSecretRef' -Ref 'AZR-000233' -Type '.json' -If { (IsParameterFile) } -Tag @{ release = 'GA'; ruleSet = '2021_09'; } { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); $parameters = @($jsonObject.parameters.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' -and $Assert.HasField($_.Value, 'reference').Result }); if ($parameters.Length -eq 0) { return $Assert.Pass(); } foreach ($parameter in $parameters) { $Assert.Match($parameter.Value, 'reference.keyVault.id', '^\/subscriptions\/(.+?)\/resourceGroups\/(.+?)\/providers\/Microsoft\.KeyVault\/vaults\/[A-Za-z](-|[A-Za-z0-9])*[A-Za-z0-9]$'); $Assert.Match($parameter.Value, 'reference.secretName', '^[A-Za-z0-9-]{1,127}$'); } } # Synopsis: Use comments for each resource in ARM template to communicate purpose. Rule 'Azure.Template.UseComments' -Ref 'AZR-000234' -Level Information -Type '.json' -If { (IsTemplateFile) -and !(IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_12'; } { $resources = @(GetTemplateResources | Where-Object { $Assert.NullOrEmpty($_, 'comments').Result }); $Assert.Count($resources, '.', 0).Reason( $LocalizedData.TemplateResourceWithoutComment, $TargetObject.FullName, $resources.Length ); } # Synopsis: Use descriptions for each resource in generated template(bicep, psarm, AzOps) to communicate purpose. Rule 'Azure.Template.UseDescriptions' -Ref 'AZR-000235' -Level Information -Type '.json' -If { (IsTemplateFile) -and (IsGenerated) } -Tag @{ release = 'GA'; ruleSet = '2021_12'; } { $resources = @(GetTemplateResources | Where-Object { $Assert.NullOrEmpty($_, 'metadata.description').Result }); $Assert.Count($resources, '.', 0).Reason( $LocalizedData.TemplateResourceWithoutDescription, $TargetObject.FullName, $resources.Length ); } #endregion Parameters #region Helper functions # Determines if the object is a Azure Resource Manager template file function global:IsTemplateFile { [CmdletBinding()] [OutputType([System.Boolean])] param ( [Parameter(Mandatory = $False)] [String]$Suffix ) process { if ($PSRule.TargetType -ne '.json') { return $False; } try { $jsonObject = $PSRule.GetContent($TargetObject)[0]; [String]$targetSchema = $jsonObject.'$schema'; $schemas = @( # Https "https://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json`#" "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json`#" "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json`#" "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json`#" "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json`#" # Http "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json`#" "http://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json`#" "http://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentTemplate.json`#" "http://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentTemplate.json`#" "http://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentTemplate.json`#" ) return $targetSchema -in $schemas -and ([String]::IsNullOrEmpty($Suffix) -or $targetSchema.Trim("`#").EndsWith($Suffix)); } catch { return $False; } } } # Determines if the object is a Azure Resource Manager parameter file function global:IsParameterFile { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if ($PSRule.TargetType -ne '.json') { return $False; } try { $jsonObject = $PSRule.GetContent($TargetObject)[0]; $schemas = @( # Https "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json`#" "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json`#" "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json`#" "https://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentParameters.json`#" "https://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentParameters.json`#" "https://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentParameters.json`#" # Http "http://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json`#" "http://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json`#" "http://schema.management.azure.com/schemas/2018-05-01/subscriptionDeploymentParameters.json`#" "http://schema.management.azure.com/schemas/2019-08-01/tenantDeploymentParameters.json`#" "http://schema.management.azure.com/schemas/2019-08-01/managementGroupDeploymentParameters.json`#" ) return $jsonObject.'$schema' -in $schemas; } catch { return $False; } } } function global:HasLocationParameter { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if (!(IsTemplateFile -Suffix '/deploymentTemplate.json')) { return $False; } $jsonObject = $PSRule.GetContent($TargetObject)[0]; return $Assert.HasField($jsonObject, 'parameters.location').Result; } } function global:HasTemplateParameters { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if (!(IsTemplateFile)) { return $False; } $parameters = @($PSRule.GetContent($TargetObject)[0].parameters.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' }); return $Assert.GreaterOrEqual($parameters, '.', 1).Result; } } function global:HasTemplateResources { [CmdletBinding()] [OutputType([System.Boolean])] param () process { if (!(IsTemplateFile)) { return $False; } $jsonObject = $PSRule.GetContent($TargetObject)[0].resources; return $Assert.GreaterOrEqual($jsonObject, '.', 1).Result; } } function global:GetTemplateParameters { [CmdletBinding()] [OutputType([PSObject])] param ( [Parameter(Mandatory = $False)] [String[]]$Name ) process { $parameters = @($PSRule.GetContent($TargetObject)[0].parameters.PSObject.Properties | Where-Object { $_.MemberType -eq 'NoteProperty' }); return $parameters | Where-Object { $Null -eq $Name -or $_.Name -in $Name }; } } function global:GetTemplateResources { [CmdletBinding()] [OutputType([PSObject])] param () process { $PSRule.GetContent($TargetObject)[0].resources | ForEach-Object { # Emit each resource $_; # Emit resources in nested templates if ($Assert.HasFieldValue($_, 'type', 'Microsoft.Resources/deployments').Result -and $Assert.GreaterOrEqual($_, 'properties.template.resources', 1).Result) { $_.properties.template.resources; } # Emit sub-resources elseif ($Assert.GreaterOrEqual($_, 'resources', 1).Result) { $_.resources; } } } } function global:IsGenerated { [CmdletBinding()] param () process { if ($PSRule.TargetType -ne '.json') { return $False; } try { $jsonObject = $PSRule.GetContentFirstOrDefault($TargetObject); return $Assert.In($jsonObject, 'metadata._generator.name', @('bicep', 'psarm', 'AzOps')).Result; } catch { return $False; } } } #endregion Helper functions # SIG # Begin signature block # MIIoPAYJKoZIhvcNAQcCoIIoLTCCKCkCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDO/dQ2M49C6jRb # p+ChM3V6gt2/AAjo3JMCDPkfYs56eqCCDYUwggYDMIID66ADAgECAhMzAAADTU6R # phoosHiPAAAAAANNMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjMwMzE2MTg0MzI4WhcNMjQwMzE0MTg0MzI4WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQDUKPcKGVa6cboGQU03ONbUKyl4WpH6Q2Xo9cP3RhXTOa6C6THltd2RfnjlUQG+ # Mwoy93iGmGKEMF/jyO2XdiwMP427j90C/PMY/d5vY31sx+udtbif7GCJ7jJ1vLzd # j28zV4r0FGG6yEv+tUNelTIsFmmSb0FUiJtU4r5sfCThvg8dI/F9Hh6xMZoVti+k # bVla+hlG8bf4s00VTw4uAZhjGTFCYFRytKJ3/mteg2qnwvHDOgV7QSdV5dWdd0+x # zcuG0qgd3oCCAjH8ZmjmowkHUe4dUmbcZfXsgWlOfc6DG7JS+DeJak1DvabamYqH # g1AUeZ0+skpkwrKwXTFwBRltAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUId2Img2Sp05U6XI04jli2KohL+8w # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzUwMDUxNzAfBgNVHSMEGDAW # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB # ACMET8WuzLrDwexuTUZe9v2xrW8WGUPRQVmyJ1b/BzKYBZ5aU4Qvh5LzZe9jOExD # YUlKb/Y73lqIIfUcEO/6W3b+7t1P9m9M1xPrZv5cfnSCguooPDq4rQe/iCdNDwHT # 6XYW6yetxTJMOo4tUDbSS0YiZr7Mab2wkjgNFa0jRFheS9daTS1oJ/z5bNlGinxq # 2v8azSP/GcH/t8eTrHQfcax3WbPELoGHIbryrSUaOCphsnCNUqUN5FbEMlat5MuY # 94rGMJnq1IEd6S8ngK6C8E9SWpGEO3NDa0NlAViorpGfI0NYIbdynyOB846aWAjN # fgThIcdzdWFvAl/6ktWXLETn8u/lYQyWGmul3yz+w06puIPD9p4KPiWBkCesKDHv # XLrT3BbLZ8dKqSOV8DtzLFAfc9qAsNiG8EoathluJBsbyFbpebadKlErFidAX8KE # usk8htHqiSkNxydamL/tKfx3V/vDAoQE59ysv4r3pE+zdyfMairvkFNNw7cPn1kH # Gcww9dFSY2QwAxhMzmoM0G+M+YvBnBu5wjfxNrMRilRbxM6Cj9hKFh0YTwba6M7z # ntHHpX3d+nabjFm/TnMRROOgIXJzYbzKKaO2g1kWeyG2QtvIR147zlrbQD4X10Ab # rRg9CpwW7xYxywezj+iNAc+QmFzR94dzJkEPUSCJPsTFMIIHejCCBWKgAwIBAgIK # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+ # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6 # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3 # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7 # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/ # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCGg0wghoJAgEBMIGVMH4x # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAANNTpGmGiiweI8AAAAA # A00wDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIOWw # H/zcXKPXAwkKqE5ICjrUGb78h9GsY5fbfPq5yIPdMEIGCisGAQQBgjcCAQwxNDAy # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20wDQYJKoZIhvcNAQEBBQAEggEAnXY05PWN5e29/sbrKEhKGM1noKFEPRHFzvOk # DV+MeYJv28y7eGvF6jMim33s9tFdZ9Zto9P8uXEfu/hLpBM2ar0ZmZ4gfnZPQHhE # KCU6n0MVDHXhneJkdVQzcTDDh7IS7fbTYMp8eXlr+TFYuMQA8uVa/YbOqcA01CxS # Oa/UuQk2yFxd0qdIeIo5ViFa6xA9xeeDEpTqDRlX7NjL3TZUL+0IXjRUh9tHbQri # hXijs4pkJ/gG0oZ/p154MOLnH7U8aHJ4L0mKiyHfzVuN23q6BAa5QQ5cwzzEo175 # QUXieBGpsBrdYnA1Qg/ktkJypE3e8ZeDrPGKAfJVOUx9b+pmpqGCF5cwgheTBgor # BgEEAYI3AwMBMYIXgzCCF38GCSqGSIb3DQEHAqCCF3AwghdsAgEDMQ8wDQYJYIZI # AWUDBAIBBQAwggFSBgsqhkiG9w0BCRABBKCCAUEEggE9MIIBOQIBAQYKKwYBBAGE # WQoDATAxMA0GCWCGSAFlAwQCAQUABCBJ6+3iDnOW0BAYWKlxZjfpPJ1BXxfMMAxq # urU4lJqKIwIGZSiND39ZGBMyMDIzMTAxOTExNTEwMy41NzJaMASAAgH0oIHRpIHO # MIHLMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH # UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQL # ExxNaWNyb3NvZnQgQW1lcmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxk # IFRTUyBFU046REMwMC0wNUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1l # LVN0YW1wIFNlcnZpY2WgghHtMIIHIDCCBQigAwIBAgITMwAAAdIhJDFKWL8tEQAB # AAAB0jANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2Fz # aGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENv # cnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAx # MDAeFw0yMzA1MjUxOTEyMjFaFw0yNDAyMDExOTEyMjFaMIHLMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1l # cmljYSBPcGVyYXRpb25zMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046REMwMC0w # NUUwLUQ5NDcxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2Uw # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDcYIhC0QI/SPaT5+nYSBsS # dhBPO2SXM40Vyyg8Fq1TPrMNDzxChxWUD7fbKwYGSsONgtjjVed5HSh5il75jNac # b6TrZwuX+Q2++f2/8CCyu8TY0rxEInD3Tj52bWz5QRWVQejfdCA/n6ZzinhcZZ7+ # VelWgTfYC7rDrhX3TBX89elqXmISOVIWeXiRK8h9hH6SXgjhQGGQbf2bSM7uGkKz # J/pZ2LvlTzq+mOW9iP2jcYEA4bpPeurpglLVUSnGGQLmjQp7Sdy1wE52WjPKdLnB # F6JbmSREM/Dj9Z7okxRNUjYSdgyvZ1LWSilhV/wegYXVQ6P9MKjRnE8CI5KMHmq7 # EsHhIBK0B99dFQydL1vduC7eWEjzz55Z/DyH6Hl2SPOf5KZ4lHf6MUwtgaf+MeZx # kW0ixh/vL1mX8VsJTHa8AH+0l/9dnWzFMFFJFG7g95nHJ6MmYPrfmoeKORoyEQRs # Sus2qCrpMjg/P3Z9WJAtFGoXYMD19NrzG4UFPpVbl3N1XvG4/uldo1+anBpDYhxQ # U7k1gfHn6QxdUU0TsrJ/JCvLffS89b4VXlIaxnVF6QZh+J7xLUNGtEmj6dwPzoCf # L7zqDZJvmsvYNk1lcbyVxMIgDFPoA2fZPXHF7dxahM2ZG7AAt3vZEiMtC6E/ciLR # cIwzlJrBiHEenIPvxW15qwIDAQABo4IBSTCCAUUwHQYDVR0OBBYEFCC2n7cnR3To # P/kbEZ2XJFFmZ1kkMB8GA1UdIwQYMBaAFJ+nFV0AXmJdg/Tl0mWnG1M1GelyMF8G # A1UdHwRYMFYwVKBSoFCGTmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMv # Y3JsL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0ElMjAyMDEwKDEpLmNybDBs # BggrBgEFBQcBAQRgMF4wXAYIKwYBBQUHMAKGUGh0dHA6Ly93d3cubWljcm9zb2Z0 # LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwVGltZS1TdGFtcCUyMFBDQSUy # MDIwMTAoMSkuY3J0MAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUH # AwgwDgYDVR0PAQH/BAQDAgeAMA0GCSqGSIb3DQEBCwUAA4ICAQCw5iq0Ey0LlAdz # 2PcqchRwW5d+fitNISCvqD0E6W/AyiTk+TM3WhYTaxQ2pP6Or4qOV+Du7/L+k18g # Yr1phshxVMVnXNcdjecMtTWUOVAwbJoeWHaAgknNIMzXK3+zguG5TVcLEh/CVMy1 # J7KPE8Q0Cz56NgWzd9urG+shSDKkKdhOYPXF970Mr1GCFFpe1oXjEy6aS+Heavp2 # wmy65mbu0AcUOPEn+hYqijgLXSPqvuFmOOo5UnSV66Dv5FdkqK7q5DReox9RPEZc # HUa+2BUKPjp+dQ3D4c9IH8727KjMD8OXZomD9A8Mr/fcDn5FI7lfZc8ghYc7spYK # TO/0Z9YRRamhVWxxrIsBN5LrWh+18soXJ++EeSjzSYdgGWYPg16hL/7Aydx4Kz/W # BTUmbGiiVUcE/I0aQU2U/0NzUiIFIW80SvxeDWn6I+hyVg/sdFSALP5JT7wAe8zT # vsrI2hMpEVLdStFAMqanFYqtwZU5FoAsoPZ7h1ElWmKLZkXk8ePuALztNY1yseO0 # TwdueIGcIwItrlBYg1XpPz1+pMhGMVble6KHunaKo5K/ldOM0mQQT4Vjg6ZbzRIV # RoDcArQ5//0875jOUvJtYyc7Hl04jcmvjEIXC3HjkUYvgHEWL0QF/4f7vLAchaEZ # 839/3GYOdqH5VVnZrUIBQB6DTaUILDCCB3EwggVZoAMCAQICEzMAAAAVxedrngKb # SZkAAAAAABUwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQI # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv # ZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmlj # YXRlIEF1dGhvcml0eSAyMDEwMB4XDTIxMDkzMDE4MjIyNVoXDTMwMDkzMDE4MzIy # NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcT # B1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UE # AxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggIiMA0GCSqGSIb3DQEB # AQUAA4ICDwAwggIKAoICAQDk4aZM57RyIQt5osvXJHm9DtWC0/3unAcH0qlsTnXI # yjVX9gF/bErg4r25PhdgM/9cT8dm95VTcVrifkpa/rg2Z4VGIwy1jRPPdzLAEBjo # YH1qUoNEt6aORmsHFPPFdvWGUNzBRMhxXFExN6AKOG6N7dcP2CZTfDlhAnrEqv1y # aa8dq6z2Nr41JmTamDu6GnszrYBbfowQHJ1S/rboYiXcag/PXfT+jlPP1uyFVk3v # 3byNpOORj7I5LFGc6XBpDco2LXCOMcg1KL3jtIckw+DJj361VI/c+gVVmG1oO5pG # ve2krnopN6zL64NF50ZuyjLVwIYwXE8s4mKyzbnijYjklqwBSru+cakXW2dg3viS # kR4dPf0gz3N9QZpGdc3EXzTdEonW/aUgfX782Z5F37ZyL9t9X4C626p+Nuw2TPYr # bqgSUei/BQOj0XOmTTd0lBw0gg/wEPK3Rxjtp+iZfD9M269ewvPV2HM9Q07BMzlM # jgK8QmguEOqEUUbi0b1qGFphAXPKZ6Je1yh2AuIzGHLXpyDwwvoSCtdjbwzJNmSL # W6CmgyFdXzB0kZSU2LlQ+QuJYfM2BjUYhEfb3BvR/bLUHMVr9lxSUV0S2yW6r1AF # emzFER1y7435UsSFF5PAPBXbGjfHCBUYP3irRbb1Hode2o+eFnJpxq57t7c+auIu # rQIDAQABo4IB3TCCAdkwEgYJKwYBBAGCNxUBBAUCAwEAATAjBgkrBgEEAYI3FQIE # FgQUKqdS/mTEmr6CkTxGNSnPEP8vBO4wHQYDVR0OBBYEFJ+nFV0AXmJdg/Tl0mWn # G1M1GelyMFwGA1UdIARVMFMwUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEW # M2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5 # Lmh0bTATBgNVHSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBi # AEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTV # 9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3Js # Lm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXRfMjAx # MC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8v # d3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dF8yMDEwLTA2 # LTIzLmNydDANBgkqhkiG9w0BAQsFAAOCAgEAnVV9/Cqt4SwfZwExJFvhnnJL/Klv # 6lwUtj5OR2R4sQaTlz0xM7U518JxNj/aZGx80HU5bbsPMeTCj/ts0aGUGCLu6WZn # OlNN3Zi6th542DYunKmCVgADsAW+iehp4LoJ7nvfam++Kctu2D9IdQHZGN5tggz1 # bSNU5HhTdSRXud2f8449xvNo32X2pFaq95W2KFUn0CS9QKC/GbYSEhFdPSfgQJY4 # rPf5KYnDvBewVIVCs/wMnosZiefwC2qBwoEZQhlSdYo2wh3DYXMuLGt7bj8sCXgU # 6ZGyqVvfSaN0DLzskYDSPeZKPmY7T7uG+jIa2Zb0j/aRAfbOxnT99kxybxCrdTDF # NLB62FD+CljdQDzHVG2dY3RILLFORy3BFARxv2T5JL5zbcqOCb2zAVdJVGTZc9d/ # HltEAY5aGZFrDZ+kKNxnGSgkujhLmm77IVRrakURR6nxt67I6IleT53S0Ex2tVdU # CbFpAUR+fKFhbHP+CrvsQWY9af3LwUFJfn6Tvsv4O+S3Fb+0zj6lMVGEvL8CwYKi # excdFYmNcP7ntdAoGokLjzbaukz5m/8K6TT4JDVnK+ANuOaMmdbhIurwJ0I9JZTm # dHRbatGePu1+oDEzfbzL6Xu/OHBE0ZDxyKs6ijoIYn/ZcGNTTY3ugm2lBRDBcQZq # ELQdVTNYs6FwZvKhggNQMIICOAIBATCB+aGB0aSBzjCByzELMAkGA1UEBhMCVVMx # EzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJp # Y2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOkRDMDAtMDVF # MC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiMK # AQEwBwYFKw4DAhoDFQCJptLCZsE06NtmHQzB5F1TroFSBqCBgzCBgKR+MHwxCzAJ # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv # c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMA0GCSqGSIb3DQEBCwUAAgUA6Nr0XDAi # GA8yMDIzMTAxOTAwMTgzNloYDzIwMjMxMDIwMDAxODM2WjB3MD0GCisGAQQBhFkK # BAExLzAtMAoCBQDo2vRcAgEAMAoCAQACAhTuAgH/MAcCAQACAhPEMAoCBQDo3EXc # AgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEAAgMHoSCh # CjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEBAG1mQQFgclC51ZVud487UTLo # eSM2LSMTLNaXgr6pwC3e3wtwWnBgDA3zBm3MLmlQlCAjMvDgPcozg3GM5HPjT1sy # aa+Na7N0AbAUjUkXPmaDSAz/ZzQMPEBpgvC2Hkcr6xsbM/mPCwU6MY48b+1N5zhi # A8eySC0uBve0DcqBHDFqF2JpmTFAtPo/F7zPI5wWQNQu4SBNzwFN+TRhcyaUIxPd # jG7fYpPNiNIBvWDNPsNY16hUVAgtfLyCSvxR+4Je2wiuTRUv3Y6Q1kqBX7QX9ZF0 # k3CGq/h59DykM2ljrLwuuyzX7zfuL4vMSxS/E9G2/danI2YJ5LKS1traSGekC3Mx # ggQNMIIECQIBATCBkzB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv # bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0 # aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAA # AdIhJDFKWL8tEQABAAAB0jANBglghkgBZQMEAgEFAKCCAUowGgYJKoZIhvcNAQkD # MQ0GCyqGSIb3DQEJEAEEMC8GCSqGSIb3DQEJBDEiBCAOyTOXGjZ+jxuVJVfFckyV # sHHAq5mNeSDHzm8H8bSrAjCB+gYLKoZIhvcNAQkQAi8xgeowgecwgeQwgb0EIMeA # IJPf30i9ZbOExU557GwWNaLH0Z5s65JFga2DeaROMIGYMIGApH4wfDELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgUENBIDIwMTACEzMAAAHSISQxSli/LREAAQAAAdIwIgQgwq5+ # uqk2fNSKmvSPb5RsnskE/7ccGPgvjbnRPtSkIXAwDQYJKoZIhvcNAQELBQAEggIA # PCKOZmXnlYSRf9MK547AI4OgzH80VTsdiispWTIfKnc9xVvgzkQjJX4xuipRE05U # qJhl7zuWy2xAs+UlMgUYW/gPPACVqMGhmml1G1etihnCJmkHjv5jslP9Zj2Hmbmw # e+huvVTIlqdqZbQSpRhx4FOk0MrW9z5tNNVklgrHu4RRp2EZUK/uVS9y1K3WTVkd # EfpE45K30DfA7xTYj7jFCFwqlAD1OZx3gmrtTSprq0YSeLxoW1qKzpnfKLcX4mfp # CvrQdFxBRfjcBf9cE/HID2CUCKYzef0p0lKnVxTH8apqMnMizUJseDFIU0atXHHn # +y3flEK52ar7mJX8V8VxStiqPu0Nkf7JWNlhqOAfcxzva8X+THDR9ijm//4lDn1L # +YjxGdVlitzUkwqX4DSf/3eoOCTqV2lT+Lp3qLxhvHBmOMKEHoRqSXRymKgozo8E # 58UOo/21PTvzCwAI4u/Amas8SR6Q0n6QVrkUx3bsbNpxk28iYeMCpKiCNiIxZXJv # lQNJSTOeREx1PREXDkf5XS8cIfFZVf99W2BVt6z4rrJ+jM30QOg5Ah/KirdVXd0/ # GfQSJiGs8HyLuw5ONCeXI+PzWT/Dm24XkuhTB8M8jw0d8yYoetTfbNBcJ+cYS1QX # tIyKIvO9r2ltiW0DZgnBkWY7CVdKGjjw3sJV9xI48UU= # SIG # End signature block |