You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1409 lines
51 KiB
PowerShell
1409 lines
51 KiB
PowerShell
# Copyright (c) Microsoft Corporation. All rights reserved.
|
|
|
|
$ErrorActionPreference = 'Stop'
|
|
$InitialDatabase = '0'
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Adds or updates an Entity Framework provider entry in the project config
|
|
file.
|
|
|
|
.DESCRIPTION
|
|
Adds an entry into the 'entityFramework' section of the project config
|
|
file for the specified provider invariant name and provider type. If an
|
|
entry for the given invariant name already exists, then that entry is
|
|
updated with the given type name, unless the given type name already
|
|
matches, in which case no action is taken. The 'entityFramework'
|
|
section is added if it does not exist. The config file is automatically
|
|
saved if and only if a change was made.
|
|
|
|
This command is typically used only by Entity Framework provider NuGet
|
|
packages and is run from the 'install.ps1' script.
|
|
|
|
.PARAMETER Project
|
|
The Visual Studio project to update. When running in the NuGet install.ps1
|
|
script the '$project' variable provided as part of that script should be
|
|
used.
|
|
|
|
.PARAMETER InvariantName
|
|
The provider invariant name that uniquely identifies this provider. For
|
|
example, the Microsoft SQL Server provider is registered with the invariant
|
|
name 'System.Data.SqlClient'.
|
|
|
|
.PARAMETER TypeName
|
|
The assembly-qualified type name of the provider-specific type that
|
|
inherits from 'System.Data.Entity.Core.Common.DbProviderServices'. For
|
|
example, for the Microsoft SQL Server provider, this type is
|
|
'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer'.
|
|
#>
|
|
function Add-EFProvider
|
|
{
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param(
|
|
[parameter(Position = 0, Mandatory = $true)]
|
|
$Project,
|
|
[parameter(Position = 1, Mandatory = $true)]
|
|
[string] $InvariantName,
|
|
[parameter(Position = 2, Mandatory = $true)]
|
|
[string] $TypeName)
|
|
|
|
$configPath = GetConfigPath $Project
|
|
if (!$configPath)
|
|
{
|
|
return
|
|
}
|
|
|
|
[xml] $configXml = Get-Content $configPath
|
|
|
|
$providers = $configXml.configuration.entityFramework.providers
|
|
|
|
$providers.provider |
|
|
where invariantName -eq $InvariantName |
|
|
%{ $providers.RemoveChild($_) | Out-Null }
|
|
|
|
$provider = $providers.AppendChild($configXml.CreateElement('provider'))
|
|
$provider.SetAttribute('invariantName', $InvariantName)
|
|
$provider.SetAttribute('type', $TypeName)
|
|
|
|
$configXml.Save($configPath)
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Adds or updates an Entity Framework default connection factory in the
|
|
project config file.
|
|
|
|
.DESCRIPTION
|
|
Adds an entry into the 'entityFramework' section of the project config
|
|
file for the connection factory that Entity Framework will use by default
|
|
when creating new connections by convention. Any existing entry will be
|
|
overridden if it does not match. The 'entityFramework' section is added if
|
|
it does not exist. The config file is automatically saved if and only if
|
|
a change was made.
|
|
|
|
This command is typically used only by Entity Framework provider NuGet
|
|
packages and is run from the 'install.ps1' script.
|
|
|
|
.PARAMETER Project
|
|
The Visual Studio project to update. When running in the NuGet install.ps1
|
|
script the '$project' variable provided as part of that script should be
|
|
used.
|
|
|
|
.PARAMETER TypeName
|
|
The assembly-qualified type name of the connection factory type that
|
|
implements the 'System.Data.Entity.Infrastructure.IDbConnectionFactory'
|
|
interface. For example, for the Microsoft SQL Server Express provider
|
|
connection factory, this type is
|
|
'System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework'.
|
|
|
|
.PARAMETER ConstructorArguments
|
|
An optional array of strings that will be passed as arguments to the
|
|
connection factory type constructor.
|
|
#>
|
|
function Add-EFDefaultConnectionFactory
|
|
{
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param(
|
|
[parameter(Position = 0, Mandatory = $true)]
|
|
$Project,
|
|
[parameter(Position = 1, Mandatory = $true)]
|
|
[string] $TypeName,
|
|
[string[]] $ConstructorArguments)
|
|
|
|
$configPath = GetConfigPath $Project
|
|
if (!$configPath)
|
|
{
|
|
return
|
|
}
|
|
|
|
[xml] $configXml = Get-Content $configPath
|
|
|
|
$entityFramework = $configXml.configuration.entityFramework
|
|
$defaultConnectionFactory = $entityFramework.defaultConnectionFactory
|
|
if ($defaultConnectionFactory)
|
|
{
|
|
$entityFramework.RemoveChild($defaultConnectionFactory) | Out-Null
|
|
}
|
|
$defaultConnectionFactory = $entityFramework.AppendChild($configXml.CreateElement('defaultConnectionFactory'))
|
|
|
|
$defaultConnectionFactory.SetAttribute('type', $TypeName)
|
|
|
|
if ($ConstructorArguments)
|
|
{
|
|
$parameters = $defaultConnectionFactory.AppendChild($configXml.CreateElement('parameters'))
|
|
|
|
foreach ($constructorArgument in $ConstructorArguments)
|
|
{
|
|
$parameter = $parameters.AppendChild($configXml.CreateElement('parameter'))
|
|
$parameter.SetAttribute('value', $constructorArgument)
|
|
}
|
|
}
|
|
|
|
$configXml.Save($configPath)
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Enables Code First Migrations in a project.
|
|
|
|
.DESCRIPTION
|
|
Enables Migrations by scaffolding a migrations configuration class in the project. If the
|
|
target database was created by an initializer, an initial migration will be created (unless
|
|
automatic migrations are enabled via the EnableAutomaticMigrations parameter).
|
|
|
|
.PARAMETER ContextTypeName
|
|
Specifies the context to use. If omitted, migrations will attempt to locate a
|
|
single context type in the target project.
|
|
|
|
.PARAMETER EnableAutomaticMigrations
|
|
Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration.
|
|
If omitted, automatic migrations will be disabled.
|
|
|
|
.PARAMETER MigrationsDirectory
|
|
Specifies the name of the directory that will contain migrations code files.
|
|
If omitted, the directory will be named "Migrations".
|
|
|
|
.PARAMETER ProjectName
|
|
Specifies the project that the scaffolded migrations configuration class will
|
|
be added to. If omitted, the default project selected in package manager
|
|
console is used.
|
|
|
|
.PARAMETER StartUpProjectName
|
|
Specifies the configuration file to use for named connection strings. If
|
|
omitted, the specified project's configuration file is used.
|
|
|
|
.PARAMETER ContextProjectName
|
|
Specifies the project which contains the DbContext class to use. If omitted,
|
|
the context is assumed to be in the same project used for migrations.
|
|
|
|
.PARAMETER ConnectionStringName
|
|
Specifies the name of a connection string to use from the application's
|
|
configuration file.
|
|
|
|
.PARAMETER ConnectionString
|
|
Specifies the connection string to use. If omitted, the context's
|
|
default connection will be used.
|
|
|
|
.PARAMETER ConnectionProviderName
|
|
Specifies the provider invariant name of the connection string.
|
|
|
|
.PARAMETER Force
|
|
Specifies that the migrations configuration be overwritten when running more
|
|
than once for a given project.
|
|
|
|
.PARAMETER ContextAssemblyName
|
|
Specifies the name of the assembly which contains the DbContext class to use. Use this
|
|
parameter instead of ContextProjectName when the context is contained in a referenced
|
|
assembly rather than in a project of the solution.
|
|
|
|
.PARAMETER AppDomainBaseDirectory
|
|
Specifies the directory to use for the app-domain that is used for running Migrations
|
|
code such that the app-domain is able to find all required assemblies. This is an
|
|
advanced option that should only be needed if the solution contains several projects
|
|
such that the assemblies needed for the context and configuration are not all
|
|
referenced from either the project containing the context or the project containing
|
|
the migrations.
|
|
|
|
.EXAMPLE
|
|
Enable-Migrations
|
|
# Scaffold a migrations configuration in a project with only one context
|
|
|
|
.EXAMPLE
|
|
Enable-Migrations -Auto
|
|
# Scaffold a migrations configuration with automatic migrations enabled for a project
|
|
# with only one context
|
|
|
|
.EXAMPLE
|
|
Enable-Migrations -ContextTypeName MyContext -MigrationsDirectory DirectoryName
|
|
# Scaffold a migrations configuration for a project with multiple contexts
|
|
# This scaffolds a migrations configuration for MyContext and will put the configuration
|
|
# and subsequent configurations in a new directory called "DirectoryName"
|
|
|
|
#>
|
|
function Enable-Migrations
|
|
{
|
|
[CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
|
|
param(
|
|
[string] $ContextTypeName,
|
|
[alias('Auto')]
|
|
[switch] $EnableAutomaticMigrations,
|
|
[string] $MigrationsDirectory,
|
|
[string] $ProjectName,
|
|
[string] $StartUpProjectName,
|
|
[string] $ContextProjectName,
|
|
[parameter(ParameterSetName = 'ConnectionStringName')]
|
|
[string] $ConnectionStringName,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionString,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionProviderName,
|
|
[switch] $Force,
|
|
[string] $ContextAssemblyName,
|
|
[string] $AppDomainBaseDirectory)
|
|
|
|
WarnIfOtherEFs 'Enable-Migrations'
|
|
|
|
$project = GetProject $ProjectName
|
|
$startupProject = GetStartupProject $StartUpProjectName $project
|
|
|
|
if (!$ContextAssemblyName -and $ContextProjectName)
|
|
{
|
|
$contextProject = Get-Project $ContextProjectName
|
|
$ContextAssemblyName = GetProperty $contextProject.Properties 'AssemblyName'
|
|
}
|
|
|
|
$params = 'migrations', 'enable', '--json'
|
|
|
|
if ($ContextTypeName)
|
|
{
|
|
$params += '--context', $ContextTypeName
|
|
}
|
|
|
|
if ($ContextAssemblyName)
|
|
{
|
|
$params += '--context-assembly', $ContextAssemblyName
|
|
}
|
|
|
|
if ($EnableAutomaticMigrations)
|
|
{
|
|
$params += '--auto'
|
|
}
|
|
|
|
if ($MigrationsDirectory)
|
|
{
|
|
$params += '--migrations-dir', $MigrationsDirectory
|
|
}
|
|
|
|
$params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
|
|
|
|
if ($Force)
|
|
{
|
|
$params += '--force'
|
|
}
|
|
|
|
# NB: -join is here to support ConvertFrom-Json on PowerShell 3.0
|
|
$result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json
|
|
|
|
$project.ProjectItems.AddFromFile($result.migrationsConfiguration) | Out-Null
|
|
$DTE.ItemOperations.OpenFile($result.migrationsConfiguration) | Out-Null
|
|
ShowConsole
|
|
|
|
if ($result.migration)
|
|
{
|
|
$project.ProjectItems.AddFromFile($result.migration) | Out-Null
|
|
$resourcesProperties = $project.ProjectItems.AddFromFile($result.migrationResources).Properties
|
|
$project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null
|
|
|
|
# HACK: Work around microsoft/msbuild#4488
|
|
if ($resourcesProperties | where Name -eq 'DependentUpon')
|
|
{
|
|
$resourcesProperties.Item('DependentUpon').Value = [IO.Path]::GetFileName($result.migration)
|
|
}
|
|
}
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Scaffolds a migration script for any pending model changes.
|
|
|
|
.DESCRIPTION
|
|
Scaffolds a new migration script and adds it to the project.
|
|
|
|
.PARAMETER Name
|
|
Specifies the name of the custom script.
|
|
|
|
.PARAMETER Force
|
|
Specifies that the migration user code be overwritten when re-scaffolding an
|
|
existing migration.
|
|
|
|
.PARAMETER ProjectName
|
|
Specifies the project that contains the migration configuration type to be
|
|
used. If omitted, the default project selected in package manager console
|
|
is used.
|
|
|
|
.PARAMETER StartUpProjectName
|
|
Specifies the configuration file to use for named connection strings. If
|
|
omitted, the specified project's configuration file is used.
|
|
|
|
.PARAMETER ConfigurationTypeName
|
|
Specifies the migrations configuration to use. If omitted, migrations will
|
|
attempt to locate a single migrations configuration type in the target
|
|
project.
|
|
|
|
.PARAMETER ConnectionStringName
|
|
Specifies the name of a connection string to use from the application's
|
|
configuration file.
|
|
|
|
.PARAMETER ConnectionString
|
|
Specifies the connection string to use. If omitted, the context's
|
|
default connection will be used.
|
|
|
|
.PARAMETER ConnectionProviderName
|
|
Specifies the provider invariant name of the connection string.
|
|
|
|
.PARAMETER IgnoreChanges
|
|
Scaffolds an empty migration ignoring any pending changes detected in the current model.
|
|
This can be used to create an initial, empty migration to enable Migrations for an existing
|
|
database. N.B. Doing this assumes that the target database schema is compatible with the
|
|
current model.
|
|
|
|
.PARAMETER AppDomainBaseDirectory
|
|
Specifies the directory to use for the app-domain that is used for running Migrations
|
|
code such that the app-domain is able to find all required assemblies. This is an
|
|
advanced option that should only be needed if the solution contains several projects
|
|
such that the assemblies needed for the context and configuration are not all
|
|
referenced from either the project containing the context or the project containing
|
|
the migrations.
|
|
|
|
.EXAMPLE
|
|
Add-Migration First
|
|
# Scaffold a new migration named "First"
|
|
|
|
.EXAMPLE
|
|
Add-Migration First -IgnoreChanges
|
|
# Scaffold an empty migration ignoring any pending changes detected in the current model.
|
|
# This can be used to create an initial, empty migration to enable Migrations for an existing
|
|
# database. N.B. Doing this assumes that the target database schema is compatible with the
|
|
# current model.
|
|
|
|
#>
|
|
function Add-Migration
|
|
{
|
|
[CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
|
|
param(
|
|
[parameter(Position = 0, Mandatory = $true)]
|
|
[string] $Name,
|
|
[switch] $Force,
|
|
[string] $ProjectName,
|
|
[string] $StartUpProjectName,
|
|
[string] $ConfigurationTypeName,
|
|
[parameter(ParameterSetName = 'ConnectionStringName')]
|
|
[string] $ConnectionStringName,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionString,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionProviderName,
|
|
[switch] $IgnoreChanges,
|
|
[string] $AppDomainBaseDirectory)
|
|
|
|
WarnIfOtherEFs 'Add-Migration'
|
|
|
|
$project = GetProject $ProjectName
|
|
$startupProject = GetStartupProject $StartUpProjectName $project
|
|
|
|
$params = 'migrations', 'add', $Name, '--json'
|
|
|
|
if ($Force)
|
|
{
|
|
$params += '--force'
|
|
}
|
|
|
|
if ($ConfigurationTypeName)
|
|
{
|
|
$params += '--migrations-config', $ConfigurationTypeName
|
|
}
|
|
|
|
if ($IgnoreChanges)
|
|
{
|
|
$params += '--ignore-changes'
|
|
}
|
|
|
|
$params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
|
|
|
|
# NB: -join is here to support ConvertFrom-Json on PowerShell 3.0
|
|
$result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json
|
|
|
|
$project.ProjectItems.AddFromFile($result.migration) | Out-Null
|
|
$DTE.ItemOperations.OpenFile($result.migration) | Out-Null
|
|
$resourcesProperties = $project.ProjectItems.AddFromFile($result.migrationResources).Properties
|
|
$project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null
|
|
|
|
# HACK: Work around microsoft/msbuild#4488
|
|
if ($resourcesProperties | where Name -eq 'DependentUpon')
|
|
{
|
|
$resourcesProperties.Item('DependentUpon').Value = [IO.Path]::GetFileName($result.migration)
|
|
}
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Applies any pending migrations to the database.
|
|
|
|
.DESCRIPTION
|
|
Updates the database to the current model by applying pending migrations.
|
|
|
|
.PARAMETER SourceMigration
|
|
Only valid with -Script. Specifies the name of a particular migration to use
|
|
as the update's starting point. If omitted, the last applied migration in
|
|
the database will be used.
|
|
|
|
.PARAMETER TargetMigration
|
|
Specifies the name of a particular migration to update the database to. If
|
|
omitted, the current model will be used.
|
|
|
|
.PARAMETER Script
|
|
Generate a SQL script rather than executing the pending changes directly.
|
|
|
|
.PARAMETER Force
|
|
Specifies that data loss is acceptable during automatic migration of the
|
|
database.
|
|
|
|
.PARAMETER ProjectName
|
|
Specifies the project that contains the migration configuration type to be
|
|
used. If omitted, the default project selected in package manager console
|
|
is used.
|
|
|
|
.PARAMETER StartUpProjectName
|
|
Specifies the configuration file to use for named connection strings. If
|
|
omitted, the specified project's configuration file is used.
|
|
|
|
.PARAMETER ConfigurationTypeName
|
|
Specifies the migrations configuration to use. If omitted, migrations will
|
|
attempt to locate a single migrations configuration type in the target
|
|
project.
|
|
|
|
.PARAMETER ConnectionStringName
|
|
Specifies the name of a connection string to use from the application's
|
|
configuration file.
|
|
|
|
.PARAMETER ConnectionString
|
|
Specifies the connection string to use. If omitted, the context's
|
|
default connection will be used.
|
|
|
|
.PARAMETER ConnectionProviderName
|
|
Specifies the provider invariant name of the connection string.
|
|
|
|
.PARAMETER AppDomainBaseDirectory
|
|
Specifies the directory to use for the app-domain that is used for running Migrations
|
|
code such that the app-domain is able to find all required assemblies. This is an
|
|
advanced option that should only be needed if the solution contains several projects
|
|
such that the assemblies needed for the context and configuration are not all
|
|
referenced from either the project containing the context or the project containing
|
|
the migrations.
|
|
|
|
.EXAMPLE
|
|
Update-Database
|
|
# Update the database to the latest migration
|
|
|
|
.EXAMPLE
|
|
Update-Database -TargetMigration Second
|
|
# Update database to a migration named "Second"
|
|
# This will apply migrations if the target hasn't been applied or roll back migrations
|
|
# if it has
|
|
|
|
.EXAMPLE
|
|
Update-Database -Script
|
|
# Generate a script to update the database from its current state to the latest migration
|
|
|
|
.EXAMPLE
|
|
Update-Database -Script -SourceMigration Second -TargetMigration First
|
|
# Generate a script to migrate the database from a specified start migration
|
|
# named "Second" to a specified target migration named "First"
|
|
|
|
.EXAMPLE
|
|
Update-Database -Script -SourceMigration $InitialDatabase
|
|
# Generate a script that can upgrade a database currently at any version to the latest version.
|
|
# The generated script includes logic to check the __MigrationsHistory table and only apply changes
|
|
# that haven't been previously applied.
|
|
|
|
.EXAMPLE
|
|
Update-Database -TargetMigration $InitialDatabase
|
|
# Runs the Down method to roll-back any migrations that have been applied to the database
|
|
|
|
|
|
#>
|
|
function Update-Database
|
|
{
|
|
[CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
|
|
param(
|
|
[string] $SourceMigration,
|
|
[string] $TargetMigration,
|
|
[switch] $Script,
|
|
[switch] $Force,
|
|
[string] $ProjectName,
|
|
[string] $StartUpProjectName,
|
|
[string] $ConfigurationTypeName,
|
|
[parameter(ParameterSetName = 'ConnectionStringName')]
|
|
[string] $ConnectionStringName,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionString,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionProviderName,
|
|
[string] $AppDomainBaseDirectory)
|
|
|
|
WarnIfOtherEFs 'Update-Database'
|
|
|
|
$project = GetProject $ProjectName
|
|
$startupProject = GetStartupProject $StartUpProjectName $project
|
|
|
|
$params = 'database', 'update'
|
|
|
|
if ($SourceMigration)
|
|
{
|
|
$params += '--source', $SourceMigration
|
|
}
|
|
|
|
if ($TargetMigration)
|
|
{
|
|
$params += '--target', $TargetMigration
|
|
}
|
|
|
|
if ($Script)
|
|
{
|
|
$params += '--script'
|
|
}
|
|
|
|
if ($Force)
|
|
{
|
|
$params += '--force'
|
|
}
|
|
|
|
$params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
|
|
|
|
$result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n"
|
|
if ($result)
|
|
{
|
|
try
|
|
{
|
|
$window = $DTE.ItemOperations.NewFile('General\Sql File')
|
|
$textDocument = $window.Document.Object('TextDocument')
|
|
$editPoint = $textDocument.StartPoint.CreateEditPoint()
|
|
$editPoint.Insert($result)
|
|
}
|
|
catch
|
|
{
|
|
$intermediatePath = GetIntermediatePath $project
|
|
if (![IO.Path]::IsPathRooted($intermediatePath))
|
|
{
|
|
$projectDir = GetProperty $project.Properties 'FullPath'
|
|
$intermediatePath = Join-Path $projectDir $intermediatePath -Resolve | Convert-Path
|
|
}
|
|
|
|
$fileName = [IO.Path]::ChangeExtension([IO.Path]::GetRandomFileName(), '.sql')
|
|
$sqlFile = Join-Path $intermediatePath $fileName
|
|
|
|
[IO.File]::WriteAllText($sqlFile, $result)
|
|
|
|
$DTE.ItemOperations.OpenFile($sqlFile) | Out-Null
|
|
}
|
|
|
|
ShowConsole
|
|
}
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Displays the migrations that have been applied to the target database.
|
|
|
|
.DESCRIPTION
|
|
Displays the migrations that have been applied to the target database.
|
|
|
|
.PARAMETER ProjectName
|
|
Specifies the project that contains the migration configuration type to be
|
|
used. If omitted, the default project selected in package manager console
|
|
is used.
|
|
|
|
.PARAMETER StartUpProjectName
|
|
Specifies the configuration file to use for named connection strings. If
|
|
omitted, the specified project's configuration file is used.
|
|
|
|
.PARAMETER ConfigurationTypeName
|
|
Specifies the migrations configuration to use. If omitted, migrations will
|
|
attempt to locate a single migrations configuration type in the target
|
|
project.
|
|
|
|
.PARAMETER ConnectionStringName
|
|
Specifies the name of a connection string to use from the application's
|
|
configuration file.
|
|
|
|
.PARAMETER ConnectionString
|
|
Specifies the connection string to use. If omitted, the context's
|
|
default connection will be used.
|
|
|
|
.PARAMETER ConnectionProviderName
|
|
Specifies the provider invariant name of the connection string.
|
|
|
|
.PARAMETER AppDomainBaseDirectory
|
|
Specifies the directory to use for the app-domain that is used for running Migrations
|
|
code such that the app-domain is able to find all required assemblies. This is an
|
|
advanced option that should only be needed if the solution contains several projects
|
|
such that the assemblies needed for the context and configuration are not all
|
|
referenced from either the project containing the context or the project containing
|
|
the migrations.
|
|
#>
|
|
function Get-Migrations
|
|
{
|
|
[CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
|
|
param(
|
|
[string] $ProjectName,
|
|
[string] $StartUpProjectName,
|
|
[string] $ConfigurationTypeName,
|
|
[parameter(ParameterSetName = 'ConnectionStringName')]
|
|
[string] $ConnectionStringName,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionString,
|
|
[parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
|
|
[string] $ConnectionProviderName,
|
|
[string] $AppDomainBaseDirectory)
|
|
|
|
WarnIfOtherEFs 'Get-Migrations'
|
|
|
|
$project = GetProject $ProjectName
|
|
$startupProject = GetStartupProject $StartUpProjectName $project
|
|
|
|
$params = 'migrations', 'list'
|
|
|
|
if ($ConfigurationTypeName)
|
|
{
|
|
$params += '--migrations-config', $ConfigurationTypeName
|
|
}
|
|
|
|
$params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
|
|
|
|
return EF6 $project $startupProject $AppDomainBaseDirectory $params
|
|
}
|
|
|
|
function WarnIfOtherEFs($cmdlet)
|
|
{
|
|
if (Get-Module 'EntityFrameworkCore')
|
|
{
|
|
Write-Warning "Both Entity Framework 6 and Entity Framework Core are installed. The Entity Framework 6 tools are running. Use 'EntityFrameworkCore\$cmdlet' for Entity Framework Core."
|
|
}
|
|
|
|
if (Get-Module 'EntityFramework')
|
|
{
|
|
Write-Warning "A version of Entity Framework older than 6.3 is also installed. The newer tools are running. Use 'EntityFramework\$cmdlet' for the older version."
|
|
}
|
|
}
|
|
|
|
function GetProject($projectName)
|
|
{
|
|
if (!$projectName)
|
|
{
|
|
return Get-Project
|
|
}
|
|
|
|
return Get-Project $projectName
|
|
}
|
|
|
|
function GetStartupProject($name, $fallbackProject)
|
|
{
|
|
if ($name)
|
|
{
|
|
return Get-Project $name
|
|
}
|
|
|
|
$startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects
|
|
if ($startupProjectPaths)
|
|
{
|
|
if ($startupProjectPaths.Length -eq 1)
|
|
{
|
|
$startupProjectPath = $startupProjectPaths[0]
|
|
if (![IO.Path]::IsPathRooted($startupProjectPath))
|
|
{
|
|
$solutionPath = Split-Path (GetProperty $DTE.Solution.Properties 'Path')
|
|
$startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve | Convert-Path
|
|
}
|
|
|
|
$startupProject = GetSolutionProjects |
|
|
?{
|
|
try
|
|
{
|
|
$fullName = $_.FullName
|
|
}
|
|
catch [NotImplementedException]
|
|
{
|
|
return $false
|
|
}
|
|
|
|
if ($fullName -and $fullName.EndsWith('\'))
|
|
{
|
|
$fullName = $fullName.Substring(0, $fullName.Length - 1)
|
|
}
|
|
|
|
return $fullName -eq $startupProjectPath
|
|
}
|
|
if ($startupProject)
|
|
{
|
|
return $startupProject
|
|
}
|
|
|
|
Write-Warning "Unable to resolve startup project '$startupProjectPath'."
|
|
}
|
|
else
|
|
{
|
|
Write-Warning 'Multiple startup projects set.'
|
|
}
|
|
}
|
|
else
|
|
{
|
|
Write-Warning 'No startup project set.'
|
|
}
|
|
|
|
Write-Warning "Using project '$($fallbackProject.ProjectName)' as the startup project."
|
|
|
|
return $fallbackProject
|
|
}
|
|
|
|
function GetSolutionProjects()
|
|
{
|
|
$projects = New-Object 'System.Collections.Stack'
|
|
|
|
$DTE.Solution.Projects |
|
|
%{ $projects.Push($_) }
|
|
|
|
while ($projects.Count)
|
|
{
|
|
$project = $projects.Pop();
|
|
|
|
<# yield return #> $project
|
|
|
|
if ($project.ProjectItems)
|
|
{
|
|
$project.ProjectItems |
|
|
?{ $_.SubProject } |
|
|
%{ $projects.Push($_.SubProject) }
|
|
}
|
|
}
|
|
}
|
|
|
|
function GetParams($connectionStringName, $connectionString, $connectionProviderName)
|
|
{
|
|
$params = @()
|
|
|
|
if ($connectionStringName)
|
|
{
|
|
$params += '--connection-string-name', $connectionStringName
|
|
}
|
|
|
|
if ($connectionString)
|
|
{
|
|
$params += '--connection-string', $connectionString,
|
|
'--connection-provider', $connectionProviderName
|
|
}
|
|
|
|
return $params
|
|
}
|
|
|
|
function ShowConsole
|
|
{
|
|
$componentModel = Get-VSComponentModel
|
|
$powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
|
|
$powerConsoleWindow.Show()
|
|
}
|
|
|
|
function WriteErrorLine($message)
|
|
{
|
|
try
|
|
{
|
|
# Call the internal API NuGet uses to display errors
|
|
$componentModel = Get-VSComponentModel
|
|
$powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
|
|
$bindingFlags = [Reflection.BindingFlags]::Instance -bor [Reflection.BindingFlags]::NonPublic
|
|
$activeHostInfo = $powerConsoleWindow.GetType().GetProperty('ActiveHostInfo', $bindingFlags).GetValue($powerConsoleWindow)
|
|
$internalHost = $activeHostInfo.WpfConsole.Host
|
|
$reportErrorMethod = $internalHost.GetType().GetMethod('ReportError', $bindingFlags, $null, [Exception], $null)
|
|
$exception = New-Object Exception $message
|
|
$reportErrorMethod.Invoke($internalHost, $exception)
|
|
}
|
|
catch
|
|
{
|
|
Write-Host $message -ForegroundColor DarkRed
|
|
}
|
|
}
|
|
|
|
function EF6($project, $startupProject, $workingDir, $params)
|
|
{
|
|
$solutionBuild = $DTE.Solution.SolutionBuild
|
|
$solutionBuild.BuildProject(
|
|
$solutionBuild.ActiveConfiguration.Name,
|
|
$project.UniqueName,
|
|
<# WaitForBuildToFinish #> $true)
|
|
if ($solutionBuild.LastBuildInfo)
|
|
{
|
|
throw "The project '$($project.ProjectName)' failed to build."
|
|
}
|
|
|
|
$projectDir = GetProperty $project.Properties 'FullPath'
|
|
$outputPath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'OutputPath'
|
|
$targetDir = [IO.Path]::GetFullPath([IO.Path]::Combine($projectDir, $outputPath))
|
|
$targetFrameworkMoniker = GetProperty $project.Properties 'TargetFrameworkMoniker'
|
|
$frameworkName = New-Object 'System.Runtime.Versioning.FrameworkName' $targetFrameworkMoniker
|
|
$targetFrameworkIdentifier = $frameworkName.Identifier
|
|
$targetFrameworkVersion = $frameworkName.Version
|
|
|
|
if ($targetFrameworkIdentifier -in '.NETFramework')
|
|
{
|
|
if ($targetFrameworkVersion -lt '4.5')
|
|
{
|
|
$frameworkDir = 'net40'
|
|
}
|
|
else
|
|
{
|
|
$frameworkDir = 'net45'
|
|
}
|
|
|
|
$platformTarget = GetPlatformTarget $project
|
|
if ($platformTarget -eq 'x86')
|
|
{
|
|
$runtimeDir = 'win-x86'
|
|
}
|
|
elseif ($platformTarget -in 'AnyCPU', 'x64')
|
|
{
|
|
$runtimeDir = 'any'
|
|
}
|
|
else
|
|
{
|
|
throw "Project '$($project.ProjectName)' has an active platform of '$platformTarget'. Select a different " +
|
|
'platform and try again.'
|
|
}
|
|
|
|
$exePath = Join-Path $PSScriptRoot "$frameworkDir\$runtimeDir\ef6.exe"
|
|
}
|
|
elseif ($targetFrameworkIdentifier -eq '.NETCoreApp')
|
|
{
|
|
$exePath = (Get-Command 'dotnet').Path
|
|
|
|
$targetName = GetProperty $project.Properties 'AssemblyName'
|
|
$depsFile = Join-Path $targetDir ($targetName + '.deps.json')
|
|
$projectAssetsFile = GetCpsProperty $project 'ProjectAssetsFile'
|
|
$runtimeConfig = Join-Path $targetDir ($targetName + '.runtimeconfig.json')
|
|
$runtimeFrameworkVersion = GetCpsProperty $project 'RuntimeFrameworkVersion'
|
|
$efPath = Join-Path $PSScriptRoot 'netcoreapp3.0\any\ef6.dll'
|
|
|
|
$dotnetParams = 'exec', '--depsfile', $depsFile
|
|
|
|
if ($projectAssetsFile)
|
|
{
|
|
# NB: Don't use Get-Content. It doesn't handle UTF-8 without a signature
|
|
# NB: Don't use ReadAllLines. ConvertFrom-Json won't work on PowerShell 3.0
|
|
$projectAssets = [IO.File]::ReadAllText($projectAssetsFile) | ConvertFrom-Json
|
|
$projectAssets.packageFolders.psobject.Properties.Name |
|
|
%{ $dotnetParams += '--additionalprobingpath', $_.TrimEnd('\') }
|
|
}
|
|
|
|
if (Test-Path $runtimeConfig)
|
|
{
|
|
$dotnetParams += '--runtimeconfig', $runtimeConfig
|
|
}
|
|
elseif ($runtimeFrameworkVersion)
|
|
{
|
|
$dotnetParams += '--fx-version', $runtimeFrameworkVersion
|
|
}
|
|
|
|
$dotnetParams += $efPath
|
|
|
|
$params = $dotnetParams + $params
|
|
}
|
|
else
|
|
{
|
|
throw "Project '$($startupProject.ProjectName)' targets framework '$targetFrameworkIdentifier'. The Entity Framework " +
|
|
'Package Manager Console Tools don''t support this framework.'
|
|
}
|
|
|
|
$targetFileName = GetProperty $project.Properties 'OutputFileName'
|
|
$targetPath = Join-Path $targetDir $targetFileName
|
|
$rootNamespace = GetProperty $project.Properties 'RootNamespace'
|
|
$language = GetLanguage $project
|
|
|
|
$params += '--verbose',
|
|
'--no-color',
|
|
'--prefix-output',
|
|
'--assembly', $targetPath,
|
|
'--project-dir', $projectDir,
|
|
'--language', $language
|
|
|
|
if (IsWeb $startupProject)
|
|
{
|
|
$params += '--data-dir', (Join-Path $startupProjectDir 'App_Data')
|
|
}
|
|
|
|
if ($rootNamespace)
|
|
{
|
|
$params += '--root-namespace', $rootNamespace
|
|
}
|
|
|
|
$configFile = GetConfigPath $startupProject
|
|
if ($configFile)
|
|
{
|
|
$params += '--config', $configFile
|
|
}
|
|
|
|
if (!$workingDir)
|
|
{
|
|
$workingDir = $targetDir
|
|
}
|
|
|
|
$arguments = ToArguments $params
|
|
$startInfo = New-Object 'System.Diagnostics.ProcessStartInfo' -Property @{
|
|
FileName = $exePath;
|
|
Arguments = $arguments;
|
|
UseShellExecute = $false;
|
|
CreateNoWindow = $true;
|
|
RedirectStandardOutput = $true;
|
|
StandardOutputEncoding = [Text.Encoding]::UTF8;
|
|
RedirectStandardError = $true;
|
|
WorkingDirectory = $workingDir;
|
|
}
|
|
|
|
Write-Verbose "$exePath $arguments"
|
|
|
|
$process = [Diagnostics.Process]::Start($startInfo)
|
|
|
|
while (($line = $process.StandardOutput.ReadLine()) -ne $null)
|
|
{
|
|
$level = $null
|
|
$text = $null
|
|
|
|
$parts = $line.Split(':', 2)
|
|
if ($parts.Length -eq 2)
|
|
{
|
|
$level = $parts[0]
|
|
|
|
$i = 0
|
|
$count = 8 - $level.Length
|
|
while ($i -lt $count -and $parts[1][$i] -eq ' ')
|
|
{
|
|
$i++
|
|
}
|
|
|
|
$text = $parts[1].Substring($i)
|
|
}
|
|
|
|
switch ($level)
|
|
{
|
|
'error' { WriteErrorLine $text }
|
|
'warn' { Write-Warning $text }
|
|
'info' { Write-Host $text }
|
|
'data' { Write-Output $text }
|
|
'verbose' { Write-Verbose $text }
|
|
default { Write-Host $line }
|
|
}
|
|
}
|
|
|
|
$process.WaitForExit()
|
|
|
|
if ($process.ExitCode)
|
|
{
|
|
while (($line = $process.StandardError.ReadLine()) -ne $null)
|
|
{
|
|
WriteErrorLine $line
|
|
}
|
|
|
|
exit
|
|
}
|
|
}
|
|
|
|
function IsCpsProject($project)
|
|
{
|
|
$hierarchy = GetVsHierarchy $project
|
|
$isCapabilityMatch = [Microsoft.VisualStudio.Shell.PackageUtilities].GetMethod(
|
|
'IsCapabilityMatch',
|
|
[type[]]([Microsoft.VisualStudio.Shell.Interop.IVsHierarchy], [string]))
|
|
|
|
return $isCapabilityMatch.Invoke($null, ($hierarchy, 'CPS'))
|
|
}
|
|
|
|
function IsWeb($project)
|
|
{
|
|
$hierarchy = GetVsHierarchy $project
|
|
|
|
$aggregatableProject = Get-Interface $hierarchy 'Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject'
|
|
if (!$aggregatableProject)
|
|
{
|
|
$projectTypes = $project.Kind
|
|
}
|
|
else
|
|
{
|
|
$projectTypeGuids = $null
|
|
$hr = $aggregatableProject.GetAggregateProjectTypeGuids([ref] $projectTypeGuids)
|
|
[Runtime.InteropServices.Marshal]::ThrowExceptionForHR($hr)
|
|
|
|
$projectTypes = $projectTypeGuids.Split(';')
|
|
}
|
|
|
|
foreach ($projectType in $projectTypes)
|
|
{
|
|
if ($projectType -in '{349C5851-65DF-11DA-9384-00065B846F21}', '{E24C65DC-7377-472B-9ABA-BC803B73C61A}')
|
|
{
|
|
return $true
|
|
}
|
|
}
|
|
|
|
return $false;
|
|
}
|
|
|
|
function GetIntermediatePath($project)
|
|
{
|
|
$intermediatePath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'IntermediatePath'
|
|
if ($intermediatePath)
|
|
{
|
|
return $intermediatePath
|
|
}
|
|
|
|
return GetMSBuildProperty $project 'IntermediateOutputPath'
|
|
}
|
|
|
|
function GetPlatformTarget($project)
|
|
{
|
|
if (IsCpsProject $project)
|
|
{
|
|
$platformTarget = GetCpsProperty $project 'PlatformTarget'
|
|
if ($platformTarget)
|
|
{
|
|
return $platformTarget
|
|
}
|
|
|
|
return GetCpsProperty $project 'Platform'
|
|
}
|
|
|
|
$platformTarget = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'PlatformTarget'
|
|
if ($platformTarget)
|
|
{
|
|
return $platformTarget
|
|
}
|
|
|
|
# NB: For classic F# projects
|
|
$platformTarget = GetMSBuildProperty $project 'PlatformTarget'
|
|
if ($platformTarget)
|
|
{
|
|
return $platformTarget
|
|
}
|
|
|
|
return 'AnyCPU'
|
|
}
|
|
|
|
function GetLanguage($project)
|
|
{
|
|
if (IsCpsProject $project)
|
|
{
|
|
return GetCpsProperty $project 'Language'
|
|
}
|
|
|
|
return GetMSBuildProperty $project 'Language'
|
|
}
|
|
|
|
function GetVsHierarchy($project)
|
|
{
|
|
$solution = Get-VSService 'Microsoft.VisualStudio.Shell.Interop.SVsSolution' 'Microsoft.VisualStudio.Shell.Interop.IVsSolution'
|
|
$hierarchy = $null
|
|
$hr = $solution.GetProjectOfUniqueName($project.UniqueName, [ref] $hierarchy)
|
|
[Runtime.InteropServices.Marshal]::ThrowExceptionForHR($hr)
|
|
|
|
return $hierarchy
|
|
}
|
|
|
|
function GetProperty($properties, $propertyName)
|
|
{
|
|
try
|
|
{
|
|
return $properties.Item($propertyName).Value
|
|
}
|
|
catch
|
|
{
|
|
return $null
|
|
}
|
|
}
|
|
|
|
function GetCpsProperty($project, $propertyName)
|
|
{
|
|
$browseObjectContext = Get-Interface $project 'Microsoft.VisualStudio.ProjectSystem.Properties.IVsBrowseObjectContext'
|
|
$unconfiguredProject = $browseObjectContext.UnconfiguredProject
|
|
$configuredProject = $unconfiguredProject.GetSuggestedConfiguredProjectAsync().Result
|
|
$properties = $configuredProject.Services.ProjectPropertiesProvider.GetCommonProperties()
|
|
|
|
return $properties.GetEvaluatedPropertyValueAsync($propertyName).Result
|
|
}
|
|
|
|
function GetMSBuildProperty($project, $propertyName)
|
|
{
|
|
$msbuildProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.LoadedProjects |
|
|
where FullPath -eq $project.FullName
|
|
|
|
return $msbuildProject.GetProperty($propertyName).EvaluatedValue
|
|
}
|
|
|
|
function ToArguments($params)
|
|
{
|
|
$arguments = ''
|
|
for ($i = 0; $i -lt $params.Length; $i++)
|
|
{
|
|
if ($i)
|
|
{
|
|
$arguments += ' '
|
|
}
|
|
|
|
if (!$params[$i].Contains(' '))
|
|
{
|
|
$arguments += $params[$i]
|
|
|
|
continue
|
|
}
|
|
|
|
$arguments += '"'
|
|
|
|
$pendingBackslashs = 0
|
|
for ($j = 0; $j -lt $params[$i].Length; $j++)
|
|
{
|
|
switch ($params[$i][$j])
|
|
{
|
|
'"'
|
|
{
|
|
if ($pendingBackslashs)
|
|
{
|
|
$arguments += '\' * $pendingBackslashs * 2
|
|
$pendingBackslashs = 0
|
|
}
|
|
$arguments += '\"'
|
|
}
|
|
|
|
'\'
|
|
{
|
|
$pendingBackslashs++
|
|
}
|
|
|
|
default
|
|
{
|
|
if ($pendingBackslashs)
|
|
{
|
|
if ($pendingBackslashs -eq 1)
|
|
{
|
|
$arguments += '\'
|
|
}
|
|
else
|
|
{
|
|
$arguments += '\' * $pendingBackslashs * 2
|
|
}
|
|
|
|
$pendingBackslashs = 0
|
|
}
|
|
|
|
$arguments += $params[$i][$j]
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($pendingBackslashs)
|
|
{
|
|
$arguments += '\' * $pendingBackslashs * 2
|
|
}
|
|
|
|
$arguments += '"'
|
|
}
|
|
|
|
return $arguments
|
|
}
|
|
|
|
function GetConfigPath($project)
|
|
{
|
|
if (IsWeb $project)
|
|
{
|
|
$configFileName = 'web.config'
|
|
}
|
|
else
|
|
{
|
|
$configFileName = 'app.config'
|
|
}
|
|
|
|
$item = $project.ProjectItems |
|
|
where Name -eq $configFileName |
|
|
select -First 1
|
|
|
|
return GetProperty $item.Properties 'FullPath'
|
|
}
|
|
|
|
Export-ModuleMember -Variable 'InitialDatabase'
|
|
|
|
# SIG # Begin signature block
|
|
# MIIjhgYJKoZIhvcNAQcCoIIjdzCCI3MCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDgSjm+qfmtWpch
|
|
# q515gzepwOPcGyrbRJYJGojeH8cRUKCCDYEwggX/MIID56ADAgECAhMzAAABUZ6N
|
|
# j0Bxow5BAAAAAAFRMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
|
# bmcgUENBIDIwMTEwHhcNMTkwNTAyMjEzNzQ2WhcNMjAwNTAyMjEzNzQ2WjB0MQsw
|
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
|
|
# AQCVWsaGaUcdNB7xVcNmdfZiVBhYFGcn8KMqxgNIvOZWNH9JYQLuhHhmJ5RWISy1
|
|
# oey3zTuxqLbkHAdmbeU8NFMo49Pv71MgIS9IG/EtqwOH7upan+lIq6NOcw5fO6Os
|
|
# +12R0Q28MzGn+3y7F2mKDnopVu0sEufy453gxz16M8bAw4+QXuv7+fR9WzRJ2CpU
|
|
# 62wQKYiFQMfew6Vh5fuPoXloN3k6+Qlz7zgcT4YRmxzx7jMVpP/uvK6sZcBxQ3Wg
|
|
# B/WkyXHgxaY19IAzLq2QiPiX2YryiR5EsYBq35BP7U15DlZtpSs2wIYTkkDBxhPJ
|
|
# IDJgowZu5GyhHdqrst3OjkSRAgMBAAGjggF+MIIBejAfBgNVHSUEGDAWBgorBgEE
|
|
# AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUV4Iarkq57esagu6FUBb270Zijc8w
|
|
# UAYDVR0RBEkwR6RFMEMxKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1
|
|
# ZXJ0byBSaWNvMRYwFAYDVQQFEw0yMzAwMTIrNDU0MTM1MB8GA1UdIwQYMBaAFEhu
|
|
# ZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEswSaBHoEWGQ2h0dHA6Ly93d3cu
|
|
# bWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0NvZFNpZ1BDQTIwMTFfMjAxMS0w
|
|
# Ny0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsGAQUFBzAChkVodHRwOi8vd3d3
|
|
# Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY0NvZFNpZ1BDQTIwMTFfMjAx
|
|
# MS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAgEAWg+A
|
|
# rS4Anq7KrogslIQnoMHSXUPr/RqOIhJX+32ObuY3MFvdlRElbSsSJxrRy/OCCZdS
|
|
# se+f2AqQ+F/2aYwBDmUQbeMB8n0pYLZnOPifqe78RBH2fVZsvXxyfizbHubWWoUf
|
|
# NW/FJlZlLXwJmF3BoL8E2p09K3hagwz/otcKtQ1+Q4+DaOYXWleqJrJUsnHs9UiL
|
|
# crVF0leL/Q1V5bshob2OTlZq0qzSdrMDLWdhyrUOxnZ+ojZ7UdTY4VnCuogbZ9Zs
|
|
# 9syJbg7ZUS9SVgYkowRsWv5jV4lbqTD+tG4FzhOwcRQwdb6A8zp2Nnd+s7VdCuYF
|
|
# sGgI41ucD8oxVfcAMjF9YX5N2s4mltkqnUe3/htVrnxKKDAwSYliaux2L7gKw+bD
|
|
# 1kEZ/5ozLRnJ3jjDkomTrPctokY/KaZ1qub0NUnmOKH+3xUK/plWJK8BOQYuU7gK
|
|
# YH7Yy9WSKNlP7pKj6i417+3Na/frInjnBkKRCJ/eYTvBH+s5guezpfQWtU4bNo/j
|
|
# 8Qw2vpTQ9w7flhH78Rmwd319+YTmhv7TcxDbWlyteaj4RK2wk3pY1oSz2JPE5PNu
|
|
# Nmd9Gmf6oePZgy7Ii9JLLq8SnULV7b+IP0UXRY9q+GdRjM2AEX6msZvvPCIoG0aY
|
|
# HQu9wZsKEK2jqvWi8/xdeeeSI9FN6K1w4oVQM4Mwggd6MIIFYqADAgECAgphDpDS
|
|
# AAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMK
|
|
# V2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0
|
|
# IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0
|
|
# ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5MDlaFw0yNjA3MDgyMTA5MDla
|
|
# MH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
|
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMT
|
|
# H01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTEwggIiMA0GCSqGSIb3DQEB
|
|
# AQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQTTS68rZYIZ9CGypr6VpQqrgG
|
|
# OBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULTiQ15ZId+lGAkbK+eSZzpaF7S
|
|
# 35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYSL+erCFDPs0S3XdjELgN1q2jz
|
|
# y23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494HDdVceaVJKecNvqATd76UPe/7
|
|
# 4ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZPrGMXeiJT4Qa8qEvWeSQOy2u
|
|
# M1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5bmR/U7qcD60ZI4TL9LoDho33
|
|
# X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGSrhwjp6lm7GEfauEoSZ1fiOIl
|
|
# XdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADhvKwCgl/bwBWzvRvUVUvnOaEP
|
|
# 6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON7E1JMKerjt/sW5+v/N2wZuLB
|
|
# l4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xcv3coKPHtbcMojyyPQDdPweGF
|
|
# RInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqwiBfenk70lrC8RqBsmNLg1oiM
|
|
# CwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFEhuZOVQ
|
|
# BdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1Ud
|
|
# DwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFHItOgIxkEO5FAVO
|
|
# 4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwubWljcm9zb2Z0
|
|
# LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
|
|
# Mi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUFBzAChkJodHRwOi8vd3d3Lm1p
|
|
# Y3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0NlckF1dDIwMTFfMjAxMV8wM18y
|
|
# Mi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGCNy4DMIGDMD8GCCsGAQUFBwIB
|
|
# FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2RvY3MvcHJpbWFyeWNw
|
|
# cy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBsAF8AcABvAGwAaQBjAHkA
|
|
# XwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcNAQELBQADggIBAGfyhqWY
|
|
# 4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4sPvjDctFtg/6+P+gKyju/R6mj
|
|
# 82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKLUtCw/WvjPgcuKZvmPRul1LUd
|
|
# d5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7pKkFDJvtaPpoLpWgKj8qa1hJ
|
|
# Yx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft0N3zDq+ZKJeYTQ49C/IIidYf
|
|
# wzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4MnEnGn+x9Cf43iw6IGmYslmJ
|
|
# aG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxvFX1Fp3blQCplo8NdUmKGwx1j
|
|
# NpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG0QaxdR8UvmFhtfDcxhsEvt9B
|
|
# xw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf0AApxbGbpT9Fdx41xtKiop96
|
|
# eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkYS//WsyNodeav+vyL6wuA6mk7
|
|
# r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrvQQqxP/uozKRdwaGIm1dxVk5I
|
|
# RcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIVWzCCFVcCAQEwgZUwfjELMAkG
|
|
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
|
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
|
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAVGejY9AcaMOQQAAAAABUTAN
|
|
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
|
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgERQHNml5
|
|
# mtQUi6SQgaszv2wr+ANZuCz8/qCL7nawlQowQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
|
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
|
# BgkqhkiG9w0BAQEFAASCAQCIFpGpG5X0LIaz5SBdL16/N54fTcIYKtGuvyePTXRD
|
|
# V1Fv9UiFJP2svuAImkKfuva1/GuAqr/89KZxPi08SU+A0zdLQ7MhJlMm+zPvJOGY
|
|
# UHupa8M2L9ngxDy9RJvOOf204gy1XId77VM9qd9U/rLRa9byqwlq+r7NOEs0tR1H
|
|
# oA2I/YbHLky6GZpxyN0XVzIvgoMDu0SQELctDfQejJyarCzMZ1rtEPvmlXO7A/NP
|
|
# qX8erbtbXBYq5CTbquXFpFPr01BI0sXliUkBj+W9RhLwfGVaSBNF/BCH9fU8rXUR
|
|
# 1VVmvy3+poQgnFJclVhhHbWmfl5m+S7BI9OEwfteL4yzoYIS5TCCEuEGCisGAQQB
|
|
# gjcDAwExghLRMIISzQYJKoZIhvcNAQcCoIISvjCCEroCAQMxDzANBglghkgBZQME
|
|
# AgEFADCCAVEGCyqGSIb3DQEJEAEEoIIBQASCATwwggE4AgEBBgorBgEEAYRZCgMB
|
|
# MDEwDQYJYIZIAWUDBAIBBQAEIPcsVEN+KEJgWioufj4B5FnI7az9M3/JCA1/bCku
|
|
# AqFvAgZdXXMC+gMYEzIwMTkwOTE0MTg1MTE1LjY4OFowBIACAfSggdCkgc0wgcox
|
|
# CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
|
|
# b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1p
|
|
# Y3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJjAkBgNVBAsTHVRoYWxlcyBUU1Mg
|
|
# RVNOOkQyQ0QtRTMxMC00QUYxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFt
|
|
# cCBTZXJ2aWNloIIOPDCCBPEwggPZoAMCAQICEzMAAAD50wuyGQEawS0AAAAAAPkw
|
|
# DQYJKoZIhvcNAQELBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
|
|
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
|
|
# dGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcN
|
|
# MTgxMDI0MjExNDI5WhcNMjAwMTEwMjExNDI5WjCByjELMAkGA1UEBhMCVVMxEzAR
|
|
# BgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1p
|
|
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMcTWljcm9zb2Z0IEFtZXJpY2Eg
|
|
# T3BlcmF0aW9uczEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046RDJDRC1FMzEwLTRB
|
|
# RjExJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2UwggEiMA0G
|
|
# CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCt59F4TCmZKO+nf9KZzXldT5atdJrY
|
|
# iuhdzE5RC7muoZivL76FktWLcjQ1Xm1ui1SP1SoUJWUSh8lMrchRiWAJGRu5QYuq
|
|
# BevvfEW8iK/FNdzu1vnsI5cxbAsoPBqwSj3uHMB6Rhyovtl5PgoP5VgYqk96YjN6
|
|
# YalSDzdzSd1xxWxpHGlA65AFLGQzFenPOe2o6j76a4oEnKzz4Eb/x2HNs6iHQzVP
|
|
# Lk/aC0o1AQa3sBffwJpDfhYtNbwgpxelGUMB10SbplA6nv0QvE0NghJ5XxqnRsy2
|
|
# tmIDzA/Cn93w+KmnrEZAgq+ohYCGr2K8GGMKo+S9NK+ArH4C5Ty7nEihAgMBAAGj
|
|
# ggEbMIIBFzAdBgNVHQ4EFgQUjqrRSwYsKtZankFP0Ps+k/omwQMwHwYDVR0jBBgw
|
|
# FoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDov
|
|
# L2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljVGltU3RhUENB
|
|
# XzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0
|
|
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNUaW1TdGFQQ0FfMjAx
|
|
# MC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUEDDAKBggrBgEFBQcDCDAN
|
|
# BgkqhkiG9w0BAQsFAAOCAQEAZaab7pU7m87N51+4T01FEClXKBTmLwCiheul3+pz
|
|
# ESwe53SUs3eHN9dFrPP+Ob7Djb+hycKXzl1lTpjt9nRKUnAV+NyRfZheGDr4unjy
|
|
# lEQqYN6uZNCSzzLChwOM4jLx4fbT4K8ywUKIfTfPWj8W/iY6Ne3mtamqlZJj+Dek
|
|
# uAgUdUSAV0GbhDu+qdBwz9afJOhjTBtKj6fvxmm+4jalZK6UsSFx2zF1aQ23t/ED
|
|
# 8dAruTO/sJEJ0en25AuNzH7Jh4uulNWboCyC4D56caGyRggk82IpxiN31+ZVLy4a
|
|
# zZu//8QkWfHqFhfZa0qd2VaFuZU43PHQ+IUh8KCOD3XbSTCCBnEwggRZoAMCAQIC
|
|
# CmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYD
|
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRp
|
|
# ZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIx
|
|
# NDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV
|
|
# BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQG
|
|
# A1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3
|
|
# DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF
|
|
# ++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRD
|
|
# DNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSx
|
|
# z5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1
|
|
# rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16Hgc
|
|
# sOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB
|
|
# 4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqF
|
|
# bVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1Ud
|
|
# EwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYD
|
|
# VR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwv
|
|
# cHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEB
|
|
# BE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9j
|
|
# ZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCB
|
|
# kjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jv
|
|
# c29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQe
|
|
# MiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQA
|
|
# LiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUx
|
|
# vs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GAS
|
|
# inbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1
|
|
# L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWO
|
|
# M7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4
|
|
# pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45
|
|
# V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x
|
|
# 4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEe
|
|
# gPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKn
|
|
# QqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp
|
|
# 3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvT
|
|
# X4/edIhJEqGCAs4wggI3AgEBMIH4oYHQpIHNMIHKMQswCQYDVQQGEwJVUzETMBEG
|
|
# A1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWlj
|
|
# cm9zb2Z0IENvcnBvcmF0aW9uMSUwIwYDVQQLExxNaWNyb3NvZnQgQW1lcmljYSBP
|
|
# cGVyYXRpb25zMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVTTjpEMkNELUUzMTAtNEFG
|
|
# MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZaIjCgEBMAcG
|
|
# BSsOAwIaAxUAAcpZPW4AjkLiMFhLNU9zK8DF0j2ggYMwgYCkfjB8MQswCQYDVQQG
|
|
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
|
|
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
|
|
# VGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQUFAAIFAOEnlSEwIhgPMjAx
|
|
# OTA5MTUwMDM0NDFaGA8yMDE5MDkxNjAwMzQ0MVowdzA9BgorBgEEAYRZCgQBMS8w
|
|
# LTAKAgUA4SeVIQIBADAKAgEAAgIuzAIB/zAHAgEAAgIReTAKAgUA4SjmoQIBADA2
|
|
# BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAowCAIBAAIDB6EgoQowCAIB
|
|
# AAIDAYagMA0GCSqGSIb3DQEBBQUAA4GBAIXOGAXtOaEQvINYQS2tioDoFNPO0NMu
|
|
# HBjSwAFFKioNdVoVfqGv19OsNGRgPUElRnzdnoOnySw0CbHmX3lqHANZuboN0y/M
|
|
# gl9QWlEQnJ2Pl9WnP+6K8GOOzEh+F9jQF7P/TMNTWmYmfjj2SYrGOi9HB8Y/L4A9
|
|
# r9XdDeInbDHWMYIDDTCCAwkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT
|
|
# Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m
|
|
# dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB
|
|
# IDIwMTACEzMAAAD50wuyGQEawS0AAAAAAPkwDQYJYIZIAWUDBAIBBQCgggFKMBoG
|
|
# CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQg39zryf7F
|
|
# aVBdWnnIbGEZWbi60e1O3UgAP8hp//0hR3wwgfoGCyqGSIb3DQEJEAIvMYHqMIHn
|
|
# MIHkMIG9BCDGo1l2ns8rTUBUtkpPBW84mPUiyjetMQ7CK9tk7lz93zCBmDCBgKR+
|
|
# MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
|
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT
|
|
# HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAA+dMLshkBGsEtAAAA
|
|
# AAD5MCIEIHtoGhjIHviJGud+neD+RZgeIHyd0zb4/Ljj0tsO4a8XMA0GCSqGSIb3
|
|
# DQEBCwUABIIBAANcc/Q113PQpcRbrMe9VmHS97O0wsQRYTMCCegLnOOaqlHUKi8R
|
|
# EStji8Dt9t2yyQ8ctL96+qPCvSrLI6I8h5QgML8Ty9EL8BX0e4I38cHJMSvJqU1+
|
|
# UK/uT8Wpo4B/2FqZbzIu0/UGm9ETbHgdIACvZBGd29l12TSIg6mhoebxHRNj1KiF
|
|
# V9ZTb5nGr+wtoZIjNc9BeFPjY11OAyNAZLKIvW2SWSRcyK2Ujlcn2ZimmdqH+r+5
|
|
# keoC7psDV9zcnYbLnD4X0fazbDYRLMt0uwm8/lehxdAZ2my+59aL6logAYeFscBL
|
|
# IQ10UxBMj9upqR62mwXw3gH+gEQUUWip7kg=
|
|
# SIG # End signature block
|