private/Update-Db.ps1
function new-db { $script:dailydb = "C:\github\kbupdate\library\db\kb.sqlite" Remove-Item -Path $dailydb -ErrorAction Ignore $null = New-SQLiteConnection -DataSource $dailydb # updateid is not uniqueidentifier cuz I can't figure out how to do WHERE # and it gets in the way of the import Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE TABLE [Kb]( [UpdateId] [nvarchar](36) PRIMARY KEY NOT NULL, [Title] [nvarchar](200) NOT NULL, [Id] int NULL, [Architecture] [nvarchar](5) NULL, [Language] [nvarchar](25) NULL, [Hotfix] bit NULL, [Description] [nvarchar](1500) NULL, [LastModified] smalldatetime NULL, [Size] [nvarchar](50) NULL, [Classification] [nvarchar](512) NULL, [SupportedProducts] [nvarchar](50) NULL, [MSRCNumber] [nvarchar](25) NULL, [MSRCSeverity] [nvarchar](50) NULL, [RebootBehavior] [nvarchar](50) NULL, [RequestsUserInput] bit NULL, [ExclusiveInstall] bit NULL, [NetworkRequired] bit NULL, [UninstallNotes] [nvarchar](1500) NULL, [UninstallSteps] [nvarchar](1500) NULL )" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE TABLE [SupersededBy]( [UpdateId] [nvarchar](36) NOT NULL, [Kb] int NULL, [Description] [nvarchar](200) NULL )" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE TABLE [Supersedes]( [UpdateId] [nvarchar](36) NOT NULL, [Kb] int NULL, [Description] [nvarchar](200) NULL )" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE TABLE [Link]( [UpdateId] [nvarchar](36) NOT NULL, [Link] [nvarchar](512) NULL )" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE TABLE [KbDupe]( [UpdateId] [nvarchar](36) NOT NULL, [Dupe] [nvarchar](36) NOT NULL )" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE TABLE [notfound]( [UpdateId] [nvarchar](36) NOT NULL )" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_kb ON Kb (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_superby ON SupersededBy (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_supers ON Supersedes (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_link ON Link (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_dupe ON KbDupe (Dupe)" Get-ChildItem $dailydb } function Get-Info { #Invoke-SqliteQuery -DataSource $dailydb -Query "select * from Kb" #Invoke-SqliteQuery -DataSource $dailydb -Query "select * from SupersededBy" #Invoke-SqliteQuery -DataSource $dailydb -Query "select * from Supersedes" Invoke-SqliteQuery -DataSource $dailydb -Query "select * from Link" #Invoke-SqliteQuery -DataSource $dailydb -Query "select * from KbDupe" } function New-Index { Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_kb ON Kb (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_superby ON SupersededBy (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_supers ON Supersedes (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_link ON Link (UpdateId)" Invoke-SqliteQuery -DataSource $dailydb -Query "CREATE INDEX tag_uid_dupe ON KbDupe (Dupe)" } function Update-Db { [CmdletBinding()] param() Import-Module C:\github\dbatools $script:db = "C:\github\kbupdate-library\library\kb.sqlite" $dailydb = "C:\github\kbupdate\library\db\kb.sqlite" #$query = "SELECT CAST(UpdateId AS VARCHAR(36)) as UpdateId FROM [SUSDB].[PUBLIC_VIEWS].[vUpdate] Where ArrivalDate >= DATEADD(hour,-4, GETDATE())" $query = "SELECT CAST(UpdateId AS VARCHAR(36)) as UpdateId FROM [SUSDB].[PUBLIC_VIEWS].[vUpdate] Where ArrivalDate >= DATEADD(hour,-24, GETDATE())" #$query = "SELECT CAST(UpdateId AS VARCHAR(36)) as UpdateId FROM [SUSDB].[PUBLIC_VIEWS].[vUpdate] Where ArrivalDate >= DATEADD(hour,-120, GETDATE())" #$query = "SELECT CAST(UpdateId AS VARCHAR(36)) as UpdateId FROM [SUSDB].[PUBLIC_VIEWS].[vUpdate] Where ArrivalDate >= '2019-07-20 18:02:25.127' and ArrivalDate <= DATEADD(hour,-24, GETDATE())" $new = (Invoke-DbaQuery -SqlInstance wsus -Database SUSDB -Query $query).UpdateId foreach ($guid in $new) { $update = Get-KbUpdate -Pattern $guid -Source Web $Kb = $update | Select-Object -Property * -ExcludeProperty SupersededBy, Supersedes, Link, InputObject $SupersededBy = $update.SupersededBy $Supersedes = $update.Supersedes $Link = $update.Link if ($update.UpdateId) { # delete old entries Invoke-SqliteQuery -DataSource $script:db -Query "delete from Kb where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from Kb where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $script:db -Query "delete from SupersededBy where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from SupersededBy where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $script:db -Query "delete from Supersedes where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from Supersedes where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $script:db -Query "delete from Link where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from Link where UpdateId = '$($update.UpdateId)'" } foreach ($item in $Kb) { $null = Add-Member -InputObject $item -NotePropertyName DateAdded -NotePropertyValue (Get-Date) -Force try { Invoke-SQLiteBulkCopy -DataTable ($item | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Kb -Confirm:$false } catch { $null = Add-Content -Value $guid -Path C:\updates\Dupes.txt Stop-PSFFunction -Message $guid -ErrorRecord $_ -Continue } } try { foreach ($item in $SupersededBy) { if ($null -ne $item.Kb -and '' -ne $item.Kb) { if ($item.Kb) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $update.UpdateId; Kb = $item.Kb; Description = $item.Description } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table SupersededBy -Confirm:$false } } } foreach ($item in $Supersedes) { if ($null -ne $item.Kb -and '' -ne $item.Kb) { if ($item.Kb) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $update.UpdateId; Kb = $item.Kb; Description = $item.Description } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Supersedes -Confirm:$false } } } foreach ($item in $Link) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{UpdateId = $update.UpdateId; Link = $item } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Link -Confirm:$false } $update $null = Add-Content -Value $guid -Path C:\updates\NewAll.txt } catch { Stop-PSFFunction -Message $guid -ErrorRecord $_ -Continue } } } function Update-DbFromFile { [CmdletBinding()] param() $files = Get-ChildItem -Path C:\temp\kbs\new\*.xml -Recurse $i = 0 foreach ($file in $files) { $update = Import-CliXml $file.FullName $guid = $update.UpdateId $i++ if (($i % 100) -eq 0) { write-warning $i } if (-not $exists) { $kb = $update | Select-Object -Property * -ExcludeProperty SupersededBy, Supersedes, Link, InputObject $SupersededBy = $update.SupersededBy $Supersedes = $update.Supersedes $Link = $update.Link try { Invoke-SQLiteBulkCopy -DataTable ($kb | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Kb -Confirm:$false } catch { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $guid; Dupe = $file.BaseName } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table KbDupe -Confirm:$false #Add-Content -Path C:\temp\dupes.txt -Value $guid, $file.BaseName Stop-PSFFunction -Message $guid -ErrorRecord $_ -Continue } try { foreach ($item in $SupersededBy) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $guid; Kb = $item.Kb; Description = $item.Description } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table SupersededBy -Confirm:$false } foreach ($item in $Supersedes) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $guid; Kb = $item.Kb; Description = $item.Description } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Supersedes -Confirm:$false } foreach ($item in $Link) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{UpdateId = $guid; Link = $item } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Link -Confirm:$false } } catch { Stop-PSFFunction -Message $guid -ErrorRecord $_ -Continue } } } } function Add-Kb { [CmdletBinding()] param( [string[]]$Name ) foreach ($guid in $Name) { $update = Get-KbUpdate -Pattern $guid -Source Web $Kb = $update | Select-Object -Property * -ExcludeProperty SupersededBy, Supersedes, Link, InputObject $SupersededBy = $update.SupersededBy $Supersedes = $update.Supersedes $Link = $update.Link if ($update.UpdateId) { # delete old entries Invoke-SqliteQuery -DataSource $script:db -Query "delete from Kb where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from Kb where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $script:db -Query "delete from SupersededBy where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from SupersededBy where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $script:db -Query "delete from Supersedes where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from Supersedes where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $script:db -Query "delete from Link where UpdateId = '$($update.UpdateId)'" Invoke-SqliteQuery -DataSource $dailydb -Query "delete from Link where UpdateId = '$($update.UpdateId)'" } foreach ($item in $Kb) { $null = Add-Member -InputObject $item -NotePropertyName DateAdded -NotePropertyValue (Get-Date) -Force try { Invoke-SQLiteBulkCopy -DataTable ($item | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Kb -Confirm:$false } catch { $null = Add-Content -Value $guid -Path C:\updates\Dupes.txt Stop-PSFFunction -Message $guid -ErrorRecord $_ -Continue } } try { foreach ($item in $SupersededBy) { if ($null -ne $item.Kb -and '' -ne $item.Kb) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $guid; Kb = $item.Kb; Description = $item.Description } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table SupersededBy -Confirm:$false } } foreach ($item in $Supersedes) { if ($null -ne $item.Kb -and '' -ne $item.Kb) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $guid; Kb = $item.Kb; Description = $item.Description } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Supersedes -Confirm:$false } } foreach ($item in $Link) { Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{UpdateId = $guid; Link = $item } | ConvertTo-DbaDataTable) -DataSource $dailydb -Table Link -Confirm:$false } $update $null = Add-Content -Value $guid -Path C:\updates\NewAll.txt } catch { Stop-PSFFunction -Message $guid -ErrorRecord $_ -Continue } } } # SIG # Begin signature block # MIIdsAYJKoZIhvcNAQcCoIIdoTCCHZ0CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUSOcaDUuqNtSy4rkKaIoMYtuV # mp6gghfOMIIFGjCCBAKgAwIBAgIQAwW7hiGwoWNfv96uEgTnbTANBgkqhkiG9w0B # AQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD # VQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBTSEEyIEFz # c3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTIwMDUxMjAwMDAwMFoXDTIzMDYw # ODEyMDAwMFowVzELMAkGA1UEBhMCVVMxETAPBgNVBAgTCFZpcmdpbmlhMQ8wDQYD # VQQHEwZWaWVubmExETAPBgNVBAoTCGRiYXRvb2xzMREwDwYDVQQDEwhkYmF0b29s # czCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALy/Y3ur47++CAG2mOa1 # 6h8WjXjSTvcldDmw4PpAvOOCKNr6xyhg/FOYVIiaeq2N9kVaa5wBawOIxVWuj/rI # aOxeYklQDugPkGUx0Ap+6KrjnnxgE6ONzQGnc1tjlka6N0KazD2WodEBWKXo/Vmk # C/cP9PJVWroCMOwlj7GtEv2IxzxikPm2ICP5KxFK5PmrA+5bzcHJEeqRonlgMn9H # zZkqHr0AU1egnfEIlH4/v6lry1t1KBF/bnDhl9g/L0icS+ychFVkx4OOO4a+qvT8 # xqvvdQjv3PQ1hbzTI3/tXOWu9XxGeeIdZjaJv16FmWKCnloSp1Xb9cVU9XhIpomz # xH0CAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5LfZldQ5Y # MB0GA1UdDgQWBBTwwKD7tgOAQ077Cdfd33qxy+OeIjAOBgNVHQ8BAf8EBAMCB4Aw # EwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0cDovL2Ny # bDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAzoDGGL2h0 # dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEuY3JsMEwG # A1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3 # LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4MHYwJAYI # KwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEFBQcwAoZC # aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFzc3VyZWRJ # RENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQAD # ggEBAI/N+XCVDB/WNqQSrKY85zScHGJjsXgXByYvsitMuG5vo+ODhlh+ILv0CTPl # o2Wo75MnSSqCWR+c6xyN8pDPMPBxm2EtVmXzeKDMIudYyjxmT8PZ3hktj16wXCo8 # 2+65UOse+CHsfoMn/M9WbkQ4rSyWNPRRDodATC2i4flLyeuoIZnyMoz/4N4mWb6s # IAYZ/tNXzm6qwCfkmoMSf9tcTUCXIbVDliJcUZLlJ/SpLg2KzDu9GtnpBzg3AG3L # hwBiPMM8OLGitYjz4VU5RYox0vu1XyLf3f9fKTCxxwKy0EKntWdJk37i+DOMQlCq # Xm5B/KyNxb2utv+qLGlyw9MphEcwggUwMIIEGKADAgECAhAECRgbX9W7ZnVTQ7Vv # lVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp # Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMTG0Rp # Z2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEwMjIxMjAwMDBaFw0yODEw # MjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMx # GTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0IFNI # QTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEBAQUA # A4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7RZmxOttE9X/lqJ3bMtdx # 6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p0WfTxvspJ8fTeyOU5JEj # lpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj6YgsIJWuHEqHCN8M9eJN # YBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grkV7tKtel05iv+bMt+dDk2 # DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHyDxL0xY4PwaLoLFH3c7y9 # hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMBAAGjggHNMIIByTASBgNV # HRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAKBggrBgEF # BQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp # Z2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu # Y29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCBgQYDVR0fBHoweDA6oDig # NoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9v # dENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgGCmCGSAGG/WwAAgQwKjAo # BggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAKBghghkgB # hv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHwYDVR0jBBgwFoAU # Reuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQELBQADggEBAD7sDVoks/Mi # 0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q3yBVN7Dh9tGSdQ9RtG6l # jlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/kLEbBw6RFfu6r7VRwo0k # riTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dcIFzZcbEMj7uo+MUSaJ/P # QMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6dGRrsutmQ9qzsIzV6Q3d # 9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT+hKUGIUukpHqaGxEMrJm # oecYpJpkUe8wggauMIIElqADAgECAhAHNje3JFR82Ees/ShmKl5bMA0GCSqGSIb3 # DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAX # BgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0 # ZWQgUm9vdCBHNDAeFw0yMjAzMjMwMDAwMDBaFw0zNzAzMjIyMzU5NTlaMGMxCzAJ # BgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMyRGln # aUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcgQ0Ew # ggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQDGhjUGSbPBPXJJUVXHJQPE # 8pE3qZdRodbSg9GeTKJtoLDMg/la9hGhRBVCX6SI82j6ffOciQt/nR+eDzMfUBML # JnOWbfhXqAJ9/UO0hNoR8XOxs+4rgISKIhjf69o9xBd/qxkrPkLcZ47qUT3w1lbU # 5ygt69OxtXXnHwZljZQp09nsad/ZkIdGAHvbREGJ3HxqV3rwN3mfXazL6IRktFLy # dkf3YYMZ3V+0VAshaG43IbtArF+y3kp9zvU5EmfvDqVjbOSmxR3NNg1c1eYbqMFk # dECnwHLFuk4fsbVYTXn+149zk6wsOeKlSNbwsDETqVcplicu9Yemj052FVUmcJgm # f6AaRyBD40NjgHt1biclkJg6OBGz9vae5jtb7IHeIhTZgirHkr+g3uM+onP65x9a # bJTyUpURK1h0QCirc0PO30qhHGs4xSnzyqqWc0Jon7ZGs506o9UD4L/wojzKQtwY # SH8UNM/STKvvmz3+DrhkKvp1KCRB7UK/BZxmSVJQ9FHzNklNiyDSLFc1eSuo80Vg # vCONWPfcYd6T/jnA+bIwpUzX6ZhKWD7TA4j+s4/TXkt2ElGTyYwMO1uKIqjBJgj5 # FBASA31fI7tk42PgpuE+9sJ0sj8eCXbsq11GdeJgo1gJASgADoRU7s7pXcheMBK9 # Rp6103a50g5rmQzSM7TNsQIDAQABo4IBXTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIB # ADAdBgNVHQ4EFgQUuhbZbU2FL3MpdpovdYxqII+eyG8wHwYDVR0jBBgwFoAU7Nfj # gtJxXWRM3y5nP+e6mK4cD08wDgYDVR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsG # AQUFBwMIMHcGCCsGAQUFBwEBBGswaTAkBggrBgEFBQcwAYYYaHR0cDovL29jc3Au # ZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVodHRwOi8vY2FjZXJ0cy5kaWdpY2Vy # dC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNydDBDBgNVHR8EPDA6MDigNqA0 # hjJodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0 # LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwDQYJKoZIhvcN # AQELBQADggIBAH1ZjsCTtm+YqUQiAX5m1tghQuGwGC4QTRPPMFPOvxj7x1Bd4ksp # +3CKDaopafxpwc8dB+k+YMjYC+VcW9dth/qEICU0MWfNthKWb8RQTGIdDAiCqBa9 # qVbPFXONASIlzpVpP0d3+3J0FNf/q0+KLHqrhc1DX+1gtqpPkWaeLJ7giqzl/Yy8 # ZCaHbJK9nXzQcAp876i8dU+6WvepELJd6f8oVInw1YpxdmXazPByoyP6wCeCRK6Z # JxurJB4mwbfeKuv2nrF5mYGjVoarCkXJ38SNoOeY+/umnXKvxMfBwWpx2cYTgAnE # tp/Nh4cku0+jSbl3ZpHxcpzpSwJSpzd+k1OsOx0ISQ+UzTl63f8lY5knLD0/a6fx # ZsNBzU+2QJshIUDQtxMkzdwdeDrknq3lNHGS1yZr5Dhzq6YBT70/O3itTK37xJV7 # 7QpfMzmHQXh6OOmc4d0j/R0o08f56PGYX/sr2H7yRp11LB4nLCbbbxV7HhmLNriT # 1ObyF5lZynDwN7+YAN8gFk8n+2BnFqFmut1VwDophrCYoCvtlUG3OtUVmDG0YgkP # Cr2B2RP+v6TR81fZvAT6gt4y3wSJ8ADNXcL50CN/AAvkdgIm2fBldkKmKYcJRyvm # fxqkhQ/8mJb2VVQrH4D6wPIOK+XW+6kvRBVK5xMOHds3OBqhK/bt1nz8MIIGxjCC # BK6gAwIBAgIQCnpKiJ7JmUKQBmM4TYaXnTANBgkqhkiG9w0BAQsFADBjMQswCQYD # VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lD # ZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBTSEEyNTYgVGltZVN0YW1waW5nIENBMB4X # DTIyMDMyOTAwMDAwMFoXDTMzMDMxNDIzNTk1OVowTDELMAkGA1UEBhMCVVMxFzAV # BgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMSQwIgYDVQQDExtEaWdpQ2VydCBUaW1lc3Rh # bXAgMjAyMiAtIDIwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC5KpYj # ply8X9ZJ8BWCGPQz7sxcbOPgJS7SMeQ8QK77q8TjeF1+XDbq9SWNQ6OB6zhj+TyI # ad480jBRDTEHukZu6aNLSOiJQX8Nstb5hPGYPgu/CoQScWyhYiYB087DbP2sO37c # KhypvTDGFtjavOuy8YPRn80JxblBakVCI0Fa+GDTZSw+fl69lqfw/LH09CjPQnkf # O8eTB2ho5UQ0Ul8PUN7UWSxEdMAyRxlb4pguj9DKP//GZ888k5VOhOl2GJiZERTF # KwygM9tNJIXogpThLwPuf4UCyYbh1RgUtwRF8+A4vaK9enGY7BXn/S7s0psAiqwd # jTuAaP7QWZgmzuDtrn8oLsKe4AtLyAjRMruD+iM82f/SjLv3QyPf58NaBWJ+cCzl # K7I9Y+rIroEga0OJyH5fsBrdGb2fdEEKr7mOCdN0oS+wVHbBkE+U7IZh/9sRL5ID # MM4wt4sPXUSzQx0jUM2R1y+d+/zNscGnxA7E70A+GToC1DGpaaBJ+XXhm+ho5GoM # j+vksSF7hmdYfn8f6CvkFLIW1oGhytowkGvub3XAsDYmsgg7/72+f2wTGN/GbaR5 # Sa2Lf2GHBWj31HDjQpXonrubS7LitkE956+nGijJrWGwoEEYGU7tR5thle0+C2Fa # 6j56mJJRzT/JROeAiylCcvd5st2E6ifu/n16awIDAQABo4IBizCCAYcwDgYDVR0P # AQH/BAQDAgeAMAwGA1UdEwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgw # IAYDVR0gBBkwFzAIBgZngQwBBAIwCwYJYIZIAYb9bAcBMB8GA1UdIwQYMBaAFLoW # 2W1NhS9zKXaaL3WMaiCPnshvMB0GA1UdDgQWBBSNZLeJIf5WWESEYafqbxw2j92v # DTBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGln # aUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3JsMIGQ # BggrBgEFBQcBAQSBgzCBgDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl # cnQuY29tMFgGCCsGAQUFBzAChkxodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v # RGlnaUNlcnRUcnVzdGVkRzRSU0E0MDk2U0hBMjU2VGltZVN0YW1waW5nQ0EuY3J0 # MA0GCSqGSIb3DQEBCwUAA4ICAQANLSN0ptH1+OpLmT8B5PYM5K8WndmzjJeCKZxD # bwEtqzi1cBG/hBmLP13lhk++kzreKjlaOU7YhFmlvBuYquhs79FIaRk4W8+JOR1w # cNlO3yMibNXf9lnLocLqTHbKodyhK5a4m1WpGmt90fUCCU+C1qVziMSYgN/uSZW3 # s8zFp+4O4e8eOIqf7xHJMUpYtt84fMv6XPfkU79uCnx+196Y1SlliQ+inMBl9AEi # ZcfqXnSmWzWSUHz0F6aHZE8+RokWYyBry/J70DXjSnBIqbbnHWC9BCIVJXAGcqlE # O2lHEdPu6cegPk8QuTA25POqaQmoi35komWUEftuMvH1uzitzcCTEdUyeEpLNypM # 81zctoXAu3AwVXjWmP5UbX9xqUgaeN1Gdy4besAzivhKKIwSqHPPLfnTI/KeGeAN # lCig69saUaCVgo4oa6TOnXbeqXOqSGpZQ65f6vgPBkKd3wZolv4qoHRbY2beayy4 # eKpNcG3wLPEHFX41tOa1DKKZpdcVazUOhdbgLMzgDCS4fFILHpl878jIxYxYaa+r # PeHPzH0VrhS/inHfypex2EfqHIXgRU4SHBQpWMxv03/LvsEOSm8gnK7ZczJZCOct # kqEaEf4ymKZdK5fgi9OczG21Da5HYzhHF1tvE9pqEG4fSbdEW7QICodaWQR2EaGn # dwITHDGCBUwwggVIAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdp # Q2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERp # Z2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0ECEAMFu4YhsKFj # X7/erhIE520wCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAIoAKAAKECgAAw # GQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwGCisG # AQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFCnTF4Gn/XBdjVU/XHr7u8scYbK9MA0G # CSqGSIb3DQEBAQUABIIBALN4afdTXCLh0jKKuJJ9bF62QwKDAh4/XT2UtMaltO/f # aFkX4CbzocvB6dYfc19uG5e6gOsy6yIiyYkhOC9Iwawyqgn02UPB4PwEa8kBBvko # iq+sL8cBeyFNjutT6aj1rqCfOhrrCoYPiOXMB0EvP8pZA4rkD9AuKEvQ0gnlFcSQ # f1ZcYVL0E+Vf1KFpPgi8Nn6McY5NyNmI5vzLjYasHcXVZtqWU+sCY4mkna3aQsLj # ov/5FO1JMIFxIn3xvEK6rQW4NtpoCn/ruSrqZnbHT7CwxHXjKOYW+mGXmU3iCWzV # 0CJTNTDYYBcSMoK2EgeYCoMHSKNM52qNtYQdm4p4Q1ahggMgMIIDHAYJKoZIhvcN # AQkGMYIDDTCCAwkCAQEwdzBjMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xOzA5BgNVBAMTMkRpZ2lDZXJ0IFRydXN0ZWQgRzQgUlNBNDA5NiBT # SEEyNTYgVGltZVN0YW1waW5nIENBAhAKekqInsmZQpAGYzhNhpedMA0GCWCGSAFl # AwQCAQUAoGkwGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx # DxcNMjIwNTEyMTU1NzQxWjAvBgkqhkiG9w0BCQQxIgQgf4UU7URmx29Nfo8MvMFK # AWokrvFRLQ6NTh4nSj+dXugwDQYJKoZIhvcNAQEBBQAEggIAljh0iq1gJm//mI+G # 0ZRe7AuenCa8Jvvppvj6s5KU4HSpHrzBh2Ati8oTmIjr+mOOaUdLUNjjdMhWtHj/ # 1AJtVAC3xHfcphN6/csB17U2F+izs69zauYslQxbfT3QDDDsYcfJuNOCotFLzKVg # h8kMKRq4sQafa7TasCXtHJxHqEdsu3DeNhQHQUoUlJJhW2ErT3mkGTRjaMuAachK # y0gNYumhsA+iS/0EGnBDr2OrvFm23J4bmxArPBxmW585oMJm/j3BI7OSRh4NpzxE # ShSm3z8TPih5uY2omblVNcc62U8YVmXku5GHsNIwSFRMYLmDCYuybedhyQsCM6Zf # 5HgUWwOIGoVyhQLgNTkDTvF9lf67itSiq9zldLDf9RW8E8AQyC4d1Kr68HfZJuzd # GLCXWZWiHBY/CS39JANJseE04ASRD5Stv5PwMCV5kjZFJsU0ZdC8+MvMqoGBX+FK # bp/A1FsQCjXGWvSJ/LuR7NQjH1tDDDxbvd7Cyc4mR93zQYDURYocmkfsNYZM+O2k # BxYwE8XF6IIqQAnw5mz/+H0ZrIsJ2HpJYN17KvFrnmMrSsEflUk2uBAO1gHs+Ynl # MAqtdFXB0PEXUWWk9zTsEd8638XRPRc0PicRbwOiBMxbdhGnRATm3wSs49eXftQW # asQ+6OEWwRVqeqJhGUjuL/T7kJs= # SIG # End signature block |