Invoke-LicenseScan.ps1
|
<#
.SYNOPSIS Free, read-only Microsoft 365 unused-license scan. Cross-checks every assigned license against real activity and reports the seats you're paying for but nobody is using. .DESCRIPTION Community edition of the ServerBridge License Auditor. Connects to Microsoft Graph with delegated, READ-ONLY scopes via device-code sign-in (nothing to register, no app, no secrets). It never writes, removes, or changes anything in your tenant, and it stores nothing. Activity signal (chosen automatically): * If the tenant has Microsoft Entra ID P1/P2, it uses directory sign-in activity (signInActivity) - the cleanest signal. * Otherwise it falls back to the Microsoft 365 usage reports (getOffice365ActiveUserDetail), which need no premium license. * Disabled accounts that still hold paid licenses are always flagged - that works on every tenant regardless of the above. Outputs: * A console summary of wasted spend by SKU * A CSV of every dormant licensed user (for your own follow-up) What it deliberately does NOT do (that's the paid ServerBridge License Auditor): * A formatted PDF report, costed recommended actions, scheduled re-audits with drift tracking, multi-tenant roll-up, and support. See https://server-bridge.com/license-auditor.html .PARAMETER InactiveDays A licensed user with no activity in this many days is counted as dormant. Default 90. Range 1-3650. (The usage-report fallback resolves to the nearest supported window: 30, 90 or 180 days.) .PARAMETER OutputCsv Path for the CSV export. Default: .\license-scan_<tenant>_<date>.csv .PARAMETER IncludeGuests Include guest (external) users. Off by default. .PARAMETER PassThru Emit the dormant-seat objects to the pipeline in addition to the CSV. .EXAMPLE .\Invoke-LicenseScan.ps1 .EXAMPLE .\Invoke-LicenseScan.ps1 -InactiveDays 60 -OutputCsv C:\reports\waste.csv .NOTES Requires the Microsoft Graph PowerShell SDK: Install-Module Microsoft.Graph -Scope CurrentUser Delegated scopes requested (all read-only): User.Read.All, Organization.Read.All, AuditLog.Read.All, Reports.Read.All You must be able to consent to these (Global Reader is sufficient). Prices are public list-price ESTIMATES (USD/user/month) - adjust the price table below to match your actual contract for exact figures. Project: https://github.com/lbcrowe-del/ServerBridge-LicenseScan License: MIT #> [CmdletBinding()] param( [ValidateRange(1, 3650)] [int]$InactiveDays = 90, [string]$OutputCsv, [switch]$IncludeGuests, [switch]$PassThru ) $script:RequiredScopes = @('User.Read.All', 'Organization.Read.All', 'AuditLog.Read.All', 'Reports.Read.All') # --- Approximate public list prices, USD / user / month, keyed by SkuPartNumber. # --- ESTIMATES so the tool can put a dollar figure on waste out of the box. # --- Edit to match your real per-seat cost for precise numbers. $script:SkuPrice = @{ 'O365_BUSINESS_ESSENTIALS' = 6.00 # Microsoft 365 Business Basic 'O365_BUSINESS_PREMIUM' = 12.50 # Microsoft 365 Business Standard 'SPB' = 22.00 # Microsoft 365 Business Premium 'ENTERPRISEPACK' = 36.00 # Office 365 E3 'ENTERPRISEPREMIUM' = 57.00 # Office 365 E5 'SPE_E3' = 36.00 # Microsoft 365 E3 'SPE_E5' = 57.00 # Microsoft 365 E5 'SPE_F1' = 8.00 # Microsoft 365 F3 'DESKLESSPACK' = 4.00 # Office 365 F3 'EXCHANGESTANDARD' = 4.00 # Exchange Online Plan 1 'EXCHANGEENTERPRISE' = 8.00 # Exchange Online Plan 2 'MCOEV' = 8.00 # Teams Phone Standard 'POWER_BI_PRO' = 10.00 # Power BI Pro 'POWER_BI_PREMIUM_PER_USER' = 20.00 # Power BI Premium Per User 'PROJECTPROFESSIONAL' = 30.00 # Project Plan 3 'PROJECTPREMIUM' = 55.00 # Project Plan 5 'VISIOCLIENT' = 15.00 # Visio Plan 2 'Microsoft_365_Copilot' = 30.00 # Microsoft 365 Copilot 'FLOW_FREE' = 0.00 # Power Automate (free) 'TEAMS_EXPLORATORY' = 0.00 # Teams Exploratory (free) 'POWERAPPS_VIRAL' = 0.00 # Power Apps (free/viral) } $script:DefaultPrice = 20.00 # fallback for SKUs not in the table # --------------------------------------------------------------------------- # Pure, testable helpers (no Graph calls - safe to dot-source) # --------------------------------------------------------------------------- function Get-SkuMonthlyPrice { [CmdletBinding()] param([Parameter(Mandatory)][string]$PartNumber) if ($script:SkuPrice.ContainsKey($PartNumber)) { return [double]$script:SkuPrice[$PartNumber] } return [double]$script:DefaultPrice } function Test-UserDormant { <# $true when a user has no activity since $Cutoff (never-active counts as dormant). #> [CmdletBinding()] param( [Parameter()][Nullable[datetime]]$LastActivity, [Parameter(Mandatory)][datetime]$Cutoff ) if ($null -eq $LastActivity) { return $true } return ($LastActivity -lt $Cutoff) } function Get-DormantLicenseRow { <# Pure projection: given normalized user objects (DisplayName, UserPrincipalName, UserType, AccountEnabled, LastActivity, AssignedLicenses[].SkuId), a SkuId->PartNumber map and a cutoff, emit one row per dormant user per priced license. No Graph, no I/O - unit-testable. A user is dormant when disabled, OR (when an activity signal is available) when last activity is older than the cutoff or unknown. With no activity signal only disabled accounts are flagged. #> [CmdletBinding()] param( [Parameter(Mandatory)][AllowNull()][AllowEmptyCollection()][object[]]$Users, [Parameter(Mandatory)][hashtable]$SkuMap, [Parameter(Mandatory)][datetime]$Cutoff, [bool]$ActivitySignalAvailable = $true, [switch]$IncludeGuests ) foreach ($u in @($Users | Where-Object { $null -ne $_ })) { if (-not $IncludeGuests -and $u.UserType -eq 'Guest') { continue } $dormant = $false $reason = $null if (-not $u.AccountEnabled) { $dormant = $true; $reason = 'disabled' } elseif ($ActivitySignalAvailable -and (Test-UserDormant -LastActivity $u.LastActivity -Cutoff $Cutoff)) { $dormant = $true; $reason = 'inactive' } if (-not $dormant) { continue } foreach ($lic in $u.AssignedLicenses) { $part = $SkuMap[$lic.SkuId] if (-not $part) { continue } $price = Get-SkuMonthlyPrice -PartNumber $part if ($price -le 0) { continue } # skip free SKUs [pscustomobject]@{ DisplayName = $u.DisplayName UserPrincipalName = $u.UserPrincipalName UserType = $u.UserType AccountEnabled = $u.AccountEnabled Reason = $reason Sku = $part LastActivity = if ($u.LastActivity) { ([datetime]$u.LastActivity).ToString('yyyy-MM-dd') } else { 'never/unknown' } MonthlyCost = $price AnnualCost = [math]::Round($price * 12, 2) } } } } # --------------------------------------------------------------------------- # Graph I/O (kept in functions so tests can dot-source without a tenant) # --------------------------------------------------------------------------- function Get-SignInActivityMap { <# Returns @{ ok=$bool; map=@{ upn(lower) -> [datetime] } }. ok=$false when the tenant lacks Entra ID P1 (signInActivity is premium-only) so the caller can fall back. Other errors are rethrown. #> [CmdletBinding()] param() $map = @{} try { $users = Get-MgUser -All -Property 'userPrincipalName,signInActivity' ` -Filter 'assignedLicenses/$count ne 0' -ConsistencyLevel eventual ` -CountVariable siaCount -ErrorAction Stop foreach ($u in $users) { if ($u.UserPrincipalName) { $map[$u.UserPrincipalName.ToLower()] = $u.SignInActivity.LastSignInDateTime } } return @{ ok = $true; map = $map } } catch { $msg = "$($_.Exception.Message)" if ($msg -match 'NonPremium' -or $msg -match 'premium') { return @{ ok = $false; map = $map } } throw } } function Get-UsageReportActivityMap { <# Fallback that needs no Entra premium: pulls the Microsoft 365 active-user detail report and returns @{ ok=$bool; map=@{ upn(lower) -> [datetime] } }. ok=$false when the tenant de-identifies report data (UPNs masked) so activity can't be matched to users. #> [CmdletBinding()] param([int]$InactiveDays = 90) # NB: the Graph reports API keeps the legacy "Office365" name for this function. $period = if ($InactiveDays -le 30) { 'D30' } elseif ($InactiveDays -le 90) { 'D90' } else { 'D180' } $uri = "https://graph.microsoft.com/v1.0/reports/getOffice365ActiveUserDetail(period='$period')" $resp = Invoke-MgGraphRequest -Method GET -Uri $uri -OutputType HttpResponseMessage -ErrorAction Stop $csv = $resp.Content.ReadAsStringAsync().Result $rows = @($csv | ConvertFrom-Csv) $map = @{} $sawUpn = $false foreach ($r in $rows) { $upn = $r.'User Principal Name' if (-not $upn) { continue } if ($upn -like '*@*') { $sawUpn = $true } # Take the most recent activity across every per-service "* Last Activity Date" column. $maxDate = $null foreach ($p in $r.PSObject.Properties) { if ($p.Name -like '*Last Activity Date' -and $p.Value) { $d = $p.Value -as [datetime] if ($d -and ($null -eq $maxDate -or $d -gt $maxDate)) { $maxDate = $d } } } $map[$upn.ToLower()] = $maxDate } if (-not $sawUpn -and $rows.Count -gt 0) { return @{ ok = $false; map = @{} } } return @{ ok = $true; map = $map } } function Test-SignInTimedOut { <# $true when Connect-MgGraph gave up because the device code wasn't used in time. Microsoft's Graph PowerShell module allows 2 minutes and the limit can't be changed, so the scan offers a new code instead of making the admin start over. #> [CmdletBinding()] param([Parameter(Mandatory)][AllowEmptyString()][string]$Message) return ($Message -match 'timed out after \d+ seconds') } function ConvertTo-SafeCsvValue { <# Spreadsheet apps run a cell as a formula when it starts with = + - @ (or tab/CR). Directory text such as a guest's display name is attacker-controllable, so prefix a single quote to keep it as plain text when the CSV is opened in Excel. #> [CmdletBinding()] param([Parameter(Mandatory)][AllowNull()][AllowEmptyString()][object]$Value) if ($Value -is [string] -and $Value -match '^[=+\-@\t\r]') { return "'" + $Value } return $Value } function Get-ConcealedNamesHelpText { <# The one-minute fix for de-identified usage reports, as lines of text (testable). #> [CmdletBinding()] param() @( 'Microsoft is hiding user names in your usage reports, so this scan cannot tell who is inactive.' 'Fix it in about a minute (needs a Global Administrator):' ' 1. Open https://admin.microsoft.com' ' 2. Go to Settings > Org settings > Services > Reports' ' 3. Untick "Conceal user, group, and site names in all reports", then click Save' 'This only changes what admins see in Microsoft''s own reports. You can turn it back on after the audit.' ) } function Test-GraphSdkPresent { <# $true when the Microsoft Graph PowerShell SDK is installed; otherwise prints the install hint and returns $false. Shared so every command in this module gives the same first-run message. #> [CmdletBinding()] param() if (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication) { return $true } Write-Host 'Microsoft Graph PowerShell SDK not found.' -ForegroundColor Yellow Write-Host 'Install it with: Install-Module Microsoft.Graph -Scope CurrentUser' -ForegroundColor Yellow return $false } function Connect-ScanGraph { <# Device-code sign-in with the read-only scopes, offering a fresh code when Microsoft's 2-minute limit expires. Returns $true once connected, $false if the user quit or it failed. Shared by every command in this module: this retry behaviour was a real bug fix (1.1.1) and must not be reimplemented per command. #> [CmdletBinding()] param() $signedIn = $false while (-not $signedIn) { try { Write-Host 'Signing you in. A device code will appear below - enter it within 2 minutes.' -ForegroundColor Cyan Connect-MgGraph -Scopes $script:RequiredScopes -UseDeviceCode -NoWelcome -ContextScope Process -ErrorAction Stop $signedIn = $true } catch { $message = "$($_.Exception.Message)" if ((Test-SignInTimedOut -Message $message) -and -not [Console]::IsInputRedirected) { Write-Host 'The sign-in code expired (Microsoft allows 2 minutes).' -ForegroundColor Yellow $answer = Read-Host 'Press Enter for a new code, or type Q to quit' if ($answer -match '^\s*[qQ]') { return $false } continue } Write-Host "Sign-in failed: $message" -ForegroundColor Red return $false } } if (-not (Get-MgContext)) { Write-Host 'Sign-in cancelled.' -ForegroundColor Red; return $false } return $true } function Resolve-ActivityMap { <# Picks the best available activity signal and returns @{ available=$bool; map=@{ upn(lower) -> [datetime] }; signalName=[string] }. Prefers directory sign-in activity (needs Entra ID P1), else the Microsoft 365 usage reports. When the tenant conceals user names in those reports it shows the one-minute fix and re-checks on Enter without a new sign-in. available=$false means the admin skipped, so only disabled accounts can be judged. Shared by every command in this module. #> [CmdletBinding()] param([int]$InactiveDays = 90) $sia = Get-SignInActivityMap if ($sia.ok) { return @{ available = $true; map = $sia.map; signalName = 'directory sign-in activity' } } Write-Host 'Sign-in activity needs Entra ID P1; falling back to Microsoft 365 usage reports...' -ForegroundColor Yellow $rep = $null $attempt = 0 while ($true) { try { $rep = Get-UsageReportActivityMap -InactiveDays $InactiveDays } catch { $rep = $null Write-Host "Usage reports unavailable: $($_.Exception.Message)" -ForegroundColor Yellow break } if ($rep.ok) { break } $attempt++ Write-Host '' if ($attempt -gt 1) { Write-Host 'Names are still hidden. Microsoft can take a few minutes to apply the change.' -ForegroundColor Yellow } else { Get-ConcealedNamesHelpText | ForEach-Object { Write-Host $_ -ForegroundColor Yellow } } if ([Console]::IsInputRedirected) { break } $answer = Read-Host 'Press Enter when done to check again (no new sign-in), or type S to skip' if ($answer -match '^\s*[sS]') { break } } if ($rep -and $rep.ok) { return @{ available = $true; map = $rep.map; signalName = 'Microsoft 365 usage reports' } } return @{ available = $false; map = @{}; signalName = $null } } function Invoke-LicenseScanMain { [CmdletBinding()] param( [int]$InactiveDays, [string]$OutputCsv, [switch]$IncludeGuests, [switch]$PassThru ) Write-Host '' Write-Host 'ServerBridge - Free M365 License Scan (read-only)' -ForegroundColor Green Write-Host '-------------------------------------------------' -ForegroundColor DarkGray if (-not (Test-GraphSdkPresent)) { return } if (-not (Connect-ScanGraph)) { return } try { $org = Get-MgOrganization -ErrorAction Stop $tenantName = ($org.DisplayName | Select-Object -First 1) Write-Host "Connected to: $tenantName (signed in as $((Get-MgContext).Account))" -ForegroundColor Green $skuMap = @{} foreach ($s in (Get-MgSubscribedSku -All -ErrorAction Stop)) { $skuMap[$s.SkuId] = $s.SkuPartNumber } $select = 'id,displayName,userPrincipalName,userType,accountEnabled,assignedLicenses' $rawUsers = Get-MgUser -All -Property $select -Filter 'assignedLicenses/$count ne 0' ` -ConsistencyLevel eventual -CountVariable userCount -ErrorAction Stop } catch { Write-Host "Graph read failed: $($_.Exception.Message)" -ForegroundColor Red Write-Host 'Confirm you consented to User.Read.All, Organization.Read.All, AuditLog.Read.All and Reports.Read.All.' -ForegroundColor Yellow Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null return } # Resolve an activity signal: prefer sign-in activity (premium), fall back to usage reports. $signal = Resolve-ActivityMap -InactiveDays $InactiveDays $activity = $signal.map $signalAvailable = $signal.available $signalName = $signal.signalName if (-not $signalAvailable) { Write-Host '' Write-Host 'PARTIAL AUDIT: only disabled accounts that still hold licenses can be checked.' -ForegroundColor Yellow } if ($signalAvailable) { Write-Host "Flagging licensed users dormant $InactiveDays+ days (via $signalName)..." -ForegroundColor Cyan } $normalized = foreach ($u in $rawUsers) { [pscustomobject]@{ DisplayName = $u.DisplayName UserPrincipalName = $u.UserPrincipalName UserType = $u.UserType AccountEnabled = $u.AccountEnabled AssignedLicenses = $u.AssignedLicenses LastActivity = if ($u.UserPrincipalName) { $activity[$u.UserPrincipalName.ToLower()] } else { $null } } } if ($signalAvailable) { $resolved = @($normalized | Where-Object { $_.LastActivity }).Count Write-Host (" activity resolved for {0} of {1} licensed users" -f $resolved, @($normalized).Count) -ForegroundColor DarkGray } $cutoff = (Get-Date).AddDays(-1 * $InactiveDays) $dormant = @(Get-DormantLicenseRow -Users $normalized -SkuMap $skuMap -Cutoff $cutoff ` -ActivitySignalAvailable $signalAvailable -IncludeGuests:$IncludeGuests) Write-Host '' Write-Host 'Wasted spend by license' -ForegroundColor Green Write-Host '-----------------------' -ForegroundColor DarkGray if ($dormant.Count -eq 0) { Write-Host ' Nothing obvious to reclaim.' -ForegroundColor Green } else { $dormant | Group-Object Sku | ForEach-Object { [pscustomobject]@{ License = $_.Name DormantSeats = $_.Count 'Annual $' = [int][math]::Round((($_.Group | Measure-Object AnnualCost -Sum).Sum), 0) } } | Sort-Object 'Annual $' -Descending | Format-Table -AutoSize } $totalAnnual = [math]::Round((($dormant | Measure-Object AnnualCost -Sum).Sum), 0) Write-Host (" Reclaimable seats : {0:N0}" -f $dormant.Count) -ForegroundColor White Write-Host (" Wasted spend : `${0:N0} / year" -f $totalAnnual) -ForegroundColor Green Write-Host '' if (-not $OutputCsv) { $safeTenant = ($tenantName -replace '[^\w]', '') $OutputCsv = Join-Path (Get-Location) ("license-scan_{0}_{1}.csv" -f $safeTenant, (Get-Date -Format 'yyyyMMdd')) } if ($dormant.Count -gt 0) { $dormant | Sort-Object AnnualCost -Descending | ForEach-Object { $row = $_.PSObject.Copy() foreach ($name in 'DisplayName', 'UserPrincipalName', 'UserType', 'Sku') { $row.$name = ConvertTo-SafeCsvValue -Value $row.$name } $row } | Export-Csv -Path $OutputCsv -NoTypeInformation -Encoding UTF8 Write-Host "Full per-user list saved to:" -ForegroundColor Cyan Write-Host " $OutputCsv" -ForegroundColor White Write-Host '' } Write-Host 'Prices are list-price estimates - edit the price table for exact figures.' -ForegroundColor DarkGray Write-Host 'Want the PDF report, costed recommended actions and scheduled re-audits?' -ForegroundColor DarkGray Write-Host ' https://server-bridge.com/license-auditor.html' -ForegroundColor Cyan Write-Host '' Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null if ($PassThru) { $dormant } } # Run unless dot-sourced (e.g. by Pester tests, where InvocationName is '.'). if ($MyInvocation.InvocationName -ne '.') { Invoke-LicenseScanMain -InactiveDays $InactiveDays -OutputCsv $OutputCsv ` -IncludeGuests:$IncludeGuests -PassThru:$PassThru } # SIG # Begin signature block # MII2xAYJKoZIhvcNAQcCoII2tTCCNrECAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDdHpgzpY+m03ZZ # zD/JSwFm3055JQ5Ar+O3W1yG3y6kE6CCG2MwggXMMIIDtKADAgECAhBUmNLR1FsZ # lUgTecgRwIeZMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVTMR4wHAYDVQQK # ExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jvc29mdCBJZGVu # dGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAy # MDAeFw0yMDA0MTYxODM2MTZaFw00NTA0MTYxODQ0NDBaMHcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv # c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo # b3JpdHkgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALORKgeD # Bmf9np3gx8C3pOZCBH8Ppttf+9Va10Wg+3cL8IDzpm1aTXlT2KCGhFdFIMeiVPvH # or+Kx24186IVxC9O40qFlkkN/76Z2BT2vCcH7kKbK/ULkgbk/WkTZaiRcvKYhOuD # PQ7k13ESSCHLDe32R0m3m/nJxxe2hE//uKya13NnSYXjhr03QNAlhtTetcJtYmrV # qXi8LW9J+eVsFBT9FMfTZRY33stuvF4pjf1imxUs1gXmuYkyM6Nix9fWUmcIxC70 # ViueC4fM7Ke0pqrrBc0ZV6U6CwQnHJFnni1iLS8evtrAIMsEGcoz+4m+mOJyoHI1 # vnnhnINv5G0Xb5DzPQCGdTiO0OBJmrvb0/gwytVXiGhNctO/bX9x2P29Da6SZEi3 # W295JrXNm5UhhNHvDzI9e1eM80UHTHzgXhgONXaLbZ7LNnSrBfjgc10yVpRnlyUK # xjU9lJfnwUSLgP3B+PR0GeUw9gb7IVc+BhyLaxWGJ0l7gpPKWeh1R+g/OPTHU3mg # trTiXFHvvV84wRPmeAyVWi7FQFkozA8kwOy6CXcjmTimthzax7ogttc32H83rwjj # O3HbbnMbfZlysOSGM1l0tRYAe1BtxoYT2v3EOYI9JACaYNq6lMAFUSw0rFCZE4e7 # swWAsk0wAly4JoNdtGNz764jlU9gKL431VulAgMBAAGjVDBSMA4GA1UdDwEB/wQE # AwIBhjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTIftJqhSobyhmYBAcnz1AQ # T2ioojAQBgkrBgEEAYI3FQEEAwIBADANBgkqhkiG9w0BAQwFAAOCAgEAr2rd5hnn # LZRDGU7L6VCVZKUDkQKL4jaAOxWiUsIWGbZqWl10QzD0m/9gdAmxIR6QFm3FJI9c # Zohj9E/MffISTEAQiwGf2qnIrvKVG8+dBetJPnSgaFvlVixlHIJ+U9pW2UYXeZJF # xBA2CFIpF8svpvJ+1Gkkih6PsHMNzBxKq7Kq7aeRYwFkIqgyuH4yKLNncy2RtNwx # AQv3Rwqm8ddK7VZgxCwIo3tAsLx0J1KH1r6I3TeKiW5niB31yV2g/rarOoDXGpc8 # FzYiQR6sTdWD5jw4vU8w6VSp07YEwzJ2YbuwGMUrGLPAgNW3lbBeUU0i/OxYqujY # lLSlLu2S3ucYfCFX3VVj979tzR/SpncocMfiWzpbCNJbTsgAlrPhgzavhgplXHT2 # 6ux6anSg8Evu75SjrFDyh+3XOjCDyft9V77l4/hByuVkrrOj7FjshZrM77nq81YY # uVxzmq/FdxeDWds3GhhyVKVB0rYjdaNDmuV3fJZ5t0GNv+zcgKCf0Xd1WF81E+Al # GmcLfc4l+gcK5GEh2NQc5QfGNpn0ltDGFf5Ozdeui53bFv0ExpK91IjmqaOqu/dk # ODtfzAzQNb50GQOmxapMomE2gj4d8yu8l13bS3g7LfU772Aj6PXsCyM2la+YZr9T # 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggbBMIIEqaADAgECAhMzAAaJW8dB # dB4thrTTAAAABolbMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ # RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQwHhcNMjYwOTE1MTYwNjE3WhcNMjYwOTE4 # MTYwNjE3WjCBgjELMAkGA1UEBhMCVVMxETAPBgNVBAgTCEtlbnR1Y2t5MRIwEAYD # VQQHEwlMZXhpbmd0b24xJTAjBgNVBAoTHExlZSBDcm93ZSBTb2Z0d2FyZSBTb2x1 # dGlvbnMxJTAjBgNVBAMTHExlZSBDcm93ZSBTb2Z0d2FyZSBTb2x1dGlvbnMwggGi # MA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCSd2o228mobihJsbTETtFQiSIC # 8UbmRzlNiSApgpG7cUd3Po8ivrlNphmBVqMexSQ8890yYs2Iqi27XypNC7eHrflt # PNl0g2q08orcJWWN3SoHlr8neihm6T7vUkygzJONHsuHSG1rip5A3VmtxdaNPaHn # TTP29w4wNv8RUUq8rUo1FEYJp1ns63YFDaqFitGIffnWvPyDIX5t/Lu9R8NFxXU+ # OYzRFPKC3Pi2eKnDBVdzAxzMWk5hNapcp57Ps9LIt/xKaM48DAwfjekjL0qIM7oy # KgxpJ6UrbyMATX+7Qhpw3GmMQZcwzGGPRGTOGqMHrqpOqIcHvPC0j9xYn/0xEBoC # JT+jCrdh7xt8aGafPcqxDg1ohPlqsdbZKoMSvtzCjoYOLi+/YXr2XvykYfWkWgwg # 3BaiXbjPsJUS6DPFhFnoz4vFcYrUfeBBmvN0s4FAbk4O27/6iMehA/Xpd5BGP5sX # PrXGFjyN/0psyna4yO+4EaFOkTDp72gIDMabIZkCAwEAAaOCAdUwggHRMAwGA1Ud # EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMDwGA1UdJQQ1MDMGCisGAQQBgjdhAQAG # CCsGAQUFBwMDBhsrBgEEAYI3YfX3xXqCm/n9aIL52tE6goGumFEwHQYDVR0OBBYE # FJQn6rcAFckIFI60xdwIYMH3RYlqMB8GA1UdIwQYMBaAFGslQd77a3z9GIAKLX+P # dl2qcz24MGcGA1UdHwRgMF4wXKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEFP # QyUyMENBJTIwMDQuY3JsMHQGCCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZYaHR0 # cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJ # RCUyMFZlcmlmaWVkJTIwQ1MlMjBBT0MlMjBDQSUyMDA0LmNydDBUBgNVHSAETTBL # MEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4ICAQCx # D2ogYhKLISVDZbdmf9Cam9XrIk3dptSXa+J91tIlShUdV6M2lzL4f5bL+kIGpqRX # y6J1hWQdI+iexz38wG/xG+hkyiC2zRU+VrzKqHdrLR6qgPvb8z2M4wvgtfVEDsSX # GJiR3ZPIxclPxqfMB7wFS3lXiLgor9qshZjteVrfJep7i8SZnnEh6UzftKhFQ5Ou # mn9+iqypnP0IA7N4pdwBQX8Kb7caH7PzCbg+8w9z5T93PxEA2Z9UpLTANXGKR4Kr # LCBfoF0Wrot8K1TZh87peRCNvCapEAFFdJQJjoTFzavSuLPVuBcCWKlhaueZc4pL # kPIyxEhKnk3fXnhsezSbSMFxa0nAWidg/E0VtemcicCaaU/gAw74F4+u5RxZ/b1M # fjkYRNbpB/Kh5G418/z/4uCkAvnRCvRpdU8XizotUGyeXBJshkOoZHc5k7AfXEK+ # 1FUyIl4bv+JQuAZ0Q9WtzRagWH8/5o8YfFL326wzN5UWORBSTWeBRFfB5E0FzG4A # zzqMtyUksU9qNuvMx9nywO35QwauLcqeqXEsLRWS/WZAT3J0ByuFgcXgsJmlfy6i # yFzbC9DczsUlZuyEKFlB5Cqw+BtaO+ZJcjP6LtSA9QWGHGCIdfq8U2xUSNbIG0yu # IdRonMxAo0u+t/KswaU0zI0svOa1TmAGTXhQkH3+4jCCBygwggUQoAMCAQICEzMA # AAAWMZKNkgJle5oAAAAAABYwDQYJKoZIhvcNAQEMBQAwYzELMAkGA1UEBhMCVVMx # HjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjE0MDIGA1UEAxMrTWljcm9z # b2Z0IElEIFZlcmlmaWVkIENvZGUgU2lnbmluZyBQQ0EgMjAyMTAeFw0yNjAzMjYx # ODExMjlaFw0zMTAzMjYxODExMjlaMFoxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJRCBWZXJp # ZmllZCBDUyBBT0MgQ0EgMDQwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC # AQDKVfrI2+gJMM/0bQ5OVKNdvOASzLbUUMvXuf+Vl7YGuofPaZHVo3gMHF5inT+G # MSpIcfIZ9qtXU1UG68ry8vNbQtOL4Nm30ifXpqI1+ByiAWLO1YT0WnzG7XPOuoTe # eWsNZv5FmjxCsReBZvyzyzCyXZbu1EQfJxWTH4ebUwtAiW9rqMf9eDj/wYhiEfNt # eJV3ZFeibD2ztCHr9JhFdd97XbnCHgQoTIqc02X5xlRKtUGBa++OtHBBjiJ/uwBn # zTkqu4FjpZjQeJtrmda+ur1CT2jflWIB/ypn7u7V9tvW9wJbJYt/H2EtJ0GONWxJ # Z7TEu8jWPindOO3lzPP7UtzS/mVDV94HucWaltmsra6zSG8BoEJ87IM8QSb7vfm/ # O41FhYkUv89WIj5ES2O4kxyiMSfe95CMivCuYrRP2hKvx7egPMrWgDDBkxMLgrKZ # O9hRNUMm8vk3w5b9SogHOyJVhxyFm8aFXfIxgqDF4S0g4bhbhnzljmSlCLlumMZc # XFGDjpF2tNoAu3VGFGYtHtTSNVKvZpgB3b4ynaoDkbPf+Wg4523jt4VneasBgZhC # 1srZI2NCnCBBfgjLq04pqEKAWEohyW2K29KSkkHvt5VaE1ac3Yt+oyiOzMS57tXw # QDJLGvLg/OXFO0VNvczDndfIfXYExB/ab2PuMSwd5VIBOwIDAQABo4IB3DCCAdgw # DgYDVR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRrJUHe # +2t8/RiACi1/j3ZdqnM9uDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEFBQcC # ARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRv # cnkuaHRtMBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMBIGA1UdEwEB/wQIMAYB # Af8CAQAwHwYDVR0jBBgwFoAU2UEpsA8PY2zvadf1zSmepEhqMOYwcAYDVR0fBGkw # ZzBloGOgYYZfaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWlj # cm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIw # MjAyMS5jcmwwfQYIKwYBBQUHAQEEcTBvMG0GCCsGAQUFBzAChmFodHRwOi8vd3d3 # Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElEJTIwVmVy # aWZpZWQlMjBDb2RlJTIwU2lnbmluZyUyMFBDQSUyMDIwMjEuY3J0MA0GCSqGSIb3 # DQEBDAUAA4ICAQAG1VBeVHTVRBljlcZD3IiMxwPyMjQyLNaEnVu5mODm2hRBJfH8 # GsBLATmrHAc8F47jmk5CnpUPiIguCbw6Z/KVj4Dsoiq228NSLMLewFfGMri7uwNG # LISC5ccp8vUdADDEIsS2dE+QI9OwkDpv3XuUD7d+hAgcLVcMOl1AsfEZtsZenhGv # SYUrm/FuLq0BqEGL9GXM5c+Ho9q8o+Vn/S+GWQN2y+gkRO15s0kI05nUpq/dOD4r # i9rgVs6tipEd0YZqGgD+CZNiaZWrDTOQbNPncd2F9qOsUa20miYruoT5PwJAaI+Q # QiTE2ZJeMJOkOpzhTUgqVMZwZidEUZKCqudaeQA08WwnkQMfKyHzaU8j48ULcU4h # UwvMsv7fSurOe9GAdRQCPvF8WcSK5oDHe8VVJM4tv6KKCm91HqLx9JamBgRI6R2S # fY3nu26EGznu0rCg/769z8xWm4PVcC2ZaL6VlKVqFp1NsN8YqMyf5t+bbGVb09no # FKcJG/UwyGlxRmQBlfeBUQx5/ytlzZzsEnhrJF9fTAfje8j3OdX5lEnePTFQLRlv # zZFBqUXnIeQKv3fHQjC9m2fo/Z01DII/qp3d8LhGVUW0BCG04fRwHJNH8iqqCG/q # ofMv+kym2AxBDnHzNgRjL60JOFiBgiurvLhYQNhB95KWojFA6shQnggkMTCCB54w # ggWGoAMCAQICEzMAAAAHh6M0o3uljhwAAAAAAAcwDQYJKoZIhvcNAQEMBQAwdzEL # MAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjFIMEYG # A1UEAxM/TWljcm9zb2Z0IElkZW50aXR5IFZlcmlmaWNhdGlvbiBSb290IENlcnRp # ZmljYXRlIEF1dGhvcml0eSAyMDIwMB4XDTIxMDQwMTIwMDUyMFoXDTM2MDQwMTIw # MTUyMFowYzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh # dGlvbjE0MDIGA1UEAxMrTWljcm9zb2Z0IElEIFZlcmlmaWVkIENvZGUgU2lnbmlu # ZyBQQ0EgMjAyMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALLwwK8Z # iCji3VR6TElsaQhVCbRS/3pK+MHrJSj3Zxd3KU3rlfL3qrZilYKJNqztA9OQacr1 # AwoNcHbKBLbsQAhBnIB34zxf52bDpIO3NJlfIaTE/xrweLoQ71lzCHkD7A4As1Bs # 076Iu+mA6cQzsYYH/Cbl1icwQ6C65rU4V9NQhNUwgrx9rGQ//h890Q8JdjLLw0nV # +ayQ2Fbkd242o9kH82RZsH3HEyqjAB5a8+Ae2nPIPc8sZU6ZE7iRrRZywRmrKDp5 # +TcmJX9MRff241UaOBs4NmHOyke8oU1TYrkxh+YeHgfWo5tTgkoSMoayqoDpHOLJ # s+qG8Tvh8SnifW2Jj3+ii11TS8/FGngEaNAWrbyfNrC69oKpRQXY9bGH6jn9NEJv # 9weFxhTwyvx9OJLXmRGbAUXN1U9nf4lXezky6Uh/cgjkVd6CGUAf0K+Jw+GE/5Vp # IVbcNr9rNE50Sbmy/4RTCEGvOq3GhjITbCa4crCzTTHgYYjHs1NbOc6brH+eKpWL # tr+bGecy9CrwQyx7S/BfYJ+ozst7+yZtG2wR461uckFu0t+gCwLdN0A6cFtSRtR8 # bvxVFyWwTtgMMFRuBa3vmUOTnfKLsLefRaQcVTgRnzeLzdpt32cdYKp+dhr2ogc+ # qM6K4CBI5/j4VFyC4QFeUP2YAidLtvpXRRo3AgMBAAGjggI1MIICMTAOBgNVHQ8B # Af8EBAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFNlBKbAPD2Ns72nX # 9c0pnqRIajDmMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRw # Oi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0w # GQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYDVR0TAQH/BAUwAwEB/zAfBgNV # HSMEGDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCBhAYDVR0fBH0wezB5oHegdYZz # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIw # SWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIwQ2VydGlmaWNhdGUlMjBB # dXRob3JpdHklMjAyMDIwLmNybDCBwwYIKwYBBQUHAQEEgbYwgbMwgYEGCCsGAQUF # BzAChnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jv # c29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmlj # YXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwLQYIKwYBBQUHMAGGIWh0dHA6Ly9v # bmVvY3NwLm1pY3Jvc29mdC5jb20vb2NzcDANBgkqhkiG9w0BAQwFAAOCAgEAfyUq # nv7Uq+rdZgrbVyNMul5skONbhls5fccPlmIbzi+OwVdPQ4H55v7VOInnmezQEeW4 # LqK0wja+fBznANbXLB0KrdMCbHQpbLvG6UA/Xv2pfpVIE1CRFfNF4XKO8XYEa3oW # 8oVH+KZHgIQRIwAbyFKQ9iyj4aOWeAzwk+f9E5StNp5T8FG7/VEURIVWArbAzPt9 # ThVN3w1fAZkF7+YU9kbq1bCR2YD+MtunSQ1Rft6XG7b4e0ejRA7mB2IoX5hNh3UE # auY0byxNRG+fT2MCEhQl9g2i2fs6VOG19CNep7SquKaBjhWmirYyANb0RJSLWjin # MLXNOAga10n8i9jqeprzSMU5ODmrMCJE12xS/NWShg/tuLjAsKP6SzYZ+1Ry358Z # TFcx0FS/mx2vSoU8s8HRvy+rnXqyUJ9HBqS0DErVLjQwK8VtsBdekBmdTbQVoCgP # Cqr+PDPB3xajYnzevs7eidBsM71PINK2BoE2UfMwxCCX3mccFgx6UsQeRSdVVVNS # yALQe6PT12418xon2iDGE81OGCreLzDcMAZnrUAx4XQLUz6ZTl65yPUiOh3k7Yww # 94lDf+8oG2oZmDh5O1Qe38E+M3vhKwmzIeoB1dVLlz4i3IpaDcR+iuGjH2TdaC1Z # OmBXiCRKJLj4DT2uhJ04ji+tHD6n58vhavFIrmcxghq3MIIaswIBATBxMFoxCzAJ # BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNV # BAMTIk1pY3Jvc29mdCBJRCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQCEzMABolbx0F0 # Hi2GtNMAAAAGiVswDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAig # AoAAoQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgEL # MQ4wDAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg/fu+UyF8M89MtMPql7BR # FmPFz+bT4V89kQSaX4jul88wDQYJKoZIhvcNAQEBBQAEggGAQ68RRBeggdyyxmiQ # M9qkDY2dfQnv3zib9uf+EcHuV6mVuL6c/4Js/tPNWN6MmH0DwNhtx3hDfjyfOS/P # YnqaUgSR6rBdxR6ZLveUyr9Zrv5icA0CpuyszYB1Fe/OtHZro2v5pF4mTJpj7/Gl # 08lIBagqN4KWw3cGfX3HHds7SNNUjTmHRR8yI7LWJ7Amt+KJ/pVwLW81fqtRaM64 # pkxsYXTZTDLG0wrYn+GRFYwMLum4xD/AuaVpbAxOAhr9Zo1xpJIIr3jJrsD6luYK # 1ux2+Qy6ByvystlteN7uW/QFhVHQAUav63evmpYRClYMKzrfIz+AlGT82ljBREbg # o6elLEPHT29/gWryIM6z62DNpTKvtfyH/Usz1ftS3GKwJwUfZaRkSiRykSZyGOSn # yik6gJAdsGPG7JyWQAijujg9lqkbEM96p9sPI9m+st/9WlD4SybbQCBjcsuoWyuT # PTFG0oMPmOFg4ROA/1S5RELa0+qYkRsxEzrUtY1J8Fz4UTGXoYIYEDCCGAwGCisG # AQQBgjcDAwExghf8MIIX+AYJKoZIhvcNAQcCoIIX6TCCF+UCAQMxDzANBglghkgB # ZQMEAgEFADCCAWEGCyqGSIb3DQEJEAEEoIIBUASCAUwwggFIAgEBBgorBgEEAYRZ # CgMBMDEwDQYJYIZIAWUDBAIBBQAEIHVJF2o52yds6YE4ZNWaJh6TRzwZ27e+VQd/ # 9ZdFurpbAgZqqXgAJGwYEjIwMjYwOTE2MjMxMjU0LjA2WjAEgAIB9KCB4aSB3jCB # 2zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1Jl # ZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjElMCMGA1UECxMc # TWljcm9zb2Z0IEFtZXJpY2EgT3BlcmF0aW9uczEnMCUGA1UECxMeblNoaWVsZCBU # U1MgRVNOOjdEMDAtMDVFMC1EOTQ3MTUwMwYDVQQDEyxNaWNyb3NvZnQgUHVibGlj # IFJTQSBUaW1lIFN0YW1waW5nIEF1dGhvcml0eaCCDyEwggeCMIIFaqADAgECAhMz # AAAABeXPD/9mLsmHAAAAAAAFMA0GCSqGSIb3DQEBDAUAMHcxCzAJBgNVBAYTAlVT # MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBGBgNVBAMTP01pY3Jv # c29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0aWZpY2F0ZSBBdXRo # b3JpdHkgMjAyMDAeFw0yMDExMTkyMDMyMzFaFw0zNTExMTkyMDQyMzFaMGExCzAJ # BgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNV # BAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMIIC # IjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnnznUmP94MWfBX1jtQYioxwe # 1+eXM9ETBb1lRkd3kcFdcG9/sqtDlwxKoVIcaqDb+omFio5DHC4RBcbyQHjXCwMk # /l3TOYtgoBjxnG/eViS4sOx8y4gSq8Zg49REAf5huXhIkQRKe3Qxs8Sgp02KHAzn # Ea/Ssah8nWo5hJM1xznkRsFPu6rfDHeZeG1Wa1wISvlkpOQooTULFm809Z0ZYlQ8 # Lp7i5F9YciFlyAKwn6yjN/kR4fkquUWfGmMopNq/B8U/pdoZkZZQbxNlqJOiBGgC # Wpx69uKqKhTPVi3gVErnc/qi+dR8A2MiAz0kN0nh7SqINGbmw5OIRC0EsZ31WF3U # xp3GgZwetEKxLms73KG/Z+MkeuaVDQQheangOEMGJ4pQZH55ngI0Tdy1bi69INBV # 5Kn2HVJo9XxRYR/JPGAaM6xGl57Ei95HUw9NV/uC3yFjrhc087qLJQawSC3xzY/E # XzsT4I7sDbxOmM2rl4uKK6eEpurRduOQ2hTkmG1hSuWYBunFGNv21Kt4N20AKmbe # uSnGnsBCd2cjRKG79+TX+sTehawOoxfeOO/jR7wo3liwkGdzPJYHgnJ54UxbckF9 # 14AqHOiEV7xTnD1a69w/UTxwjEugpIPMIIE67SFZ2PMo27xjlLAHWW3l1CEAFjLN # Hd3EQ79PUr8FUXetXr0CAwEAAaOCAhswggIXMA4GA1UdDwEB/wQEAwIBhjAQBgkr # BgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUa2koOjUvSGNAz3vYr0npPtk92yEwVAYD # VR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9z # b2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTATBgNVHSUEDDAKBggr # BgEFBQcDCDAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNVHRMBAf8EBTAD # AQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGEBgNVHR8EfTB7 # MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NybC9NaWNy # b3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZp # Y2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIGUBggrBgEFBQcBAQSBhzCBhDCB # gQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2Vy # dHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290JTIw # Q2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDANBgkqhkiG9w0BAQwF # AAOCAgEAX4h2x35ttVoVdedMeGj6TuHYRJklFaW4sTQ5r+k77iB79cSLNe+GzRjv # 4pVjJviceW6AF6ycWoEYR0LYhaa0ozJLU5Yi+LCmcrdovkl53DNt4EXs87KDogYb # 9eGEndSpZ5ZM74LNvVzY0/nPISHz0Xva71QjD4h+8z2XMOZzY7YQ0Psw+etyNZ1C # esufU211rLslLKsO8F2aBs2cIo1k+aHOhrw9xw6JCWONNboZ497mwYW5EfN0W3zL # 5s3ad4Xtm7yFM7Ujrhc0aqy3xL7D5FR2J7x9cLWMq7eb0oYioXhqV2tgFqbKHeDi # ck+P8tHYIFovIP7YG4ZkJWag1H91KlELGWi3SLv10o4KGag42pswjybTi4toQcC/ # irAodDW8HNtX+cbz0sMptFJK+KObAnDFHEsukxD+7jFfEV9Hh/+CSxKRsmnuiovC # WIOb+H7DRon9TlxydiFhvu88o0w35JkNbJxTk4MhF/KgaXn0GxdH8elEa2Imq45g # aa8D+mTm8LWVydt4ytxYP/bqjN49D9NZ81coE6aQWm88TwIf4R4YZbOpMKN0Cyej # aPNN41LGXHeCUMYmBx3PkP8ADHD1J2Cr/6tjuOOCztfp+o9Nc+ZoIAkpUcA/X2gS # MkgHAPUvIdtoSAHEUKiBhI6JQivRepyvWcl+JYbYbBh7pmgAXVswggeXMIIFf6AD # AgECAhMzAAAAVdndaSYo+fjiAAAAAABVMA0GCSqGSIb3DQEBDAUAMGExCzAJBgNV # BAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMT # KU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMB4XDTI1 # MTAyMzIwNDY0OVoXDTI2MTAyMjIwNDY0OVowgdsxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xJTAjBgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9w # ZXJhdGlvbnMxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVTTjo3RDAwLTA1RTAtRDk0 # NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBB # dXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQC9uR+SHllI # s/QwJRZp9rD8pmhVm72JDHyvknCFm92tSLzpSMIIVA42NBqesjEYX2FEYhktBnnS # AessL7h+lQQl9/m3ThXAHJYLb9tY66To2ZpOH0mk9kNwbM1H3lCWvKN8SO2X6DGP # XbM08R0AM+mVV/O3xxhFYUHH8Vt9yHTyTo/2nuNfarWMU9tTFZgn7E7IYLVoqEMZ # jlv7zAvf2/qoLQcUjH+/fL5t6n5oReigrxWh5Yr6zN9oWNejxhNy9DxQvizO70cV # O5k2/q++gnsm76jlpOPnWymH7T4VdbfxOUv+sMF3mJrv2OyQu054dsOORuWOKXDN # 6BzG/2Lj0XTlmtL/kQtkIJjVVqo7sQ4spVrHF0A7mjLW9vQHHRlFVfWbEWNjNrLY # QLTnWTrIYkebnzLWh7YgpFr9IzX4FMax7q8c2LlDZ3lmehH0A4BQMPAkgipEjitn # PYxKKeHXVatdMb26sXa6jJ3lV77yHF6z0AF4/Y9hAqVdhMDG91p5qcNND+/Cacz7 # JNxbOtWbzhnfxdUXDgbun9k1naexy+/q6u7YB69dzJXW3yFruJaaGGBNYE0GtWK4 # OVzeI+87PZJU9s96qHJj81fA1kICBzYfmk7O27ozBDEMiO17dcz8WQoHEeh9LZps # 1P/Qcb7Fm0WpQkNrGBslrqU3XOHuymO5DwIDAQABo4IByzCCAccwHQYDVR0OBBYE # FFYEXxBt3AgD8Mi/qckWysHXrGW2MB8GA1UdIwQYMBaAFGtpKDo1L0hjQM972K9J # 6T7ZPdshMGwGA1UdHwRlMGMwYaBfoF2GW2h0dHA6Ly93d3cubWljcm9zb2Z0LmNv # bS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFt # cGluZyUyMENBJTIwMjAyMC5jcmwweQYIKwYBBQUHAQEEbTBrMGkGCCsGAQUFBzAC # hl1odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29m # dCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5jcnQw # DAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcDCDAOBgNVHQ8BAf8E # BAMCB4AwZgYDVR0gBF8wXTBRBgwrBgEEAYI3TIN9AQEwQTA/BggrBgEFBQcCARYz # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnku # aHRtMAgGBmeBDAEEAjANBgkqhkiG9w0BAQwFAAOCAgEAUh7hklR72pQpxZ5bKlyE # Hnx9cT9kha/YPlc/n+T+0HssI30G+Y1JUpndV5yVAz3vzB8S+690xBJS/pjbRugg # zwMrUrUhT1w/bUwbQTGIfFqqOuKR/apt+tciKngR/e/Zs1gpDELE3dJzOnVJfQfu # 6orYvk6F8MSJd/XmKi7mGH4Q9pqqnj1zM1CkkM5H+98mCFRz+pyyUM+GgJmlnHxv # Y4O/LAZA1fCqVuyYJLbi4aYSRDdQfklR43pz3XJqxVyFLvyuIyubpH1mkCI7ml80 # owZTYwubUDemnT3wNxsVMBz3keHpC+SH//bwX9d7ZswVvoMvtLDRk73m/SC/RlPI # l/FL8sLF+tp4Qgj0VIU4oAwSnXM0VKza57QYaMG33IQQxTC/Gr0TEXPRpnNibyK8 # l99+khUOdf/6tVFNhzEiRDIViyUiFiVYX1KMLDmvj2pqSMxE2Hxb07tpqiiVJVmV # 5BmMa3QrwnMyXKnqGnaVtbpepHHZw4dtvEkPGYQ3OiEZTOIjXeUjaDYF/mqJt8Lh # so1Gkmj2VsTwdRtjSomITy7dJTx4NBrJI9c4SEmPFEJDDA696NiYEbk/sJyRA0FK # eeXXb4UpEqA+iPQy/7Pk4yGP3PYy2luccsCR6nSh1AKUTLIIb+5Hm0rmtbqZkfk6 # rnpRZLQ0jo1XUkZLsmuLqMUxggdDMIIHPwIBATB4MGExCzAJBgNVBAYTAlVTMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29m # dCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAVdndaSYo+fji # AAAAAABVMA0GCWCGSAFlAwQCAQUAoIIEnDARBgsqhkiG9w0BCRACDzECBQAwGgYJ # KoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEEMBwGCSqGSIb3DQEJBTEPFw0yNjA5MTYy # MzEyNTRaMC8GCSqGSIb3DQEJBDEiBCCphRfN7LhE5lQ7XMmjFEwoQkQbeBk8AlWz # zwtng5cqlDCBuQYLKoZIhvcNAQkQAi8xgakwgaYwgaMwgaAEINi5PJdkhmK7v33+ # /g9qqyZ5LMHGHSuqRiruxhhq+P7NMHwwZaRjMGExCzAJBgNVBAYTAlVTMR4wHAYD # VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQ # dWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAVdndaSYo+fjiAAAA # AABVMIIDXgYLKoZIhvcNAQkQAhIxggNNMIIDSaGCA0UwggNBMIICKQIBATCCAQmh # geGkgd4wgdsxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJTAj # BgNVBAsTHE1pY3Jvc29mdCBBbWVyaWNhIE9wZXJhdGlvbnMxJzAlBgNVBAsTHm5T # aGllbGQgVFNTIEVTTjo3RDAwLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0 # IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHmiIwoBATAHBgUrDgMC # GgMVAB07VAGCZb+24FlXkQaOF+xXhw3qoGcwZaRjMGExCzAJBgNVBAYTAlVTMR4w # HAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29m # dCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwMA0GCSqGSIb3DQEBCwUA # AgUA7lVIAjAiGA8yMDI2MDkxNjE2NTMyMloYDzIwMjYwOTE3MTY1MzIyWjB0MDoG # CisGAQQBhFkKBAExLDAqMAoCBQDuVUgCAgEAMAcCAQACAibEMAcCAQACAhIzMAoC # BQDuVpmCAgEAMDYGCisGAQQBhFkKBAIxKDAmMAwGCisGAQQBhFkKAwKgCjAIAgEA # AgMHoSChCjAIAgEAAgMBhqAwDQYJKoZIhvcNAQELBQADggEBABEofIT7H4/Z8Vze # FAhrP5WuJsDAy17TXhk6eRVLPo7vYL+TTUXQxcsasIaKk0SEmn8XxJW5wHUujsVj # nSBgGuBvVZrXRV5wHnj+u2r+AmLBnQiTcrBhziD7y+jC9gD265aPAEivQPoW8Zjs # Nrd8q35XzHm5/GY9SdM4KFUMT7VP2Fy1covIblYFXl0KucKn9fAScdCZdyNmE6XA # NxYlnSxaonQHdBtBuezAPS0VTDWNmAQrj3diPgdA5kVbTCBwZyt4NgrDnigbDcKp # R8OKCCEiRc8srL45QoRxZkvB4d74Wv6BBMMTDhbjTy4Xc0RHJletMqCkBNGSfHm+ # MpmQDRAwDQYJKoZIhvcNAQEBBQAEggIApwOJasCnxwNch1qPE9YO/mxGnpIEr7DZ # KGAKa4p6TwxlCAoaurdFFDa0mfNfVIyZcE6MPHnPWlu5gyRu5tus3lPil0NYkvpK # Wx5cAD/e034/2YgVvZhHMGeMfjsrSLKfuti00uz0CeTW29z12KT78/eyffNGG8eL # S6i4Yi148Xeru0PloMnFjgF9sA+aUlJoNLS+IVO8S4zfa12nzR/n17pbGVg39Hdk # evF9VjotqMgx10Iw2PB3eaSeyRhT5F4M8mPCegAqp59BVi40kFTMjw+kSs9sVr+B # /S/L7Pz2UM8gk7mr7pgMvZxDP3+pAV8DMjbgfcu2tOP+uV0hx8mhbXl2dP/I2QBS # 0EO93lP5URoMEK+7fwnlr4hqDpkZw5zeZVii4/f9L9sLOP53NazHom6p3Ao+Pd8F # yfFdgi8hVbSt0Ch9C46X27pZLSLf7A2fTEhWIgIYUBaDpiGYWiPWKep9KSbUp45Q # 2DAAJPNuuP6qdsUJR68w0nCvIDQow0dNa8F9lpY2WUk43RZYCw+sx4P8cV+xH2Tn # olm/HAHk9CvzkpBRwPP0WwIfNs3mx7jANY5FveDeagtxfLUKNd0aXtfrF2tIkP3n # cg3OxIr41xBGroJbpZx1o/MqXjnS13bxPmfhdNuwCwcYB1m6geQpg0P+nyGNJEJE # GJ3lm5R4iyM= # SIG # End signature block |