OSS인증 - 팀장 : 서영민 - 팀원 : 김현, 박상진, 박승영, 윤동수, 김성미
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

441 lines
22 KiB

4 years ago
  1. # Copyright (c) .NET Foundation. All rights reserved.
  2. # Licensed under the MIT license. See LICENSE file in the project root for full license information.
  3. ##
  4. ## Assigning a "DefaultValue" to a ParameterDescription will result in emitting this parameter when
  5. ## writing out a default compiler declaration.
  6. ##
  7. ## Setting IsRequired to $true will require the attribute to be set on all declarations in config.
  8. ##
  9. Add-Type @"
  10. using System;
  11. public class CompilerParameterDescription {
  12. public string Name;
  13. public string DefaultValue;
  14. public bool IsRequired;
  15. public bool IsProviderOption;
  16. }
  17. public class CodeDomProviderDescription {
  18. public string TypeName;
  19. public string Assembly;
  20. public string Version;
  21. public string FileExtension;
  22. public CompilerParameterDescription[] Parameters;
  23. }
  24. "@
  25. function InstallCodeDomProvider($providerDescription) {
  26. ##### Update/Rehydrate config declarations #####
  27. $config = ReadConfigFile
  28. $rehydratedCount = RehydrateOldDeclarations $config $providerDescription
  29. $updatedCount = UpdateDeclarations $config $providerDescription
  30. ##### Add the default provider if it wasn't rehydrated above
  31. $defaultProvider = $config.xml.configuration["system.codedom"].compilers.compiler | where { $_.extension -eq $providerDescription.FileExtension }
  32. if ($defaultProvider -eq $null) { AddDefaultDeclaration $config $providerDescription }
  33. SaveConfigFile $config
  34. }
  35. function UninstallCodeDomProvider($providerType) {
  36. ##### Dehydrate config declarations #####
  37. $config = ReadConfigFile
  38. DehydrateDeclarations $config $providerType | Out-Null
  39. SaveConfigFile $config
  40. }
  41. function GetConfigFileName() {
  42. # Try web.config first. Then fall back to app.config.
  43. $configFile = $project.ProjectItems | where { $_.Name -ieq "web.config" }
  44. if ($configFile -eq $null) { $configFile = $project.ProjectItems | where { $_.Name -ieq "app.config" } }
  45. $configPath = $configFile.Properties | where { $_.Name -ieq "LocalPath" }
  46. if ($configPath -eq $null) { $configPath = $configFile.Properties | where { $_.Name -ieq "FullPath" } }
  47. return $configPath.Value
  48. }
  49. function GetTempFileName() {
  50. $uname = $project.UniqueName
  51. if ([io.path]::IsPathRooted($uname)) { $uname = $project.Name }
  52. return [io.path]::Combine($env:TEMP, "Microsoft.CodeDom.Providers.DotNetCompilerPlatform.Temp", $uname + ".xml")
  53. }
  54. function ReadConfigFile() {
  55. $configFile = GetConfigFileName
  56. $configObj = @{ fileName = $configFile; xml = (Select-Xml -Path "$configFile" -XPath /).Node }
  57. $configObj.xml.PreserveWhitespace = $true
  58. return $configObj
  59. }
  60. function DehydrateDeclarations($config, $typeName) {
  61. $tempFile = GetTempFileName
  62. $xml
  63. $count = 0
  64. if ([io.file]::Exists($tempFile)) {
  65. $xml = (Select-Xml -Path "$tempFile" -XPath /).Node
  66. $xml.PreserveWhitespace = $true
  67. } else {
  68. $xml = New-Object System.Xml.XmlDocument
  69. $xml.PreserveWhitespace = $true
  70. $dd = $xml.CreateElement("driedDeclarations")
  71. $xml.AppendChild($dd) | Out-Null
  72. }
  73. foreach ($rec in $config.xml.configuration["system.codedom"].compilers.compiler | where { IsSameType $_.type $typeName }) {
  74. # Remove records from config.
  75. $config.xml.configuration["system.codedom"].compilers.RemoveChild($rec) | Out-Null
  76. # Add the record to the temp stash. Don't worry about duplicates.
  77. AppendChildNode $xml.ImportNode($rec, $true) $xml.DocumentElement
  78. $count++
  79. }
  80. # Save the dehydrated declarations
  81. $tmpFolder = Split-Path $tempFile
  82. md -Force $tmpFolder | Out-Null
  83. $xml.Save($tempFile) | Out-Null
  84. return $count
  85. }
  86. function RehydrateOldDeclarations($config, $providerDescription) {
  87. $tempFile = GetTempFileName
  88. if (![io.file]::Exists($tempFile)) { return 0 }
  89. $count = 0
  90. $xml = (Select-Xml -Path "$tempFile" -XPath /).Node
  91. $xml.PreserveWhitespace = $true
  92. foreach($rec in $xml.driedDeclarations.compiler | where { IsSameType $_.type ($providerDescription.TypeName + "," + $providerDescription.Assembly) }) {
  93. # Remove records that match type, even if we don't end up rehydrating them.
  94. $xml.driedDeclarations.RemoveChild($rec) | Out-Null
  95. # Skip if an existing record of the same file extension already exists.
  96. $existingRecord = $config.xml.configuration["system.codedom"].compilers.compiler | where { $_.extension -eq $rec.extension }
  97. if ($existingRecord -ne $null) { continue }
  98. # Bring the record back to life
  99. AppendChildNode $config.xml.ImportNode($rec, $true) $config.xml.configuration["system.codedom"]["compilers"]
  100. $count++
  101. }
  102. # Make dried record removal permanent
  103. $xml.Save($tempFile) | Out-Null
  104. return $count
  105. }
  106. function UpdateDeclarations($config, $providerDescription) {
  107. $count = 0
  108. foreach ($provider in $config.xml.configuration["system.codedom"].compilers.compiler | where { IsSameType $_.type ($providerDescription.TypeName + "," + $providerDescription.Assembly) }) {
  109. # Count the existing declaration as found
  110. $count++
  111. # Update type
  112. $provider.type = "$($providerDescription.TypeName), $($providerDescription.Assembly), Version=$($providerDescription.Version), Culture=neutral, PublicKeyToken=31bf3856ad364e35"
  113. # Add default attributes if they are required and not already present
  114. foreach ($p in $providerDescription.Parameters | where { ($_.IsRequired -eq $true) -and ($_.IsProviderOption -eq $false) }) {
  115. if ($provider.($p.Name) -eq $null) {
  116. if ($p.DefaultValue -eq $null) {
  117. Write-Host "Failed to add parameter to '$($provider.name)' codeDom provider: '$($p.Name)' is required, but does not have a default value."
  118. return
  119. }
  120. $attr = $config.xml.CreateAttribute($p.Name)
  121. $attr.Value = $p.DefaultValue
  122. $provider.Attributes.InsertBefore($attr, $provider.Attributes["type"]) | Out-Null
  123. }
  124. }
  125. # Do the same thing for default providerOptions if not already present
  126. foreach ($p in $providerDescription.Parameters | where { ($_.IsRequired -eq $true) -and ($_.IsProviderOption -eq $true)}) {
  127. $existing = $provider.providerOption | where { $_.name -eq $p.Name }
  128. if ($existing -eq $null) {
  129. if ($p.DefaultValue -eq $null) {
  130. Write-Host "Failed to add providerOption to '$($provider.name)' codeDom provider: '$($p.Name)' is required, but does not have a default value."
  131. return
  132. }
  133. $po = $config.xml.CreateElement("providerOption")
  134. $po.SetAttribute("name", $p.Name)
  135. $po.SetAttribute("value", $p.DefaultValue)
  136. AppendChildNode $po $provider 4
  137. }
  138. }
  139. }
  140. return $count
  141. }
  142. function AddDefaultDeclaration($config, $providerDescription) {
  143. $dd = $config.xml.CreateElement("compiler")
  144. # file extension first
  145. $dd.SetAttribute("extension", $providerDescription.FileExtension)
  146. # everything else in the middle
  147. foreach ($p in $providerDescription.Parameters) {
  148. if ($p.IsRequired -and ($p.DefaultValue -eq $null)) {
  149. Write-Host "Failed to add default declaration for code dom extension '$($providerDescription.FileExtension)': '$($p.Name)' is required, but does not have a default value."
  150. return
  151. }
  152. if ($p.DefaultValue -ne $null) {
  153. if ($p.IsProviderOption -eq $true) {
  154. $po = $config.xml.CreateElement("providerOption")
  155. $po.SetAttribute("name", $p.Name)
  156. $po.SetAttribute("value", $p.DefaultValue)
  157. AppendChildNode $po $dd 4
  158. } else {
  159. $dd.SetAttribute($p.Name, $p.DefaultValue)
  160. }
  161. }
  162. }
  163. # type last
  164. $dd.SetAttribute("type", "$($providerDescription.TypeName), $($providerDescription.Assembly), Version=$($providerDescription.Version), Culture=neutral, PublicKeyToken=31bf3856ad364e35")
  165. AppendChildNode $dd $config.xml.configuration["system.codedom"]["compilers"]
  166. }
  167. function AppendChildNode($provider, $parent, $indentLevel = 3) {
  168. $lastSibling = $parent.ChildNodes | where { $_ -isnot [System.Xml.XmlWhitespace] } | select -Last 1
  169. if ($lastSibling -ne $null) {
  170. # If not the first child, then copy the whitespace convention of the existing child
  171. $ws = "";
  172. $prev = $lastSibling.PreviousSibling | where { $_ -is [System.Xml.XmlWhitespace] }
  173. while ($prev -ne $null) {
  174. $ws = $prev.data + $ws
  175. $prev = $prev.PreviousSibling | where { $_ -is [System.Xml.XmlWhitespace] }
  176. }
  177. $parent.InsertAfter($provider, $lastSibling) | Out-Null
  178. if ($ws.length -gt 0) { $parent.InsertAfter($parent.OwnerDocument.CreateWhitespace($ws), $lastSibling) | Out-Null }
  179. return
  180. }
  181. # Add on a new line with indents. Make sure there is no existing whitespace mucking this up.
  182. foreach ($exws in $parent.ChildNodes | where { $_ -is [System.Xml.XmlWhitespace] }) { $parent.RemoveChild($exws) }
  183. $parent.AppendChild($parent.OwnerDocument.CreateWhitespace("`r`n")) | Out-Null
  184. $parent.AppendChild($parent.OwnerDocument.CreateWhitespace(" " * $indentLevel)) | Out-Null
  185. $parent.AppendChild($provider) | Out-Null
  186. $parent.AppendChild($parent.OwnerDocument.CreateWhitespace("`r`n")) | Out-Null
  187. $parent.AppendChild($parent.OwnerDocument.CreateWhitespace(" " * ($indentLevel - 1))) | Out-Null
  188. }
  189. function SaveConfigFile($config) {
  190. $config.xml.Save($config.fileName)
  191. }
  192. function IsSameType($typeString1, $typeString2) {
  193. if (($typeString1 -eq $null) -or ($typeString2 -eq $null)) { return $false }
  194. # First check the type
  195. $t1 = $typeString1.Split(',')[0].Trim()
  196. $t2 = $typeString2.Split(',')[0].Trim()
  197. if ($t1 -cne $t2) { return $false }
  198. # Then check for assembly match if possible
  199. $a1 = $typeString1.Split(',')[1]
  200. $a2 = $typeString2.Split(',')[1]
  201. if (($a1 -ne $null) -and ($a2 -ne $null)) {
  202. return ($a1.Trim() -eq $a2.Trim())
  203. }
  204. # Don't care about assembly. Match is good.
  205. return $true
  206. }
  207. # SIG # Begin signature block
  208. # MIIjigYJKoZIhvcNAQcCoIIjezCCI3cCAQExDzANBglghkgBZQMEAgEFADB5Bgor
  209. # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
  210. # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAKaw8D28PUyqaj
  211. # 8cg1N507irkPJtijF01kKz3vbQKlfqCCDYUwggYDMIID66ADAgECAhMzAAABiK9S
  212. # 1rmSbej5AAAAAAGIMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD
  213. # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
  214. # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p
  215. # bmcgUENBIDIwMTEwHhcNMjAwMzA0MTgzOTQ4WhcNMjEwMzAzMTgzOTQ4WjB0MQsw
  216. # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u
  217. # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy
  218. # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB
  219. # AQCSCNryE+Cewy2m4t/a74wZ7C9YTwv1PyC4BvM/kSWPNs8n0RTe+FvYfU+E9uf0
  220. # t7nYlAzHjK+plif2BhD+NgdhIUQ8sVwWO39tjvQRHjP2//vSvIfmmkRoML1Ihnjs
  221. # 9kQiZQzYRDYYRp9xSQYmRwQjk5hl8/U7RgOiQDitVHaU7BT1MI92lfZRuIIDDYBd
  222. # vXtbclYJMVOwqZtv0O9zQCret6R+fRSGaDNfEEpcILL+D7RV3M4uaJE4Ta6KAOdv
  223. # V+MVaJp1YXFTZPKtpjHO6d9pHQPZiG7NdC6QbnRGmsa48uNQrb6AfmLKDI1Lp31W
  224. # MogTaX5tZf+CZT9PSuvjOCLNAgMBAAGjggGCMIIBfjAfBgNVHSUEGDAWBgorBgEE
  225. # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQUj9RJL9zNrPcL10RZdMQIXZN7MG8w
  226. # VAYDVR0RBE0wS6RJMEcxLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
  227. # dGlvbnMgTGltaXRlZDEWMBQGA1UEBRMNMjMwMDEyKzQ1ODM4NjAfBgNVHSMEGDAW
  228. # gBRIbmTlUAXTgqoXNzcitW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8v
  229. # d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIw
  230. # MTEtMDctMDguY3JsMGEGCCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDov
  231. # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDEx
  232. # XzIwMTEtMDctMDguY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIB
  233. # ACnXo8hjp7FeT+H6iQlV3CcGnkSbFvIpKYafgzYCFo3UHY1VHYJVb5jHEO8oG26Q
  234. # qBELmak6MTI+ra3WKMTGhE1sEIlowTcp4IAs8a5wpCh6Vf4Z/bAtIppP3p3gXk2X
  235. # 8UXTc+WxjQYsDkFiSzo/OBa5hkdW1g4EpO43l9mjToBdqEPtIXsZ7Hi1/6y4gK0P
  236. # mMiwG8LMpSn0n/oSHGjrUNBgHJPxgs63Slf58QGBznuXiRaXmfTUDdrvhRocdxIM
  237. # i8nXQwWACMiQzJSRzBP5S2wUq7nMAqjaTbeXhJqD2SFVHdUYlKruvtPSwbnqSRWT
  238. # GI8s4FEXt+TL3w5JnwVZmZkUFoioQDMMjFyaKurdJ6pnzbr1h6QW0R97fWc8xEIz
  239. # LIOiU2rjwWAtlQqFO8KNiykjYGyEf5LyAJKAO+rJd9fsYR+VBauIEQoYmjnUbTXM
  240. # SY2Lf5KMluWlDOGVh8q6XjmBccpaT+8tCfxpaVYPi1ncnwTwaPQvVq8RjWDRB7Pa
  241. # 8ruHgj2HJFi69+hcq7mWx5nTUtzzFa7RSZfE5a1a5AuBmGNRr7f8cNfa01+tiWjV
  242. # Kk1a+gJUBSP0sIxecFbVSXTZ7bqeal45XSDIisZBkWb+83TbXdTGMDSUFKTAdtC+
  243. # r35GfsN8QVy59Hb5ZYzAXczhgRmk7NyE6jD0Ym5TKiW5MIIHejCCBWKgAwIBAgIK
  244. # YQ6Q0gAAAAAAAzANBgkqhkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNV
  245. # BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
  246. # c29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlm
  247. # aWNhdGUgQXV0aG9yaXR5IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEw
  248. # OTA5WjB+MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
  249. # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYD
  250. # VQQDEx9NaWNyb3NvZnQgQ29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG
  251. # 9w0BAQEFAAOCAg8AMIICCgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+la
  252. # UKq4BjgaBEm6f8MMHt03a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc
  253. # 6Whe0t+bU7IKLMOv2akrrnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4D
  254. # dato88tt8zpcoRb0RrrgOGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+
  255. # lD3v++MrWhAfTVYoonpy4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nk
  256. # kDstrjNYxbc+/jLTswM9sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6
  257. # A4aN91/w0FK/jJSHvMAhdCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmd
  258. # X4jiJV3TIUs+UsS1Vz8kA/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL
  259. # 5zmhD+kjSbwYuER8ReTBw3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zd
  260. # sGbiwZeBe+3W7UvnSSmnEyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3
  261. # T8HhhUSJxAlMxdSlQy90lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS
  262. # 4NaIjAsCAwEAAaOCAe0wggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRI
  263. # bmTlUAXTgqoXNzcitW2oynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAL
  264. # BgNVHQ8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBD
  265. # uRQFTuHqp8cx0SOJNDBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jv
  266. # c29mdC5jb20vcGtpL2NybC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
  267. # MDNfMjIuY3JsMF4GCCsGAQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3
  268. # dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFf
  269. # MDNfMjIuY3J0MIGfBgNVHSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEF
  270. # BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1h
  271. # cnljcHMuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkA
  272. # YwB5AF8AcwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn
  273. # 8oalmOBUeRou09h0ZyKbC5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7
  274. # v0epo/Np22O/IjWll11lhJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0b
  275. # pdS1HXeUOeLpZMlEPXh6I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/
  276. # KmtYSWMfCWluWpiW5IP0wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvy
  277. # CInWH8MyGOLwxS3OW560STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBp
  278. # mLJZiWhub6e3dMNABQamASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJi
  279. # hsMdYzaXht/a8/jyFqGaJ+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYb
  280. # BL7fQccOKO7eZS/sl/ahXJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbS
  281. # oqKfenoi+kiVH6v7RyOA9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sL
  282. # gOppO6/8MO0ETI7f33VtY5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtX
  283. # cVZOSEXAQsmbdlsKgEhr/Xmfwb1tbWrJUnMTDXpQzTGCFVswghVXAgEBMIGVMH4x
  284. # CzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRt
  285. # b25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01p
  286. # Y3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIwMTECEzMAAAGIr1LWuZJt6PkAAAAA
  287. # AYgwDQYJYIZIAWUDBAIBBQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQw
  288. # HAYKKwYBBAGCNwIBCzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIL5x
  289. # 0or5GQPS6af3tBiDwBk2UUOeG6wM9iNlhfHGNf+1MEIGCisGAQQBgjcCAQwxNDAy
  290. # oBSAEgBNAGkAYwByAG8AcwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
  291. # b20wDQYJKoZIhvcNAQEBBQAEggEATGapXiAQNux1fvxhV7On0D6F41Wxiek4L+4d
  292. # r0oeClirnH/LS/x/BIo/5jxTX7PSCBO+RoCjnX1UzVk+eXHLVt0ah0y2XktYBjI0
  293. # 7hvKQg2oC24LWbMNbRqNV/NuhXBQqPBrRJS8pd0FEbg4AclzmBWyvE3OAlYOouy3
  294. # A0M4Tj+w5hgg0MRTQ1XCyg5QeGvrmHg+NSejBQrCgatwhB4zr8QkARjyx7n6OBpj
  295. # JNQrsDog02X9mxJglQqBtNw2wqiOVjoZ6yOBJu50I5chgN7jrDZOkiNHzhj71G9O
  296. # xCcghyt+DSxsxNWT4kOeUijaIBazfNeQgH2CrWjabbDBU96rR6GCEuUwghLhBgor
  297. # BgEEAYI3AwMBMYIS0TCCEs0GCSqGSIb3DQEHAqCCEr4wghK6AgEDMQ8wDQYJYIZI
  298. # AWUDBAIBBQAwggFRBgsqhkiG9w0BCRABBKCCAUAEggE8MIIBOAIBAQYKKwYBBAGE
  299. # WQoDATAxMA0GCWCGSAFlAwQCAQUABCAIxnYmZyKGatNcxpWyN2p/5x8E5+Oxdr7E
  300. # usWmDSl8kwIGXvOkDyUPGBMyMDIwMDcwODIxNTQyMy4wODFaMASAAgH0oIHQpIHN
  301. # MIHKMQswCQYDVQQGEwJVUzELMAkGA1UECBMCV0ExEDAOBgNVBAcTB1JlZG1vbmQx
  302. # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9z
  303. # b2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1pdGVkMSYwJAYDVQQLEx1UaGFsZXMg
  304. # VFNTIEVTTjo4NkRGLTRCQkMtOTMzNTElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUt
  305. # U3RhbXAgU2VydmljZaCCDjwwggTxMIID2aADAgECAhMzAAABD4By9jqHCIitAAAA
  306. # AAEPMA0GCSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo
  307. # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y
  308. # cG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEw
  309. # MB4XDTE5MTAyMzIzMTkxOFoXDTIxMDEyMTIzMTkxOFowgcoxCzAJBgNVBAYTAlVT
  310. # MQswCQYDVQQIEwJXQTEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z
  311. # b2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVy
  312. # YXRpb25zIExpbWl0ZWQxJjAkBgNVBAsTHVRoYWxlcyBUU1MgRVNOOjg2REYtNEJC
  313. # Qy05MzM1MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIB
  314. # IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA3005QKre87GV4WKCCDXMQWYH
  315. # 5eWI0RsTG+2ZUI1Ana3OpPvM2mx32cdM5bSGx80uyTwvPEoKwgLPzJivRQcVw65y
  316. # dOdICgWYp6BECNwkiRGcOFrnwk/DuhQgJm5+TGq3rUnaoDiuJflc/gTlQ9C4qE0W
  317. # r19gnoOIiWBk3TspV4nmK6Q03fUZk4lAmIuFbuBBWViaGdmGqUxU2Fe8CHLgCGSg
  318. # 6LL/hGf8FSS98UmtX6AGAn/8PKhEW/DVYmpYzh9nxNy3+aEHoP4/+M1a5ie8YqT8
  319. # jTd5pbcSe2dV8hkOx/ZC7ZrFrxrAMJdEFlWuWVj+1L10fojPPQw/31VU7p3DMwID
  320. # AQABo4IBGzCCARcwHQYDVR0OBBYEFOeVIYAZbVLGoBeW7HaqypbvGOV7MB8GA1Ud
  321. # IwQYMBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0
  322. # dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0
  323. # YVBDQV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKG
  324. # Pmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENB
  325. # XzIwMTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUH
  326. # AwgwDQYJKoZIhvcNAQELBQADggEBAFCCsTZ3FVppoaTLKFatxHl9n4WEyxHgyeh4
  327. # g3d83G7xLKIBX6be8avIga+GKYT6oYLOsmWsiuTRDOsjlxMew2Gjx99iRCyh2t5F
  328. # s91bF5SAFKyZORb1F2BGUtqNzoNhd0QbxrVEB83uGUfq6UgjYr0b42WLex0Df8+L
  329. # nFolQwiWXqvsjQoIBU3K1ilthYo+Ta3mHDrwaMevcR8jWu37qdoEqjtoex+baCDe
  330. # S0PebIUbfB3ERgC2spuFjrI0OTvbP+MqSybPOMymNpzECY2XuuMBA7heVJAGUAZK
  331. # 9csdRtB0j/ELCxm1xAVT/W4uZrtuarqA1bgeKPN9nisHMzZN2X4wggZxMIIEWaAD
  332. # AgECAgphCYEqAAAAAAACMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzET
  333. # MBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMV
  334. # TWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBD
  335. # ZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0xMDA3MDEyMTM2NTVaFw0yNTA3
  336. # MDEyMTQ2NTVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw
  337. # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
  338. # JjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIIBIjANBgkq
  339. # hkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqR0NvHcRijog7PwTl/X6f2mUa3RUENWl
  340. # CgCChfvtfGhLLF/Fw+Vhwna3PmYrW/AVUycEMR9BGxqVHc4JE458YTBZsTBED/Fg
  341. # iIRUQwzXTbg4CLNC3ZOs1nMwVyaCo0UN0Or1R4HNvyRgMlhgRvJYR4YyhB50YWeR
  342. # X4FUsc+TTJLBxKZd0WETbijGGvmGgLvfYfxGwScdJGcSchohiq9LZIlQYrFd/Xcf
  343. # PfBXday9ikJNQFHRD5wGPmd/9WbAA5ZEfu/QS/1u5ZrKsajyeioKMfDaTgaRtogI
  344. # Neh4HLDpmc085y9Euqf03GS9pAHBIAmTeM38vMDJRF1eFpwBBU8iTQIDAQABo4IB
  345. # 5jCCAeIwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNVjOlyKMZDzQ3t8RhvF
  346. # M2hahW1VMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAP
  347. # BgNVHRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFNX2VsuP6KJcYmjRPZSQW9fOmhjE
  348. # MFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kv
  349. # Y3JsL3Byb2R1Y3RzL01pY1Jvb0NlckF1dF8yMDEwLTA2LTIzLmNybDBaBggrBgEF
  350. # BQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
  351. # a2kvY2VydHMvTWljUm9vQ2VyQXV0XzIwMTAtMDYtMjMuY3J0MIGgBgNVHSABAf8E
  352. # gZUwgZIwgY8GCSsGAQQBgjcuAzCBgTA9BggrBgEFBQcCARYxaHR0cDovL3d3dy5t
  353. # aWNyb3NvZnQuY29tL1BLSS9kb2NzL0NQUy9kZWZhdWx0Lmh0bTBABggrBgEFBQcC
  354. # AjA0HjIgHQBMAGUAZwBhAGwAXwBQAG8AbABpAGMAeQBfAFMAdABhAHQAZQBtAGUA
  355. # bgB0AC4gHTANBgkqhkiG9w0BAQsFAAOCAgEAB+aIUQ3ixuCYP4FxAz2do6Ehb7Pr
  356. # psz1Mb7PBeKp/vpXbRkws8LFZslq3/Xn8Hi9x6ieJeP5vO1rVFcIK1GCRBL7uVOM
  357. # zPRgEop2zEBAQZvcXBf/XPleFzWYJFZLdO9CEMivv3/Gf/I3fVo/HPKZeUqRUgCv
  358. # OA8X9S95gWXZqbVr5MfO9sp6AG9LMEQkIjzP7QOllo9ZKby2/QThcJ8ySif9Va8v
  359. # /rbljjO7Yl+a21dA6fHOmWaQjP9qYn/dxUoLkSbiOewZSnFjnXshbcOco6I8+n99
  360. # lmqQeKZt0uGc+R38ONiU9MalCpaGpL2eGq4EQoO4tYCbIjggtSXlZOz39L9+Y1kl
  361. # D3ouOVd2onGqBooPiRa6YacRy5rYDkeagMXQzafQ732D8OE7cQnfXXSYIghh2rBQ
  362. # Hm+98eEA3+cxB6STOvdlR3jo+KhIq/fecn5ha293qYHLpwmsObvsxsvYgrRyzR30
  363. # uIUBHoD7G4kqVDmyW9rIDVWZeodzOwjmmC3qjeAzLhIp9cAvVCch98isTtoouLGp
  364. # 25ayp0Kiyc8ZQU3ghvkqmqMRZjDTu3QyS99je/WZii8bxyGvWbWu3EQ8l1Bx16HS
  365. # xVXjad5XwdHeMMD9zOZN+w2/XU/pnR4ZOC+8z1gFLu8NoFA12u8JJxzVs341Hgi6
  366. # 2jbb01+P3nSISRKhggLOMIICNwIBATCB+KGB0KSBzTCByjELMAkGA1UEBhMCVVMx
  367. # CzAJBgNVBAgTAldBMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3Nv
  368. # ZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJh
  369. # dGlvbnMgTGltaXRlZDEmMCQGA1UECxMdVGhhbGVzIFRTUyBFU046ODZERi00QkJD
  370. # LTkzMzUxJTAjBgNVBAMTHE1pY3Jvc29mdCBUaW1lLVN0YW1wIFNlcnZpY2WiIwoB
  371. # ATAHBgUrDgMCGgMVACRBu0KfU5QdFnnbtKCSQXqhZLdpoIGDMIGApH4wfDELMAkG
  372. # A1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQx
  373. # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9z
  374. # b2Z0IFRpbWUtU3RhbXAgUENBIDIwMTAwDQYJKoZIhvcNAQEFBQACBQDisJc3MCIY
  375. # DzIwMjAwNzA5MDMwNDIzWhgPMjAyMDA3MTAwMzA0MjNaMHcwPQYKKwYBBAGEWQoE
  376. # ATEvMC0wCgIFAOKwlzcCAQAwCgIBAAICBTUCAf8wBwIBAAICEbswCgIFAOKx6LcC
  377. # AQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGEWQoDAqAKMAgCAQACAwehIKEK
  378. # MAgCAQACAwGGoDANBgkqhkiG9w0BAQUFAAOBgQBc60zftvglC4XTAWkGh+sdBLzQ
  379. # /uFSMGMdXjfNxlIFx6qOSLKISNiW/MbybfHppgXOeeGjV9Z1I148Yym5SvB3QaMB
  380. # t/qjGyrYKP9VkehxDIqHJ1ZWAItPwfKrftEDAG/8a1iKYsDZiGEhVCmMfFeTybXI
  381. # i27VVtb9BR5ITHlk4zGCAw0wggMJAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMwEQYD
  382. # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy
  383. # b3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1w
  384. # IFBDQSAyMDEwAhMzAAABD4By9jqHCIitAAAAAAEPMA0GCWCGSAFlAwQCAQUAoIIB
  385. # SjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIMlo
  386. # MAROR4VzpJB1a9PL+n96Q2zmPkuwAduk3dc++74fMIH6BgsqhkiG9w0BCRACLzGB
  387. # 6jCB5zCB5DCBvQQgP5q9DnloLRRs8qdBDFvVa0QW4LZL99DesxTe8HR0Po4wgZgw
  388. # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE
  389. # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD
  390. # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAAQ+AcvY6hwiI
  391. # rQAAAAABDzAiBCDG2xJLw7wsX4gKRkiaeIZzlzmdqHBm/mOZJqEMe548+TANBgkq
  392. # hkiG9w0BAQsFAASCAQCMbnwN0CmmJN/eok0yGkCf/8LkqWkC8Ihpe7AyjqbHqVdT
  393. # 9qJmYFtj/gYHECFbUEz3e9KcmqnKmp0xSRHCNQLzdeo/LfwojFCozmvbQ8JLc27b
  394. # vEX6C2IWh7D0J82GF1wgHkK5KxZk7bJISNkuAttlMRQF6stb50ygtv5B6/+7c6Xv
  395. # LzU4H9BuJU+joalojZt3ok2HQAyJHcPqOX+2uET+ozvclYybg2cJdAsXpgYGdi2X
  396. # CsPIC+VRyY69Zze6Bdmi0J+6VGdqBJ6tRSji9wGTrJ8NA6Iha2OkRzsXLy2hAHzs
  397. # JIpbNViNZTeRw7fp4LRoUwpNQf8vdmH/MPX8m8kp
  398. # SIG # End signature block