private/Update-KbDatabase.ps1

function Update-KbDatabase {
    [CmdletBinding()]
    param(
        [switch]$EnableException
    )
    begin {
        if ($EnableException) { $ee = $true } else { $ee = $false }
        $PSDefaultParameterValues["*:EnableException"] = $ee
        $PSDefaultParameterValues["Invoke-WebRequest:SkipHeaderValidation"] = $true
        $PSDefaultParameterValues["*:Confirm"] = $false
        # Bunch of functions are needed to help parallelization

        function Update-KbDb {
            [CmdletBinding()]
            param(
                $recent
            )
            begin {

                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
                    }
                }

                function Get-SuperInfo ($Text, $Pattern) {
                    # this works, but may also summon cthulhu
                    $span = [regex]::match($Text, $pattern + '[\s\S]*?<div id')

                    switch -Wildcard ($span.Value) {
                        "*div style*" { $regex = '">\s*(.*?)\s*<\/div>' }
                        "*a href*" { $regex = "<div[\s\S]*?'>(.*?)<\/a" }
                        default { $regex = '"\s?>\s*(\S+?)\s*<\/div>' }
                    }

                    $spanMatches = [regex]::Matches($span, $regex).ForEach( { $_.Groups[1].Value })
                    if ($spanMatches -eq 'n/a') { $spanMatches = $null }

                    if ($spanMatches) {
                        foreach ($superMatch in $spanMatches) {
                            $detailedMatches = [regex]::Matches($superMatch, '\b[kK][bB]([0-9]{6,})\b')
                            # $null -ne $detailedMatches can throw cant index null errors, get more detailed
                            if ($null -ne $detailedMatches.Groups) {
                                [PSCustomObject] @{
                                    'KB'          = $detailedMatches.Groups[1].Value
                                    'Description' = $superMatch
                                } | Add-Member -MemberType ScriptMethod -Name ToString -Value { $this.Description } -PassThru -Force
                            }
                        }
                    }
                }
                function ConvertTo-DataTable {
                    [OutputType([Data.DataTable])]
                    param(
                        # The input objects
                        [Parameter(Mandatory, ValueFromPipeline)]
                        [PSObject[]]$InputObject
                    )
                    begin {
                        $outputDataTable = New-Object System.Data.DataTable

                    }
                    process {
                        foreach ($object in $InputObject) {
                            $DataRow = $outputDataTable.NewRow()

                            foreach ($property in $object.PsObject.properties) {
                                $propName = $property.Name
                                $propValue = $property.Value

                                if (-not $outputDataTable.Columns.Contains($propName)) {
                                    $outputDataTable.Columns.Add((
                                            New-Object System.Data.DataColumn -Property @{
                                                ColumnName = $propName
                                                DataType   = 'System.Object'
                                            }
                                        ))
                                }

                                $DataRow.Item($propName) = if ($propValue) {
                                    [PSObject]$propValue
                                } else {
                                    [DBNull]::Value
                                }

                            }
                            $outputDataTable.Rows.Add($DataRow)
                        }
                    }
                    end {
                        ,$outputDataTable
                    }
                }

                function Get-KbItemFromWeb ($kb) {
                    try {
                        # long story
                        $guids = @()
                        $guids += [PSCustomObject]@{
                            Guid  = $kb
                            Title = $kb
                        }

                        $sb = {
                            $post = @{ size = 0
                                updateID    = $psitem.Guid
                                uidInfo     = $psitem.Guid
                            } | ConvertTo-Json -Compress

                            $parms = @{
                                Uri    = 'https://www.catalog.update.microsoft.com/DownloadDialog.aspx'
                                Method = "POST"
                                Body   = @{ updateIDs = "[$post]" }
                            }
                            Invoke-TlsWebRequest @parms | Select-Object -ExpandProperty Content
                        }

                        $downloaddialogs = $guids | ForEach-Object -Process $sb

                        foreach ($downloaddialog in $downloaddialogs) {
                            $title = Get-Info -Text $downloaddialog -Pattern 'enTitle ='
                            $arch = Get-Info -Text $downloaddialog -Pattern 'architectures ='
                            $longlang = Get-Info -Text $downloaddialog -Pattern 'longLanguages ='
                            if ($Pattern -match '^[0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12}$') {
                                $updateid = "$Pattern"
                            } else {
                                $updateid = Get-Info -Text $downloaddialog -Pattern 'updateID ='
                            }
                            $ishotfix = Get-Info -Text $downloaddialog -Pattern 'isHotFix ='

                            if ($ishotfix) {
                                $ishotfix = "True"
                            } else {
                                $ishotfix = "False"
                            }
                            if ($longlang -eq "all") {
                                $longlang = "All"
                            }

                            if ($arch -eq "") {
                                $arch = $null
                            }
                            if ($arch -eq "AMD64") {
                                $arch = "x64"
                            }
                            if ($arch -eq "n/a") {
                                $arch = $null
                            }
                            if ($item.title -match "ia32") {
                                $arch = "IA32"
                            }
                            if ($item.title -match "ia64") {
                                $arch = "IA64"
                            }

                            if ($title -match '64-Bit' -and ($title -notmatch '32-Bit' -and $title -notmatch 'x86')) {
                                $arch = "x64"
                            }

                            if (($title -notmatch 'x64' -and $title -notmatch '64-Bit') -and $title -match 'x86') {
                                $arch = "x86"
                            }

                            if (($title -notmatch '64-Bit' -and $title -notmatch 'x64') -and $title -match '32-Bit') {
                                $arch = "x86"
                            }

                            if ($title -match 'x64' -and ($title -notmatch 'x86' -and $title -notmatch '32-bit')) {
                                $arch = "x64"
                            }

                            if ($arch -eq "n/a") {
                                $arch = $null
                            }
                            if ($link -match "x64" -or $link -match "AMD64" -and -not $arch) {
                                $arch = "x64"
                            }
                            if ($link -match "x86" -and -not $arch) {
                                $arch = "x86"
                            }
                            if ($link -match "ARM64" -and -not $arch) {
                                $arch = "ARM64"
                            }
                            if ($link -match "ARM-based" -and -not $arch) {
                                $arch = "ARM32"
                            }

                            $detaildialog = Invoke-TlsWebRequest -Uri "https://www.catalog.update.microsoft.com/ScopedViewInline.aspx?updateid=$updateid"
                            $description = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_desc">'
                            $lastmodified = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_date">'
                            $size = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_size">'
                            $classification = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelClassification_Separator" class="labelTitle">'
                            $supportedproducts = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelSupportedProducts_Separator" class="labelTitle">'
                            $msrcnumber = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelSecurityBulliten_Separator" class="labelTitle">'
                            $msrcseverity = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_msrcSeverity">'
                            $kbnumbers = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelKBArticle_Separator" class="labelTitle">'
                            $rebootbehavior = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_rebootBehavior">'
                            $requestuserinput = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_userInput">'
                            $exclusiveinstall = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_installationImpact">'
                            $networkrequired = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_connectivity">'
                            $uninstallnotes = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelUninstallNotes_Separator" class="labelTitle">'
                            $uninstallsteps = Get-Info -Text $detaildialog -Pattern '<span id="ScopedViewHandler_labelUninstallSteps_Separator" class="labelTitle">'
                            # Thanks @klorgas! https://github.com/potatoqualitee/kbupdate/issues/131
                            $supersededby = Get-SuperInfo -Text $detaildialog -Pattern '<div id="supersededbyInfo".*>'
                            $supersedes = Get-SuperInfo -Text $detaildialog -Pattern '<div id="supersedesInfo".*>'

                            if ($uninstallsteps -eq "n/a") {
                                $uninstallsteps = $null
                            }

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

                            $downloaddialog = $downloaddialog.Replace('www.download.windowsupdate', 'download.windowsupdate')

                            if ($kbnumbers -eq "n/a") {
                                $kbnumbers = $null
                            }

                            $ishotfix = switch ($ishotfix) {
                                'Yes' { $true }
                                'No' { $false }
                                default { $ishotfix }
                            }

                            $requestuserinput = switch ($requestuserinput) {
                                'Yes' { $true }
                                'No' { $false }
                                default { $requestuserinput }
                            }

                            $exclusiveinstall = switch ($exclusiveinstall) {
                                'Yes' { $true }
                                'No' { $false }
                                default { $exclusiveinstall }
                            }

                            $networkrequired = switch ($networkrequired) {
                                'Yes' { $true }
                                'No' { $false }
                                default { $networkrequired }
                            }

                            if ('n/a' -eq $uninstallnotes) { $uninstallnotes = $null }
                            if ('n/a' -eq $uninstallsteps) { $uninstallsteps = $null }

                            # find links that contain windowsupdate.com using regex

                            $downloaddialog = $downloaddialog.Replace('www.download.windowsupdate', 'download.windowsupdate')
                            $links = $downloaddialog | Select-String -AllMatches -Pattern "(http[s]?\://.*download\.windowsupdate\.com\/[^\'\""]*)" | Select-Object -Unique

                            [pscustomobject]@{
                                Title             = $title
                                Id                = $kbnumbers
                                Architecture      = $arch
                                Language          = $longlang
                                Hotfix            = $ishotfix
                                Description       = $description
                                LastModified      = $lastmodified
                                Size              = $size
                                Classification    = $classification
                                SupportedProducts = $supportedproducts
                                MSRCNumber        = $msrcnumber
                                MSRCSeverity      = $msrcseverity
                                RebootBehavior    = $rebootbehavior
                                RequestsUserInput = $requestuserinput
                                ExclusiveInstall  = $exclusiveinstall
                                NetworkRequired   = $networkrequired
                                UninstallNotes    = $uninstallnotes
                                UninstallSteps    = $uninstallsteps
                                UpdateId          = $updateid
                                Supersedes        = $supersedes
                                SupersededBy      = $supersededby
                                Link              = $links.matches.value -join "|"
                                InputObject       = $kb
                            }
                        }
                    } catch {
                        throw $PSitem
                    }
                }

                $scriptblock = {
                    $PSDefaultParameterValues["Invoke-WebRequest:SkipHeaderValidation"] = $true
                    Import-Module PSSQLite -Verbose:$false
                    $update = $PSItem
                    $guid = $update.UpdateID

                    # Links

                    try {
                        # Adding 04f45522-c78e-45d8-82a1-5614e9ab8596 to kb table
                        Write-Verbose -Message "Getting fresh web data for $guid"
                        try {
                            $webupdate = Get-KbItemFromWeb $guid
                        } catch {
                            throw "Unable to get details for $guid | $PSItem"
                        }

                        if ($update.PayloadFiles.File) {
                            Write-Verbose -Message "Found $(($update.PayloadFiles.File).Count) link(s), deleting old ones from the db and adding updated links"
                            Invoke-SQLiteQuery -DataSource $db -Query "delete from Link where UpdateId = '$guid'"

                            foreach ($file in $update.PayloadFiles.File) {
                                $fileid = $file.id
                                $url = ($ds.Tables["FileLocation"].Select("Id = '$fileid'")).Url
                                $url = $url.Replace("http://download.windowsupdate.com", "https://catalog.s.download.windowsupdate.com")
                                $url = $url.Replace("http://www.download.windowsupdate.com", "https://catalog.s.download.windowsupdate.com")

                                if ($url) {
                                    Invoke-SQLiteBulkCopy -DataTable (
                                        [pscustomobject]@{
                                            UpdateId = $guid
                                            Link     = $url
                                        } | ConvertTo-DataTable) -DataSource $db -Table Link -Confirm:$false
                                }
                            }
                        } elseif ($webupdate.Link) {
                            Write-Warning "no link in xml but found in webupdate $guid"

                            Write-Verbose -Message "Found $(($update.PayloadFiles.File).Count) link(s), deleting old ones from the db and adding updated links"
                            Invoke-SQLiteQuery -DataSource $db -Query "delete from Link where UpdateId = '$guid'"

                            $links = $webupdate.Link -split "\|"
                            foreach ($link in $links) {
                                Invoke-SQLiteBulkCopy -DataTable (
                                    [pscustomobject]@{
                                        UpdateId = $guid
                                        Link     = $link
                                    } | ConvertTo-DataTable) -DataSource $db -Table Link -Confirm:$false
                            }
                        }


                        if (-not $webupdate.UpdateId) {
                            return
                        }

                        try {
                            Write-Verbose -Message "Deleting old entries from $db"
                            Invoke-SQLiteQuery -DataSource $db -Query "delete from Kb where UpdateId = '$guid'"
                            Invoke-SQLiteQuery -DataSource $db -Query "delete from SupersededBy where UpdateId = '$guid'"
                            Invoke-SQLiteQuery -DataSource $db -Query "delete from Supersedes where UpdateId = '$guid'"

                            $kb = $webupdate | Select-Object -Property * -ExcludeProperty SupersededBy, Supersedes, Link, InputObject
                        } catch {
                            throw "Unable to delete db entries for $guid | $PSItem"
                        }

                        # Saved to DB as a full string then split by pipe in PowerShell
                        if ($kb.SupportedProducts) {
                            $kb.SupportedProducts = $kb.SupportedProducts -join "|"
                        }

                        Write-Verbose -Message "Adding $guid to kb table"
                        $null = Add-Member -InputObject $kb -NotePropertyName DateAdded -NotePropertyValue (Get-Date) -Force
                        try {
                            Invoke-SQLiteBulkCopy -DataTable ($kb | ConvertTo-DataTable) -DataSource $db -Table Kb -Confirm:$false
                        } catch {
                            Write-Warning -Message "Failure on $guid | $PSItem"
                            continue
                        }

                        try {
                            if ($webupdate.SupersededBy) {
                                Write-Verbose -Message "Processing $(($webupdate.SupersededBy).Count) SupersededBy matches"
                                foreach ($item in $webupdate.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-DataTable) -DataSource $db -Table SupersededBy -Confirm:$false
                                        }
                                    }
                                }
                            }
                        } catch {
                            Write-Warning -Message $PSItem
                            continue
                        }

                        try {
                            Write-Verbose -Message "Processing $(($webupdate.Supersedes).Count) Supersedes matches"
                            if ($webupdate.Supersedes) {
                                foreach ($item in $webupdate.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-DataTable) -DataSource $db -Table Supersedes -Confirm:$false
                                        }
                                    }
                                }
                            }

                        } catch {
                            Write-Warning -Message $PSItem
                            continue
                        }
                    } catch {
                        Write-Warning -Message "Failure for $guid | $PSItem"
                        continue
                    }
                }
            }
            process {
                $parm = @{
                    ImportVariables = $true
                    ImportFunctions = $true
                    Quiet           = $true
                    RunspaceTimeout = 180
                    ScriptBlock     = $scriptblock
                    ErrorAction     = "Stop"

                }
                try {
                    $recent | Invoke-Parallel @parm
                } catch {
                    Write-Warning "Error: $PSItem"
                    try {
                        $PSItem.UpdateId | ForEach-Object -Process $scriptblock
                    } catch {
                        Write-Warning "Error: $PSItem"
                        continue
                    }
                }
                # if going one-by-one is needed for debugging
                # $recent | ForEach-Object -Process $scriptblock
            }
        }
    }
    process {
        <#
        KB5013944
 
            $xml.OfflineSyncPackage.CreationDate
            MinimumClientVersion : 5.8.0.2678
            PackageId : c837c786-be39-4f17-8ec5-ede03ad2c80a
            PackageVersion : 1.1
            ProtocolVersion : 1.0
            CreationDate : 2022-05-10T16:25:52Z
            SourceId : 802cb907-a558-4033-9844-bbf65cd3481e
            xmlns : http://schemas.microsoft.com/msus/2004/02/OfflineSync
            Updates : Updates
            FileLocations : FileLocations
        #>

        Write-ProgressHelper -StepNumber 1 -Activity "Setting up prerequisites" -Message "Getting database details"

        try {
            $null = Import-Module kbupdate-library -ErrorAction Stop
        } catch {
            $null = Set-PSRepository PSGallery -InstallationPolicy Trusted
            $null = Install-Module kbupdate-library -ErrorAction Stop -Scope CurrentUser
            $null = Import-Module kbupdate-library -ErrorAction Stop
        }
        $modpath = Split-Path (Get-Module kbupdate-library).Path | Select-Object -Last 1
        $kblib = Join-PSFPath -Path $modpath -Child library
        $db = Join-PSFPath -Path $kblib -Child kb.sqlite

        $size = [int]((Get-ChildItem -Path $db).Length / 1MB)
        "The db is $size MB" | Write-Warning

        Write-ProgressHelper -StepNumber 2 -Activity "Setting up prerequisites" -Message "Saving scanfile using Save-KbScanFile and Microsoft.Update.ServiceManager"

        Write-PSFMessage -Level Verbose -Message "Saving scanfile"
        $scanfile = Save-KbScanFile
        $basedir = Split-Path $scanfile
        $cabfile = Join-PSFPath $basedir -Child package.cab

        Write-ProgressHelper -StepNumber 3 -Activity "Setting up prerequisites" -Message "Unpacking $scanfile"

        Write-PSFMessage -Level Verbose -Message "Unpacking $scanfile"
        $cab = New-Object Microsoft.Deployment.Compression.Cab.Cabinfo $scanfile
        $null = $cab.UnpackFile("package.cab", $cabfile)
        $xmlfile = Join-PSFPath $basedir -Child package.xml

        Write-ProgressHelper -StepNumber 4 -Activity "Setting up prerequisites" -Message "Importing $xmlfile"

        $cab = New-Object Microsoft.Deployment.Compression.Cab.Cabinfo $cabfile
        $null = $cab.UnpackFile("package.xml", $xmlfile)
        $xml = [xml](Get-Content -Path $xmlfile)
        $updates = $xml.OfflineSyncPackage.Updates.Update

        Write-ProgressHelper -StepNumber 5 -Activity "Setting up prerequisites" -Message "Loading $xmlfile into dataset"

        Write-PSFMessage -Level Verbose -Message "Loading $xmlfile into dataset"
        # This takes 30 seconds but saves time in the long-run 200ms per execution X thousands
        if (-not $ds) {
            $ds = New-Object System.Data.DataSet
            $null = $ds.ReadXml($xmlfile)
        }

        Write-PSFMessage -Level Verbose -Message "$($updates.Count) total items in the database"

        Write-ProgressHelper -StepNumber 6 -Activity "Setting up prerequisites" -Message "Searching for recent updates"

        # Only process from the last 3 months, this is an arbitrary amount that will cover
        # since the last release of the offline wsus db which usually occurs every 30 days
        $recent = $updates.Where({ ([datetime]($PSItem.CreationDate)) -gt ((Get-Date).AddMonths(-3)) })
        Write-Warning "$($recent.Count) updates to process"
        Write-PSFMessage -Level Verbose -Message "Processing $($recent.Count) kbs"

        Write-ProgressHelper -StepNumber 7 -Activity "Setting up prerequisites" -Message "Processing $($recent.Count) kbs"
        Write-Progress -Activity "Setting up prerequisites" -Completed
        Write-Warning "About to run Update-KbDb"
        $output = Update-KbDb $recent
        Write-Warning "Just ran Update-KbDb"
        if ($output.UpdateId) {
            $output.UpdateId | Write-Warning "Trying to grab $PSItem again"
            foreach ($object in $output) {
                $null = $object.UpdateId | ForEach-Object -Process $scriptblock -ErrorAction SilentlyContinue
            }
        }
    }
    end {
        if ($db) {
            $updatesfile = Resolve-Path -Path $script:ModuleRoot\build\updates.sql
            $null = Invoke-SQLiteQuery -DataSource $db -InputFile $updatesfile -Verbose

            $size = [int]((Get-ChildItem -Path $db).Length / 1MB)
            Write-ProgressHelper -StepNumber 1 -Activity "Compressing db" -Message "Compressing db"
            try {
                Write-PSFMessage -Level Verbose -Message "Compressing db ($size)"
                $null = Invoke-SqliteQuery -DataSource $db -Query "VACUUM;" -ErrorAction Stop
                $size = [int]((Get-ChildItem -Path $db).Length / 1MB)
                Write-PSFMessage -Level Verbose -Message "Done compressing db ($size)"
            } catch {
                Write-PSFMessage -Level Warning -Message "DB compression failed: $PSItem"
            }
            Write-Progress -Activity "Compressing db" -Completed
            "The db is $size MB" | Write-Warning
            Get-ChildItem -Path $db
        } else {
            Write-Warning "No db to compress"
        }
    }
}
# SIG # Begin signature block
# MIIjYAYJKoZIhvcNAQcCoIIjUTCCI00CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDFho7QwhYOawES
# PJXHbZSIhlBsdPLl+wiYt7DXCykD7aCCHVkwggUaMIIEAqADAgECAhADBbuGIbCh
# 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
# ggbAMIIEqKADAgECAhAMTWlyS5T6PCpKPSkHgD1aMA0GCSqGSIb3DQEBCwUAMGMx
# CzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjE7MDkGA1UEAxMy
# RGlnaUNlcnQgVHJ1c3RlZCBHNCBSU0E0MDk2IFNIQTI1NiBUaW1lU3RhbXBpbmcg
# Q0EwHhcNMjIwOTIxMDAwMDAwWhcNMzMxMTIxMjM1OTU5WjBGMQswCQYDVQQGEwJV
# 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
# DQYJKoZIhvcNAQELBQADggIBAFWqKhrzRvN4Vzcw/HXjT9aFI/H8+ZU5myXm93KK
# mMN31GT8Ffs2wklRLHiIY1UJRjkA/GnUypsp+6M/wMkAmxMdsJiJ3HjyzXyFzVOd
# r2LiYWajFCpFh0qYQitQ/Bu1nggwCfrkLdcJiXn5CeaIzn0buGqim8FTYAnoo7id
# 160fHLjsmEHw9g6A++T/350Qp+sAul9Kjxo6UrTqvwlJFTU2WZoPVNKyG39+Xgmt
# dlSKdG3K0gVnK3br/5iyJpU4GYhEFOUKWaJr5yI+RCHSPxzAm+18SLLYkgyRTzxm
# lK9dAlPrnuKe5NMfhgFknADC6Vp0dQ094XmIvxwBl8kZI4DXNlpflhaxYwzGRkA7
# zl011Fk+Q5oYrsPJy8P7mxNfarXH4PMFw1nfJ2Ir3kHJU7n/NBBn9iYymHv+XEKU
# gZSCnawKi8ZLFUrTmJBFYDOA4CPe+AOk9kVH5c64A0JH6EE2cXet/aLol3ROLtoe
# HYxayB6a1cLwxiKoT5u92ByaUcQvmvZfpyeXupYuhVfAYOd4Vn9q78KVmksRAsiC
# nMkaBXy6cbVOepls9Oie1FqYyJ+/jbsYXEP10Cro4mLueATbvdH7WwqocH7wl4R4
# 4wgDXUcsY6glOJcB0j862uXl9uab3H4szP8XTE0AotjWAQ64i+7m4HJViSwnGWH2
# dwGMMYIFXTCCBVkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lD
# ZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGln
# aUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQAwW7hiGwoWNf
# v96uEgTnbTANBglghkgBZQMEAgEFAKCBhDAYBgorBgEEAYI3AgEMMQowCKACgACh
# AoAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMBwGCisGAQQBgjcCAQsxDjAM
# BgorBgEEAYI3AgEVMC8GCSqGSIb3DQEJBDEiBCD6/1Tq9ZbuikxGP+M+FTuTGojN
# s4hwxhlanMNSV9exkjANBgkqhkiG9w0BAQEFAASCAQBkehb5Apk5GjscRkaF6OXC
# qEPdDOB5b2Wa6s27kOC4XHPGry/SnbdvBybO1umwt4i8YQuLR7i2YNTuoUaSdWpn
# fGasbrkLNXLZp8Jk3YYo/AVvWahmAYxApOpPklyVqpBQ9Hmg3FH1N1eARFwmlP6B
# pF1UkHIuDauvWPDb40nziCJcmVf+QaboJP4gyBvMkJovscuyr9DX7lxumvnroyZa
# TBrhDiloHdFwT2IGlGZf4cS7sY0yJIoLWRW8nwj4TPElvqHEu8MJLD9OqYLOhQz4
# vxGEnlAuHixivhugEkEFaywt7EMfa85zk1t5CZPIi3PN4TvYdfnFj4h/OOG/ylxh
# oYIDIDCCAxwGCSqGSIb3DQEJBjGCAw0wggMJAgEBMHcwYzELMAkGA1UEBhMCVVMx
# FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTswOQYDVQQDEzJEaWdpQ2VydCBUcnVz
# dGVkIEc0IFJTQTQwOTYgU0hBMjU2IFRpbWVTdGFtcGluZyBDQQIQDE1pckuU+jwq
# Sj0pB4A9WjANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzELBgkqhkiG9w0B
# BwEwHAYJKoZIhvcNAQkFMQ8XDTIzMDUxMjAwMjUzM1owLwYJKoZIhvcNAQkEMSIE
# ING2giqSG20TxIKewISa3NKXjgtZ2d/ddP6WUMqXyYo9MA0GCSqGSIb3DQEBAQUA
# BIICAGaE8sTL8yZzl+HQMbt4abBbSSBp5yBdbpxDD0lIxVc9R0Uju5CE9ZOlQ9ey
# T47UbuK15C4B0Ub0opEEV3/KMwrm/D9EJzusnPKLO/R4p0NYh+FwHXF1lCNu1d3v
# MpZ/y/dFJX4gvvPb0HBRWQwenE3zPDLbH014tUq14n0K8NOar0N8FNahLF05OJj3
# pVhr2aWB+w+nJnCZAzfgFMj9aMwhE1wsqLoCX1+FYtaDY4SVuXXpjTEka8TnRqEk
# yiK9ZJTafx8J/yzbc4wfBKwt5idU/YBYbv0f383sLiRti69s/vjXxQTBxvk/8nKV
# AfnnC5pKt/wj93qDAG72HK0Y8ex6NwUSecAL5MAc9+1ZM9WAA4xKnFnxQJh2l9p4
# cd5B15UDWqhcgAmXCzH8D4nWdMuocahETWfoW9+NN/s4fijeY2yEUBxaandH5arw
# iEwPJvgvTls6DNHqKOjDfpxSPPLKhzC4zR3Ppl0Uj9DTn7nqy+6+Ax1QmHkYpMuR
# rmQBbmfCPvceHxrIpyYZWbk274apCm/L+Gn1Yy2z8rBBHBFAZKDLqWHNptZrNNTh
# HN/xodNqsnxTUI4KDVwHi6de454N3O0AjgS7DTAWyANnO1pyVpCybZNYrvzu5Sys
# hDt+xgxw8aP11FTnTQWj/tvTpwea5MVTI1DON9YTNi02N8NM
# SIG # End signature block