955 lines
37 KiB
PowerShell
955 lines
37 KiB
PowerShell
$ErrorActionPreference = 'Stop'
|
|
|
|
$EFDefaultParameterValues = @{
|
|
ProjectName = ''
|
|
ContextTypeName = ''
|
|
}
|
|
|
|
#
|
|
# Use-DbContext
|
|
#
|
|
|
|
Register-TabExpansion Use-DbContext @{
|
|
Context = { param ($tabExpansionContext) GetContextTypes $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Project = { GetProjects }
|
|
StartupProject = { GetProjects }
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Sets the default DbContext to use.
|
|
|
|
.DESCRIPTION
|
|
Sets the default DbContext to use.
|
|
|
|
.PARAMETER Context
|
|
Specifies the DbContext to use.
|
|
|
|
.PARAMETER Project
|
|
Specifies the project to use. If omitted, the default project is used.
|
|
|
|
.PARAMETER StartupProject
|
|
Specifies the startup project to use. If omitted, the solution's startup project is used.
|
|
|
|
.PARAMETER Environment
|
|
Specifies the environment to use. If omitted, "Development" is used.
|
|
|
|
.LINK
|
|
about_EntityFramework
|
|
#>
|
|
function Use-DbContext {
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param ([Parameter(Position = 0, Mandatory = $true)] [string] $Context, [string] $Project, [string] $StartupProject, [string] $Environment)
|
|
|
|
$dteProject = GetProject $Project
|
|
$dteStartupProject = GetStartupProject $StartupProject $dteProject
|
|
$contextTypeName = InvokeOperation $dteStartupProject $Environment $dteProject GetContextType @{ name = $Context }
|
|
|
|
$EFDefaultParameterValues.ContextTypeName = $contextTypeName
|
|
$EFDefaultParameterValues.ProjectName = $dteProject.ProjectName
|
|
}
|
|
|
|
#
|
|
# Add-Migration
|
|
#
|
|
|
|
Register-TabExpansion Add-Migration @{
|
|
Context = { param ($tabExpansionContext) GetContextTypes $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Project = { GetProjects }
|
|
StartupProject = { GetProjects }
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Adds a new migration.
|
|
|
|
.DESCRIPTION
|
|
Adds a new migration.
|
|
|
|
.PARAMETER Name
|
|
Specifies the name of the migration.
|
|
|
|
.PARAMETER OutputDir
|
|
The directory (and sub-namespace) to use. If omitted, "Migrations" is used.
|
|
|
|
.PARAMETER Context
|
|
Specifies the DbContext to use. If omitted, the default DbContext is used.
|
|
|
|
.PARAMETER Project
|
|
Specifies the project to use. If omitted, the default project is used.
|
|
|
|
.PARAMETER StartupProject
|
|
Specifies the startup project to use. If omitted, the solution's startup project is used.
|
|
|
|
.PARAMETER Environment
|
|
Specifies the environment to use. If omitted, "Development" is used.
|
|
|
|
.LINK
|
|
Remove-Migration
|
|
Update-Database
|
|
about_EntityFramework
|
|
#>
|
|
function Add-Migration {
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param (
|
|
[Parameter(Position = 0, Mandatory = $true)]
|
|
[string] $Name,
|
|
[string] $OutputDir,
|
|
[string] $Context,
|
|
[string] $Project,
|
|
[string] $StartupProject,
|
|
[string] $Environment)
|
|
|
|
$values = ProcessCommonParameters $StartupProject $Project $Context
|
|
$dteStartupProject = $values.StartupProject
|
|
$dteProject = $values.Project
|
|
$contextTypeName = $values.ContextTypeName
|
|
|
|
$artifacts = InvokeOperation $dteStartupProject $Environment $dteProject AddMigration @{
|
|
name = $Name
|
|
outputDir = $OutputDir
|
|
contextType = $contextTypeName
|
|
}
|
|
|
|
$artifacts | %{ $dteProject.ProjectItems.AddFromFile($_) | Out-Null }
|
|
$DTE.ItemOperations.OpenFile($artifacts[0]) | Out-Null
|
|
ShowConsole
|
|
|
|
Write-Output 'To undo this action, use Remove-Migration.'
|
|
}
|
|
|
|
#
|
|
# Update-Database
|
|
#
|
|
|
|
Register-TabExpansion Update-Database @{
|
|
Migration = { param ($tabExpansionContext) GetMigrations $tabExpansionContext.Context $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Context = { param ($tabExpansionContext) GetContextTypes $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Project = { GetProjects }
|
|
StartupProject = { GetProjects }
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Updates the database to a specified migration.
|
|
|
|
.DESCRIPTION
|
|
Updates the database to a specified migration.
|
|
|
|
.PARAMETER Migration
|
|
Specifies the target migration. If '0', all migrations will be reverted. If omitted, all pending migrations will be applied.
|
|
|
|
.PARAMETER Context
|
|
Specifies the DbContext to use. If omitted, the default DbContext is used.
|
|
|
|
.PARAMETER Project
|
|
Specifies the project to use. If omitted, the default project is used.
|
|
|
|
.PARAMETER StartupProject
|
|
Specifies the startup project to use. If omitted, the solution's startup project is used.
|
|
|
|
.PARAMETER Environment
|
|
Specifies the environment to use. If omitted, "Development" is used.
|
|
|
|
.LINK
|
|
Script-Migration
|
|
about_EntityFramework
|
|
#>
|
|
function Update-Database {
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param (
|
|
[Parameter(Position = 0)]
|
|
[string] $Migration,
|
|
[string] $Context,
|
|
[string] $Project,
|
|
[string] $StartupProject,
|
|
[string] $Environment)
|
|
|
|
$values = ProcessCommonParameters $StartupProject $Project $Context
|
|
$dteStartupProject = $values.StartupProject
|
|
$dteProject = $values.Project
|
|
$contextTypeName = $values.ContextTypeName
|
|
|
|
$targetFrameworkMoniker = GetProperty $dteProject.Properties TargetFrameworkMoniker
|
|
$frameworkName = New-Object System.Runtime.Versioning.FrameworkName $targetFrameworkMoniker
|
|
if ($frameworkName.Identifier -eq '.NETCore') {
|
|
throw 'Update-Database should not be used with Universal Windows apps. Instead, call DbContext.Database.Migrate() at runtime.'
|
|
}
|
|
|
|
InvokeOperation $dteStartupProject $Environment $dteProject UpdateDatabase @{
|
|
targetMigration = $Migration
|
|
contextType = $contextTypeName
|
|
}
|
|
}
|
|
|
|
#
|
|
# Apply-Migration (Obsolete)
|
|
#
|
|
|
|
function Apply-Migration {
|
|
# TODO: Remove before RTM
|
|
throw 'Apply-Migration has been removed. Use Update-Database instead.'
|
|
}
|
|
|
|
#
|
|
# Script-Migration
|
|
#
|
|
|
|
Register-TabExpansion Script-Migration @{
|
|
From = { param ($tabExpansionContext) GetMigrations $tabExpansionContext.Context $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
To = { param ($tabExpansionContext) GetMigrations $tabExpansionContext.Context $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Context = { param ($tabExpansionContext) GetContextTypes $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Project = { GetProjects }
|
|
StartupProject = { GetProjects }
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Generates a SQL script from migrations.
|
|
|
|
.DESCRIPTION
|
|
Generates a SQL script from migrations.
|
|
|
|
.PARAMETER From
|
|
Specifies the starting migration. If omitted, '0' (the initial database) is used.
|
|
|
|
.PARAMETER To
|
|
Specifies the ending migration. If omitted, the last migration is used.
|
|
|
|
.PARAMETER Idempotent
|
|
Generates an idempotent script that can used on a database at any migration.
|
|
|
|
.PARAMETER Context
|
|
Specifies the DbContext to use. If omitted, the default DbContext is used.
|
|
|
|
.PARAMETER Project
|
|
Specifies the project to use. If omitted, the default project is used.
|
|
|
|
.PARAMETER StartupProject
|
|
Specifies the startup project to use. If omitted, the solution's startup project is used.
|
|
|
|
.PARAMETER Environment
|
|
Specifies the environment to use. If omitted, "Development" is used.
|
|
|
|
.LINK
|
|
Update-Database
|
|
about_EntityFramework
|
|
#>
|
|
function Script-Migration {
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param (
|
|
[Parameter(ParameterSetName = 'WithoutTo')]
|
|
[Parameter(ParameterSetName = 'WithTo', Mandatory = $true)]
|
|
[string] $From,
|
|
[Parameter(ParameterSetName = 'WithTo', Mandatory = $true)]
|
|
[string] $To,
|
|
[switch] $Idempotent,
|
|
[string] $Context,
|
|
[string] $Project,
|
|
[string] $StartupProject,
|
|
[string] $Environment)
|
|
|
|
$values = ProcessCommonParameters $StartupProject $Project $Context
|
|
$dteStartupProject = $values.StartupProject
|
|
$dteProject = $values.Project
|
|
$contextTypeName = $values.ContextTypeName
|
|
|
|
$script = InvokeOperation $dteStartupProject $Environment $dteProject ScriptMigration @{
|
|
fromMigration = $From
|
|
toMigration = $To
|
|
idempotent = [bool]$Idempotent
|
|
contextType = $contextTypeName
|
|
}
|
|
|
|
try {
|
|
# NOTE: Certain SKUs cannot create new SQL files
|
|
$window = $DTE.ItemOperations.NewFile('General\Sql File')
|
|
$textDocument = $window.Document.Object('TextDocument')
|
|
$editPoint = $textDocument.StartPoint.CreateEditPoint()
|
|
$editPoint.Insert($script)
|
|
}
|
|
catch {
|
|
$fullPath = GetProperty $dteProject.Properties FullPath
|
|
$intermediatePath = GetProperty $dteProject.ConfigurationManager.ActiveConfiguration.Properties IntermediatePath
|
|
$fullIntermediatePath = Join-Path $fullPath $intermediatePath
|
|
$fileName = [IO.Path]::GetRandomFileName()
|
|
$fileName = [IO.Path]::ChangeExtension($fileName, '.sql')
|
|
$scriptFile = Join-Path $fullIntermediatePath $fileName
|
|
$script | Out-File $scriptFile
|
|
$DTE.ItemOperations.OpenFile($scriptFile) | Out-Null
|
|
}
|
|
|
|
ShowConsole
|
|
}
|
|
|
|
#
|
|
# Remove-Migration
|
|
#
|
|
|
|
Register-TabExpansion Remove-Migration @{
|
|
Context = { param ($tabExpansionContext) GetContextTypes $tabExpansionContext.Project $tabExpansionContext.StartupProject $tabExpansionContext.Environment }
|
|
Project = { GetProjects }
|
|
StartupProject = { GetProjects }
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Removes the last migration.
|
|
|
|
.DESCRIPTION
|
|
Removes the last migration.
|
|
|
|
.PARAMETER Context
|
|
Specifies the DbContext to use. If omitted, the default DbContext is used.
|
|
|
|
.PARAMETER Project
|
|
Specifies the project to use. If omitted, the default project is used.
|
|
|
|
.PARAMETER StartupProject
|
|
Specifies the startup project to use. If omitted, the solution's startup project is used.
|
|
|
|
.PARAMETER Environment
|
|
Specifies the environment to use. If omitted, "Development" is used.
|
|
|
|
.LINK
|
|
Add-Migration
|
|
about_EntityFramework
|
|
#>
|
|
function Remove-Migration {
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param ([string] $Context, [string] $Project, [string] $StartupProject, [string] $Environment)
|
|
|
|
$values = ProcessCommonParameters $StartupProject $Project $Context
|
|
$dteProject = $values.Project
|
|
$contextTypeName = $values.ContextTypeName
|
|
$dteStartupProject = $values.StartupProject
|
|
|
|
$filesToRemove = InvokeOperation $dteStartupProject $Environment $dteProject RemoveMigration @{
|
|
contextType = $contextTypeName
|
|
}
|
|
|
|
$filesToRemove | %{
|
|
$projectItem = GetProjectItem $dteProject $_
|
|
if ($projectItem) {
|
|
$projectItem.Remove()
|
|
}
|
|
}
|
|
}
|
|
|
|
#
|
|
# Scaffold-DbContext
|
|
#
|
|
|
|
Register-TabExpansion Scaffold-DbContext @{
|
|
Provider = { param ($tabExpansionContext) GetProviders $tabExpansionContext.Project }
|
|
Project = { GetProjects }
|
|
StartupProject = { GetProjects }
|
|
}
|
|
|
|
<#
|
|
.SYNOPSIS
|
|
Scaffolds a DbContext and entity type classes for a specified database.
|
|
|
|
.DESCRIPTION
|
|
Scaffolds a DbContext and entity type classes for a specified database.
|
|
|
|
.PARAMETER Connection
|
|
Specifies the connection string of the database.
|
|
|
|
.PARAMETER Provider
|
|
Specifies the provider to use. For example, EntityFramework.MicrosoftSqlServer.
|
|
|
|
.PARAMETER OutputDirectory
|
|
Specifies the directory to use to output the classes. If omitted, the top-level project directory is used.
|
|
|
|
.PARAMETER Context
|
|
Specifies the name of the generated DbContext class.
|
|
|
|
.PARAMETER Schemas
|
|
Specifies the schemas for which to generate classes.
|
|
|
|
.PARAMETER Tables
|
|
Specifies the tables for which to generate classes.
|
|
|
|
.PARAMETER DataAnnotations
|
|
Use DataAnnotation attributes to configure the model where possible. If omitted, the output code will use only the fluent API.
|
|
|
|
.PARAMETER Project
|
|
Specifies the project to use. If omitted, the default project is used.
|
|
|
|
.PARAMETER StartupProject
|
|
Specifies the startup project to use. If omitted, the solution's startup project is used.
|
|
|
|
.PARAMETER Environment
|
|
Specifies the environment to use. If omitted, "Development" is used.
|
|
|
|
.LINK
|
|
about_EntityFramework
|
|
#>
|
|
function Scaffold-DbContext {
|
|
[CmdletBinding(PositionalBinding = $false)]
|
|
param (
|
|
[Parameter(Position = 0, Mandatory = $true)]
|
|
[string] $Connection,
|
|
[Parameter(Position = 1, Mandatory = $true)]
|
|
[string] $Provider,
|
|
[string] $OutputDirectory,
|
|
[string] $ContextClassName,
|
|
[string[]] $Schemas,
|
|
[string[]] $Tables,
|
|
[switch] $DataAnnotations,
|
|
[string] $Project,
|
|
[string] $StartupProject,
|
|
[string] $Environment)
|
|
|
|
$values = ProcessCommonParameters $StartupProject $Project
|
|
$dteStartupProject = $values.StartupProject
|
|
$dteProject = $values.Project
|
|
|
|
$artifacts = InvokeOperation $dteStartupProject $Environment $dteProject ReverseEngineer @{
|
|
connectionString = $Connection
|
|
provider = $Provider
|
|
outputDir = $OutputDirectory
|
|
dbContextClassName = $ContextClassName
|
|
schemaFilters = $Schemas
|
|
tableFilters = $Tables
|
|
useDataAnnotations = [bool]$DataAnnotations
|
|
}
|
|
|
|
$artifacts | %{ $dteProject.ProjectItems.AddFromFile($_) | Out-Null }
|
|
$DTE.ItemOperations.OpenFile($artifacts[0]) | Out-Null
|
|
ShowConsole
|
|
}
|
|
|
|
#
|
|
# Enable-Migrations (Obsolete)
|
|
#
|
|
|
|
function Enable-Migrations {
|
|
# TODO: Link to some docs on the changes to Migrations
|
|
Write-Warning 'Enable-Migrations is obsolete. Use Add-Migration to start using Migrations.'
|
|
}
|
|
|
|
#
|
|
# (Private Helpers)
|
|
#
|
|
|
|
function GetProjects {
|
|
$projects = Get-Project -All
|
|
$groups = $projects | group Name
|
|
|
|
return $projects | %{
|
|
if ($groups | ? Name -eq $_.Name | ? Count -eq 1) {
|
|
return $_.Name
|
|
}
|
|
|
|
return $_.ProjectName
|
|
}
|
|
}
|
|
|
|
function GetContextTypes($projectName, $startupProjectName, $environment) {
|
|
$values = ProcessCommonParameters $startupProjectName $projectName
|
|
$startupProject = $values.StartupProject
|
|
$project = $values.Project
|
|
|
|
$contextTypes = InvokeOperation $startupProject $environment $project GetContextTypes -skipBuild
|
|
|
|
return $contextTypes | %{ $_.SafeName }
|
|
}
|
|
|
|
function GetMigrations($contextTypeName, $projectName, $startupProjectName, $environment) {
|
|
$values = ProcessCommonParameters $startupProjectName $projectName $contextTypeName
|
|
$startupProject = $values.StartupProject
|
|
$project = $values.Project
|
|
$contextTypeName = $values.ContextTypeName
|
|
|
|
$migrations = InvokeOperation $startupProject $environment $project GetMigrations @{ contextTypeName = $contextTypeName } -skipBuild
|
|
|
|
return $migrations | %{ $_.SafeName }
|
|
}
|
|
|
|
function ProcessCommonParameters($startupProjectName, $projectName, $contextTypeName) {
|
|
$project = GetProject $projectName
|
|
|
|
if (!$contextTypeName -and $project.ProjectName -eq $EFDefaultParameterValues.ProjectName) {
|
|
$contextTypeName = $EFDefaultParameterValues.ContextTypeName
|
|
}
|
|
|
|
$startupProject = GetStartupProject $startupProjectName $project
|
|
|
|
return @{
|
|
Project = $project
|
|
ContextTypeName = $contextTypeName
|
|
StartupProject = $startupProject
|
|
}
|
|
}
|
|
|
|
function GetProject($projectName) {
|
|
if ($projectName) {
|
|
return Get-Project $projectName
|
|
}
|
|
|
|
return Get-Project
|
|
}
|
|
|
|
function ShowConsole {
|
|
$componentModel = Get-VSComponentModel
|
|
$powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
|
|
$powerConsoleWindow.Show()
|
|
}
|
|
|
|
function InvokeOperation($startupProject, $environment, $project, $operation, $arguments = @{}, [switch] $skipBuild) {
|
|
$startupProjectName = $startupProject.ProjectName
|
|
|
|
Write-Verbose "Using startup project '$startupProjectName'."
|
|
|
|
$projectName = $project.ProjectName
|
|
|
|
Write-Verbose "Using project '$projectName'"
|
|
|
|
$package = Get-Package -ProjectName $startupProjectName | ? Id -eq EntityFramework.Commands
|
|
if (!($package)) {
|
|
throw "Cannot execute this command because EntityFramework.Commands is not installed in the startup project '$startupProjectName'."
|
|
}
|
|
|
|
if (!$skipBuild) {
|
|
Write-Verbose 'Build started...'
|
|
|
|
# TODO: Only build required project. Don't use BuildProject, you can't specify platform
|
|
$solutionBuild = $DTE.Solution.SolutionBuild
|
|
$solutionBuild.Build($true)
|
|
if ($solutionBuild.LastBuildInfo) {
|
|
throw "Build failed."
|
|
}
|
|
|
|
Write-Verbose 'Build succeeded.'
|
|
}
|
|
|
|
if (![Type]::GetType('Microsoft.Data.Entity.Design.OperationResultHandler')) {
|
|
Add-Type -Path (Join-Path $PSScriptRoot OperationHandlers.cs) -CompilerParameters (
|
|
New-Object CodeDom.Compiler.CompilerParameters -Property @{
|
|
CompilerOptions = '/d:ENABLE_HANDLERS'
|
|
})
|
|
}
|
|
|
|
$logHandler = New-Object Microsoft.Data.Entity.Design.OperationLogHandler @(
|
|
{ param ($message) Write-Error $message }
|
|
{ param ($message) Write-Warning $message }
|
|
{ param ($message) Write-Host $message }
|
|
{ param ($message) Write-Verbose $message }
|
|
{ param ($message) Write-Debug $message }
|
|
)
|
|
|
|
$properties = $project.Properties
|
|
$fullPath = GetProperty $properties FullPath
|
|
|
|
$startupOutputPath = GetProperty $startupProject.ConfigurationManager.ActiveConfiguration.Properties OutputPath
|
|
$startupProperties = $startupProject.Properties
|
|
$startupFullPath = GetProperty $startupProperties FullPath
|
|
$startupTargetDir = Join-Path $startupFullPath $startupOutputPath
|
|
|
|
$webConfig = GetProjectItem $startupProject 'Web.Config'
|
|
$appConfig = GetProjectItem $startupProject 'App.Config'
|
|
|
|
if ($webConfig) {
|
|
$configurationFile = GetProperty $webConfig.Properties FullPath
|
|
$dataDirectory = Join-Path $startupFullPath 'App_Data'
|
|
}
|
|
elseif ($appConfig) {
|
|
$configurationFile = GetProperty $appConfig.Properties FullPath
|
|
}
|
|
|
|
Write-Verbose "Using application base '$startupTargetDir'."
|
|
|
|
$info = New-Object AppDomainSetup -Property @{
|
|
ApplicationBase = $startupTargetDir
|
|
ShadowCopyFiles = 'true'
|
|
}
|
|
|
|
if ($configurationFile) {
|
|
Write-Verbose "Using application configuration '$configurationFile'"
|
|
$info.ConfigurationFile = $configurationFile
|
|
}
|
|
else {
|
|
Write-Verbose 'No configuration file found.'
|
|
}
|
|
|
|
$domain = [AppDomain]::CreateDomain('EntityFrameworkDesignDomain', $null, $info)
|
|
if ($dataDirectory) {
|
|
Write-Verbose "Using data directory '$dataDirectory'"
|
|
$domain.SetData('DataDirectory', $dataDirectory)
|
|
}
|
|
try {
|
|
$commandsAssembly = 'EntityFramework.Commands'
|
|
$operationExecutorTypeName = 'Microsoft.Data.Entity.Design.OperationExecutor'
|
|
$targetAssemblyName = GetProperty $properties AssemblyName
|
|
$startupAssemblyName = GetProperty $startupProperties AssemblyName
|
|
$rootNamespace = GetProperty $properties RootNamespace
|
|
|
|
$executor = $domain.CreateInstanceAndUnwrap(
|
|
$commandsAssembly,
|
|
$operationExecutorTypeName,
|
|
$false,
|
|
0,
|
|
$null,
|
|
@(
|
|
[MarshalByRefObject]$logHandler,
|
|
@{
|
|
startupTargetName = $startupAssemblyName
|
|
targetName = $targetAssemblyName
|
|
environment = $environment
|
|
projectDir = $fullPath
|
|
rootNamespace = $rootNamespace
|
|
}
|
|
),
|
|
$null,
|
|
$null)
|
|
|
|
$resultHandler = New-Object Microsoft.Data.Entity.Design.OperationResultHandler
|
|
$currentDirectory = [IO.Directory]::GetCurrentDirectory()
|
|
|
|
Write-Verbose "Using current directory '$startupTargetDir'."
|
|
|
|
[IO.Directory]::SetCurrentDirectory($startupTargetDir)
|
|
try {
|
|
$domain.CreateInstance(
|
|
$commandsAssembly,
|
|
"$operationExecutorTypeName+$operation",
|
|
$false,
|
|
0,
|
|
$null,
|
|
($executor, [MarshalByRefObject]$resultHandler, $arguments),
|
|
$null,
|
|
$null) | Out-Null
|
|
}
|
|
finally {
|
|
[IO.Directory]::SetCurrentDirectory($currentDirectory)
|
|
}
|
|
}
|
|
finally {
|
|
[AppDomain]::Unload($domain)
|
|
}
|
|
|
|
if ($resultHandler.ErrorType) {
|
|
if ($resultHandler.ErrorType -eq 'Microsoft.Data.Entity.Design.OperationException') {
|
|
Write-Verbose $resultHandler.ErrorStackTrace
|
|
}
|
|
else {
|
|
Write-Host $resultHandler.ErrorStackTrace
|
|
}
|
|
|
|
throw $resultHandler.ErrorMessage
|
|
}
|
|
if ($resultHandler.HasResult) {
|
|
return $resultHandler.Result
|
|
}
|
|
}
|
|
|
|
function GetProperty($properties, $propertyName) {
|
|
$property = $properties.Item($propertyName)
|
|
if (!$property) {
|
|
return $null
|
|
}
|
|
|
|
return $property.Value
|
|
}
|
|
|
|
function GetProjectItem($project, $path) {
|
|
$fullPath = GetProperty $project.Properties FullPath
|
|
|
|
if (Split-Path $path -IsAbsolute) {
|
|
$path = $path.Substring($fullPath.Length)
|
|
}
|
|
|
|
$itemDirectory = (Split-Path $path -Parent)
|
|
|
|
$projectItems = $project.ProjectItems
|
|
if ($itemDirectory) {
|
|
$directories = $itemDirectory.Split('\')
|
|
$directories | %{
|
|
$projectItems = $projectItems.Item($_).ProjectItems
|
|
}
|
|
}
|
|
|
|
$itemName = Split-Path $path -Leaf
|
|
|
|
try {
|
|
return $projectItems.Item($itemName)
|
|
}
|
|
catch [Exception] {
|
|
}
|
|
|
|
return $null
|
|
}
|
|
|
|
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 (!(Split-Path -IsAbsolute $startupProjectPath)) {
|
|
$solutionPath = Split-Path (GetProperty $DTE.Solution.Properties Path)
|
|
$startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve
|
|
}
|
|
|
|
$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-Verbose 'More than one startup project found.'
|
|
}
|
|
}
|
|
else {
|
|
Write-Verbose 'No startup project found.'
|
|
}
|
|
|
|
return $fallbackProject
|
|
}
|
|
|
|
function GetSolutionProjects() {
|
|
$projects = New-Object System.Collections.Stack
|
|
|
|
$DTE.Solution.Projects | %{
|
|
$projects.Push($_)
|
|
}
|
|
|
|
while ($projects.Count -ne 0) {
|
|
$project = $projects.Pop();
|
|
|
|
# NOTE: This line is similar to doing a "yield return" in C#
|
|
$project
|
|
|
|
if ($project.ProjectItems) {
|
|
$project.ProjectItems | ?{ $_.SubProject } | %{
|
|
$projects.Push($_.SubProject)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
function GetProviders($projectName) {
|
|
if (!($projectName)) {
|
|
$projectName = (Get-Project).ProjectName
|
|
}
|
|
|
|
return Get-Package -ProjectName $projectName | select -ExpandProperty Id
|
|
}
|
|
|
|
|
|
# SIG # Begin signature block
|
|
# MIIkCAYJKoZIhvcNAQcCoIIj+TCCI/UCAQExDzANBglghkgBZQMEAgEFADB5Bgor
|
|
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
|
|
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBb+AHUwlUcC0P0
|
|
# KEW7krPhrAf1rCRDDgYuENfAzicT/aCCDZIwggYQMIID+KADAgECAhMzAAAAZEeE
|
|
# lIbbQRk4AAAAAABkMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
|
|
# VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
|
|
# b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
|
|
# bmcgUENBIDIwMTEwHhcNMTUxMDI4MjAzMTQ2WhcNMTcwMTI4MjAzMTQ2WjCBgzEL
|
|
# MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v
|
|
# bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q
|
|
# UjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0B
|
|
# AQEFAAOCAQ8AMIIBCgKCAQEAky7a2OY+mNkbD2RfTahYTRQ793qE/DwRMTrvicJK
|
|
# LUGlSF3dEp7vq2YoNNV9KlV7TE2K8sDxstNSFYu2swi4i1AL3X/7agmg3GcExPHf
|
|
# vHUYIEC+eCyZVt3u9S7dPkL5Wh8wrgEUirCCtVGg4m1l/vcYCo0wbU06p8XzNi3u
|
|
# XyygkgCxHEziy/f/JCV/14/A3ZduzrIXtsccRKckyn6B5uYxuRbZXT7RaO6+zUjQ
|
|
# hiyu3A4hwcCKw+4bk1kT9sY7gHIYiFP7q78wPqB3vVKIv3rY6LCTraEbjNR+phBQ
|
|
# EL7hyBxk+ocu+8RHZhbAhHs2r1+6hURsAg8t4LAOG6I+JQIDAQABo4IBfzCCAXsw
|
|
# HwYDVR0lBBgwFgYIKwYBBQUHAwMGCisGAQQBgjdMCAEwHQYDVR0OBBYEFFhWcQTw
|
|
# vbsz9YNozOeARvdXr9IiMFEGA1UdEQRKMEikRjBEMQ0wCwYDVQQLEwRNT1BSMTMw
|
|
# MQYDVQQFEyozMTY0Mis0OWU4YzNmMy0yMzU5LTQ3ZjYtYTNiZS02YzhjNDc1MWM0
|
|
# YjYwHwYDVR0jBBgwFoAUSG5k5VAF04KqFzc3IrVtqMp1ApUwVAYDVR0fBE0wSzBJ
|
|
# oEegRYZDaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljQ29k
|
|
# U2lnUENBMjAxMV8yMDExLTA3LTA4LmNybDBhBggrBgEFBQcBAQRVMFMwUQYIKwYB
|
|
# BQUHMAKGRWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj
|
|
# Q29kU2lnUENBMjAxMV8yMDExLTA3LTA4LmNydDAMBgNVHRMBAf8EAjAAMA0GCSqG
|
|
# SIb3DQEBCwUAA4ICAQCI4gxkQx3dXK6MO4UktZ1A1r1mrFtXNdn06DrARZkQTdu0
|
|
# kOTLdlGBCfCzk0309RLkvUgnFKpvLddrg9TGp3n80yUbRsp2AogyrlBU+gP5ggHF
|
|
# i7NjGEpj5bH+FDsMw9PygLg8JelgsvBVudw1SgUt625nY7w1vrwk+cDd58TvAyJQ
|
|
# FAW1zJ+0ySgB9lu2vwg0NKetOyL7dxe3KoRLaztUcqXoYW5CkI+Mv3m8HOeqlhyf
|
|
# FTYxPB5YXyQJPKQJYh8zC9b90JXLT7raM7mQ94ygDuFmlaiZ+QSUR3XVupdEngrm
|
|
# ZgUB5jX13M+Pl2Vv7PPFU3xlo3Uhj1wtupNC81epoxGhJ0tRuLdEajD/dCZ0xIni
|
|
# esRXCKSC4HCL3BMnSwVXtIoj/QFymFYwD5+sAZuvRSgkKyD1rDA7MPcEI2i/Bh5O
|
|
# MAo9App4sR0Gp049oSkXNhvRi/au7QG6NJBTSBbNBGJG8Qp+5QThKoQUk8mj0ugr
|
|
# 4yWRsA9JTbmqVw7u9suB5OKYBMUN4hL/yI+aFVsE/KJInvnxSzXJ1YHka45ADYMK
|
|
# AMl+fLdIqm3nx6rIN0RkoDAbvTAAXGehUCsIod049A1T3IJyUJXt3OsTd3WabhIB
|
|
# XICYfxMg10naaWcyUePgW3+VwP0XLKu4O1+8ZeGyaDSi33GnzmmyYacX3BTqMDCC
|
|
# B3owggVioAMCAQICCmEOkNIAAAAAAAMwDQYJKoZIhvcNAQELBQAwgYgxCzAJBgNV
|
|
# BAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4w
|
|
# HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29m
|
|
# dCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDExMB4XDTExMDcwODIwNTkw
|
|
# OVoXDTI2MDcwODIxMDkwOVowfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hp
|
|
# bmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jw
|
|
# b3JhdGlvbjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAx
|
|
# MTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAKvw+nIQHC6t2G6qghBN
|
|
# NLrytlghn0IbKmvpWlCquAY4GgRJun/DDB7dN2vGEtgL8DjCmQawyDnVARQxQtOJ
|
|
# DXlkh36UYCRsr55JnOloXtLfm1OyCizDr9mpK656Ca/XllnKYBoF6WZ26DJSJhIv
|
|
# 56sIUM+zRLdd2MQuA3WraPPLbfM6XKEW9Ea64DhkrG5kNXimoGMPLdNAk/jj3gcN
|
|
# 1Vx5pUkp5w2+oBN3vpQ97/vjK1oQH01WKKJ6cuASOrdJXtjt7UORg9l7snuGG9k+
|
|
# sYxd6IlPhBryoS9Z5JA7La4zWMW3Pv4y07MDPbGyr5I4ftKdgCz1TlaRITUlwzlu
|
|
# ZH9TupwPrRkjhMv0ugOGjfdf8NBSv4yUh7zAIXQlXxgotswnKDglmDlKNs98sZKu
|
|
# HCOnqWbsYR9q4ShJnV+I4iVd0yFLPlLEtVc/JAPw0XpbL9Uj43BdD1FGd7P4AOG8
|
|
# rAKCX9vAFbO9G9RVS+c5oQ/pI0m8GLhEfEXkwcNyeuBy5yTfv0aZxe/CHFfbg43s
|
|
# TUkwp6uO3+xbn6/83bBm4sGXgXvt1u1L50kppxMopqd9Z4DmimJ4X7IvhNdXnFy/
|
|
# dygo8e1twyiPLI9AN0/B4YVEicQJTMXUpUMvdJX3bvh4IFgsE11glZo+TzOE2rCI
|
|
# F96eTvSWsLxGoGyY0uDWiIwLAgMBAAGjggHtMIIB6TAQBgkrBgEEAYI3FQEEAwIB
|
|
# ADAdBgNVHQ4EFgQUSG5k5VAF04KqFzc3IrVtqMp1ApUwGQYJKwYBBAGCNxQCBAwe
|
|
# CgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j
|
|
# BBgwFoAUci06AjGQQ7kUBU7h6qfHMdEjiTQwWgYDVR0fBFMwUTBPoE2gS4ZJaHR0
|
|
# cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2Vy
|
|
# QXV0MjAxMV8yMDExXzAzXzIyLmNybDBeBggrBgEFBQcBAQRSMFAwTgYIKwYBBQUH
|
|
# MAKGQmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljUm9vQ2Vy
|
|
# QXV0MjAxMV8yMDExXzAzXzIyLmNydDCBnwYDVR0gBIGXMIGUMIGRBgkrBgEEAYI3
|
|
# LgMwgYMwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lv
|
|
# cHMvZG9jcy9wcmltYXJ5Y3BzLmh0bTBABggrBgEFBQcCAjA0HjIgHQBMAGUAZwBh
|
|
# AGwAXwBwAG8AbABpAGMAeQBfAHMAdABhAHQAZQBtAGUAbgB0AC4gHTANBgkqhkiG
|
|
# 9w0BAQsFAAOCAgEAZ/KGpZjgVHkaLtPYdGcimwuWEeFjkplCln3SeQyQwWVfLiw+
|
|
# +MNy0W2D/r4/6ArKO79HqaPzadtjvyI1pZddZYSQfYtGUFXYDJJ80hpLHPM8QotS
|
|
# 0LD9a+M+By4pm+Y9G6XUtR13lDni6WTJRD14eiPzE32mkHSDjfTLJgJGKsKKELuk
|
|
# qQUMm+1o+mgulaAqPyprWEljHwlpblqYluSD9MCP80Yr3vw70L01724lruWvJ+3Q
|
|
# 3fMOr5kol5hNDj0L8giJ1h/DMhji8MUtzluetEk5CsYKwsatruWy2dsViFFFWDgy
|
|
# cScaf7H0J/jeLDogaZiyWYlobm+nt3TDQAUGpgEqKD6CPxNNZgvAs0314Y9/HG8V
|
|
# fUWnduVAKmWjw11SYobDHWM2l4bf2vP48hahmifhzaWX0O5dY0HjWwechz4GdwbR
|
|
# BrF1HxS+YWG18NzGGwS+30HHDiju3mUv7Jf2oVyW2ADWoUa9WfOXpQlLSBCZgB/Q
|
|
# ACnFsZulP0V3HjXG0qKin3p6IvpIlR+r+0cjgPWe+L9rt0uX4ut1eBrs6jeZeRhL
|
|
# /9azI2h15q/6/IvrC4DqaTuv/DDtBEyO3991bWORPdGdVk5Pv4BXIqF4ETIheu9B
|
|
# CrE/+6jMpF3BoYibV3FWTkhFwELJm3ZbCoBIa/15n8G9bW1qyVJzEw16UM0xghXM
|
|
# MIIVyAIBATCBlTB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQ
|
|
# MA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
|
|
# MSgwJgYDVQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExAhMzAAAA
|
|
# ZEeElIbbQRk4AAAAAABkMA0GCWCGSAFlAwQCAQUAoIG6MBkGCSqGSIb3DQEJAzEM
|
|
# BgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAMBgorBgEEAYI3AgEVMC8GCSqG
|
|
# SIb3DQEJBDEiBCANVv19l8rn4c1QuRlGPJQ3b4ubzgxowZjqY7YfFyLeEDBOBgor
|
|
# BgEEAYI3AgEMMUAwPqAkgCIATQBpAGMAcgBvAHMAbwBmAHQAIABBAFMAUAAuAE4A
|
|
# RQBUoRaAFGh0dHA6Ly93d3cuYXNwLm5ldC8gMA0GCSqGSIb3DQEBAQUABIIBAD7/
|
|
# xK5eHMaXbVfA7waWvQkzx5olLN5kYFnPyDrL20LnF5B3sXT2Ln7LsYotNYRJWiE/
|
|
# /DmdioFvnp6dfx12wxEGSK9pPIyaJJHtz8bH/6EoTp0igFOfTqOH3AHK4uQe9JfQ
|
|
# 6ONr7aYoF6kfzOq133WCgNJ/wU0pKva0S8ZxbzhnektaHO2ufsF+Ls1VID8/5Rvs
|
|
# laS0BeEpLqxlLgPqKu4r8qmruTghY5fwLGu3rlg+GuG+8QdWSRN1cTfHgSJ13iiX
|
|
# Vgah/8aAAXjrrbh8PV7nJEwNtZkCgDvawIZJfypSxpE08Y5VrdQ8KSQKJm4tckj+
|
|
# kL8ZgGhsAIm/bSWpxoehghNKMIITRgYKKwYBBAGCNwMDATGCEzYwghMyBgkqhkiG
|
|
# 9w0BBwKgghMjMIITHwIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBPAYLKoZIhvcNAQkQ
|
|
# AQSgggErBIIBJzCCASMCAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQg
|
|
# ECS/t9aSzk2D6TdYMWhFaIHuvFSJcL8SQbM7GUBrIjsCBlYqdFSZDxgTMjAxNTEx
|
|
# MTcwMDAyMTYuMTA1WjAHAgEBgAIB9KCBuKSBtTCBsjELMAkGA1UEBhMCVVMxEzAR
|
|
# BgNVBAgTCldhc2hpbmd0b24xDzANBgNVBAcTBlJlZG1vZDEeMBwGA1UEChMVTWlj
|
|
# cm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRNT1BSMScwJQYDVQQLEx5uQ2lw
|
|
# aGVyIERTRSBFU046MzFDNS0zMEJBLTdDOTExJTAjBgNVBAMTHE1pY3Jvc29mdCBU
|
|
# aW1lLVN0YW1wIFNlcnZpY2Wggg7OMIIGcTCCBFmgAwIBAgIKYQmBKgAAAAAAAjAN
|
|
# BgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
|
|
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
|
|
# dGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9y
|
|
# aXR5IDIwMTAwHhcNMTAwNzAxMjEzNjU1WhcNMjUwNzAxMjE0NjU1WjB8MQswCQYD
|
|
# VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
|
|
# MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3Nv
|
|
# ZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC
|
|
# AQoCggEBAKkdDbx3EYo6IOz8E5f1+n9plGt0VBDVpQoAgoX77XxoSyxfxcPlYcJ2
|
|
# tz5mK1vwFVMnBDEfQRsalR3OCROOfGEwWbEwRA/xYIiEVEMM1024OAizQt2TrNZz
|
|
# MFcmgqNFDdDq9UeBzb8kYDJYYEbyWEeGMoQedGFnkV+BVLHPk0ySwcSmXdFhE24o
|
|
# xhr5hoC732H8RsEnHSRnEnIaIYqvS2SJUGKxXf13Hz3wV3WsvYpCTUBR0Q+cBj5n
|
|
# f/VmwAOWRH7v0Ev9buWayrGo8noqCjHw2k4GkbaICDXoeByw6ZnNPOcvRLqn9Nxk
|
|
# vaQBwSAJk3jN/LzAyURdXhacAQVPIk0CAwEAAaOCAeYwggHiMBAGCSsGAQQBgjcV
|
|
# AQQDAgEAMB0GA1UdDgQWBBTVYzpcijGQ80N7fEYbxTNoWoVtVTAZBgkrBgEEAYI3
|
|
# FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAf
|
|
# BgNVHSMEGDAWgBTV9lbLj+iiXGJo0T2UkFvXzpoYxDBWBgNVHR8ETzBNMEugSaBH
|
|
# hkVodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNS
|
|
# b29DZXJBdXRfMjAxMC0wNi0yMy5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUF
|
|
# BzAChj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl
|
|
# ckF1dF8yMDEwLTA2LTIzLmNydDCBoAYDVR0gAQH/BIGVMIGSMIGPBgkrBgEEAYI3
|
|
# LgMwgYEwPQYIKwYBBQUHAgEWMWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9QS0kv
|
|
# ZG9jcy9DUFMvZGVmYXVsdC5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcAYQBs
|
|
# AF8AUABvAGwAaQBjAHkAXwBTAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZIhvcN
|
|
# AQELBQADggIBAAfmiFEN4sbgmD+BcQM9naOhIW+z66bM9TG+zwXiqf76V20ZMLPC
|
|
# xWbJat/15/B4vceoniXj+bzta1RXCCtRgkQS+7lTjMz0YBKKdsxAQEGb3FwX/1z5
|
|
# Xhc1mCRWS3TvQhDIr79/xn/yN31aPxzymXlKkVIArzgPF/UveYFl2am1a+THzvbK
|
|
# egBvSzBEJCI8z+0DpZaPWSm8tv0E4XCfMkon/VWvL/625Y4zu2JfmttXQOnxzplm
|
|
# kIz/amJ/3cVKC5Em4jnsGUpxY517IW3DnKOiPPp/fZZqkHimbdLhnPkd/DjYlPTG
|
|
# pQqWhqS9nhquBEKDuLWAmyI4ILUl5WTs9/S/fmNZJQ96LjlXdqJxqgaKD4kWumGn
|
|
# Ecua2A5HmoDF0M2n0O99g/DhO3EJ3110mCIIYdqwUB5vvfHhAN/nMQekkzr3ZUd4
|
|
# 6PioSKv33nJ+YWtvd6mBy6cJrDm77MbL2IK0cs0d9LiFAR6A+xuJKlQ5slvayA1V
|
|
# mXqHczsI5pgt6o3gMy4SKfXAL1QnIffIrE7aKLixqduWsqdCosnPGUFN4Ib5Kpqj
|
|
# EWYw07t0MkvfY3v1mYovG8chr1m1rtxEPJdQcdeh0sVV42neV8HR3jDA/czmTfsN
|
|
# v11P6Z0eGTgvvM9YBS7vDaBQNdrvCScc1bN+NR4Iuto229Nfj950iEkSMIIE2TCC
|
|
# A8GgAwIBAgITMwAAAHR0zK2pPny1rAAAAAAAdDANBgkqhkiG9w0BAQsFADB8MQsw
|
|
# CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
|
|
# ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy
|
|
# b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDAeFw0xNTEwMDcxODE3MzlaFw0xNzAx
|
|
# MDcxODE3MzlaMIGyMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEP
|
|
# MA0GA1UEBxMGUmVkbW9kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
|
|
# DTALBgNVBAsTBE1PUFIxJzAlBgNVBAsTHm5DaXBoZXIgRFNFIEVTTjozMUM1LTMw
|
|
# QkEtN0M5MTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAgU2VydmljZTCC
|
|
# ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKtD2GPlo0EP5ToGkaOTIK29
|
|
# Kq7brXtNqFhfOgUJwUtYQhc6JI5tqN1F5JRSMOJ+9jAWrCAEkXx3eU20k56+ehNq
|
|
# fWjE8UIz2NRljSi8J1NynAcCVgSJFuKjYAdOljvWU8rxFSI6P/KRoMPbictp6jL/
|
|
# PzRG/BmlkhvMjNyspPfNlbH5bJRY89ihU2gNlzALmGkWfiOgdK/oRPOe+ZPU42i1
|
|
# at+WOCReoWX2Z8mtsNn4gH9yt1NmK4cCoAgKuvuNmQVf0L+NGE2/Lx9jPJSx52Nc
|
|
# CcbqtK60yRE8x83K9944NHb9iyQROUD5fuq9rvfESl7BwVOUoWtgvMZE77Ez2skC
|
|
# AwEAAaOCARswggEXMB0GA1UdDgQWBBQ0xqxSiifT0x6XvwwDdXdKutjkMTAfBgNV
|
|
# HSMEGDAWgBTVYzpcijGQ80N7fEYbxTNoWoVtVTBWBgNVHR8ETzBNMEugSaBHhkVo
|
|
# dHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNUaW1T
|
|
# dGFQQ0FfMjAxMC0wNy0wMS5jcmwwWgYIKwYBBQUHAQEETjBMMEoGCCsGAQUFBzAC
|
|
# hj5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1RpbVN0YVBD
|
|
# QV8yMDEwLTA3LTAxLmNydDAMBgNVHRMBAf8EAjAAMBMGA1UdJQQMMAoGCCsGAQUF
|
|
# BwMIMA0GCSqGSIb3DQEBCwUAA4IBAQBZkYwuw6ioh0NFGo6Zk8hEbrRwkVNITye1
|
|
# +EbXXG4siy5OCF4iXWRR9domidXuE3uMsbjqHgHfgDYVAovD0Oi9Zqxbkc0vPEhX
|
|
# qi8xRQMLLwy4jFSjTJ6S52DlcIr+EIBQj4pOUFqvcRdO8bSFsDIKUVJxCHDkDKyK
|
|
# MwY008TjNB+OKBvhcQND6+nbQOLWtUnGYKOWEUgQpNVyKrEu90fq4yvbuEq68CMQ
|
|
# GrhHTLXSpSyxSjrE1j+OXz+e95D/jeUs4G7323tx0Q0oihO8sm+aJsC8iFmb5c8X
|
|
# HVmIof4wKgCzDkDTGwdUnpnL+kOs7FXQm07NmbPsHIKI2WA74OgSoYIDeDCCAmAC
|
|
# AQEwgeKhgbikgbUwgbIxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
|
|
# MQ8wDQYDVQQHEwZSZWRtb2QxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv
|
|
# bjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjMxQzUt
|
|
# MzBCQS03QzkxMSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl
|
|
# oiUKAQEwCQYFKw4DAhoFAAMVABB2BqyiAFCEUKaVc38ZxJdOER74oIHCMIG/pIG8
|
|
# MIG5MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
|
|
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQL
|
|
# EwRNT1BSMScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NTdGNi1DMUUwLTU1NEMx
|
|
# KzApBgNVBAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJ
|
|
# KoZIhvcNAQEFBQACBQDZ9InrMCIYDzIwMTUxMTE2MTY1OTIzWhgPMjAxNTExMTcx
|
|
# NjU5MjNaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFANn0iesCAQAwCgIBAAICHnAC
|
|
# Af8wBwIBAAICGH8wCgIFANn122sCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYB
|
|
# BAGEWQoDAaAKMAgCAQACAxbjYKEKMAgCAQACAwehIDANBgkqhkiG9w0BAQUFAAOC
|
|
# AQEAGXYdsvH8BO5ykyXOHXanfUMbeqhL+u7tX7wN5xwL9lSKg2asdnYO53AFBg+x
|
|
# +MbVYUkW/u4IYuBW1WA981NLdzV1oDtsdkvC4aJfA/M8X7HXOd6jMfHuXMfIHeR6
|
|
# C5dR95bwwVCVKlwhnnnYAKBH8tbw3kOZ/6oP4iS8bI1k9Nihiebb6WF1ocuAtu3I
|
|
# M1mJt3VS2G2jRWdXO/MNrmlssB+1Km4CkvRZV70ZmWssZy09L6hP0xvqd4AnKSDW
|
|
# 2X4T3PUF8OR4uUZ0aYjlkHJkfJPf1Yh0Oe/sCf5A5Qas88BlSmATyU0WSRd1YR7m
|
|
# YICUMkoEQxAzNMjGF825rTGqSzGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVT
|
|
# MRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQK
|
|
# ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1l
|
|
# LVN0YW1wIFBDQSAyMDEwAhMzAAAAdHTMrak+fLWsAAAAAAB0MA0GCWCGSAFlAwQC
|
|
# AQUAoIIBMjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkE
|
|
# MSIEIOrJJOKLinmYlSOIyanQfvQZGZ74mWwLN2A2/enCQgCiMIHiBgsqhkiG9w0B
|
|
# CRACDDGB0jCBzzCBzDCBsQQUEHYGrKIAUIRQppVzfxnEl04RHvgwgZgwgYCkfjB8
|
|
# MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk
|
|
# bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1N
|
|
# aWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAHR0zK2pPny1rAAAAAAA
|
|
# dDAWBBQnnC6SnEZmRR+MN+ymmnNCdB8rqzANBgkqhkiG9w0BAQsFAASCAQCKhi57
|
|
# UtfKy3nfOc/QsYoMYAwMEcw+O0QeYSc+usQnY7OuJeTFG8jbb363S9AJOEQNm8C4
|
|
# Aq4KRfewKuxWuLYOQVwKOm67NlgmuwhvpKOpQ8wpRs110AQhpn3o7L3W4IN4XrA1
|
|
# W72gy0sSUuMKamkj6BQ3A2FQAMzCF1a4+Fao19HXAMPblelbYVmxADqL6Ai8jGkP
|
|
# 3+lZE0/sZVxsmGnjqWi2OsurfhMnw1kiZ7gQqk6WR22Lt8LCi9RblfuZGKMyecn2
|
|
# cY5LxEKqMlfSuF0K9Rt+4jz9Z5UbBko2540XN08Hgu1JpxFwrcygxO22CsrnT3Xl
|
|
# qdvbsRKWbxqq6IXp
|
|
# SIG # End signature block
|