private/scripts/logfilescript.ps1
|
$scriptBlock = { $script:___ScriptName = 'dbatools-logging' #region Helper Functions function Clean-ErrorXml { [CmdletBinding()] param ( $Path ) $totalLength = $Null $files = Get-ChildItem -Path $Path.FullName -Filter "dbatools_$($pid)_error_*.xml" | Sort-Object LastWriteTime $totalLength = $files | Measure-Object Length -Sum | Select-Object -ExpandProperty Sum if (([Dataplat.Dbatools.Message.LogHost]::MaxErrorFileBytes) -gt $totalLength) { return } $removed = 0 foreach ($file in $files) { $removed += $file.Length Remove-Item -Path $file.FullName -Force -Confirm:$false if (($totalLength - $removed) -lt ([Dataplat.Dbatools.Message.LogHost]::MaxErrorFileBytes)) { break } } } function Clean-MessageLog { [CmdletBinding()] param ( $Path ) if ([Dataplat.Dbatools.Message.LogHost]::MaxMessagefileCount -eq 0) { return } $files = Get-ChildItem -Path $Path.FullName -Filter "dbatools_$($pid)_message_*.log" | Sort-Object LastWriteTime if (([Dataplat.Dbatools.Message.LogHost]::MaxMessagefileCount) -ge $files.Count) { return } $removed = 0 foreach ($file in $files) { $removed++ Remove-Item -Path $file.FullName -Force -Confirm:$false if (($files.Count - $removed) -le ([Dataplat.Dbatools.Message.LogHost]::MaxMessagefileCount)) { break } } } function Clean-GlobalLog { [CmdletBinding()] param ( $Path ) # Kill too old files Get-ChildItem -Path "$($Path.FullName)\*" -Include "*.xml", "*.log" -Filter "*" | Where-Object LastWriteTime -LT ((Get-Date) - ([Dataplat.Dbatools.Message.LogHost]::MaxLogFileAge)) |Remove-Item -Force -Confirm:$false # Handle the global overcrowding $files = Get-ChildItem -Path "$($Path.FullName)\*" -Include "*.xml", "*.log" -Filter "*" | Sort-Object LastWriteTime if (-not ($files)) { return } $totalLength = $files | Measure-Object Length -Sum | Select-Object -ExpandProperty Sum if (([Dataplat.Dbatools.Message.LogHost]::MaxTotalFolderSize) -gt $totalLength) { return } $removed = 0 foreach ($file in $files) { $removed += $file.Length Remove-Item -Path $file.FullName -Force -Confirm:$false if (($totalLength - $removed) -lt ([Dataplat.Dbatools.Message.LogHost]::MaxTotalFolderSize)) { break } } } #endregion Helper Functions try { while ($true) { # This portion is critical to gracefully closing the script if ([Dataplat.Dbatools.Runspace.RunspaceHost]::Runspaces[$___ScriptName.ToLowerInvariant()].State -notlike "Running") { break } $path = [Dataplat.Dbatools.Message.LogHost]::LoggingPath if (-not (Test-Path $path)) { $root = New-Item $path -ItemType Directory -Force -ErrorAction Stop } else { $root = Get-Item -Path $path } $errorFiles = Get-ChildItem -Path $root.FullName -Filter "dbatools_$($pid)_error_*.xml" | Sort-Object LastWriteTime -Descending [int]$num_Error = if ($errorFiles) { (Select-String -InputObject $errorFiles[0].Name -Pattern "(\d+)" -AllMatches).Matches[1].Value } else { 0 } $messageFiles = Get-ChildItem -Path $root.FullName -Filter "dbatools_$($pid)_message_*.log" | Sort-Object LastWriteTime -Descending [int]$num_Message = if ($messageFiles) { (Select-String -InputObject $messageFiles[0].Name -Pattern "(\d+)" -AllMatches).Matches[1].Value } else { 0 } #region Process Errors while ([Dataplat.Dbatools.Message.LogHost]::OutQueueError.Count -gt 0) { $num_Error++ $Record = $null $null = [Dataplat.Dbatools.Message.LogHost]::OutQueueError.TryDequeue([ref]$Record) if ($Record) { $Record | Export-Clixml -Path "$($root.FullName)\dbatools_$($pid)_error_$($num_Error).xml" -Depth 3 } Clean-ErrorXml -Path $root } #endregion Process Errors #region Process Logs while ([Dataplat.Dbatools.Message.LogHost]::OutQueueLog.Count -gt 0) { $CurrentFile = "$($root.FullName)\dbatools_$($pid)_message_$($num_Message).log" if (Test-Path $CurrentFile) { $item = Get-Item $CurrentFile if ($item.Length -gt ([Dataplat.Dbatools.Message.LogHost]::MaxMessagefileBytes)) { $num_Message++ $CurrentFile = "$($root.FullName)\dbatools_$($pid)_message_$($num_Message).log" } } $Entry = $null $null = [Dataplat.Dbatools.Message.LogHost]::OutQueueLog.TryDequeue([ref]$Entry) if ($Entry) { # ConvertTo-Csv calls ToString() on every property, which returns the type name for the list of tags. # So we join the tags into one string and keep all other columns in their order. $csvProperties = foreach ($propertyName in $Entry.PSObject.Properties.Name) { if ($propertyName -eq "Tags") { @{ Name = "Tags" Expression = { $PSItem.Tags -join ", " } } } else { $propertyName } } $csvEntry = $Entry | Select-Object -Property $csvProperties Add-Content -Path $CurrentFile -Value (ConvertTo-Csv -InputObject $csvEntry -NoTypeInformation)[1] } } #endregion Process Logs Clean-MessageLog -Path $root Clean-GlobalLog -Path $root Start-Sleep -Seconds 5 } } catch { } finally { [Dataplat.Dbatools.Runspace.RunspaceHost]::Runspaces[$___ScriptName.ToLowerInvariant()].SignalStopped() } } Register-DbaRunspace -ScriptBlock $scriptBlock -Name "dbatools-logging" Start-DbaRunspace -Name "dbatools-logging" # SIG # Begin signature block # MIItZgYJKoZIhvcNAQcCoIItVzCCLVMCAQMxDTALBglghkgBZQMEAgEwewYKKwYB # BAGCNwIBBKBtBGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCC9PRuNrlSBbfAj # cvdmhPzAXu35fy8wY80UsuK2cWNxHqCCFWUwggaTMIIEe6ADAgECAhMzAAhQvC/V # 2KdBaYGiAAAACFC8MA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ # RCBWZXJpZmllZCBDUyBFT0MgQ0EgMDQwHhcNMjYxMDE0MDI0NTE1WhcNMjYxMDE3 # MDI0NTE1WjBXMQswCQYDVQQGEwJVUzERMA8GA1UECBMIVmlyZ2luaWExDzANBgNV # BAcTBlZpZW5uYTERMA8GA1UEChMIZGJhdG9vbHMxETAPBgNVBAMTCGRiYXRvb2xz # MIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIBigKCAYEAkyXrYmh3hUg+igahmqfc # uPn8UU25vMufdgNzVV9vmM/GRhS+LD0XJ7sNqQUdXTmhtFN5iczhE+rnmPm3/zDU # cWEqYAJ8y46Y0x+IrmfbbIqQMEYveIT/wbNUC3baYSnfd5CHTBhc2w0SeWiqRW56 # 244+9w7LkTHkTHp+WJRLIWW9am2hjgRwG8Fvaqq/0KbBAHbUeGF3a57e+9QpB7vS # R3PyZoS8wZ03edj1BM/SGAg76f9k7fnELp/HOtTt6gyaFs8AsA+6HYVJHiqJM74K # WTYyHtLt9kWK1sea5/C/KXpbW9+sMP+b/JSlFaifLfuWp0oPUUO/Pby/+NdiNxrD # 3tAg4UiWaPFlPXw6r6X5I29t88wEh0eik9tkjikaDikKioQt3B5Bu6d4KINaL0vl # ymXJV1bOLknkBWnWwrvQxDNnEK6s/MLUW4h7ixLNlrbg3DYqrh0NRCUNvJg4IqyO # z5r0ZnwgHMRkFePXCl7Gytfm5Tz0B7haUSfpOjcKQHAJAgMBAAGjggHTMIIBzzAM # BgNVHRMBAf8EAjAAMA4GA1UdDwEB/wQEAwIHgDA6BgNVHSUEMzAxBgorBgEEAYI3 # YQEABggrBgEFBQcDAwYZKwYBBAGCN2H5+cEspPS4DoOuxLIcm56wGDAdBgNVHQ4E # FgQU8iEP+t70ALlNYB0WwXz7yUQM8DgwHwYDVR0jBBgwFoAUmvFUd3UMhxY3RqCs # 3nn59H/BeOkwZwYDVR0fBGAwXjBcoFqgWIZWaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENTJTIw # RU9DJTIwQ0ElMjAwNC5jcmwwdAYIKwYBBQUHAQEEaDBmMGQGCCsGAQUFBzAChlho # dHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUy # MElEJTIwVmVyaWZpZWQlMjBDUyUyMEVPQyUyMENBJTIwMDQuY3J0MFQGA1UdIARN # MEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wDQYJKoZIhvcNAQEMBQADggIB # ABmg2ZWx48fFny1C7m/4QszNMrFckHVw2U2dfvtjv/5dthl+dhJwQvYauUdJjjyK # lT/aS5sEII3mO7oxmvaQN+Vw2SqmP9zK0e40R8IyHoNlK+CKj5UuLA3/oibeJU5y # Y3pbl3etCfYJngK1HUyKfSiu7kn7OOiluFAab5Gf6JHuW00dNYSGxQ663Axcb4GV # dXjTfWOGovdVIelGGDaEQl5cqeL7IHP+/QSsnNhHY2akT4lwgMHSjqeuF6q72pq+ # VZTv+avySJmLlhhACZhbOPGj3P/RC/1jb0P1g9h32Ff3mP5ZsFuVQklNefaxFPbU # hgAMPrtvttd3bBumHEnA3mgqQJJni/aKn2XSgXo6SC53PfexxOeScF4h7pXLBSLV # +fpwFpJzvgdQsB5ZuNNb4lFsvAUbkwkfqV/FSBgTpUYBOqZJtYizA9b3EhgaikqU # 05I3RNVZvePolX3Q9FoI7/ZrrphdCDhRviZTzmA4ajc5EB0UOyLRKZt/qY8KxYRB # BS13LFQSIVyl1cLsbBz0yaFQEpRg2gJ6KfnKOjozlO+0jog1jPF+R0sgLy/3UN8M # l447L3W752urIJRfzzirGodTrVLjkrtnNma5w+SdHN7e8/1JSPNxEcCmTzIseQza # GHUCNNoUYAFCnULSU/w+3I/mPWuFsvPKDfiXrTdE8eehMIIHKDCCBRCgAwIBAgIT # MwAAABcnRQkLi4evxgAAAAAAFzANBgkqhkiG9w0BAQwFADBjMQswCQYDVQQGEwJV # UzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTQwMgYDVQQDEytNaWNy # b3NvZnQgSUQgVmVyaWZpZWQgQ29kZSBTaWduaW5nIFBDQSAyMDIxMB4XDTI2MDMy # NjE4MTEzMVoXDTMxMDMyNjE4MTEzMVowWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoT # FU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZl # cmlmaWVkIENTIEVPQyBDQSAwNDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC # ggIBAILHZP4DD2YqAZXMn5OrQ8yfj0beK0ixilvHsKUtJEcV7VEQt09xnWwipY6G # xJ/LrLKoRqkKUYf0l70VcDVxCBm++lBuSD5AidUuv/QQ+tUELCsz3qVtEjY/E14L # Bcb0uzJbaEbopCCKe0OY0IGjjOkMivfvumVV1KWJmbpQHusfCa8GdHTZBPq2eupa # raKHMHqVElVMTO6HQ5p/Mgx4ydgzT7H697kQ4sd1+Kr4deIx/0lvtgse1iDIciIk # DttNYuoVIsZpOHtmVvFuwtcD3U46ugSm/s6PMW67e2SkL0V+UDgOnYS6rj6o+bFS # p8an5NfSAtEmn00k7PMguNxMPeuQUUVvFS/XHKDpq+K8UMu2goGEzZN3Xfy6YTWk # 05pxqe5Ji08ch5AeYHqFoWLrhq8sEvBNMCb9FuK3zrRwVdHvbCr7lCHiFKZ7Meop # cRFY+lUF74A+sngipz5o94yYiSgJZlA7bYecs0VQVJeOLDIhuC+Uf8sgAkSpNp9P # PENmAqGUtTvOvqDCyrdY2lxhAjo27FafCHdVUMPIXuidCoqzkuXtuV5U3RjxW+qA # TjmmnIFu/Co39G6fl8wIJHPdpgxjSRmEo73Z4/u3jMepnltAwCBnS0TY/P+NvTCL # KRQX89yg6qqTe9UuJENiy3q93cYQw3MylRS9By8Ebjr4I4hvAgMBAAGjggHcMIIB # 2DAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFJrx # VHd1DIcWN0agrN55+fR/wXjpMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUF # BwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3Np # dG9yeS5odG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwEgYDVR0TAQH/BAgw # BgEB/wIBADAfBgNVHSMEGDAWgBTZQSmwDw9jbO9p1/XNKZ6kSGow5jBwBgNVHR8E # aTBnMGWgY6Bhhl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9N # aWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUyMFNpZ25pbmclMjBQQ0El # MjAyMDIxLmNybDB9BggrBgEFBQcBAQRxMG8wbQYIKwYBBQUHMAKGYWh0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSUQlMjBW # ZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIwMjAyMS5jcnQwDQYJKoZI # hvcNAQEMBQADggIBAJB1Whn9TSbfyXaIppkWWzFq+m2mg4vJpHVr1krZNIXWQ6cU # mEwOx7oqQKCy96iISNdNVzpe3zogoefvo2TmpkHQFe/aIxFDaCIAmZi9lyay2hmp # 8HYzcp3nCcmFQk60X9voeypJ6VjqeGsXTrOivWUOYNCLEFlwsH3NHX5EpCyjWN6Q # 3Fi5ST4do3eTVLnuqTQ7/9huTBTSYQsJbTg3m8gIxnHlPlzs2r/u4u9tWEJ0Pt/Z # tmkDhTu86QHWigHgBoRHemOgnQxp3ksXKLo1r2n1m7+Gst46NTkUi1LljGyq+V9f # EBOEnXvoKaRiy0pGbK1IdnsmEpF9Xp71l+2T84Nv8IrikZUBWqw5/jffttAas4cc # JDci832CadS4OHwl29uF6hY8fEg3UYHmxSJjnzi1c3vF0PwsJKxGom9Dx7treBlZ # OBWK6BGzVBar43Qb02N7okeU3UKMl6GB74fk8aS0mNr6O4YSvQ/66RKRwvqppnEV # BOHdIMjvWW9b77duX8TN3pI7w31R3D6t6jK9EcLJOJKymVlBIFNUl0+ajeoKka7I # cW0+jkIGff8U9OKol3cz0Eeiop3Qb0qaDp8ZwC8XCcs1cDaSi/vbvBGWMvfKl+ov # uIBP9ienG6XpHAdGVw5/10MaDVFG+v3Y0/8JZVchvryB5Hau9T82x+a2MXXAMIIH # njCCBYagAwIBAgITMwAAAAeHozSje6WOHAAAAAAABzANBgkqhkiG9w0BAQwFADB3 # MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMUgw # RgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkgVmVyaWZpY2F0aW9uIFJvb3QgQ2Vy # dGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjEwNDAxMjAwNTIwWhcNMzYwNDAx # MjAxNTIwWjBjMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBv # cmF0aW9uMTQwMgYDVQQDEytNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ29kZSBTaWdu # aW5nIFBDQSAyMDIxMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAsvDA # rxmIKOLdVHpMSWxpCFUJtFL/ekr4weslKPdnF3cpTeuV8veqtmKVgok2rO0D05Bp # yvUDCg1wdsoEtuxACEGcgHfjPF/nZsOkg7c0mV8hpMT/GvB4uhDvWXMIeQPsDgCz # UGzTvoi76YDpxDOxhgf8JuXWJzBDoLrmtThX01CE1TCCvH2sZD/+Hz3RDwl2MsvD # SdX5rJDYVuR3bjaj2QfzZFmwfccTKqMAHlrz4B7ac8g9zyxlTpkTuJGtFnLBGaso # Onn5NyYlf0xF9/bjVRo4Gzg2Yc7KR7yhTVNiuTGH5h4eB9ajm1OCShIyhrKqgOkc # 4smz6obxO+HxKeJ9bYmPf6KLXVNLz8UaeARo0BatvJ82sLr2gqlFBdj1sYfqOf00 # Qm/3B4XGFPDK/H04kteZEZsBRc3VT2d/iVd7OTLpSH9yCORV3oIZQB/Qr4nD4YT/ # lWkhVtw2v2s0TnRJubL/hFMIQa86rcaGMhNsJrhysLNNMeBhiMezU1s5zpusf54q # lYu2v5sZ5zL0KvBDLHtL8F9gn6jOy3v7Jm0bbBHjrW5yQW7S36ALAt03QDpwW1JG # 1Hxu/FUXJbBO2AwwVG4Fre+ZQ5Od8ouwt59FpBxVOBGfN4vN2m3fZx1gqn52Gvai # Bz6ozorgIEjn+PhUXILhAV5Q/ZgCJ0u2+ldFGjcCAwEAAaOCAjUwggIxMA4GA1Ud # DwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQU2UEpsA8PY2zv # adf1zSmepEhqMOYwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0 # bTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNVHRMBAf8EBTADAQH/MB8G # A1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGEBgNVHR8EfTB7MHmgd6B1 # hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNyb3NvZnQl # MjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUy # MEF1dGhvcml0eSUyMDIwMjAuY3JsMIHDBggrBgEFBQcBAQSBtjCBszCBgQYIKwYB # BQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj # cm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlm # aWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDAtBggrBgEFBQcwAYYhaHR0cDov # L29uZW9jc3AubWljcm9zb2Z0LmNvbS9vY3NwMA0GCSqGSIb3DQEBDAUAA4ICAQB/ # JSqe/tSr6t1mCttXI0y6XmyQ41uGWzl9xw+WYhvOL47BV09Dgfnm/tU4ieeZ7NAR # 5bguorTCNr58HOcA1tcsHQqt0wJsdClsu8bpQD9e/al+lUgTUJEV80Xhco7xdgRr # ehbyhUf4pkeAhBEjABvIUpD2LKPho5Z4DPCT5/0TlK02nlPwUbv9URREhVYCtsDM # +31OFU3fDV8BmQXv5hT2RurVsJHZgP4y26dJDVF+3pcbtvh7R6NEDuYHYihfmE2H # dQRq5jRvLE1Eb59PYwISFCX2DaLZ+zpU4bX0I16ntKq4poGOFaaKtjIA1vRElIta # OKcwtc04CBrXSfyL2Op6mvNIxTk4OaswIkTXbFL81ZKGD+24uMCwo/pLNhn7VHLf # nxlMVzHQVL+bHa9KhTyzwdG/L6uderJQn0cGpLQMStUuNDArxW2wF16QGZ1NtBWg # KA8Kqv48M8HfFqNifN6+zt6J0GwzvU8g0rYGgTZR8zDEIJfeZxwWDHpSxB5FJ1VV # U1LIAtB7o9PXbjXzGifaIMYTzU4YKt4vMNwwBmetQDHhdAtTPplOXrnI9SI6HeTt # jDD3iUN/7ygbahmYOHk7VB7fwT4ze+ErCbMh6gHV1UuXPiLciloNxH6K4aMfZN1o # LVk6YFeIJEokuPgNPa6EnTiOL60cPqfny+Fq8UiuZzGCF1cwghdTAgEBMHEwWjEL # MAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkG # A1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENTIEVPQyBDQSAwNAITMwAIULwv # 1dinQWmBogAAAAhQvDALBglghkgBZQMEAgGgfDAQBgorBgEEAYI3AgEMMQIwADAZ # BgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYB # BAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQgh/oYkl8sKM6dz1rYaeNK3y3fz1Y9A5vt # CFMwTDRVKVEwCwYJKoZIhvcNAQEBBIIBgELY1jXXfZ90h75/mjTnOgu3xqNkhgLj # SBV59oLnMuwbOtvWTgOjNFM0+L9PcxmdZFm87IiObFO88tea3uBk2o3vTxQy7j/n # xgqBwOFRewii8a0zqYCYD0PwCCyk0HJDkVMvKPik7s6hsDhzAR25bx+OD8gHFqh9 # ScvVdroDDE7vbTt5+/jdexe7rq1bYnIvgHKsK9hrM1SZqM4gW/mtBAfO6N1MZ3jz # v7x4R9SkMO79jZo3UMcaM3L1AGOwTYyNNRpA/OzhDbwjMpMZANKywXmkAelkgkAx # dYV/MjFc8ful4vGomCyjT2nYTYrp4F12OpppGdSnT1nk3GPbcpAQ2UaSNMCtInFS # cRkH3KDWi73IN4l1qAKnE8jXt9B4gTJBliT2sXX4JrH5mWPaAU+8yDIM2oPYSAMO # vrEGD15oFPIRy6SrE0RGL9RKrBLzH1l1RyT/kcUcyl2HJ+Iag4e41rjqaMp+RBQW # 2w461Bp8o4AcdVd4itSjAcVPfjUTwjeEfaGCFL0wghS5BgorBgEEAYI3AwMBMYIU # qTCCFKUGCSqGSIb3DQEHAqCCFJYwghSSAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggF1 # BgsqhkiG9w0BCRABBKCCAWQEggFgMIIBXAIBAQYKKwYBBAGEWQoDATAxMA0GCWCG # SAFlAwQCAQUABCCxnXzjJmkfLFeR2YhlbqCPzw2b/KNnODKx5RZ89JCl+QIGar+j # GvUgGBMyMDI2MTAxNTA4NTU1Ni4yNzdaMASAAgH0AgkA1yEXE6SDajKggemkgeYw # geMxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsT # JE1pY3Jvc29mdCBJcmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMe # blNoaWVsZCBUU1MgRVNOOjdCMUEtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3Nv # ZnQgUHVibGljIFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eaCCDykwggeCMIIF # aqADAgECAhMzAAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3DQEBDAUAMHcxCzAJ # BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNV # BAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZp # Y2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFaFw0zNTExMTkyMDQy # MzFaMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBD # QSAyMDIwMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnnznUmP94MWf # BX1jtQYioxwe1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIcaqDb+omFio5DHC4R # BcbyQHjXCwMk/l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49REAf5huXhIkQRKe3Qx # s8Sgp02KHAznEa/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1Wa1wISvlkpOQooTUL # Fm809Z0ZYlQ8Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMopNq/B8U/pdoZkZZQ # bxNlqJOiBGgCWpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0kN0nh7SqINGbmw5OI # RC0EsZ31WF3Uxp3GgZwetEKxLms73KG/Z+MkeuaVDQQheangOEMGJ4pQZH55ngI0 # Tdy1bi69INBV5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9NV/uC3yFjrhc087qL # JQawSC3xzY/EXzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTkmG1hSuWYBunFGNv2 # 1Kt4N20AKmbeuSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/jR7wo3liwkGdzPJYH # gnJ54UxbckF914AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE67SFZ2PMo27xjlLAH # WW3l1CEAFjLNHd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIXMA4GA1UdDwEB/wQE # AwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2koOjUvSGNAz3vYr0np # Ptk92yEwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93 # d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNV # HSUEDDAKBggrBgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNV # HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGE # BgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3Ql # MjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIGUBggrBgEFBQcB # AQSBhzCBhDCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w # a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24l # MjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDANBgkq # hkiG9w0BAQwFAAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJklFaW4sTQ5r+k77iB7 # 9cSLNe+GzRjv4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi+LCmcrdovkl53DNt # 4EXs87KDogYb9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71QjD4h+8z2XMOZzY7YQ # 0Psw+etyNZ1CesufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9xw6JCWONNboZ497m # wYW5EfN0W3zL5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9cLWMq7eb0oYioXhq # V2tgFqbKHeDick+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3SLv10o4KGag42psw # jybTi4toQcC/irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsukxD+7jFfEV9Hh/+C # SxKRsmnuiovCWIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxTk4MhF/KgaXn0GxdH # 8elEa2Imq45gaa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81coE6aQWm88TwIf4R4Y # ZbOpMKN0CyejaPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tjuOOCztfp+o9Nc+Zo # IAkpUcA/X2gSMkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+JYbYbBh7pmgAXVsw # ggefMIIFh6ADAgECAhMzAAAAWXzacemNXvXAAAAAAABZMA0GCSqGSIb3DQEBDAUA # MGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # MjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAy # MDIwMB4XDTI2MDEwODE4NTkwMVoXDTI3MDEwNzE4NTkwMVowgeMxCzAJBgNVBAYT # AlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJ # cmVsYW5kIE9wZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1Mg # RVNOOjdCMUEtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVibGljIFJT # QSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIP # ADCCAgoCggIBAKYu5/40eEX+hT+5jFa146bid3dA4LnXYntvkP3CGw4LGARFhnvL # MSJ/VtsubzDaeFnm7yb2KSM70WmHQprdCVqpvUH7l0uB4jNw7urLoAR9kKHLE0Vl # MlDStDSxUBI3qwsdrjvdmvV0k+9/njuDEiSlzJTf7Dowd1K3bO4beRyaFhR+Y8ty # mECOqlOAffYrG2wZdVM51+QSBSe+PEykr8C6OnnqSipuF8fZvCb6/huk0Zm6Zwsa # ixSHIAT2IEGvS7c63Im8jV3a8R0K6i2yiw0NNlnTSpwy/Zfv7iwsLBwhfbjBTn+X # Ol6mPzDXQQ3V+SRP9xXbGKOsBTxzGid7aKAHw3o4Ahl9UGWLH9kNP3VUokE6JYkj # lfpuUGZ6gQyqDewfxD4VoYIlopt4HZ0xQvqajuJx+cr8LR/IZ56gLLmwyMzde5+v # tjBoilry/gSZwVGwgkvkIgpKPBQHGsSB0y3szr7Y7wEb6v0yZal1XUvWnnz3inTa # SWsCFrLPVwVmXy3ncY5/d25VpOkht+m697GWNbvsNOhAOHRaftE9j/hhkoM6RsyJ # fBLnhqMcA/wcavf5oj5NeyRQdGZeLKcls9csKS3sBUzPidxx2iiNH9CPaDq/bLJE # OXasYohXMnRinu+fUk81s8VO7DQSF6ffn5oqSHoV8lf1Ax6u+kdShb8BAgMBAAGj # ggHLMIIBxzAdBgNVHQ4EFgQUj5bnC18D0vlnSRhCOiODGGuXNnYwHwYDVR0jBBgw # FoAUa2koOjUvSGNAz3vYr0npPtk92yEwbAYDVR0fBGUwYzBhoF+gXYZbaHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwUHVibGlj # JTIwUlNBJTIwVGltZXN0YW1waW5nJTIwQ0ElMjAyMDIwLmNybDB5BggrBgEFBQcB # AQRtMGswaQYIKwYBBQUHMAKGXWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lv # cHMvY2VydHMvTWljcm9zb2Z0JTIwUHVibGljJTIwUlNBJTIwVGltZXN0YW1waW5n # JTIwQ0ElMjAyMDIwLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsG # AQUFBwMIMA4GA1UdDwEB/wQEAwIHgDBmBgNVHSAEXzBdMFEGDCsGAQQBgjdMg30B # ATBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L0RvY3MvUmVwb3NpdG9yeS5odG0wCAYGZ4EMAQQCMA0GCSqGSIb3DQEBDAUAA4IC # AQBEMhzC/ZcjpG/zURE7z2Yp5vrUxUjsE5Xa3t/2RGvESwvbmsk3bLHhSFAajgo2 # XQ8xoGDP3sUhKCLPeICSbkVv6V8sSp8fJ8Jos6yrawf2YVis8tcV+OO7U9S6JGPQ # zpmPncfzQc4ne1fqZ4+HiKabIDEoFdddQT2Egkk9fzxCY/EZ52avJ27dSfrI/IDm # yn9V10O3iQpg2F+C9vNTrk7nVgoDoHa9+Q3pYr0IHGnSmt5irgGT436zo5WnXP8F # xMhswH1aiyiSZiVzhor10C9C52cP3C8/PEoMKUXstLjoPO0TMkeW/1Fr186KXD45 # QRgBo0xImgtWTdzWFnlD+p7+iDBIuSrNcRXDRYuq/aYZaDhWSI0SYdPIWVh5XvXu # WA31a8oQ0SO+oPa3Nk80k0864wiiyJ1KsbSnaaefg9vspeghrpY8ljCwxfCUtx5H # QRNgAJOI8IKACK4d014Mk0hlRO0lQVRHegqIg29K6Xqkc360W2ZJGUcstlKokkVj # 6KAHjGyrLRPzepYfiZUJq4gXyxbpvKb1XJ2FN2682aUoNXo9RyRK1ch0f66k6+yj # 88kzvuC7+vJWtNDs/UpIM6Hhm0kU64JUJ7MMEQcAc7kpft7Gm7YeRK+oKgqUgYXC # fmzbX8nJXJZnPa8ADWVsIqsuNAxCI0CZXkULofqo5Be6zzGCA9QwggPQAgEBMHgw # YTELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEy # MDAGA1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIw # MjACEzMAAABZfNpx6Y1e9cAAAAAAAFkwDQYJYIZIAWUDBAIBBQCgggEtMBoGCSqG # SIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgZLpAKDz4HJsY # lObhYTnE1xmHCFWn6K2mwHjQKqqgKrMwgd0GCyqGSIb3DQEJEAIvMYHNMIHKMIHH # MIGgBCDLRbqx24bpscXEJ+Hjj9xrcUVw7R8OyyMfSB2YGK3+vDB8MGWkYzBhMQsw # CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYD # VQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAIT # MwAAAFl82nHpjV71wAAAAAAAWTAiBCBmGx3do+zrDnW+EeuaRnK/aqr7bm8Iito/ # iCcASTvI1zANBgkqhkiG9w0BAQsFAASCAgCa9uXVvAbrRm1zsayB6TkybCUx6r9Q # nZCjHjqT2yx3PXUG2aL8WqYnmFeP3XxjNQM2toOguJ1x3MlV7Hz9tmtMCjnxPf6z # c+ZE8Y61v8PBzT7MuJfnTpPy63hLfYj1UM37qL59RSfIIqeG/5lOag8Clmi7z9t9 # MATWPhdTOXmBuVlziWCaKG/hen5fJI+ogwXLD4Ke6e9AStER5kGAER2konkrNdv7 # zYwwMKpEOUKgpM0ARTWQO4+soDWTstv/S4HCsoGPnNNciC8FlMujtPT0feefV+Zu # +ASIXq/vfWgP/JhLrF1EQJjKW/+Mz63kvl+ULU/eMJsrLuCpuAg7e1h3KZnbqE5T # wqPUJY+9j/oCFb8bHpePK6ylkNIWipSxZlC9rKHl3445fIhFNrhMFCHetLGKHGhU # 9Rc+ESg8Ser5xII6V1n6PQ4p0M1OkjZ9OyUSi41eq7yp/NIlidLa4iVG47JufaJ+ # 548o5bFFEYqG4eBpeXMe0RJQs5HS8eaMx4Cu8eEEwJsUu2b8t5TgWahLlfUqHYOz # koULVOxql5VLsylQY1jFzXfS/yU8ySTniRTnS3zx2ms29lhb+vmvsF33M9zF8EVb # r4ReTitWZBa/whX7bBlIhwm0TFJjwIHYbitl01axrViR7Mj45fBnvaBNmznVZGz+ # ciNNqycxdDTXkw== # SIG # End signature block |