1407 lines
53 KiB
PowerShell
Executable File
1407 lines
53 KiB
PowerShell
Executable File
# 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
|
|
}
|
|
}
|
|
|
|
<#
|
|
.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
|
|
}
|
|
|
|
<#
|
|
.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'
|
|
}
|
|
|
|
if ($ConfigurationTypeName)
|
|
{
|
|
$params += '--migrations-config', $ConfigurationTypeName
|
|
}
|
|
|
|
$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)
|
|
{
|
|
$startupProjectDir = GetProperty $startupProject.Properties 'FullPath'
|
|
$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 'Add-EFDefaultConnectionFactory', 'Add-EFProvider', 'Add-Migration', 'Enable-Migrations', 'Get-Migrations', 'Update-Database' -Variable 'InitialDatabase'
|
|
|
|
# SIG # Begin signature block
|
|
# MIIkWAYJKoZIhvcNAQcCoIIkSTCCJEUCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBU8UKKdFAqCZNi
|
|
# qPoRSiuscSg+YrZwC3TMOd7p8fuNZKCCDYEwggX/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/BvW1taslScxMNelDNMYIWLTCCFikCAQEwgZUwfjELMAkG
|
|
# A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
|
|
# HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEoMCYGA1UEAxMfTWljcm9z
|
|
# b2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAAAVGejY9AcaMOQQAAAAABUTAN
|
|
# BglghkgBZQMEAgEFAKCBrjAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgor
|
|
# BgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg2WtigxAj
|
|
# Szfxqqdh6zz13s7WyYGwCYznISnC+usF34IwQgYKKwYBBAGCNwIBDDE0MDKgFIAS
|
|
# AE0AaQBjAHIAbwBzAG8AZgB0oRqAGGh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbTAN
|
|
# BgkqhkiG9w0BAQEFAASCAQA2S2sCreRpLI9W0DFWRPY7mNwItsQCQ+U3OmimoDrE
|
|
# Ar/bxo9hJMLm3DlzOFqO/8djKo3gvjL5pfhclUtkgPChpYWM+6aln/J7RIb3ZNjw
|
|
# 6lWic4QZRD0qYTVLit4i+I4Ew+CYjfmDJP7pwLppqWaqnF0T8qRk5TrzS0tQL/5p
|
|
# lxZzUZwGMkwwB9srwUwE+hy8tZS3H1BWbJ8mumlhi9X9cDF+nL3pOFFXVPM13zs8
|
|
# ZfvjqzlDPnOcRt2FW8kN3OloRa7bl4Lu6LEXbn8n+wbuyJKwwTCNCSU26RQesPQB
|
|
# uqTG0L7mjmZlJsF1Ga+gefD3PqbG+df7cXzSPDNR649DoYITtzCCE7MGCisGAQQB
|
|
# gjcDAwExghOjMIITnwYJKoZIhvcNAQcCoIITkDCCE4wCAQMxDzANBglghkgBZQME
|
|
# AgEFADCCAVgGCyqGSIb3DQEJEAEEoIIBRwSCAUMwggE/AgEBBgorBgEEAYRZCgMB
|
|
# MDEwDQYJYIZIAWUDBAIBBQAEINWdRiCiKsTCKKoWnNe7xytEww32lPP/4fMUMSuG
|
|
# nDHpAgZdrfQxYwgYEzIwMTkxMTE2MDQ1MjM5LjQ4OVowBwIBAYACAfSggdSkgdEw
|
|
# gc4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS
|
|
# ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsT
|
|
# IE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFs
|
|
# ZXMgVFNTIEVTTjo3RDJFLTM3ODItQjBGNzElMCMGA1UEAxMcTWljcm9zb2Z0IFRp
|
|
# bWUtU3RhbXAgU2VydmljZaCCDx8wggZxMIIEWaADAgECAgphCYEqAAAAAAACMA0G
|
|
# CSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3Rv
|
|
# bjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
|
|
# aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3Jp
|
|
# dHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0yNTA3MDEyMTQ2NTVaMHwxCzAJBgNV
|
|
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
|
|
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29m
|
|
# dCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
|
|
# CgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RUENWlCgCChfvtfGhLLF/Fw+Vhwna3
|
|
# PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBED/FgiIRUQwzXTbg4CLNC3ZOs1nMw
|
|
# VyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50YWeRX4FUsc+TTJLBxKZd0WETbijG
|
|
# GvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd/XcfPfBXday9ikJNQFHRD5wGPmd/
|
|
# 9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaRtogINeh4HLDpmc085y9Euqf03GS9
|
|
# pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQABo4IB5jCCAeIwEAYJKwYBBAGCNxUB
|
|
# BAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8RhvFM2hahW1VMBkGCSsGAQQBgjcU
|
|
# AgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8G
|
|
# A1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjEMFYGA1UdHwRPME0wS6BJoEeG
|
|
# RWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jv
|
|
# b0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUH
|
|
# MAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2Vy
|
|
# QXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSABAf8EgZUwgZIwgY8GCSsGAQQBgjcu
|
|
# AzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL1BLSS9k
|
|
# b2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEFBQcCAjA0HjIgHQBMAGUAZwBhAGwA
|
|
# XwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBtAGUAbgB0AC4gHTANBgkqhkiG9w0B
|
|
# AQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Ehb7Prpsz1Mb7PBeKp/vpXbRkws8LF
|
|
# Zslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7uVOMzPRgEop2zEBAQZvcXBf/XPle
|
|
# FzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqRUgCvOA8X9S95gWXZqbVr5MfO9sp6
|
|
# AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9Va8v/rbljjO7Yl+a21dA6fHOmWaQ
|
|
# jP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8+n99lmqQeKZt0uGc+R38ONiU9Mal
|
|
# CpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+Y1klD3ouOVd2onGqBooPiRa6YacR
|
|
# y5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh2rBQHm+98eEA3+cxB6STOvdlR3jo
|
|
# +KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRyzR30uIUBHoD7G4kqVDmyW9rIDVWZ
|
|
# eodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoouLGp25ayp0Kiyc8ZQU3ghvkqmqMR
|
|
# ZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx16HSxVXjad5XwdHeMMD9zOZN+w2/
|
|
# XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341Hgi62jbb01+P3nSISRIwggT1MIID
|
|
# 3aADAgECAhMzAAABACD3XJNW1XfQAAAAAAEAMA0GCSqGSIb3DQEBCwUAMHwxCzAJ
|
|
# BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
|
|
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jv
|
|
# c29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTE5MDkwNjIwNDEwOVoXDTIwMTIw
|
|
# NDIwNDEwOVowgc4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
|
|
# DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
|
|
# KTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYD
|
|
# VQQLEx1UaGFsZXMgVFNTIEVTTjo3RDJFLTM3ODItQjBGNzElMCMGA1UEAxMcTWlj
|
|
# cm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCCASIwDQYJKoZIhvcNAQEBBQADggEP
|
|
# ADCCAQoCggEBAMnIkckxDYWl2r86ny3RRNZPgnu8mFPweH7BDSkOhGLAQO58RqX3
|
|
# n1EH8/Z6vb3kIxVQfV9fBCv3klv1HenWK0QDRIjrgWeWA1liAVWYe+Ob1uyntMQn
|
|
# m224xp1Rev33lwbxZU+nDohaSyebrtSIfa56YgA2jYwutY+fs/GDSGRRJXeO5N1x
|
|
# NKe+JsVXXc0vm50L2pMlYIOnGslEDLZmxXrPl1c7GC2Dp/V+errggr5I93acDZTU
|
|
# oY0VaGRXpt2hUm824/ExFXaQILhL9DFlqgmiHvZXukoSRyTfklLVoI3vX+I6ZMcT
|
|
# ciD9K8Rdx6wbB51VgASO5cDnEhqb3E+eKdECAwEAAaOCARswggEXMB0GA1UdDgQW
|
|
# BBRoV5MnLIc6idXGditSix4avdXG1zAfBgNVHSMEGDAWgBTVYzpcijGQ80N7fEYb
|
|
# xTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVodHRwOi8vY3JsLm1pY3Jvc29mdC5j
|
|
# b20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcmww
|
|
# WgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAChj5odHRwOi8vd3d3Lm1pY3Jvc29m
|
|
# dC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBDQV8yMDEwLTA3LTAxLmNydDAMBgNV
|
|
# HRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUFBwMIMA0GCSqGSIb3DQEBCwUAA4IB
|
|
# AQCifptCMXyHpJghB7zNYXmFzlzpxLlmtFAkiBOdn99EnxrCJda/EZuTt9gJROel
|
|
# 99Iy3IUpX3y/5AIZTQHPqEISnCs9Y327HWMwkZtWNnp/PPv7V6eZhYgE5gsNwxKW
|
|
# eH8A5oI2m8Xa3wSDCOPHCEF9IvEHaeisGY3tlU9ZlQLnj9aeJS2JqusHfsyyUYQ6
|
|
# eX5ZQiONaTmYCwiC8oeF2QNhCKiEhb28vqpMj6HCDfL4u55u5cRME/d3YvRUgp4m
|
|
# 02gu7Jk97u9nig5+eGH56pk7J9pkNBlXGWMATawGLUyl1N+V0yY8muWHBoAS55Lo
|
|
# Z7Rzh4aBJoi2YH5snmzSWGskoYIDrTCCApUCAQEwgf6hgdSkgdEwgc4xCzAJBgNV
|
|
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
|
|
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAnBgNVBAsTIE1pY3Jvc29m
|
|
# dCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMSYwJAYDVQQLEx1UaGFsZXMgVFNTIEVT
|
|
# Tjo3RDJFLTM3ODItQjBGNzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg
|
|
# U2VydmljZaIlCgEBMAkGBSsOAwIaBQADFQA4Bx/wN9XcVHYBftuNY7yzHqGMxaCB
|
|
# 3jCB26SB2DCB1TELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO
|
|
# BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEp
|
|
# MCcGA1UECxMgTWljcm9zb2Z0IE9wZXJhdGlvbnMgUHVlcnRvIFJpY28xJzAlBgNV
|
|
# BAsTHm5DaXBoZXIgTlRTIEVTTjo0REU5LTBDNUUtM0UwOTErMCkGA1UEAxMiTWlj
|
|
# cm9zb2Z0IFRpbWUgU291cmNlIE1hc3RlciBDbG9jazANBgkqhkiG9w0BAQUFAAIF
|
|
# AOF5q+IwIhgPMjAxOTExMTUyMjU3MzhaGA8yMDE5MTExNjIyNTczOFowdDA6Bgor
|
|
# BgEEAYRZCgQBMSwwKjAKAgUA4Xmr4gIBADAHAgEAAgIhQDAHAgEAAgIbDTAKAgUA
|
|
# 4Xr9YgIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMBoAowCAIBAAID
|
|
# FuNgoQowCAIBAAIDB6EgMA0GCSqGSIb3DQEBBQUAA4IBAQBrXPxPFldZ3BGA7waF
|
|
# bdOirq8oCBtE81jJO2BENnEFaxjUsbxIvoYB8odfcRNw3RjGH607OK2rY5NyJSs7
|
|
# mx49lP0OSIQaUtm0JuIwBOD45+zpnBEHTjBce/ciO8K6olJ6Hs/iFowkrWoEgnas
|
|
# EfDafVrHqZDKn1l17MF3XkA/Wg8a15rFphDe0H90qcWjfQOK/G4lqFpGydhAqE22
|
|
# aOEkwHunN/sTYeFo0PK19RUQVu/Hm4mA+1zCElRa/gnWaCiT9NgTiS0JugfI16dn
|
|
# E18OSTAIUsOQk4SYH1O5BHLutWbtZvPv8mLcv9xwOpBqkhfYNZkyRE3FGFhyiWbg
|
|
# 3QU1MYIC9TCCAvECAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
|
|
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
|
|
# b3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAC
|
|
# EzMAAAEAIPdck1bVd9AAAAAAAQAwDQYJYIZIAWUDBAIBBQCgggEyMBoGCSqGSIb3
|
|
# DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgV6mhqFSGtTlYwL+6
|
|
# PsDgVLgoVSnoI8//MHa8YbducJAwgeIGCyqGSIb3DQEJEAIMMYHSMIHPMIHMMIGx
|
|
# BBQ4Bx/wN9XcVHYBftuNY7yzHqGMxTCBmDCBgKR+MHwxCzAJBgNVBAYTAlVTMRMw
|
|
# EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN
|
|
# aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0
|
|
# YW1wIFBDQSAyMDEwAhMzAAABACD3XJNW1XfQAAAAAAEAMBYEFIE7+LoOlImaaqB1
|
|
# i3tr5UrinFzPMA0GCSqGSIb3DQEBCwUABIIBADYOPGsSJ/BDYgITjyla3fi9ynH3
|
|
# oKVMHzzBT71kHErwNzS+D3soFP8ySkM21R78sbWG6VBVcsyQudlKj6PqwbREElpF
|
|
# xQti5m5XmEUzOaG4/MSnu3H1whoUBZWYvD1NQ+nATbqAGPtc0OqkJ+ULQtTs3lEr
|
|
# oCzeEKmHUbzc40JGs00A/nZtJbAj3qUxm7XUy4GepFAB5lEqOsvCRQdTyauTkqip
|
|
# S+nKvpjIv4N4SqViBeFseUKcHuQy4D6N5NKQK+nM5Jvlp2irax81/eCM7+/tCb6N
|
|
# aZa64XKo7HGgzKTD3PGd9w5RGGXLGtjYxKar0mLUlp+WVR9QUTnnP2crlH0=
|
|
# SIG # End signature block
|