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-Info1 {
    #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\sqldb\kbold.sqlite"
    $dailydb = "C:\github\sqldb\kbnew.sqlite"
    #$new = (Get-ChildItem C:\temp\kb\newoutput).BaseName

    $new = "313e209f-aaac-4694-ac61-675f6e9e6b60","4eb83e93-c0f2-4a71-ba43-053787ecfa2e","b46acc67-3232-4a91-88d2-867cb9d0286c","be4386c2-16b5-4f26-a574-915648bcec2d","d0478bde-b17d-4cd7-9cbc-939c62b62c96"
    $new | Invoke-Parallel -ImportVariables -ImportFunctions -RunspaceTimeout 180 -Quiet -ScriptBlock {
        Import-Module PSFramework, PSSQLite, dbatools
        #$update = Get-KbUpdate -Pattern $guid -Source Web
        $guid = $PSItem
        $update = Get-KbUpdate -Pattern $guid
        if ($update.SupportedProducts) {
            $update.SupportedProducts = $update.SupportedProducts -join "|"
        }
        $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 $PSItem -Path C:\temp\kbs\new\Dupes.txt
                Stop-PSFFunction -Message $PSItem -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
                        }
                        $null = Add-Content -Value $guid -Path C:\temp\kbs\new\NewAll.txt
                    } catch {
                        $null = Add-Content -Value $PSItem -Path C:\temp\kbs\new\errors.txt
                        Stop-PSFFunction -Message $gui$PSItemd -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 {
                            if ($file.BaseName) {
                                $value = $file.BaseName
                            } else {
                                $value = $file
                            }
                            Invoke-SQLiteBulkCopy -DataTable ([pscustomobject]@{ UpdateId = $guid; Dupe = $value } |
                                    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
        $update.SupportedProducts = $update.SupportedProducts -join ", "
        $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
        }
    }





    $newer = $xml.OfflineSyncPackage.Updates.Update


    $ds = New-Object System.Data.DataSet
    $ds.ReadXml($xmlfile)
    ($ds.Tables["FileLocation"].Select("Id = '$fileid'")).Url







    function Fix-Db {
        [CmdletBinding()]
        param()

        function Get-Info ($Text, $Pattern) {
            if ($Pattern -match "labelTitle") {
                if ($Pattern -match "SupportedProducts") {
                    # no idea what the regex below does but it's not working for SupportedProducts
                    # do it the manual way instead
                    $block = [regex]::Match($Text, $Pattern + '[\s\S]*?\s*(.*?)\s*<\/div>').Groups[0].Value
                    $supported = $block -split "</span>" | Select-Object -Last 1
                    $supported.Trim().Replace("</div>","").Split(",").Trim()
                } else {
                    # this should work... not accounting for multiple divs however?
                    [regex]::Match($Text, $Pattern + '[\s\S]*?\s*(.*?)\s*<\/div>').Groups[1].Value
                }
            } elseif ($Pattern -match "span ") {
                [regex]::Match($Text, $Pattern + '(.*?)<\/span>').Groups[1].Value
            } else {
                [regex]::Match($Text, $Pattern + "\s?'?(.*?)'?;").Groups[1].Value
            }
        }

        $new = (Invoke-SqliteQuery -DataSource "C:\github\kbupdate-library\library\kb.sqlite" -Query "select UpdateId from kb where Classification like '%security%' and MSRCNumber is NULL").UpdateId
        #$new | Invoke-Parallel -ImportVariables -ImportFunctions -RunspaceTimeout 180 -ScriptBlock {
        Import-Module PSSQLite
        $new | ForEach-Object {
            $updateid = $PSItem

            $detaildialog = Invoke-TlsWebRequest -Uri "https://www.catalog.update.microsoft.com/ScopedViewInline.aspx?updateid=$updateid"
            $msrcnumber = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelSecurityBulliten_Separator" class="labelTitle">'

            if ($msrcnumber -eq "n/a" -or $msrcnumber -eq "Unspecified") {
                $msrcnumber = $null
            }

            if ($msrcnumber) {
                $query = "update Kb set MSRCNumber = '$msrcnumber' where UpdateId = '$updateid';"
                write-warning $query
                Invoke-SqliteQuery -DataSource "C:\github\kbupdate-library\library\kb.sqlite" -Query $query
            } else {
                write-warning nope
            }
        }




    }





}


# SIG # Begin signature block
# MIIjYAYJKoZIhvcNAQcCoIIjUTCCI00CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBJUbo1K7tGhnKy
# wI9R/OboKMnYM3P8EvClAjxJbIyJ2qCCHVkwggUaMIIEAqADAgECAhADBbuGIbCh
# Y1+/3q4SBOdtMA0GCSqGSIb3DQEBCwUAMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV
# BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwHhcN
# MjAwNTEyMDAwMDAwWhcNMjMwNjA4MTIwMDAwWjBXMQswCQYDVQQGEwJVUzERMA8G
# A1UECBMIVmlyZ2luaWExDzANBgNVBAcTBlZpZW5uYTERMA8GA1UEChMIZGJhdG9v
# bHMxETAPBgNVBAMTCGRiYXRvb2xzMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIB
# CgKCAQEAvL9je6vjv74IAbaY5rXqHxaNeNJO9yV0ObDg+kC844Io2vrHKGD8U5hU
# iJp6rY32RVprnAFrA4jFVa6P+sho7F5iSVAO6A+QZTHQCn7oquOefGATo43NAadz
# W2OWRro3QprMPZah0QFYpej9WaQL9w/08lVaugIw7CWPsa0S/YjHPGKQ+bYgI/kr
# EUrk+asD7lvNwckR6pGieWAyf0fNmSoevQBTV6Cd8QiUfj+/qWvLW3UoEX9ucOGX
# 2D8vSJxL7JyEVWTHg447hr6q9PzGq+91CO/c9DWFvNMjf+1c5a71fEZ54h1mNom/
# XoWZYoKeWhKnVdv1xVT1eEimibPEfQIDAQABo4IBxTCCAcEwHwYDVR0jBBgwFoAU
# WsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0OBBYEFPDAoPu2A4BDTvsJ193ferHL
# 454iMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzB3BgNVHR8E
# cDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVk
# LWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2NybDQuZGlnaWNlcnQuY29tL3NoYTIt
# YXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUwQzA3BglghkgBhv1sAwEwKjAoBggr
# BgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQuY29tL0NQUzAIBgZngQwBBAEw
# gYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNl
# cnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20v
# RGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNpZ25pbmdDQS5jcnQwDAYDVR0TAQH/
# BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAj835cJUMH9Y2pBKspjznNJwcYmOxeBcH
# Ji+yK0y4bm+j44OGWH4gu/QJM+WjZajvkydJKoJZH5zrHI3ykM8w8HGbYS1WZfN4
# oMwi51jKPGZPw9neGS2PXrBcKjzb7rlQ6x74Iex+gyf8z1ZuRDitLJY09FEOh0BM
# LaLh+UvJ66ghmfIyjP/g3iZZvqwgBhn+01fObqrAJ+SagxJ/21xNQJchtUOWIlxR
# kuUn9KkuDYrMO70a2ekHODcAbcuHAGI8wzw4saK1iPPhVTlFijHS+7VfIt/d/18p
# MLHHArLQQqe1Z0mTfuL4M4xCUKpebkH8rI3Fva62/6osaXLD0ymERzCCBTAwggQY
# oAMCAQICEAQJGBtf1btmdVNDtW+VUAgwDQYJKoZIhvcNAQELBQAwZTELMAkGA1UE
# BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj
# ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X
# DTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcjELMAkGA1UEBhMCVVMxFTAT
# BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEx
# MC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBD
# QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPjTsxx/DhGvZ3cH0wsx
# SRnP0PtFmbE620T1f+Wondsy13Hqdp0FLreP+pJDwKX5idQ3Gde2qvCchqXYJawO
# eSg6funRZ9PG+yknx9N7I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrskacLCUvIUZ4qJ
# RdQtoaPpiCwgla4cSocI3wz14k1gGL6qxLKucDFmM3E+rHCiq85/6XzLkqHlOzEc
# z+ryCuRXu0q16XTmK/5sy350OTYNkO/ktU6kqepqCquE86xnTrXE94zRICUj6whk
# PlKWwfIPEvTFjg/BougsUfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8np+mM6n9Gd8l
# k9ECAwEAAaOCAc0wggHJMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYDVR0PAQH/BAQD
# AgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0wazAkBggrBgEF
# BQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUFBzAChjdodHRw
# Oi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0Eu
# Y3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdpY2VydC5jb20v
# RGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRwOi8vY3JsMy5k
# aWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsME8GA1UdIARI
# MEYwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdp
# Y2VydC5jb20vQ1BTMAoGCGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7KgqjpepxA8Bg
# +S32ZXUOWDAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823IDzANBgkqhkiG
# 9w0BAQsFAAOCAQEAPuwNWiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh134LYP3DPQ/E
# r4v97yrfIFU3sOH20ZJ1D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63XX0R58zYUBor3
# nEZOXP+QsRsHDpEV+7qvtVHCjSSuJMbHJyqhKSgaOnEoAjwukaPAJRHinBRHoXpo
# aK+bp1wgXNlxsQyPu6j4xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC/i9yfhzXSUWW
# 6Fkd6fp0ZGuy62ZD2rOwjNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG/AeB+ova+YJJ
# 92JuoVP6EpQYhS6SkepobEQysmah5xikmmRR7zCCBY0wggR1oAMCAQICEA6bGI75
# 0C3n79tQ4ghAGFowDQYJKoZIhvcNAQEMBQAwZTELMAkGA1UEBhMCVVMxFTATBgNV
# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEkMCIG
# A1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4XDTIyMDgwMTAwMDAw
# MFoXDTMxMTEwOTIzNTk1OVowYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGln
# aUNlcnQgVHJ1c3RlZCBSb290IEc0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC
# CgKCAgEAv+aQc2jeu+RdSjwwIjBpM+zCpyUuySE98orYWcLhKac9WKt2ms2uexuE
# DcQwH/MbpDgW61bGl20dq7J58soR0uRf1gU8Ug9SH8aeFaV+vp+pVxZZVXKvaJNw
# wrK6dZlqczKU0RBEEC7fgvMHhOZ0O21x4i0MG+4g1ckgHWMpLc7sXk7Ik/ghYZs0
# 6wXGXuxbGrzryc/NrDRAX7F6Zu53yEioZldXn1RYjgwrt0+nMNlW7sp7XeOtyU9e
# 5TXnMcvak17cjo+A2raRmECQecN4x7axxLVqGDgDEI3Y1DekLgV9iPWCPhCRcKtV
# gkEy19sEcypukQF8IUzUvK4bA3VdeGbZOjFEmjNAvwjXWkmkwuapoGfdpCe8oU85
# tRFYF/ckXEaPZPfBaYh2mHY9WV1CdoeJl2l6SPDgohIbZpp0yt5LHucOY67m1O+S
# kjqePdwA5EUlibaaRBkrfsCUtNJhbesz2cXfSwQAzH0clcOP9yGyshG3u3/y1Yxw
# LEFgqrFjGESVGnZifvaAsPvoZKYz0YkH4b235kOkGLimdwHhD5QMIR2yVCkliWzl
# DlJRR3S+Jqy2QXXeeqxfjT/JvNNBERJb5RBQ6zHFynIWIgnffEx1P2PsIV/EIFFr
# b7GrhotPwtZFX50g/KEexcCPorF+CiaZ9eRpL5gdLfXZqbId5RsCAwEAAaOCATow
# ggE2MA8GA1UdEwEB/wQFMAMBAf8wHQYDVR0OBBYEFOzX44LScV1kTN8uZz/nupiu
# HA9PMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6enIZ3zbcgPMA4GA1UdDwEB/wQE
# AwIBhjB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRp
# Z2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2NhY2VydHMuZGlnaWNlcnQu
# Y29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDBFBgNVHR8EPjA8MDqgOKA2
# hjRodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290
# Q0EuY3JsMBEGA1UdIAQKMAgwBgYEVR0gADANBgkqhkiG9w0BAQwFAAOCAQEAcKC/
# Q1xV5zhfoKN0Gz22Ftf3v1cHvZqsoYcs7IVeqRq7IviHGmlUIu2kiHdtvRoU9BNK
# ei8ttzjv9P+Aufih9/Jy3iS8UgPITtAq3votVs/59PesMHqai7Je1M/RQ0SbQyHr
# lnKhSLSZy51PpwYDE3cnRNTnf+hZqPC/Lwum6fI0POz3A8eHqNJMQBk1RmppVLC4
# oVaO7KTVPeix3P0c2PR3WlxUjG/voVA9/HYJaISfb8rbII01YBwCA8sgsKxYoA5A
# Y8WYIsGyWfVVa88nq2x2zm8jLfR+cWojayL/ErhULSd+2DrZ8LaHlv1b0VysGMNN
# n3O3AamfV6peKOK5lDCCBq4wggSWoAMCAQICEAc2N7ckVHzYR6z9KGYqXlswDQYJ
# KoZIhvcNAQELBQAwYjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IElu
# YzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEhMB8GA1UEAxMYRGlnaUNlcnQg
# VHJ1c3RlZCBSb290IEc0MB4XDTIyMDMyMzAwMDAwMFoXDTM3MDMyMjIzNTk1OVow
# YzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQD
# EzJEaWdpQ2VydCBUcnVzdGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGlu
# ZyBDQTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAMaGNQZJs8E9cklR
# VcclA8TykTepl1Gh1tKD0Z5Mom2gsMyD+Vr2EaFEFUJfpIjzaPp985yJC3+dH54P
# Mx9QEwsmc5Zt+FeoAn39Q7SE2hHxc7Gz7iuAhIoiGN/r2j3EF3+rGSs+QtxnjupR
# PfDWVtTnKC3r07G1decfBmWNlCnT2exp39mQh0YAe9tEQYncfGpXevA3eZ9drMvo
# hGS0UvJ2R/dhgxndX7RUCyFobjchu0CsX7LeSn3O9TkSZ+8OpWNs5KbFHc02DVzV
# 5huowWR0QKfAcsW6Th+xtVhNef7Xj3OTrCw54qVI1vCwMROpVymWJy71h6aPTnYV
# VSZwmCZ/oBpHIEPjQ2OAe3VuJyWQmDo4EbP29p7mO1vsgd4iFNmCKseSv6De4z6i
# c/rnH1pslPJSlRErWHRAKKtzQ87fSqEcazjFKfPKqpZzQmiftkaznTqj1QPgv/Ci
# PMpC3BhIfxQ0z9JMq++bPf4OuGQq+nUoJEHtQr8FnGZJUlD0UfM2SU2LINIsVzV5
# K6jzRWC8I41Y99xh3pP+OcD5sjClTNfpmEpYPtMDiP6zj9NeS3YSUZPJjAw7W4oi
# qMEmCPkUEBIDfV8ju2TjY+Cm4T72wnSyPx4JduyrXUZ14mCjWAkBKAAOhFTuzuld
# yF4wEr1GnrXTdrnSDmuZDNIztM2xAgMBAAGjggFdMIIBWTASBgNVHRMBAf8ECDAG
# AQH/AgEAMB0GA1UdDgQWBBS6FtltTYUvcyl2mi91jGogj57IbzAfBgNVHSMEGDAW
# gBTs1+OC0nFdZEzfLmc/57qYrhwPTzAOBgNVHQ8BAf8EBAMCAYYwEwYDVR0lBAww
# CgYIKwYBBQUHAwgwdwYIKwYBBQUHAQEEazBpMCQGCCsGAQUFBzABhhhodHRwOi8v
# b2NzcC5kaWdpY2VydC5jb20wQQYIKwYBBQUHMAKGNWh0dHA6Ly9jYWNlcnRzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRSb290RzQuY3J0MEMGA1UdHwQ8MDow
# OKA2oDSGMmh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRS
# b290RzQuY3JsMCAGA1UdIAQZMBcwCAYGZ4EMAQQCMAsGCWCGSAGG/WwHATANBgkq
# hkiG9w0BAQsFAAOCAgEAfVmOwJO2b5ipRCIBfmbW2CFC4bAYLhBNE88wU86/GPvH
# UF3iSyn7cIoNqilp/GnBzx0H6T5gyNgL5Vxb122H+oQgJTQxZ822EpZvxFBMYh0M
# CIKoFr2pVs8Vc40BIiXOlWk/R3f7cnQU1/+rT4osequFzUNf7WC2qk+RZp4snuCK
# rOX9jLxkJodskr2dfNBwCnzvqLx1T7pa96kQsl3p/yhUifDVinF2ZdrM8HKjI/rA
# J4JErpknG6skHibBt94q6/aesXmZgaNWhqsKRcnfxI2g55j7+6adcq/Ex8HBanHZ
# xhOACcS2n82HhyS7T6NJuXdmkfFynOlLAlKnN36TU6w7HQhJD5TNOXrd/yVjmScs
# PT9rp/Fmw0HNT7ZAmyEhQNC3EyTN3B14OuSereU0cZLXJmvkOHOrpgFPvT87eK1M
# rfvElXvtCl8zOYdBeHo46Zzh3SP9HSjTx/no8Zhf+yvYfvJGnXUsHicsJttvFXse
# GYs2uJPU5vIXmVnKcPA3v5gA3yAWTyf7YGcWoWa63VXAOimGsJigK+2VQbc61RWY
# MbRiCQ8KvYHZE/6/pNHzV9m8BPqC3jLfBInwAM1dwvnQI38AC+R2AibZ8GV2QqYp
# hwlHK+Z/GqSFD/yYlvZVVCsfgPrA8g4r5db7qS9EFUrnEw4d2zc4GqEr9u3WfPww
# ggbAMIIEqKADAgECAhADyzT9Pf8SETOf8HxLIVfHMA0GCSqGSIb3DQEBCwUAMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwHhcNMjIwODMwMDAwMDAwWhcNMjMwODI5MjM1OTU5WjBGMQswCQYDVQQGEwJV
# UzERMA8GA1UEChMIRGlnaUNlcnQxJDAiBgNVBAMTG0RpZ2lDZXJ0IFRpbWVzdGFt
# cCAyMDIyIC0gMjCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAM/spSY6
# xqnya7uNwQ2a26HoFIV0MxomrNAcVR4eNm28klUMYfSdCXc9FZYIL2tkpP0GgxbX
# kZI4HDEClvtysZc6Va8z7GGK6aYo25BjXL2JU+A6LYyHQq4mpOS7eHi5ehbhVsbA
# umRTuyoW51BIu4hpDIjG8b7gL307scpTjUCDHufLckkoHkyAHoVW54Xt8mG8qjoH
# ffarbuVm3eJc9S/tjdRNlYRo44DLannR0hCRRinrPibytIzNTLlmyLuqUDgN5YyU
# XRlav/V7QG5vFqianJVHhoV5PgxeZowaCiS+nKrSnLb3T254xCg/oxwPUAY3ugjZ
# Naa1Htp4WB056PhMkRCWfk3h3cKtpX74LRsf7CtGGKMZ9jn39cFPcS6JAxGiS7uY
# v/pP5Hs27wZE5FX/NurlfDHn88JSxOYWe1p+pSVz28BqmSEtY+VZ9U0vkB8nt9Kr
# FOU4ZodRCGv7U0M50GT6Vs/g9ArmFG1keLuY/ZTDcyHzL8IuINeBrNPxB9Thvdld
# S24xlCmL5kGkZZTAWOXlLimQprdhZPrZIGwYUWC6poEPCSVT8b876asHDmoHOWIZ
# ydaFfxPZjXnPYsXs4Xu5zGcTB5rBeO3GiMiwbjJ5xwtZg43G7vUsfHuOy2SJ8bHE
# uOdTXl9V0n0ZKVkDTvpd6kVzHIR+187i1Dp3AgMBAAGjggGLMIIBhzAOBgNVHQ8B
# Af8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAg
# BgNVHSAEGTAXMAgGBmeBDAEEAjALBglghkgBhv1sBwEwHwYDVR0jBBgwFoAUuhbZ
# bU2FL3MpdpovdYxqII+eyG8wHQYDVR0OBBYEFGKK3tBh/I8xFO2XC809KpQU31Kc
# MFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9EaWdp
# Q2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcmwwgZAG
# CCsGAQUFBwEBBIGDMIGAMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2Vy
# dC5jb20wWAYIKwYBBQUHMAKGTGh0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydFRydXN0ZWRHNFJTQTQwOTZTSEEyNTZUaW1lU3RhbXBpbmdDQS5jcnQw
# DQYJKoZIhvcNAQELBQADggIBAC0UyaEGSS3dimxaHgXjrMnYnjeKsKYhIj9EyjE9
# ywwM33xT5ZRqdiX3Isk7nEIElPWCRN5u4oTo7k5EGGktx3ZsrHpzf0siEEmEdDfy
# gtNBlXYxLvlZab8HVrslWfexM+66XRCFK19PgSnudu0gC3XaxWbC6eAeWmgBTLRk
# tDRpqbY9fj1d6REtuXxf4RNrN0MDT+kVDdt1BVTHDTlfGDbA6HAXR1Vc+khF8cv4
# RMJ8vvP3p6z05qFttPe3RMWPCC+d8hKtJI+2C3hBwdKChzJizkfq60Vrqqj+dEeB
# nrUYhUcYIIz6WeVYk72r/31a9SowYPuTzNCktU59LF6Y2/bMPIpHeHhsBAvg2RMx
# DzH4TfzgKkGM8F8VDpTAKUXe8vlzzsNjJ4m+oeGi72Kj6if/M07iiT4kMEQV5Fg8
# BotKdIqx7a1Cf+aqpZq5+DAcFhPwo4uoKtSLAWY0aIACxRKSFqIHngiuc2t9n+vB
# /oM/rtlQNnnlt8E2hvC3yQl5+M/7sqzX4vI3BBv6ASmOsDaYOGrb90BA77kpxccg
# avKscb/UdmJ+yGZjMyuuUzjPpKpGxMG95S9ATieDVuDFi68taSY81PJVmxBD/MrB
# bfTZ9JBLS5F1s0ecKEr6OOY1PvLIry+8TrgnFUP5KT019GjiRV2GVCOBx9aBB9M+
# oTliMYIFXTCCBVkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln
# aUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQAwW7hiGwoWNf
# v96uEgTnbTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgACh
# AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM
# BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCD/dmMP+WVqt9VUSyonWl4i3kdQ
# fFFzcVPSD+g79qRz9jANBgkqhkiG9w0BAQEFAASCAQATe2Dm7G53Dk+ejGfvekY7
# gzkZwNht3rPYEW7Is3upvmAwcjnQD1VNexeQHWKHBeCQKPe1CWzqROS9JIgg2p+0
# IiSht6SyyL7A28DAPxdEGPHqA4hPi3RVi6vy/rn6uuoAEE3puo3ghgqA/OAntr8B
# gtkcapgEBDZW/0KvBtOEyc+EdJtnuv7t9sGvwcmgWxTgbQhaesdWwUG47JFRu+Io
# F7dJFbKdRsrjsfwStB5LkikAoYieSLCgvfeQ2ma6iEGscNeBeT3iiEP6xJJ6ubV4
# K0vjqYL/6c83dkxBT/1zZE6KqlWbjMmouoFNoEaYRKAtINfQ0ut6jH9FKmUiQY1x
# oYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMx
# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVz
# dGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQA8s0/T3/EhEz
# n/B8SyFXxzANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B
# BwEwHAYJKoZIhvcNAQkFMQ8XDTIyMDkxNTIzMTQ1OFowLwYJKoZIhvcNAQkEMSIE
# II5R9VSBa0VK6HcY061p9Zn+npXMRvT9xUB+/tdLu/F6MA0GCSqGSIb3DQEBAQUA
# BIICAMqclGhx9hiDO8H25ETHSO/3JeT5SBp1xOyDRg1HhJx8O/lbYBHLwNjTsbXk
# QS7csYKvjQpF5F0VZzArZyrFv/pg22vrAXdhxNIPAYUTHOA6n0fZE+2JExMzAXhb
# RfDyykVIzeY2R4k7lL/7gUF0SaznascOyIQ+hn/2xZ3neEzeO+0jI4Joma1JQ0fd
# MXn3fkxoc3rRq/LqdCSTmz0RLMMQ7aQuT5ZzIp4L0QaRuvvdVJoS7EiVIPdf1l2j
# XSkCnZBXjqoLgc+tjYVH/BEMoC6C37fz8fS35qDHy2QEe/1BC5Ru94ordZKHwpG0
# cvo6PGrjKzgsNNAhQMEYwR92bgqBNLV32i+FVNUzL5dEOhhMauYv40E2e8L6NDDd
# fl8v3wST7g9sN5Ec82OVMSLAfw0GYzj+iqsS0nYM2bIwphzoLl7tpFAfEaHpuLlW
# 4hEs96dz61Ly85tOK56PLYF/us3p5/u8B/ssYhcQJuyRnmeSNQ/LiTM+gz+FyNiH
# TY2FncZ0Si+Aq5aCbB8P9mdDSa7OS/Xr1LpSh9yjkaFANEVaG2R9bHDUhw/Z3i7m
# 5ESqR4vfUHhfMqiZrNAcf4La6cdYb78lK/LLnyN+EueX/1HDJUQBuoRT71R/awyN
# X4ZIUrydoe3dQUfx8cLIonw/wzHccNEiMbSRNBxgSdE80kHn
# SIG # End signature block