EntityFramework6.psm1 51 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407
  1. # Copyright (c) Microsoft Corporation. All rights reserved.
  2. $ErrorActionPreference = 'Stop'
  3. $InitialDatabase = '0'
  4. <#
  5. .SYNOPSIS
  6. Adds or updates an Entity Framework provider entry in the project config
  7. file.
  8. .DESCRIPTION
  9. Adds an entry into the 'entityFramework' section of the project config
  10. file for the specified provider invariant name and provider type. If an
  11. entry for the given invariant name already exists, then that entry is
  12. updated with the given type name, unless the given type name already
  13. matches, in which case no action is taken. The 'entityFramework'
  14. section is added if it does not exist. The config file is automatically
  15. saved if and only if a change was made.
  16. This command is typically used only by Entity Framework provider NuGet
  17. packages and is run from the 'install.ps1' script.
  18. .PARAMETER Project
  19. The Visual Studio project to update. When running in the NuGet install.ps1
  20. script the '$project' variable provided as part of that script should be
  21. used.
  22. .PARAMETER InvariantName
  23. The provider invariant name that uniquely identifies this provider. For
  24. example, the Microsoft SQL Server provider is registered with the invariant
  25. name 'System.Data.SqlClient'.
  26. .PARAMETER TypeName
  27. The assembly-qualified type name of the provider-specific type that
  28. inherits from 'System.Data.Entity.Core.Common.DbProviderServices'. For
  29. example, for the Microsoft SQL Server provider, this type is
  30. 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer'.
  31. #>
  32. function Add-EFProvider
  33. {
  34. [CmdletBinding(PositionalBinding = $false)]
  35. param(
  36. [parameter(Position = 0, Mandatory = $true)]
  37. $Project,
  38. [parameter(Position = 1, Mandatory = $true)]
  39. [string] $InvariantName,
  40. [parameter(Position = 2, Mandatory = $true)]
  41. [string] $TypeName)
  42. $configPath = GetConfigPath $Project
  43. if (!$configPath)
  44. {
  45. return
  46. }
  47. [xml] $configXml = Get-Content $configPath
  48. $providers = $configXml.configuration.entityFramework.providers
  49. $providers.provider |
  50. where invariantName -eq $InvariantName |
  51. %{ $providers.RemoveChild($_) | Out-Null }
  52. $provider = $providers.AppendChild($configXml.CreateElement('provider'))
  53. $provider.SetAttribute('invariantName', $InvariantName)
  54. $provider.SetAttribute('type', $TypeName)
  55. $configXml.Save($configPath)
  56. }
  57. <#
  58. .SYNOPSIS
  59. Adds or updates an Entity Framework default connection factory in the
  60. project config file.
  61. .DESCRIPTION
  62. Adds an entry into the 'entityFramework' section of the project config
  63. file for the connection factory that Entity Framework will use by default
  64. when creating new connections by convention. Any existing entry will be
  65. overridden if it does not match. The 'entityFramework' section is added if
  66. it does not exist. The config file is automatically saved if and only if
  67. a change was made.
  68. This command is typically used only by Entity Framework provider NuGet
  69. packages and is run from the 'install.ps1' script.
  70. .PARAMETER Project
  71. The Visual Studio project to update. When running in the NuGet install.ps1
  72. script the '$project' variable provided as part of that script should be
  73. used.
  74. .PARAMETER TypeName
  75. The assembly-qualified type name of the connection factory type that
  76. implements the 'System.Data.Entity.Infrastructure.IDbConnectionFactory'
  77. interface. For example, for the Microsoft SQL Server Express provider
  78. connection factory, this type is
  79. 'System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework'.
  80. .PARAMETER ConstructorArguments
  81. An optional array of strings that will be passed as arguments to the
  82. connection factory type constructor.
  83. #>
  84. function Add-EFDefaultConnectionFactory
  85. {
  86. [CmdletBinding(PositionalBinding = $false)]
  87. param(
  88. [parameter(Position = 0, Mandatory = $true)]
  89. $Project,
  90. [parameter(Position = 1, Mandatory = $true)]
  91. [string] $TypeName,
  92. [string[]] $ConstructorArguments)
  93. $configPath = GetConfigPath $Project
  94. if (!$configPath)
  95. {
  96. return
  97. }
  98. [xml] $configXml = Get-Content $configPath
  99. $entityFramework = $configXml.configuration.entityFramework
  100. $defaultConnectionFactory = $entityFramework.defaultConnectionFactory
  101. if ($defaultConnectionFactory)
  102. {
  103. $entityFramework.RemoveChild($defaultConnectionFactory) | Out-Null
  104. }
  105. $defaultConnectionFactory = $entityFramework.AppendChild($configXml.CreateElement('defaultConnectionFactory'))
  106. $defaultConnectionFactory.SetAttribute('type', $TypeName)
  107. if ($ConstructorArguments)
  108. {
  109. $parameters = $defaultConnectionFactory.AppendChild($configXml.CreateElement('parameters'))
  110. foreach ($constructorArgument in $ConstructorArguments)
  111. {
  112. $parameter = $parameters.AppendChild($configXml.CreateElement('parameter'))
  113. $parameter.SetAttribute('value', $constructorArgument)
  114. }
  115. }
  116. $configXml.Save($configPath)
  117. }
  118. <#
  119. .SYNOPSIS
  120. Enables Code First Migrations in a project.
  121. .DESCRIPTION
  122. Enables Migrations by scaffolding a migrations configuration class in the project. If the
  123. target database was created by an initializer, an initial migration will be created (unless
  124. automatic migrations are enabled via the EnableAutomaticMigrations parameter).
  125. .PARAMETER ContextTypeName
  126. Specifies the context to use. If omitted, migrations will attempt to locate a
  127. single context type in the target project.
  128. .PARAMETER EnableAutomaticMigrations
  129. Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration.
  130. If omitted, automatic migrations will be disabled.
  131. .PARAMETER MigrationsDirectory
  132. Specifies the name of the directory that will contain migrations code files.
  133. If omitted, the directory will be named "Migrations".
  134. .PARAMETER ProjectName
  135. Specifies the project that the scaffolded migrations configuration class will
  136. be added to. If omitted, the default project selected in package manager
  137. console is used.
  138. .PARAMETER StartUpProjectName
  139. Specifies the configuration file to use for named connection strings. If
  140. omitted, the specified project's configuration file is used.
  141. .PARAMETER ContextProjectName
  142. Specifies the project which contains the DbContext class to use. If omitted,
  143. the context is assumed to be in the same project used for migrations.
  144. .PARAMETER ConnectionStringName
  145. Specifies the name of a connection string to use from the application's
  146. configuration file.
  147. .PARAMETER ConnectionString
  148. Specifies the connection string to use. If omitted, the context's
  149. default connection will be used.
  150. .PARAMETER ConnectionProviderName
  151. Specifies the provider invariant name of the connection string.
  152. .PARAMETER Force
  153. Specifies that the migrations configuration be overwritten when running more
  154. than once for a given project.
  155. .PARAMETER ContextAssemblyName
  156. Specifies the name of the assembly which contains the DbContext class to use. Use this
  157. parameter instead of ContextProjectName when the context is contained in a referenced
  158. assembly rather than in a project of the solution.
  159. .PARAMETER AppDomainBaseDirectory
  160. Specifies the directory to use for the app-domain that is used for running Migrations
  161. code such that the app-domain is able to find all required assemblies. This is an
  162. advanced option that should only be needed if the solution contains several projects
  163. such that the assemblies needed for the context and configuration are not all
  164. referenced from either the project containing the context or the project containing
  165. the migrations.
  166. .EXAMPLE
  167. Enable-Migrations
  168. # Scaffold a migrations configuration in a project with only one context
  169. .EXAMPLE
  170. Enable-Migrations -Auto
  171. # Scaffold a migrations configuration with automatic migrations enabled for a project
  172. # with only one context
  173. .EXAMPLE
  174. Enable-Migrations -ContextTypeName MyContext -MigrationsDirectory DirectoryName
  175. # Scaffold a migrations configuration for a project with multiple contexts
  176. # This scaffolds a migrations configuration for MyContext and will put the configuration
  177. # and subsequent configurations in a new directory called "DirectoryName"
  178. #>
  179. function Enable-Migrations
  180. {
  181. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  182. param(
  183. [string] $ContextTypeName,
  184. [alias('Auto')]
  185. [switch] $EnableAutomaticMigrations,
  186. [string] $MigrationsDirectory,
  187. [string] $ProjectName,
  188. [string] $StartUpProjectName,
  189. [string] $ContextProjectName,
  190. [parameter(ParameterSetName = 'ConnectionStringName')]
  191. [string] $ConnectionStringName,
  192. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  193. [string] $ConnectionString,
  194. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  195. [string] $ConnectionProviderName,
  196. [switch] $Force,
  197. [string] $ContextAssemblyName,
  198. [string] $AppDomainBaseDirectory)
  199. WarnIfOtherEFs 'Enable-Migrations'
  200. $project = GetProject $ProjectName
  201. $startupProject = GetStartupProject $StartUpProjectName $project
  202. if (!$ContextAssemblyName -and $ContextProjectName)
  203. {
  204. $contextProject = Get-Project $ContextProjectName
  205. $ContextAssemblyName = GetProperty $contextProject.Properties 'AssemblyName'
  206. }
  207. $params = 'migrations', 'enable', '--json'
  208. if ($ContextTypeName)
  209. {
  210. $params += '--context', $ContextTypeName
  211. }
  212. if ($ContextAssemblyName)
  213. {
  214. $params += '--context-assembly', $ContextAssemblyName
  215. }
  216. if ($EnableAutomaticMigrations)
  217. {
  218. $params += '--auto'
  219. }
  220. if ($MigrationsDirectory)
  221. {
  222. $params += '--migrations-dir', $MigrationsDirectory
  223. }
  224. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  225. if ($Force)
  226. {
  227. $params += '--force'
  228. }
  229. # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0
  230. $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json
  231. $project.ProjectItems.AddFromFile($result.migrationsConfiguration) | Out-Null
  232. $DTE.ItemOperations.OpenFile($result.migrationsConfiguration) | Out-Null
  233. ShowConsole
  234. if ($result.migration)
  235. {
  236. $project.ProjectItems.AddFromFile($result.migration) | Out-Null
  237. $resourcesProperties = $project.ProjectItems.AddFromFile($result.migrationResources).Properties
  238. $project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null
  239. }
  240. }
  241. <#
  242. .SYNOPSIS
  243. Scaffolds a migration script for any pending model changes.
  244. .DESCRIPTION
  245. Scaffolds a new migration script and adds it to the project.
  246. .PARAMETER Name
  247. Specifies the name of the custom script.
  248. .PARAMETER Force
  249. Specifies that the migration user code be overwritten when re-scaffolding an
  250. existing migration.
  251. .PARAMETER ProjectName
  252. Specifies the project that contains the migration configuration type to be
  253. used. If omitted, the default project selected in package manager console
  254. is used.
  255. .PARAMETER StartUpProjectName
  256. Specifies the configuration file to use for named connection strings. If
  257. omitted, the specified project's configuration file is used.
  258. .PARAMETER ConfigurationTypeName
  259. Specifies the migrations configuration to use. If omitted, migrations will
  260. attempt to locate a single migrations configuration type in the target
  261. project.
  262. .PARAMETER ConnectionStringName
  263. Specifies the name of a connection string to use from the application's
  264. configuration file.
  265. .PARAMETER ConnectionString
  266. Specifies the connection string to use. If omitted, the context's
  267. default connection will be used.
  268. .PARAMETER ConnectionProviderName
  269. Specifies the provider invariant name of the connection string.
  270. .PARAMETER IgnoreChanges
  271. Scaffolds an empty migration ignoring any pending changes detected in the current model.
  272. This can be used to create an initial, empty migration to enable Migrations for an existing
  273. database. N.B. Doing this assumes that the target database schema is compatible with the
  274. current model.
  275. .PARAMETER AppDomainBaseDirectory
  276. Specifies the directory to use for the app-domain that is used for running Migrations
  277. code such that the app-domain is able to find all required assemblies. This is an
  278. advanced option that should only be needed if the solution contains several projects
  279. such that the assemblies needed for the context and configuration are not all
  280. referenced from either the project containing the context or the project containing
  281. the migrations.
  282. .EXAMPLE
  283. Add-Migration First
  284. # Scaffold a new migration named "First"
  285. .EXAMPLE
  286. Add-Migration First -IgnoreChanges
  287. # Scaffold an empty migration ignoring any pending changes detected in the current model.
  288. # This can be used to create an initial, empty migration to enable Migrations for an existing
  289. # database. N.B. Doing this assumes that the target database schema is compatible with the
  290. # current model.
  291. #>
  292. function Add-Migration
  293. {
  294. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  295. param(
  296. [parameter(Position = 0, Mandatory = $true)]
  297. [string] $Name,
  298. [switch] $Force,
  299. [string] $ProjectName,
  300. [string] $StartUpProjectName,
  301. [string] $ConfigurationTypeName,
  302. [parameter(ParameterSetName = 'ConnectionStringName')]
  303. [string] $ConnectionStringName,
  304. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  305. [string] $ConnectionString,
  306. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  307. [string] $ConnectionProviderName,
  308. [switch] $IgnoreChanges,
  309. [string] $AppDomainBaseDirectory)
  310. WarnIfOtherEFs 'Add-Migration'
  311. $project = GetProject $ProjectName
  312. $startupProject = GetStartupProject $StartUpProjectName $project
  313. $params = 'migrations', 'add', $Name, '--json'
  314. if ($Force)
  315. {
  316. $params += '--force'
  317. }
  318. if ($ConfigurationTypeName)
  319. {
  320. $params += '--migrations-config', $ConfigurationTypeName
  321. }
  322. if ($IgnoreChanges)
  323. {
  324. $params += '--ignore-changes'
  325. }
  326. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  327. # NB: -join is here to support ConvertFrom-Json on PowerShell 3.0
  328. $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n" | ConvertFrom-Json
  329. $project.ProjectItems.AddFromFile($result.migration) | Out-Null
  330. $DTE.ItemOperations.OpenFile($result.migration) | Out-Null
  331. $resourcesProperties = $project.ProjectItems.AddFromFile($result.migrationResources).Properties
  332. $project.ProjectItems.AddFromFile($result.migrationDesigner) | Out-Null
  333. }
  334. <#
  335. .SYNOPSIS
  336. Applies any pending migrations to the database.
  337. .DESCRIPTION
  338. Updates the database to the current model by applying pending migrations.
  339. .PARAMETER SourceMigration
  340. Only valid with -Script. Specifies the name of a particular migration to use
  341. as the update's starting point. If omitted, the last applied migration in
  342. the database will be used.
  343. .PARAMETER TargetMigration
  344. Specifies the name of a particular migration to update the database to. If
  345. omitted, the current model will be used.
  346. .PARAMETER Script
  347. Generate a SQL script rather than executing the pending changes directly.
  348. .PARAMETER Force
  349. Specifies that data loss is acceptable during automatic migration of the
  350. database.
  351. .PARAMETER ProjectName
  352. Specifies the project that contains the migration configuration type to be
  353. used. If omitted, the default project selected in package manager console
  354. is used.
  355. .PARAMETER StartUpProjectName
  356. Specifies the configuration file to use for named connection strings. If
  357. omitted, the specified project's configuration file is used.
  358. .PARAMETER ConfigurationTypeName
  359. Specifies the migrations configuration to use. If omitted, migrations will
  360. attempt to locate a single migrations configuration type in the target
  361. project.
  362. .PARAMETER ConnectionStringName
  363. Specifies the name of a connection string to use from the application's
  364. configuration file.
  365. .PARAMETER ConnectionString
  366. Specifies the connection string to use. If omitted, the context's
  367. default connection will be used.
  368. .PARAMETER ConnectionProviderName
  369. Specifies the provider invariant name of the connection string.
  370. .PARAMETER AppDomainBaseDirectory
  371. Specifies the directory to use for the app-domain that is used for running Migrations
  372. code such that the app-domain is able to find all required assemblies. This is an
  373. advanced option that should only be needed if the solution contains several projects
  374. such that the assemblies needed for the context and configuration are not all
  375. referenced from either the project containing the context or the project containing
  376. the migrations.
  377. .EXAMPLE
  378. Update-Database
  379. # Update the database to the latest migration
  380. .EXAMPLE
  381. Update-Database -TargetMigration Second
  382. # Update database to a migration named "Second"
  383. # This will apply migrations if the target hasn't been applied or roll back migrations
  384. # if it has
  385. .EXAMPLE
  386. Update-Database -Script
  387. # Generate a script to update the database from its current state to the latest migration
  388. .EXAMPLE
  389. Update-Database -Script -SourceMigration Second -TargetMigration First
  390. # Generate a script to migrate the database from a specified start migration
  391. # named "Second" to a specified target migration named "First"
  392. .EXAMPLE
  393. Update-Database -Script -SourceMigration $InitialDatabase
  394. # Generate a script that can upgrade a database currently at any version to the latest version.
  395. # The generated script includes logic to check the __MigrationsHistory table and only apply changes
  396. # that haven't been previously applied.
  397. .EXAMPLE
  398. Update-Database -TargetMigration $InitialDatabase
  399. # Runs the Down method to roll-back any migrations that have been applied to the database
  400. #>
  401. function Update-Database
  402. {
  403. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  404. param(
  405. [string] $SourceMigration,
  406. [string] $TargetMigration,
  407. [switch] $Script,
  408. [switch] $Force,
  409. [string] $ProjectName,
  410. [string] $StartUpProjectName,
  411. [string] $ConfigurationTypeName,
  412. [parameter(ParameterSetName = 'ConnectionStringName')]
  413. [string] $ConnectionStringName,
  414. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  415. [string] $ConnectionString,
  416. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  417. [string] $ConnectionProviderName,
  418. [string] $AppDomainBaseDirectory)
  419. WarnIfOtherEFs 'Update-Database'
  420. $project = GetProject $ProjectName
  421. $startupProject = GetStartupProject $StartUpProjectName $project
  422. $params = 'database', 'update'
  423. if ($SourceMigration)
  424. {
  425. $params += '--source', $SourceMigration
  426. }
  427. if ($TargetMigration)
  428. {
  429. $params += '--target', $TargetMigration
  430. }
  431. if ($Script)
  432. {
  433. $params += '--script'
  434. }
  435. if ($Force)
  436. {
  437. $params += '--force'
  438. }
  439. if ($ConfigurationTypeName)
  440. {
  441. $params += '--migrations-config', $ConfigurationTypeName
  442. }
  443. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  444. $result = (EF6 $project $startupProject $AppDomainBaseDirectory $params) -join "`n"
  445. if ($result)
  446. {
  447. try
  448. {
  449. $window = $DTE.ItemOperations.NewFile('General\Sql File')
  450. $textDocument = $window.Document.Object('TextDocument')
  451. $editPoint = $textDocument.StartPoint.CreateEditPoint()
  452. $editPoint.Insert($result)
  453. }
  454. catch
  455. {
  456. $intermediatePath = GetIntermediatePath $project
  457. if (![IO.Path]::IsPathRooted($intermediatePath))
  458. {
  459. $projectDir = GetProperty $project.Properties 'FullPath'
  460. $intermediatePath = Join-Path $projectDir $intermediatePath -Resolve | Convert-Path
  461. }
  462. $fileName = [IO.Path]::ChangeExtension([IO.Path]::GetRandomFileName(), '.sql')
  463. $sqlFile = Join-Path $intermediatePath $fileName
  464. [IO.File]::WriteAllText($sqlFile, $result)
  465. $DTE.ItemOperations.OpenFile($sqlFile) | Out-Null
  466. }
  467. ShowConsole
  468. }
  469. }
  470. <#
  471. .SYNOPSIS
  472. Displays the migrations that have been applied to the target database.
  473. .DESCRIPTION
  474. Displays the migrations that have been applied to the target database.
  475. .PARAMETER ProjectName
  476. Specifies the project that contains the migration configuration type to be
  477. used. If omitted, the default project selected in package manager console
  478. is used.
  479. .PARAMETER StartUpProjectName
  480. Specifies the configuration file to use for named connection strings. If
  481. omitted, the specified project's configuration file is used.
  482. .PARAMETER ConfigurationTypeName
  483. Specifies the migrations configuration to use. If omitted, migrations will
  484. attempt to locate a single migrations configuration type in the target
  485. project.
  486. .PARAMETER ConnectionStringName
  487. Specifies the name of a connection string to use from the application's
  488. configuration file.
  489. .PARAMETER ConnectionString
  490. Specifies the connection string to use. If omitted, the context's
  491. default connection will be used.
  492. .PARAMETER ConnectionProviderName
  493. Specifies the provider invariant name of the connection string.
  494. .PARAMETER AppDomainBaseDirectory
  495. Specifies the directory to use for the app-domain that is used for running Migrations
  496. code such that the app-domain is able to find all required assemblies. This is an
  497. advanced option that should only be needed if the solution contains several projects
  498. such that the assemblies needed for the context and configuration are not all
  499. referenced from either the project containing the context or the project containing
  500. the migrations.
  501. #>
  502. function Get-Migrations
  503. {
  504. [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName', PositionalBinding = $false)]
  505. param(
  506. [string] $ProjectName,
  507. [string] $StartUpProjectName,
  508. [string] $ConfigurationTypeName,
  509. [parameter(ParameterSetName = 'ConnectionStringName')]
  510. [string] $ConnectionStringName,
  511. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  512. [string] $ConnectionString,
  513. [parameter(ParameterSetName = 'ConnectionStringAndProviderName', Mandatory = $true)]
  514. [string] $ConnectionProviderName,
  515. [string] $AppDomainBaseDirectory)
  516. WarnIfOtherEFs 'Get-Migrations'
  517. $project = GetProject $ProjectName
  518. $startupProject = GetStartupProject $StartUpProjectName $project
  519. $params = 'migrations', 'list'
  520. if ($ConfigurationTypeName)
  521. {
  522. $params += '--migrations-config', $ConfigurationTypeName
  523. }
  524. $params += GetParams $ConnectionStringName $ConnectionString $ConnectionProviderName
  525. return EF6 $project $startupProject $AppDomainBaseDirectory $params
  526. }
  527. function WarnIfOtherEFs($cmdlet)
  528. {
  529. if (Get-Module 'EntityFrameworkCore')
  530. {
  531. 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."
  532. }
  533. if (Get-Module 'EntityFramework')
  534. {
  535. 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."
  536. }
  537. }
  538. function GetProject($projectName)
  539. {
  540. if (!$projectName)
  541. {
  542. return Get-Project
  543. }
  544. return Get-Project $projectName
  545. }
  546. function GetStartupProject($name, $fallbackProject)
  547. {
  548. if ($name)
  549. {
  550. return Get-Project $name
  551. }
  552. $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects
  553. if ($startupProjectPaths)
  554. {
  555. if ($startupProjectPaths.Length -eq 1)
  556. {
  557. $startupProjectPath = $startupProjectPaths[0]
  558. if (![IO.Path]::IsPathRooted($startupProjectPath))
  559. {
  560. $solutionPath = Split-Path (GetProperty $DTE.Solution.Properties 'Path')
  561. $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve | Convert-Path
  562. }
  563. $startupProject = GetSolutionProjects |
  564. ?{
  565. try
  566. {
  567. $fullName = $_.FullName
  568. }
  569. catch [NotImplementedException]
  570. {
  571. return $false
  572. }
  573. if ($fullName -and $fullName.EndsWith('\'))
  574. {
  575. $fullName = $fullName.Substring(0, $fullName.Length - 1)
  576. }
  577. return $fullName -eq $startupProjectPath
  578. }
  579. if ($startupProject)
  580. {
  581. return $startupProject
  582. }
  583. Write-Warning "Unable to resolve startup project '$startupProjectPath'."
  584. }
  585. else
  586. {
  587. Write-Warning 'Multiple startup projects set.'
  588. }
  589. }
  590. else
  591. {
  592. Write-Warning 'No startup project set.'
  593. }
  594. Write-Warning "Using project '$($fallbackProject.ProjectName)' as the startup project."
  595. return $fallbackProject
  596. }
  597. function GetSolutionProjects()
  598. {
  599. $projects = New-Object 'System.Collections.Stack'
  600. $DTE.Solution.Projects |
  601. %{ $projects.Push($_) }
  602. while ($projects.Count)
  603. {
  604. $project = $projects.Pop();
  605. <# yield return #> $project
  606. if ($project.ProjectItems)
  607. {
  608. $project.ProjectItems |
  609. ?{ $_.SubProject } |
  610. %{ $projects.Push($_.SubProject) }
  611. }
  612. }
  613. }
  614. function GetParams($connectionStringName, $connectionString, $connectionProviderName)
  615. {
  616. $params = @()
  617. if ($connectionStringName)
  618. {
  619. $params += '--connection-string-name', $connectionStringName
  620. }
  621. if ($connectionString)
  622. {
  623. $params += '--connection-string', $connectionString,
  624. '--connection-provider', $connectionProviderName
  625. }
  626. return $params
  627. }
  628. function ShowConsole
  629. {
  630. $componentModel = Get-VSComponentModel
  631. $powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
  632. $powerConsoleWindow.Show()
  633. }
  634. function WriteErrorLine($message)
  635. {
  636. try
  637. {
  638. # Call the internal API NuGet uses to display errors
  639. $componentModel = Get-VSComponentModel
  640. $powerConsoleWindow = $componentModel.GetService([NuGetConsole.IPowerConsoleWindow])
  641. $bindingFlags = [Reflection.BindingFlags]::Instance -bor [Reflection.BindingFlags]::NonPublic
  642. $activeHostInfo = $powerConsoleWindow.GetType().GetProperty('ActiveHostInfo', $bindingFlags).GetValue($powerConsoleWindow)
  643. $internalHost = $activeHostInfo.WpfConsole.Host
  644. $reportErrorMethod = $internalHost.GetType().GetMethod('ReportError', $bindingFlags, $null, [Exception], $null)
  645. $exception = New-Object Exception $message
  646. $reportErrorMethod.Invoke($internalHost, $exception)
  647. }
  648. catch
  649. {
  650. Write-Host $message -ForegroundColor DarkRed
  651. }
  652. }
  653. function EF6($project, $startupProject, $workingDir, $params)
  654. {
  655. $solutionBuild = $DTE.Solution.SolutionBuild
  656. $solutionBuild.BuildProject(
  657. $solutionBuild.ActiveConfiguration.Name,
  658. $project.UniqueName,
  659. <# WaitForBuildToFinish #> $true)
  660. if ($solutionBuild.LastBuildInfo)
  661. {
  662. throw "The project '$($project.ProjectName)' failed to build."
  663. }
  664. $projectDir = GetProperty $project.Properties 'FullPath'
  665. $outputPath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'OutputPath'
  666. $targetDir = [IO.Path]::GetFullPath([IO.Path]::Combine($projectDir, $outputPath))
  667. $targetFrameworkMoniker = GetProperty $project.Properties 'TargetFrameworkMoniker'
  668. $frameworkName = New-Object 'System.Runtime.Versioning.FrameworkName' $targetFrameworkMoniker
  669. $targetFrameworkIdentifier = $frameworkName.Identifier
  670. $targetFrameworkVersion = $frameworkName.Version
  671. if ($targetFrameworkIdentifier -in '.NETFramework')
  672. {
  673. if ($targetFrameworkVersion -lt '4.5')
  674. {
  675. $frameworkDir = 'net40'
  676. }
  677. else
  678. {
  679. $frameworkDir = 'net45'
  680. }
  681. $platformTarget = GetPlatformTarget $project
  682. if ($platformTarget -eq 'x86')
  683. {
  684. $runtimeDir = 'win-x86'
  685. }
  686. elseif ($platformTarget -in 'AnyCPU', 'x64')
  687. {
  688. $runtimeDir = 'any'
  689. }
  690. else
  691. {
  692. throw "Project '$($project.ProjectName)' has an active platform of '$platformTarget'. Select a different " +
  693. 'platform and try again.'
  694. }
  695. $exePath = Join-Path $PSScriptRoot "$frameworkDir\$runtimeDir\ef6.exe"
  696. }
  697. elseif ($targetFrameworkIdentifier -eq '.NETCoreApp')
  698. {
  699. $exePath = (Get-Command 'dotnet').Path
  700. $targetName = GetProperty $project.Properties 'AssemblyName'
  701. $depsFile = Join-Path $targetDir ($targetName + '.deps.json')
  702. $projectAssetsFile = GetCpsProperty $project 'ProjectAssetsFile'
  703. $runtimeConfig = Join-Path $targetDir ($targetName + '.runtimeconfig.json')
  704. $runtimeFrameworkVersion = GetCpsProperty $project 'RuntimeFrameworkVersion'
  705. $efPath = Join-Path $PSScriptRoot 'netcoreapp3.0\any\ef6.dll'
  706. $dotnetParams = 'exec', '--depsfile', $depsFile
  707. if ($projectAssetsFile)
  708. {
  709. # NB: Don't use Get-Content. It doesn't handle UTF-8 without a signature
  710. # NB: Don't use ReadAllLines. ConvertFrom-Json won't work on PowerShell 3.0
  711. $projectAssets = [IO.File]::ReadAllText($projectAssetsFile) | ConvertFrom-Json
  712. $projectAssets.packageFolders.psobject.Properties.Name |
  713. %{ $dotnetParams += '--additionalprobingpath', $_.TrimEnd('\') }
  714. }
  715. if (Test-Path $runtimeConfig)
  716. {
  717. $dotnetParams += '--runtimeconfig', $runtimeConfig
  718. }
  719. elseif ($runtimeFrameworkVersion)
  720. {
  721. $dotnetParams += '--fx-version', $runtimeFrameworkVersion
  722. }
  723. $dotnetParams += $efPath
  724. $params = $dotnetParams + $params
  725. }
  726. else
  727. {
  728. throw "Project '$($startupProject.ProjectName)' targets framework '$targetFrameworkIdentifier'. The Entity Framework " +
  729. 'Package Manager Console Tools don''t support this framework.'
  730. }
  731. $targetFileName = GetProperty $project.Properties 'OutputFileName'
  732. $targetPath = Join-Path $targetDir $targetFileName
  733. $rootNamespace = GetProperty $project.Properties 'RootNamespace'
  734. $language = GetLanguage $project
  735. $params += '--verbose',
  736. '--no-color',
  737. '--prefix-output',
  738. '--assembly', $targetPath,
  739. '--project-dir', $projectDir,
  740. '--language', $language
  741. if (IsWeb $startupProject)
  742. {
  743. $startupProjectDir = GetProperty $startupProject.Properties 'FullPath'
  744. $params += '--data-dir', (Join-Path $startupProjectDir 'App_Data')
  745. }
  746. if ($rootNamespace)
  747. {
  748. $params += '--root-namespace', $rootNamespace
  749. }
  750. $configFile = GetConfigPath $startupProject
  751. if ($configFile)
  752. {
  753. $params += '--config', $configFile
  754. }
  755. if (!$workingDir)
  756. {
  757. $workingDir = $targetDir
  758. }
  759. $arguments = ToArguments $params
  760. $startInfo = New-Object 'System.Diagnostics.ProcessStartInfo' -Property @{
  761. FileName = $exePath;
  762. Arguments = $arguments;
  763. UseShellExecute = $false;
  764. CreateNoWindow = $true;
  765. RedirectStandardOutput = $true;
  766. StandardOutputEncoding = [Text.Encoding]::UTF8;
  767. RedirectStandardError = $true;
  768. WorkingDirectory = $workingDir;
  769. }
  770. Write-Verbose "$exePath $arguments"
  771. $process = [Diagnostics.Process]::Start($startInfo)
  772. while (($line = $process.StandardOutput.ReadLine()) -ne $null)
  773. {
  774. $level = $null
  775. $text = $null
  776. $parts = $line.Split(':', 2)
  777. if ($parts.Length -eq 2)
  778. {
  779. $level = $parts[0]
  780. $i = 0
  781. $count = 8 - $level.Length
  782. while ($i -lt $count -and $parts[1][$i] -eq ' ')
  783. {
  784. $i++
  785. }
  786. $text = $parts[1].Substring($i)
  787. }
  788. switch ($level)
  789. {
  790. 'error' { WriteErrorLine $text }
  791. 'warn' { Write-Warning $text }
  792. 'info' { Write-Host $text }
  793. 'data' { Write-Output $text }
  794. 'verbose' { Write-Verbose $text }
  795. default { Write-Host $line }
  796. }
  797. }
  798. $process.WaitForExit()
  799. if ($process.ExitCode)
  800. {
  801. while (($line = $process.StandardError.ReadLine()) -ne $null)
  802. {
  803. WriteErrorLine $line
  804. }
  805. exit
  806. }
  807. }
  808. function IsCpsProject($project)
  809. {
  810. $hierarchy = GetVsHierarchy $project
  811. $isCapabilityMatch = [Microsoft.VisualStudio.Shell.PackageUtilities].GetMethod(
  812. 'IsCapabilityMatch',
  813. [type[]]([Microsoft.VisualStudio.Shell.Interop.IVsHierarchy], [string]))
  814. return $isCapabilityMatch.Invoke($null, ($hierarchy, 'CPS'))
  815. }
  816. function IsWeb($project)
  817. {
  818. $hierarchy = GetVsHierarchy $project
  819. $aggregatableProject = Get-Interface $hierarchy 'Microsoft.VisualStudio.Shell.Interop.IVsAggregatableProject'
  820. if (!$aggregatableProject)
  821. {
  822. $projectTypes = $project.Kind
  823. }
  824. else
  825. {
  826. $projectTypeGuids = $null
  827. $hr = $aggregatableProject.GetAggregateProjectTypeGuids([ref] $projectTypeGuids)
  828. [Runtime.InteropServices.Marshal]::ThrowExceptionForHR($hr)
  829. $projectTypes = $projectTypeGuids.Split(';')
  830. }
  831. foreach ($projectType in $projectTypes)
  832. {
  833. if ($projectType -in '{349C5851-65DF-11DA-9384-00065B846F21}', '{E24C65DC-7377-472B-9ABA-BC803B73C61A}')
  834. {
  835. return $true
  836. }
  837. }
  838. return $false;
  839. }
  840. function GetIntermediatePath($project)
  841. {
  842. $intermediatePath = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'IntermediatePath'
  843. if ($intermediatePath)
  844. {
  845. return $intermediatePath
  846. }
  847. return GetMSBuildProperty $project 'IntermediateOutputPath'
  848. }
  849. function GetPlatformTarget($project)
  850. {
  851. if (IsCpsProject $project)
  852. {
  853. $platformTarget = GetCpsProperty $project 'PlatformTarget'
  854. if ($platformTarget)
  855. {
  856. return $platformTarget
  857. }
  858. return GetCpsProperty $project 'Platform'
  859. }
  860. $platformTarget = GetProperty $project.ConfigurationManager.ActiveConfiguration.Properties 'PlatformTarget'
  861. if ($platformTarget)
  862. {
  863. return $platformTarget
  864. }
  865. # NB: For classic F# projects
  866. $platformTarget = GetMSBuildProperty $project 'PlatformTarget'
  867. if ($platformTarget)
  868. {
  869. return $platformTarget
  870. }
  871. return 'AnyCPU'
  872. }
  873. function GetLanguage($project)
  874. {
  875. if (IsCpsProject $project)
  876. {
  877. return GetCpsProperty $project 'Language'
  878. }
  879. return GetMSBuildProperty $project 'Language'
  880. }
  881. function GetVsHierarchy($project)
  882. {
  883. $solution = Get-VSService 'Microsoft.VisualStudio.Shell.Interop.SVsSolution' 'Microsoft.VisualStudio.Shell.Interop.IVsSolution'
  884. $hierarchy = $null
  885. $hr = $solution.GetProjectOfUniqueName($project.UniqueName, [ref] $hierarchy)
  886. [Runtime.InteropServices.Marshal]::ThrowExceptionForHR($hr)
  887. return $hierarchy
  888. }
  889. function GetProperty($properties, $propertyName)
  890. {
  891. try
  892. {
  893. return $properties.Item($propertyName).Value
  894. }
  895. catch
  896. {
  897. return $null
  898. }
  899. }
  900. function GetCpsProperty($project, $propertyName)
  901. {
  902. $browseObjectContext = Get-Interface $project 'Microsoft.VisualStudio.ProjectSystem.Properties.IVsBrowseObjectContext'
  903. $unconfiguredProject = $browseObjectContext.UnconfiguredProject
  904. $configuredProject = $unconfiguredProject.GetSuggestedConfiguredProjectAsync().Result
  905. $properties = $configuredProject.Services.ProjectPropertiesProvider.GetCommonProperties()
  906. return $properties.GetEvaluatedPropertyValueAsync($propertyName).Result
  907. }
  908. function GetMSBuildProperty($project, $propertyName)
  909. {
  910. $msbuildProject = [Microsoft.Build.Evaluation.ProjectCollection]::GlobalProjectCollection.LoadedProjects |
  911. where FullPath -eq $project.FullName
  912. return $msbuildProject.GetProperty($propertyName).EvaluatedValue
  913. }
  914. function ToArguments($params)
  915. {
  916. $arguments = ''
  917. for ($i = 0; $i -lt $params.Length; $i++)
  918. {
  919. if ($i)
  920. {
  921. $arguments += ' '
  922. }
  923. if (!$params[$i].Contains(' '))
  924. {
  925. $arguments += $params[$i]
  926. continue
  927. }
  928. $arguments += '"'
  929. $pendingBackslashs = 0
  930. for ($j = 0; $j -lt $params[$i].Length; $j++)
  931. {
  932. switch ($params[$i][$j])
  933. {
  934. '"'
  935. {
  936. if ($pendingBackslashs)
  937. {
  938. $arguments += '\' * $pendingBackslashs * 2
  939. $pendingBackslashs = 0
  940. }
  941. $arguments += '\"'
  942. }
  943. '\'
  944. {
  945. $pendingBackslashs++
  946. }
  947. default
  948. {
  949. if ($pendingBackslashs)
  950. {
  951. if ($pendingBackslashs -eq 1)
  952. {
  953. $arguments += '\'
  954. }
  955. else
  956. {
  957. $arguments += '\' * $pendingBackslashs * 2
  958. }
  959. $pendingBackslashs = 0
  960. }
  961. $arguments += $params[$i][$j]
  962. }
  963. }
  964. }
  965. if ($pendingBackslashs)
  966. {
  967. $arguments += '\' * $pendingBackslashs * 2
  968. }
  969. $arguments += '"'
  970. }
  971. return $arguments
  972. }
  973. function GetConfigPath($project)
  974. {
  975. if (IsWeb $project)
  976. {
  977. $configFileName = 'web.config'
  978. }
  979. else
  980. {
  981. $configFileName = 'app.config'
  982. }
  983. $item = $project.ProjectItems |
  984. where Name -eq $configFileName |
  985. select -First 1
  986. return GetProperty $item.Properties 'FullPath'
  987. }
  988. Export-ModuleMember 'Add-EFDefaultConnectionFactory', 'Add-EFProvider', 'Add-Migration', 'Enable-Migrations', 'Get-Migrations', 'Update-Database' -Variable 'InitialDatabase'
  989. # SIG # Begin signature block
  990. # MIIkXwYJKoZIhvcNAQcCoIIkUDCCJEwCAQExDzANBglghkgBZQMEAgEFADB5Bgor
  991. # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
  992. # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBU8UKKdFAqCZNi
  993. # qPoRSiuscSg+YrZwC3TMOd7p8fuNZKCCDYUwggYDMIID66ADAgECAhMzAAABUptA
  994. # n1BWmXWIAAAAAAFSMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
  995. # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
  996. # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
  997. # bmcgUENBIDIwMTEwHhcNMTkwNTAyMjEzNzQ2WhcNMjAwNTAyMjEzNzQ2WjB0MQsw
  998. # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
  999. # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
  1000. # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
  1001. # AQCxp4nT9qfu9O10iJyewYXHlN+WEh79Noor9nhM6enUNbCbhX9vS+8c/3eIVazS
  1002. # YnVBTqLzW7xWN1bCcItDbsEzKEE2BswSun7J9xCaLwcGHKFr+qWUlz7hh9RcmjYS
  1003. # kOGNybOfrgj3sm0DStoK8ljwEyUVeRfMHx9E/7Ca/OEq2cXBT3L0fVnlEkfal310
  1004. # EFCLDo2BrE35NGRjG+/nnZiqKqEh5lWNk33JV8/I0fIcUKrLEmUGrv0CgC7w2cjm
  1005. # bBhBIJ+0KzSnSWingXol/3iUdBBy4QQNH767kYGunJeY08RjHMIgjJCdAoEM+2mX
  1006. # v1phaV7j+M3dNzZ/cdsz3oDfAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
  1007. # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU3f8Aw1sW72WcJ2bo/QSYGzVrRYcw
  1008. # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
  1009. # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ1NDEzNjAfBgNVHSMEGDAW
  1010. # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
  1011. # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
  1012. # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
  1013. # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
  1014. # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
  1015. # AJTwROaHvogXgixWjyjvLfiRgqI2QK8GoG23eqAgNjX7V/WdUWBbs0aIC3k49cd0
  1016. # zdq+JJImixcX6UOTpz2LZPFSh23l0/Mo35wG7JXUxgO0U+5drbQht5xoMl1n7/TQ
  1017. # 4iKcmAYSAPxTq5lFnoV2+fAeljVA7O43szjs7LR09D0wFHwzZco/iE8Hlakl23ZT
  1018. # 7FnB5AfU2hwfv87y3q3a5qFiugSykILpK0/vqnlEVB0KAdQVzYULQ/U4eFEjnis3
  1019. # Js9UrAvtIhIs26445Rj3UP6U4GgOjgQonlRA+mDlsh78wFSGbASIvK+fkONUhvj8
  1020. # B8ZHNn4TFfnct+a0ZueY4f6aRPxr8beNSUKn7QW/FQmn422bE7KfnqWncsH7vbNh
  1021. # G929prVHPsaa7J22i9wyHj7m0oATXJ+YjfyoEAtd5/NyIYaE4Uu0j1EhuYUo5VaJ
  1022. # JnMaTER0qX8+/YZRWrFN/heps41XNVjiAawpbAa0fUa3R9RNBjPiBnM0gvNPorM4
  1023. # dsV2VJ8GluIQOrJlOvuCrOYDGirGnadOmQ21wPBoGFCWpK56PxzliKsy5NNmAXcE
  1024. # x7Qb9vUjY1WlYtrdwOXTpxN4slzIht69BaZlLIjLVWwqIfuNrhHKNDM9K+v7vgrI
  1025. # bf7l5/665g0gjQCDCN6Q5sxuttTAEKtJeS/pkpI+DbZ/MIIHejCCBWKgAwIBAgIK
  1026. # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
  1027. # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
  1028. # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
  1029. # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
  1030. # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
  1031. # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
  1032. # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
  1033. # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
  1034. # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
  1035. # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
  1036. # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
  1037. # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
  1038. # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
  1039. # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
  1040. # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
  1041. # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
  1042. # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
  1043. # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
  1044. # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
  1045. # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
  1046. # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
  1047. # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
  1048. # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
  1049. # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
  1050. # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
  1051. # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
  1052. # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
  1053. # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
  1054. # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
  1055. # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
  1056. # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
  1057. # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
  1058. # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
  1059. # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
  1060. # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
  1061. # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
  1062. # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
  1063. # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
  1064. # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
  1065. # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCFjAwghYsAgEBMIGVMH4x
  1066. # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
  1067. # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
  1068. # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAFSm0CfUFaZdYgAAAAA
  1069. # AVIwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
  1070. # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEINlr
  1071. # YoMQI0s38aqnYes89d7O1smBsAmM5yEpwvrrBd+CMEIGCisGAQQBgjcCAQwxNDAy
  1072. # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
  1073. # b20wDQYJKoZIhvcNAQEBBQAEggEAA4wFr+j9nOalk2Cbg/LovvaZmWFRfopTwGj9
  1074. # QbzMUO6cby0vTfP/4Mn2UI603aPDCIt96YavP5mbGk2oIHe51CZLRkVZyv2dO0l4
  1075. # McDfHEbRYUQ7Ya9FEfpF9FJ5sieT8hKbqkj0ajqLAHEmW6kVmioXqj0xQya3j5zI
  1076. # 7t2WnMIDsUNLWYI3dlLo50rPd87ZVxWnDIE2IVhyMMtsK5urrL4WYcgGjT8jihVE
  1077. # FbQo9nL5y1hWd0ZSGMfLwCoVmDq4wVki9f5WjT/gPkrS/F+TrP+GZZPvyrhf0PTN
  1078. # R0BJPgugbrZr/lfPpPfb8r367uJYNIq0ChMNLrUdmAUWLQn23aGCE7owghO2Bgor
  1079. # BgEEAYI3AwMBMYITpjCCE6IGCSqGSIb3DQEHAqCCE5MwghOPAgEDMQ8wDQYJYIZI
  1080. # AWUDBAIBBQAwggFYBgsqhkiG9w0BCRABBKCCAUcEggFDMIIBPwIBAQYKKwYBBAGE
  1081. # WQoDATAxMA0GCWCGSAFlAwQCAQUABCARzTf7SSdAq/qlhyAN9oDwFAkk/oxC+YnX
  1082. # h2AQyOBq8gIGXno7qpjuGBMyMDIwMDQxNjIyMTM0MC45NDFaMAcCAQGAAgH0oIHU
  1083. # pIHRMIHOMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
  1084. # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYD
  1085. # VQQLEyBNaWNyb3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMd
  1086. # VGhhbGVzIFRTUyBFU046NTg0Ny1GNzYxLTRGNzAxJTAjBgNVBAMTHE1pY3Jvc29m
  1087. # dCBUaW1lLVN0YW1wIFNlcnZpY2Wggg8iMIIE9TCCA92gAwIBAgITMwAAAQUHOepZ
  1088. # 81W/KgAAAAABBTANBgkqhkiG9w0BAQsFADB8MQswCQYDVQQGEwJVUzETMBEGA1UE
  1089. # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
  1090. # b2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQ
  1091. # Q0EgMjAxMDAeFw0xOTA5MDYyMDQxMThaFw0yMDEyMDQyMDQxMThaMIHOMQswCQYD
  1092. # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe
  1093. # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNyb3Nv
  1094. # ZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRTUyBF
  1095. # U046NTg0Ny1GNzYxLTRGNzAxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1w
  1096. # IFNlcnZpY2UwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDMIpZjVUiL
  1097. # WQGqDFLLaeGfhc9bxCwi8HQx+gcaF5Zz2GodhM71oyjal6uqnRM8QHxj49uKFmY/
  1098. # SWEhlV+so3IrmEHVLmskeEQaio5PxVgUWRm+sBIJpS9GjwKrGPZ2ub4ST2J9fu5F
  1099. # xbfTmJyB2AL6W7WcSUON8tyuz2/NRAII6YuojdMa6mjVXamL2AS7PBo1GW4Pa4Xb
  1100. # NhEQoA4/siS4JGbcfAwVMGv87bhKapDqpXLbDq6LbFdLAv7Q7eUHiHS4eccXRNGA
  1101. # npkdhHOK7s1O9FqpRZYsbx/UpkaoyqiQe/JFTA+1keYZsZgaQqgPNpGYD50SDDyQ
  1102. # Z2vtNx7KVgXtAgMBAAGjggEbMIIBFzAdBgNVHQ4EFgQUPXQb/rp3KEzK6DYOy3Fn
  1103. # /QIzNyIwHwYDVR0jBBgwFoAU1WM6XIoxkPNDe3xGG8UzaFqFbVUwVgYDVR0fBE8w
  1104. # TTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVj
  1105. # dHMvTWljVGltU3RhUENBXzIwMTAtMDctMDEuY3JsMFoGCCsGAQUFBwEBBE4wTDBK
  1106. # BggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9N
  1107. # aWNUaW1TdGFQQ0FfMjAxMC0wNy0wMS5jcnQwDAYDVR0TAQH/BAIwADATBgNVHSUE
  1108. # DDAKBggrBgEFBQcDCDANBgkqhkiG9w0BAQsFAAOCAQEAp85hd3trAVfmVAPmcOAq
  1109. # nM47TbWB9S0ySGG/eNvIfhgYC0YjCLEZhiiQyOeRTws0lIOWGv7tM5tr70RGzNo1
  1110. # /C7SQadqQ2dT5sUj7Ga6LHO2excdzRvUIwdeOaVuaj4VpiXnhjPBRu2CVNGXPe1d
  1111. # 7Zzw7di8xh2D6ooZBjhHLh7yGf2ZFjBjLcDVjrfaLwd4YqefJgg42s8EMUoXzsTp
  1112. # PlS0IBKWeX+RbBycOUhXpK9qlvFbBQGp4N+uLEV6haG33oVOtWwrbhu5F0E4UDzs
  1113. # FUaZ8OALyKraR1dIo+ZU+zjpn3Na7KUkrT/1UFYdnWYwoUDm9e+DmBhqdhUlxIhR
  1114. # nzCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZIhvcNAQELBQAwgYgxCzAJ
  1115. # BgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25k
  1116. # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jv
  1117. # c29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDEwMB4XDTEwMDcwMTIx
  1118. # MzY1NVoXDTI1MDcwMTIxNDY1NVowfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldh
  1119. # c2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
  1120. # b3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENBIDIw
  1121. # MTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCpHQ28dxGKOiDs/BOX
  1122. # 9fp/aZRrdFQQ1aUKAIKF++18aEssX8XD5WHCdrc+Zitb8BVTJwQxH0EbGpUdzgkT
  1123. # jnxhMFmxMEQP8WCIhFRDDNdNuDgIs0Ldk6zWczBXJoKjRQ3Q6vVHgc2/JGAyWGBG
  1124. # 8lhHhjKEHnRhZ5FfgVSxz5NMksHEpl3RYRNuKMYa+YaAu99h/EbBJx0kZxJyGiGK
  1125. # r0tkiVBisV39dx898Fd1rL2KQk1AUdEPnAY+Z3/1ZsADlkR+79BL/W7lmsqxqPJ6
  1126. # Kgox8NpOBpG2iAg16HgcsOmZzTznL0S6p/TcZL2kAcEgCZN4zfy8wMlEXV4WnAEF
  1127. # TyJNAgMBAAGjggHmMIIB4jAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU1WM6
  1128. # XIoxkPNDe3xGG8UzaFqFbVUwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwCwYD
  1129. # VR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU1fZWy4/oolxi
  1130. # aNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2NybC5taWNyb3Nv
  1131. # ZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMu
  1132. # Y3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDovL3d3dy5taWNy
  1133. # b3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0wNi0yMy5jcnQw
  1134. # gaAGA1UdIAEB/wSBlTCBkjCBjwYJKwYBBAGCNy4DMIGBMD0GCCsGAQUFBwIBFjFo
  1135. # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3MvQ1BTL2RlZmF1bHQuaHRt
  1136. # MEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAAbwBsAGkAYwB5AF8AUwB0
  1137. # AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQAH5ohRDeLG4Jg/
  1138. # gXEDPZ2joSFvs+umzPUxvs8F4qn++ldtGTCzwsVmyWrf9efweL3HqJ4l4/m87WtU
  1139. # VwgrUYJEEvu5U4zM9GASinbMQEBBm9xcF/9c+V4XNZgkVkt070IQyK+/f8Z/8jd9
  1140. # Wj8c8pl5SpFSAK84Dxf1L3mBZdmptWvkx872ynoAb0swRCQiPM/tA6WWj1kpvLb9
  1141. # BOFwnzJKJ/1Vry/+tuWOM7tiX5rbV0Dp8c6ZZpCM/2pif93FSguRJuI57BlKcWOd
  1142. # eyFtw5yjojz6f32WapB4pm3S4Zz5Hfw42JT0xqUKloakvZ4argRCg7i1gJsiOCC1
  1143. # JeVk7Pf0v35jWSUPei45V3aicaoGig+JFrphpxHLmtgOR5qAxdDNp9DvfYPw4Ttx
  1144. # Cd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir995yfmFrb3epgcunCaw5
  1145. # u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7COaYLeqN4DMuEin1wC9U
  1146. # JyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7dDJL32N79ZmKLxvHIa9Z
  1147. # ta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+mdHhk4L7zPWAUu7w2gUDXa
  1148. # 7wknHNWzfjUeCLraNtvTX4/edIhJEqGCA7AwggKYAgEBMIH+oYHUpIHRMIHOMQsw
  1149. # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
  1150. # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSkwJwYDVQQLEyBNaWNy
  1151. # b3NvZnQgT3BlcmF0aW9ucyBQdWVydG8gUmljbzEmMCQGA1UECxMdVGhhbGVzIFRT
  1152. # UyBFU046NTg0Ny1GNzYxLTRGNzAxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0
  1153. # YW1wIFNlcnZpY2WiJQoBATAJBgUrDgMCGgUAAxUA0nmc7MiH2Pr0x33n13Zg4RlV
  1154. # 9qqggd4wgdukgdgwgdUxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u
  1155. # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp
  1156. # b24xKTAnBgNVBAsTIE1pY3Jvc29mdCBPcGVyYXRpb25zIFB1ZXJ0byBSaWNvMScw
  1157. # JQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NERFOS0wQzVFLTNFMDkxKzApBgNVBAMT
  1158. # Ik1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZIhvcNAQEF
  1159. # BQACBQDiQwziMCIYDzIwMjAwNDE3MDA1NzA2WhgPMjAyMDA0MTgwMDU3MDZaMHcw
  1160. # PQYKKwYBBAGEWQoEATEvMC0wCgIFAOJDDOICAQAwCgIBAAICGcICAf8wBwIBAAIC
  1161. # GH4wCgIFAOJEXmICAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAaAK
  1162. # MAgCAQACAxbjYKEKMAgCAQACAwehIDANBgkqhkiG9w0BAQUFAAOCAQEATA6xpN+7
  1163. # +epEr0I3lwl33d7P6eYuhfTZxDtgP5dr9jnFv/10jXgI47Qs0KHY4jwkeLZ9ExCM
  1164. # muBD0RcyOx/T0xkUANz57TNPssoqTztK5hHmt6ZmwTNyzUYxVJ8ARFPp62WhWiJ9
  1165. # Tt9vKtuPrDIuVuHzxjY63QEPhZ1+UYAnQwu+DT1XPG1rikQOEXBM9MkzTgD/8AxY
  1166. # prHt87u+g7MObUd0t1sAyJI+0lzgJRlqeEAw5pW4CfkzGfEGXPgT/HfjWVIc176l
  1167. # C0ntYiOma8s4znFps5hAgnxSApopGy9c9QuuNuOfiSNa3/L5ws6RYulq/qHTuifW
  1168. # gZ90UMQ7TrA2VjGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQI
  1169. # EwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
  1170. # ZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBD
  1171. # QSAyMDEwAhMzAAABBQc56lnzVb8qAAAAAAEFMA0GCWCGSAFlAwQCAQUAoIIBMjAa
  1172. # BgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIEIjFCBe
  1173. # 4MtXOBW+4EQjXEL8OLx5+eGw0ZT8w0o9gW4DMIHiBgsqhkiG9w0BCRACDDGB0jCB
  1174. # zzCBzDCBsQQU0nmc7MiH2Pr0x33n13Zg4RlV9qowgZgwgYCkfjB8MQswCQYDVQQG
  1175. # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
  1176. # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNyb3NvZnQg
  1177. # VGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAQUHOepZ81W/KgAAAAABBTAWBBS6OC+C
  1178. # 8E5t3KIl3SZn6YRcv4X++TANBgkqhkiG9w0BAQsFAASCAQBtzHRroeehPY5IFmFC
  1179. # 0CCu+fgjt2iyDYX1P1rHZUyU1YseSFj4GEaOj5vSW2VKxlJzVl0C5/xZjQCZ73+j
  1180. # xRFZaUKSVkh5rPDV7++x6wUcCYAfj+b0QwRh5XH3HYMB8HUwusbG2WRnZCpjmrB6
  1181. # EQfRZcvyWiD+Lcc+QXgt0/JyOEtVpMIfwWclbYX3wltt9H3Q1PXQy5pf26A5Yu6Q
  1182. # 58h3xsTXCXyJZ3jUrP6qImMS4KrsXrgh6OQWczyL3E+dzOm2OvF8QfErkK0ooXGh
  1183. # zbodmkxNfq4WhN/BpRMKsRi8QdURQ1q3qLB2GJ4JjgLBzkhXvEtWD1xqF9AINmTe
  1184. # 3n5C
  1185. # SIG # End signature block