param(
    [Parameter(Mandatory = $true)]
    [string]$Action,

    [Parameter(ValueFromRemainingArguments = $true)]
    [string[]]$Arguments
)

function Exit-WithUsage {
    Write-Error "Usage: upgradeClientHelper.ps1 <Action> [arguments]"
    exit 64
}

function Get-Argument {
    param(
        [int]$Index,
        [string]$Name
    )

    if ($null -eq $Arguments -or $Arguments.Length -le $Index -or [string]::IsNullOrEmpty($Arguments[$Index])) {
        Write-Error "Missing argument: $Name"
        exit 64
    }

    return $Arguments[$Index]
}

function Write-UpgradeLog {
    param(
        [string]$Message
    )

    $path = $null
    if (![string]::IsNullOrEmpty($env:FW_UPGRADE_HELPER_LOG)) {
        $path = $env:FW_UPGRADE_HELPER_LOG
    } elseif (![string]::IsNullOrEmpty($env:FW_UPGRADE_LOG)) {
        $path = $env:FW_UPGRADE_LOG
    }
    if ([string]::IsNullOrEmpty($path)) {
        return
    }

    $stamp = Get-Date -Format 'yyyy-MM-dd HH:mm:ss.fff'
    $line = '"{0} == PS helper: {1}"' -f $stamp, $Message
    try {
        Add-Content -Path $path -Value $line -ErrorAction SilentlyContinue
    } catch {
    }
}

function Trim-Log {
    $path = Get-Argument 0 'Path'
    $maxBytes = [int64](Get-Argument 1 'MaxBytes')

    if (Test-Path $path) {
        $item = Get-Item $path
        if ($item.Length -gt $maxBytes) {
            $bytes = [System.IO.File]::ReadAllBytes($path)
            [System.IO.File]::WriteAllBytes($path, $bytes[($bytes.Length - $maxBytes)..($bytes.Length - 1)])
        }
    }
}

function Test-LockStale {
    $path = Get-Argument 0 'Path'
    $maxAgeMinutes = [int](Get-Argument 1 'MaxAgeMinutes')

    if (!(Test-Path $path)) {
        exit 0
    }

    $heartbeat = Join-Path $path 'heartbeat.txt'
    $created = Join-Path $path 'created.txt'

    if (Test-Path $heartbeat) {
        $stamp = (Get-Item $heartbeat).LastWriteTime
    } elseif (Test-Path $created) {
        $stamp = (Get-Item $created).LastWriteTime
    } else {
        $stamp = (Get-Item $path).LastWriteTime
    }

    $age = ((Get-Date) - $stamp).TotalMinutes
    if ($age -gt $maxAgeMinutes) {
        exit 0
    }

    exit 1
}

function Test-MsiAvailable {
    $created = $false
    $mutex = $null

    try {
        $mutex = New-Object System.Threading.Mutex($true, 'Global\_MSIExecute', [ref]$created)
        if ($created) {
            Write-UpgradeLog 'Windows Installer mutex is available.'
            $mutex.ReleaseMutex()
            exit 0
        }

        Write-UpgradeLog 'Windows Installer mutex is busy.'
        exit 1
    } catch {
        Write-UpgradeLog ('Windows Installer mutex check failed: {0}' -f $_.Exception.Message)
        exit 1
    } finally {
        if ($mutex) {
            $mutex.Dispose()
        }
    }
}

function Read-MsiVersion {
    $path = Get-Argument 0 'MsiPath'

    try {
        if (Test-Path $path) {
            $item = Get-Item $path
            Write-UpgradeLog ('Reading MSI ProductVersion from {0}; size {1} bytes.' -f $path, $item.Length)
        } else {
            Write-UpgradeLog ('MSI path does not exist while reading ProductVersion: {0}' -f $path)
        }

        $installer = New-Object -ComObject WindowsInstaller.Installer
        $database = $installer.GetType().InvokeMember('OpenDatabase', 'InvokeMethod', $null, $installer, @($path, 0))
        $view = $database.OpenView("SELECT Value FROM Property WHERE Property = 'ProductVersion'")
        $view.Execute()
        $record = $view.Fetch()
        if ($record) {
            $version = $record.StringData(1)
            Write-UpgradeLog ('MSI ProductVersion read successfully: {0}' -f $version)
            $version
            exit 0
        }

        Write-UpgradeLog ('MSI ProductVersion record was not found in {0}.' -f $path)
        exit 1
    } catch {
        Write-UpgradeLog ('MSI ProductVersion read failed: {0}' -f $_.Exception.Message)
        Write-Error $_.Exception.Message
        exit 1
    }
}

function Get-PackageField {
    param(
        [string]$PackageName,
        [string]$FieldName
    )

    $package = Get-Package -Name $PackageName -ErrorAction SilentlyContinue
    if ($package) {
        Write-UpgradeLog ('Found package: {0}; version {1}' -f $package.Name, $package.Version)
        $package.$FieldName
        exit 0
    }

    Write-UpgradeLog ('Package not found by Get-Package: {0}' -f $PackageName)

    $application = Get-InstalledApplication $PackageName
    if ($application) {
        Write-UpgradeLog ('Found application in uninstall registry: {0}; version {1}; key {2}' -f $application.DisplayName, $application.DisplayVersion, $application.PSChildName)
        if ($FieldName -eq 'Name') {
            $application.DisplayName
        } elseif ($FieldName -eq 'Version') {
            $application.DisplayVersion
        } else {
            $application.$FieldName
        }
        exit 0
    }

    if ($PackageName -eq 'FileWave Client') {
        $fwcldVersion = Get-FwcldVersion
        if ($fwcldVersion) {
            Write-UpgradeLog ('Found FileWave Client version from installed fwcld.exe: {0}' -f $fwcldVersion)
            if ($FieldName -eq 'Name') {
                'FileWave Client'
            } elseif ($FieldName -eq 'Version') {
                $fwcldVersion
            } else {
                $fwcldVersion
            }
            exit 0
        }
    }

    Write-UpgradeLog ('Application not found in uninstall registry: {0}' -f $PackageName)
    exit 1
}

function Test-InstalledVersion {
    $expected = Get-Argument 0 'ExpectedVersion'
    $version = (Get-Package -Name 'FileWave Client' -ErrorAction SilentlyContinue).Version

    if (!$version) {
        Write-UpgradeLog 'Installed FileWave Client version was not found by Get-Package.'
        $application = Get-InstalledApplication 'FileWave Client'
        if ($application) {
            Write-UpgradeLog ('Found installed FileWave Client in uninstall registry; version {0}; key {1}' -f $application.DisplayVersion, $application.PSChildName)
            $version = $application.DisplayVersion
        }
    }

    if (!$version) {
        $version = Get-FwcldVersion
        if ($version) {
            Write-UpgradeLog ('Found installed FileWave Client version from installed fwcld.exe: {0}' -f $version)
        }
    }

    if (!$version) {
        Write-UpgradeLog 'Installed FileWave Client version was not found by Get-Package, uninstall registry, or fwcld.exe -V.'
        exit 1
    }

    $version

    if (Test-VersionMatches $version $expected) {
        Write-UpgradeLog ('Installed FileWave Client version {0} matches expected version {1}.' -f $version, $expected)
        exit 0
    }

    Write-UpgradeLog ('Installed FileWave Client version {0} does not match expected version {1}.' -f $version, $expected)
    exit 2
}

function Test-VersionMatches {
    param(
        [string]$Version,
        [string]$Expected
    )

    if ($Version -eq $Expected) {
        return $true
    }

    try {
        $actualVersion = [version]$Version
        $expectedVersion = [version]$Expected

        if ($actualVersion -eq $expectedVersion) {
            return $true
        }

        if ($expectedVersion.Revision -lt 0) {
            return $actualVersion.Major -eq $expectedVersion.Major -and
                $actualVersion.Minor -eq $expectedVersion.Minor -and
                $actualVersion.Build -eq $expectedVersion.Build
        }
    } catch {
    }

    return $false
}

function Get-InstalledApplication {
    param(
        [string]$DisplayName
    )

    $paths = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
    )

    Get-ItemProperty $paths -ErrorAction SilentlyContinue |
        Where-Object { $_.DisplayName -eq $DisplayName } |
        Select-Object -First 1
}

function Get-FwcldVersion {
    $paths = Get-FwcldPaths

    foreach ($path in $paths) {
        if (!(Test-Path $path)) {
            Write-UpgradeLog ('fwcld.exe candidate not found: {0}' -f $path)
            continue
        }

        $fileVersion = Get-FwcldFileVersion $path
        if ($fileVersion) {
            return $fileVersion
        }

        try {
            $output = & $path -V 2>&1
            $exitCode = $LASTEXITCODE
            Write-UpgradeLog ('fwcld.exe -V at {0} exited with {1}; output: {2}' -f $path, $exitCode, ($output -join ' '))
            if ($exitCode -ne 0) {
                continue
            }

            foreach ($line in $output) {
                if ($line -match '\b(\d+(?:\.\d+){1,3})\b') {
                    return $Matches[1]
                }
            }
        } catch {
            Write-UpgradeLog ('fwcld.exe -V failed at {0}: {1}' -f $path, $_.Exception.Message)
        }
    }

    return $null
}

function Get-FwcldPaths {
    @(
        'C:\Program Files\FileWave\client\fwcld.exe',
        'C:\Program Files\FileWave\fwcld.exe',
        'C:\Program Files (x86)\FileWave\fwcld.exe'
    )
}

function Get-FwcldFileVersion {
    param(
        [string]$Path
    )

    try {
        $versionInfo = [System.Diagnostics.FileVersionInfo]::GetVersionInfo($Path)
        foreach ($candidate in @($versionInfo.ProductVersion, $versionInfo.FileVersion)) {
            if ([string]::IsNullOrWhiteSpace($candidate)) {
                continue
            }

            Write-UpgradeLog ('fwcld.exe version resource at {0}: {1}' -f $Path, $candidate)
            if ($candidate -match '\b(\d+(?:\.\d+){1,3})\b') {
                return $Matches[1]
            }
        }
    } catch {
        Write-UpgradeLog ('Could not read fwcld.exe version resource at {0}: {1}' -f $Path, $_.Exception.Message)
    }

    return $null
}

function Test-MsiLogMissingSource {
    $path = Get-Argument 0 'MsiLogPath'

    if (!(Test-Path $path)) {
        exit 1
    }

    $patterns = @(
        '\b1706\b',
        'no valid source',
        'installation source',
        'source for this product',
        'network resource',
        'SourceList',
        'cannot find.*\.msi',
        'use source',
        'failed to resolve source'
    )

    $text = Get-Content -Path $path -Raw -ErrorAction SilentlyContinue
    foreach ($pattern in $patterns) {
        if ($text -match $pattern) {
            Write-UpgradeLog ('MSI log missing-source pattern matched: {0}' -f $pattern)
            exit 0
        }
    }

    Write-UpgradeLog 'MSI log did not contain missing-source patterns.'
    exit 1
}

function Scrub-FileWaveMsiRegistration {
    $paths = @(
        'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*',
        'HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'
    )

    $apps = Get-ItemProperty $paths -ErrorAction SilentlyContinue | Where-Object { $_.DisplayName -like 'FileWave Client*' }
    foreach ($app in $apps) {
        $code = $app.PSChildName -replace '[-{}]', ''
        if ($code.Length -eq 32) {
            $packedCode = -join ($code[7..0] + $code[11..8] + $code[15..12] + $code[17, 16, 19, 18, 21, 20, 23, 22, 25, 24, 27, 26, 29, 28, 31, 30])
            Remove-Item "HKLM:\SOFTWARE\Classes\Installer\Products\$packedCode" -Recurse -Force -ErrorAction SilentlyContinue
            Remove-Item $app.PSPath -Recurse -Force -ErrorAction SilentlyContinue
            Write-Output "Scrubbed old MSI registration for $($app.DisplayName)"
        }
    }
}

function Count-Lines {
    $path = Get-Argument 0 'Path'

    if (Test-Path $path) {
        (Get-Content $path).Length
    } else {
        0
    }
}

if ($Action -ne 'TrimLog') {
    $argumentCount = 0
    if ($null -ne $Arguments) {
        $argumentCount = $Arguments.Length
    }
    Write-UpgradeLog ('Action {0} started with {1} argument(s).' -f $Action, $argumentCount)
}

switch ($Action) {
    'TrimLog' {
        Trim-Log
        exit 0
    }
    'IsLockStale' {
        Test-LockStale
    }
    'MsiAvailable' {
        Test-MsiAvailable
    }
    'ReadMsiVersion' {
        Read-MsiVersion
    }
    'GetPackageName' {
        $name = Get-Argument 0 'PackageName'
        Get-PackageField $name 'Name'
    }
    'GetPackageVersion' {
        $name = Get-Argument 0 'PackageName'
        Get-PackageField $name 'Version'
    }
    'VerifyInstalledVersion' {
        Test-InstalledVersion
    }
    'MsiLogMissingSource' {
        Test-MsiLogMissingSource
    }
    'ScrubFileWaveMsiRegistration' {
        Scrub-FileWaveMsiRegistration
        exit 0
    }
    'CountLines' {
        Count-Lines
        exit 0
    }
    default {
        Exit-WithUsage
    }
}

# SIG # Begin signature block
# MII54AYJKoZIhvcNAQcCoII50TCCOc0CAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCpZO/aMx45OVRe
# /suJ4xj1Ey9VrwqGJenyf4BmGwSrUqCCIgQwggXMMIIDtKADAgECAhBUmNLR1FsZ
# 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
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggavMIIEl6ADAgECAhMzAAUxCiha
# YAKVk22hAAAABTEKMA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBFT0MgQ0EgMDMwHhcNMjYwODI5MjE1NjA2WhcNMjYwOTAx
# MjE1NjA2WjByMQswCQYDVQQGEwJVUzEQMA4GA1UECBMHSW5kaWFuYTEVMBMGA1UE
# BxMMSW5kaWFuYXBvbGlzMRwwGgYDVQQKExNGaWxlV2F2ZSAoVVNBKSBJbmMuMRww
# GgYDVQQDExNGaWxlV2F2ZSAoVVNBKSBJbmMuMIIBojANBgkqhkiG9w0BAQEFAAOC
# AY8AMIIBigKCAYEArskMXhGpAkFl40//b3p1TCPqQWNxyREu9X1lqDPvhvmjOZJB
# h8FHy3q9GnOksov8SdYm9ZsTscbQCtlMGALPuVtblk2Xew+VZ0wtzbphrqMp+Q9U
# QwEWWLkWodGAL0NMKnBbvZUY5elpEjey39GwhelO2354FID22r8IuKX4MqDvfS+T
# qs5bmrkfjYpJaTx3SDqJZcA6B//CzvN4MTrG/2vhvoqOqx20pz7TT59AQ5Opc7E3
# bXGF2hc2NrW6HJKEGwo2RZB+Ifvd1P8cgpqvqBqmw6+Awegb1UsiYd9ZBeU2Y4zV
# TxWYaXXA/hYcPDVIgzM9IbIHjMCK+BW71KHvPjWUxvUk9gte1SeH2RIEWwHxyAvx
# oyU3nDSNt2opEZIdnM1SWqW5+KSJX/IUVDKXk3p3ywYAQS9H1giGlGGsjpH/tARV
# 9/FSIttDwki+15OQnH+L1iWke6KPiWohCEMIuoaslJNJfOAPHEcpEWzr+OZkPD9a
# q0l6TPTkHufXjcO1AgMBAAGjggHUMIIB0DAMBgNVHRMBAf8EAjAAMA4GA1UdDwEB
# /wQEAwIHgDA7BgNVHSUENDAyBgorBgEEAYI3YQEABggrBgEFBQcDAwYaKwYBBAGC
# N2G8ycRpgvKdiAWCxsqSJMvg7XMwHQYDVR0OBBYEFG6hEawceyFzgNaPQlTaMj5R
# cjmZMB8GA1UdIwQYMBaAFGtepTTDBcViSiFajqtzYGLUrGOFMGcGA1UdHwRgMF4w
# XKBaoFiGVmh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jv
# c29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEVPQyUyMENBJTIwMDMuY3JsMHQG
# CCsGAQUFBwEBBGgwZjBkBggrBgEFBQcwAoZYaHR0cDovL3d3dy5taWNyb3NvZnQu
# Y29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ1Ml
# MjBFT0MlMjBDQSUyMDAzLmNydDBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEF
# BQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9z
# aXRvcnkuaHRtMA0GCSqGSIb3DQEBDAUAA4ICAQBIhtC157J4b76MZyNKk+0KJrdu
# wn0Eo8+Z7iJPKBfQZU8I1CnrPh25+wsxPc1tNdi9uSFJ5wqjYSR4grwdJydhPVKc
# vnw0+Hfn/KEijnqQG1Z4FpSZ/mPKaL0w+ohHHCl+aIqlHrz6dfwVXDFmolHLV5gJ
# 7kmBmb5w8fROGiBRgUgMiR6JXTWxaMVDrh89hX3fy7jWYSnxL4L0h3NhqIw6rpM2
# pdrfRKINXCrsOoZdE819+OtOnqmZLNqXeOaE7701R/bIkiGoDZ/DETKuX+yrRhJO
# ThJYDtSkcISNn3Mi9tVLWYWfviV6w/71ZCWmngRop2/DBkhEuFTiS4lOqHkUwJvb
# AdYVQv0OhrulZsvPb1kJIIakA7sKAy2jnXNCzahqGQmG6Nf+iFhC1lEcokmNCsL1
# CqSW8dulmPiGTEN5YeMfEwzhzfp++RP2ztIWWP0mI7RYP1Fv7+zn2tVTaoeMjdgb
# Wok8vPRirk64PGaQ+ugL6nSVc2Sg9c3PA3iZE89x5FjxwxAUaK4BgoMFF0SgC9w3
# vEREF6wc4jjDz5jWtJA2FTGrZHOaobDE2H1wW89vTnHv9xy2zdci56NG7b4NEc2I
# N7HUfNCy4CaOk9K53FW8tXVZMU7J2Bu5n5sZQEhh0yFDZv8R67OHc7Ip+f8TOpA+
# eghFVFpFw9Zaa1GIczCCBq8wggSXoAMCAQICEzMABTEKKFpgApWTbaEAAAAFMQow
# DQYJKoZIhvcNAQEMBQAwWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29m
# dCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENT
# IEVPQyBDQSAwMzAeFw0yNjA4MjkyMTU2MDZaFw0yNjA5MDEyMTU2MDZaMHIxCzAJ
# BgNVBAYTAlVTMRAwDgYDVQQIEwdJbmRpYW5hMRUwEwYDVQQHEwxJbmRpYW5hcG9s
# aXMxHDAaBgNVBAoTE0ZpbGVXYXZlIChVU0EpIEluYy4xHDAaBgNVBAMTE0ZpbGVX
# YXZlIChVU0EpIEluYy4wggGiMA0GCSqGSIb3DQEBAQUAA4IBjwAwggGKAoIBgQCu
# yQxeEakCQWXjT/9venVMI+pBY3HJES71fWWoM++G+aM5kkGHwUfLer0ac6Syi/xJ
# 1ib1mxOxxtAK2UwYAs+5W1uWTZd7D5VnTC3NumGuoyn5D1RDARZYuRah0YAvQ0wq
# cFu9lRjl6WkSN7Lf0bCF6U7bfngUgPbavwi4pfgyoO99L5OqzluauR+NiklpPHdI
# OollwDoH/8LO83gxOsb/a+G+io6rHbSnPtNPn0BDk6lzsTdtcYXaFzY2tbockoQb
# CjZFkH4h+93U/xyCmq+oGqbDr4DB6BvVSyJh31kF5TZjjNVPFZhpdcD+Fhw8NUiD
# Mz0hsgeMwIr4FbvUoe8+NZTG9ST2C17VJ4fZEgRbAfHIC/GjJTecNI23aikRkh2c
# zVJapbn4pIlf8hRUMpeTenfLBgBBL0fWCIaUYayOkf+0BFX38VIi20PCSL7Xk5Cc
# f4vWJaR7oo+JaiEIQwi6hqyUk0l84A8cRykRbOv45mQ8P1qrSXpM9OQe59eNw7UC
# AwEAAaOCAdQwggHQMAwGA1UdEwEB/wQCMAAwDgYDVR0PAQH/BAQDAgeAMDsGA1Ud
# JQQ0MDIGCisGAQQBgjdhAQAGCCsGAQUFBwMDBhorBgEEAYI3YbzJxGmC8p2IBYLG
# ypIky+DtczAdBgNVHQ4EFgQUbqERrBx7IXOA1o9CVNoyPlFyOZkwHwYDVR0jBBgw
# FoAUa16lNMMFxWJKIVqOq3NgYtSsY4UwZwYDVR0fBGAwXjBcoFqgWIZWaHR0cDov
# L3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jcmwvTWljcm9zb2Z0JTIwSUQlMjBW
# ZXJpZmllZCUyMENTJTIwRU9DJTIwQ0ElMjAwMy5jcmwwdAYIKwYBBQUHAQEEaDBm
# MGQGCCsGAQUFBzAChlhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2Nl
# cnRzL01pY3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDUyUyMEVPQyUyMENBJTIw
# MDMuY3J0MFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wDQYJ
# KoZIhvcNAQEMBQADggIBAEiG0LXnsnhvvoxnI0qT7Qomt27CfQSjz5nuIk8oF9Bl
# TwjUKes+Hbn7CzE9zW012L25IUnnCqNhJHiCvB0nJ2E9Upy+fDT4d+f8oSKOepAb
# VngWlJn+Y8povTD6iEccKX5oiqUevPp1/BVcMWaiUctXmAnuSYGZvnDx9E4aIFGB
# SAyJHoldNbFoxUOuHz2Ffd/LuNZhKfEvgvSHc2GojDqukzal2t9Eog1cKuw6hl0T
# zX34606eqZks2pd45oTvvTVH9siSIagNn8MRMq5f7KtGEk5OElgO1KRwhI2fcyL2
# 1UtZhZ++JXrD/vVkJaaeBGinb8MGSES4VOJLiU6oeRTAm9sB1hVC/Q6Gu6Vmy89v
# WQkghqQDuwoDLaOdc0LNqGoZCYbo1/6IWELWURyiSY0KwvUKpJbx26WY+IZMQ3lh
# 4x8TDOHN+n75E/bO0hZY/SYjtFg/UW/v7Ofa1VNqh4yN2BtaiTy89GKuTrg8ZpD6
# 6AvqdJVzZKD1zc8DeJkTz3HkWPHDEBRorgGCgwUXRKAL3De8REQXrBziOMPPmNa0
# kDYVMatkc5qhsMTYfXBbz29Oce/3HLbN1yLno0btvg0RzYg3sdR80LLgJo6T0rnc
# Vby1dVkxTsnYG7mfmxlASGHTIUNm/xHrs4dzsin5/xM6kD56CEVUWkXD1lprUYhz
# MIIHKDCCBRCgAwIBAgITMwAAABUFPm4ZjpMp2QAAAAAAFTANBgkqhkiG9w0BAQwF
# ADBjMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
# MTQwMgYDVQQDEytNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ29kZSBTaWduaW5nIFBD
# QSAyMDIxMB4XDTI2MDMyNjE4MTEyOFoXDTMxMDMyNjE4MTEyOFowWjELMAkGA1UE
# BhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjErMCkGA1UEAxMi
# TWljcm9zb2Z0IElEIFZlcmlmaWVkIENTIEVPQyBDQSAwMzCCAiIwDQYJKoZIhvcN
# AQEBBQADggIPADCCAgoCggIBAOD0yz0Cqi8Ocx4+8w574rJuEJ3z6WiTNg5GVLeQ
# FVex55xvIbAFyx6eWblsu0wY+OIgUvMFAX6CGVVX9Tb2rkZx14QQEIdNMaEvaSgi
# stzhSuWIxFxu/2Y4y1H+Xv/ECa/QXHgEkefV0e3ft++sGpeYqMp8Z/kOnI7/6GdX
# tMSt4y1LX2I75uNn/0eemDc8KTR7thJtFMWTH3sVnBFakLizc16lF9FdCH9YwCPs
# maxh5VmiGLhMXnJbYkyslmrAdzLMlli0PYeWejlkQmR2JlwRrEc6hubA7TpnUn1z
# bemz08YiEZqrWwosQDP0OhzmsuRhYa14OuxwqECnaQhz+hiUf0iPoGQ6qqBYg0SQ
# S0Lxk0bUxqT6HejrlqPSJAqZ3Fbshloc7ly7KgyL4q1h9d4giDexUhtLYQvyRS2w
# MZ0So2oCr+KypOLWNeot7qIqnWeLVI9289b0bTcJOxgXrxv/K4hBHBt2gEJd6Yw0
# kJLR2isJFjhvZYADLieDtIA1wSCsGBl/nfn5B8tTmEbOsqMilsxptq5ZvkUpZQqQ
# yw9xcWRdFY7iego+bgpaUXKmo6lsn8o41VF4iXEdBF6AA4HMiFEHuCv0gNDWxzYy
# A6BD7FUZbiirgcPSZ8CLCLIuyRmuRpDsmhqdiME1xH1FLbpjEBVtwG0uK0VPMIgS
# Dll1AgMBAAGjggHcMIIB2DAOBgNVHQ8BAf8EBAMCAYYwEAYJKwYBBAGCNxUBBAMC
# AQAwHQYDVR0OBBYEFGtepTTDBcViSiFajqtzYGLUrGOFMFQGA1UdIARNMEswSQYE
# VR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBD
# AEEwEgYDVR0TAQH/BAgwBgEB/wIBADAfBgNVHSMEGDAWgBTZQSmwDw9jbO9p1/XN
# KZ6kSGow5jBwBgNVHR8EaTBnMGWgY6Bhhl9odHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ29kZSUy
# MFNpZ25pbmclMjBQQ0ElMjAyMDIxLmNybDB9BggrBgEFBQcBAQRxMG8wbQYIKwYB
# BQUHMAKGYWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWlj
# cm9zb2Z0JTIwSUQlMjBWZXJpZmllZCUyMENvZGUlMjBTaWduaW5nJTIwUENBJTIw
# MjAyMS5jcnQwDQYJKoZIhvcNAQEMBQADggIBAF1uIjzPBctfyCUkSH/xDbZQwJSF
# YE7jpn0U+HA5HeZ2WpFUuRg6if8xzNTCuMOHHdf31I8fk9J+WQahO+c71lYczlgV
# Vik7s1i4H6Z9VIYAZnCIY4BJaTSLYHu+f2cSUkmaiJfG6B8flh0GytSBO3QAU1eT
# OapOCT5LUfFvW7/QcKoQdVk+TYD/p4ldhu2lEzkVzPTSOKxSX0FFmBJ5s4NXzlsH
# M696rILd/Q+ccLFEk2ExvzE/+wH9Ujul/auF5JXvOpRK/y+f98gxuVd5pUiWmqir
# xI/0EkyMT8KhVcnGeRlBEzUVruQ33LO29F46HFKA+ClnH9eX+OTDIQVUlMF8Gnex
# OB8hz+maq/Z6G1qQvYASPvwSY49CiHElPfDJf4/vwYDbm0ukC/OPdEwwd3zPXxm6
# 5WL7rQwDMak4BIfUvw2Wvd9lFmdA76nLJ7YMK9iYdoh91SBgmqfuejHEZW/z35Fo
# ROHW2AIO/A2kUJIbu+XkDhqSj7Z/HjT2v1NaNcLs6J/UhDlknMHhF/wa8GIdiO8y
# YemV52nUUZEt1JEVWkLf84qlljpq8ipmnv7yk/9ZA/3TcN2Cu8BPpbjE84HFc9ri
# 0aSw3dK6olqIVgdI3J4G5+fyKx66NbghsFJscPgE+psXepn7ucb13938bb8vHiQf
# 1wKYF+axl1KQea6QMIIHnjCCBYagAwIBAgITMwAAAAeHozSje6WOHAAAAAAABzAN
# BgkqhkiG9w0BAQwFADB3MQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0
# IENvcnBvcmF0aW9uMUgwRgYDVQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkgVmVyaWZp
# Y2F0aW9uIFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjEwNDAx
# MjAwNTIwWhcNMzYwNDAxMjAxNTIwWjBjMQswCQYDVQQGEwJVUzEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMTQwMgYDVQQDEytNaWNyb3NvZnQgSUQgVmVy
# aWZpZWQgQ29kZSBTaWduaW5nIFBDQSAyMDIxMIICIjANBgkqhkiG9w0BAQEFAAOC
# Ag8AMIICCgKCAgEAsvDArxmIKOLdVHpMSWxpCFUJtFL/ekr4weslKPdnF3cpTeuV
# 8veqtmKVgok2rO0D05BpyvUDCg1wdsoEtuxACEGcgHfjPF/nZsOkg7c0mV8hpMT/
# GvB4uhDvWXMIeQPsDgCzUGzTvoi76YDpxDOxhgf8JuXWJzBDoLrmtThX01CE1TCC
# vH2sZD/+Hz3RDwl2MsvDSdX5rJDYVuR3bjaj2QfzZFmwfccTKqMAHlrz4B7ac8g9
# zyxlTpkTuJGtFnLBGasoOnn5NyYlf0xF9/bjVRo4Gzg2Yc7KR7yhTVNiuTGH5h4e
# B9ajm1OCShIyhrKqgOkc4smz6obxO+HxKeJ9bYmPf6KLXVNLz8UaeARo0BatvJ82
# sLr2gqlFBdj1sYfqOf00Qm/3B4XGFPDK/H04kteZEZsBRc3VT2d/iVd7OTLpSH9y
# CORV3oIZQB/Qr4nD4YT/lWkhVtw2v2s0TnRJubL/hFMIQa86rcaGMhNsJrhysLNN
# MeBhiMezU1s5zpusf54qlYu2v5sZ5zL0KvBDLHtL8F9gn6jOy3v7Jm0bbBHjrW5y
# QW7S36ALAt03QDpwW1JG1Hxu/FUXJbBO2AwwVG4Fre+ZQ5Od8ouwt59FpBxVOBGf
# N4vN2m3fZx1gqn52GvaiBz6ozorgIEjn+PhUXILhAV5Q/ZgCJ0u2+ldFGjcCAwEA
# AaOCAjUwggIxMA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNV
# HQ4EFgQU2UEpsA8PY2zvadf1zSmepEhqMOYwVAYDVR0gBE0wSzBJBgRVHSAAMEEw
# PwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9j
# cy9SZXBvc2l0b3J5Lmh0bTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAPBgNV
# HRMBAf8EBTADAQH/MB8GA1UdIwQYMBaAFMh+0mqFKhvKGZgEByfPUBBPaKiiMIGE
# BgNVHR8EfTB7MHmgd6B1hnNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz
# L2NybC9NaWNyb3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3Ql
# MjBDZXJ0aWZpY2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3JsMIHDBggrBgEFBQcB
# AQSBtjCBszCBgQYIKwYBBQUHMAKGdWh0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9w
# a2lvcHMvY2VydHMvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24l
# MjBSb290JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNydDAtBggr
# BgEFBQcwAYYhaHR0cDovL29uZW9jc3AubWljcm9zb2Z0LmNvbS9vY3NwMA0GCSqG
# SIb3DQEBDAUAA4ICAQB/JSqe/tSr6t1mCttXI0y6XmyQ41uGWzl9xw+WYhvOL47B
# V09Dgfnm/tU4ieeZ7NAR5bguorTCNr58HOcA1tcsHQqt0wJsdClsu8bpQD9e/al+
# lUgTUJEV80Xhco7xdgRrehbyhUf4pkeAhBEjABvIUpD2LKPho5Z4DPCT5/0TlK02
# nlPwUbv9URREhVYCtsDM+31OFU3fDV8BmQXv5hT2RurVsJHZgP4y26dJDVF+3pcb
# tvh7R6NEDuYHYihfmE2HdQRq5jRvLE1Eb59PYwISFCX2DaLZ+zpU4bX0I16ntKq4
# poGOFaaKtjIA1vRElItaOKcwtc04CBrXSfyL2Op6mvNIxTk4OaswIkTXbFL81ZKG
# D+24uMCwo/pLNhn7VHLfnxlMVzHQVL+bHa9KhTyzwdG/L6uderJQn0cGpLQMStUu
# NDArxW2wF16QGZ1NtBWgKA8Kqv48M8HfFqNifN6+zt6J0GwzvU8g0rYGgTZR8zDE
# IJfeZxwWDHpSxB5FJ1VVU1LIAtB7o9PXbjXzGifaIMYTzU4YKt4vMNwwBmetQDHh
# dAtTPplOXrnI9SI6HeTtjDD3iUN/7ygbahmYOHk7VB7fwT4ze+ErCbMh6gHV1UuX
# PiLciloNxH6K4aMfZN1oLVk6YFeIJEokuPgNPa6EnTiOL60cPqfny+Fq8UiuZzGC
# FzIwghcuAgEBMHEwWjELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBD
# b3Jwb3JhdGlvbjErMCkGA1UEAxMiTWljcm9zb2Z0IElEIFZlcmlmaWVkIENTIEVP
# QyBDQSAwMwITMwAFMQooWmAClZNtoQAAAAUxCjANBglghkgBZQMEAgEFAKBeMBAG
# CisGAQQBgjcCAQwxAjAAMBkGCSqGSIb3DQEJAzEMBgorBgEEAYI3AgEEMC8GCSqG
# SIb3DQEJBDEiBCBf2PfXr4F8otV61m8l5wEWboOHsuL9Ii/02TwWuiG24TANBgkq
# hkiG9w0BAQEFAASCAYCun+3yw/vHznKjbMaI9/Fqo8s5n0NdAgbP8ZFNBLMOuZAC
# WMteaOeWK1wrsSlTCy6DSu5ytry/py25naMrOrPzSQi2AKQy65MrrmLtcDBCbBjB
# ZMSpqlN95MbPKcQ3BfqPhPxwUFFUed1KcA9RwTINJwFPTeOU4FMp+KZ66Kndv9BU
# aQFafgak9beeIfvLEOvShXHRwQD3dU84wp7v6yszC5BOTeNHO2ibXjvHCw6O4I99
# Idnkib6MrICIeUqMzrj3Zs8cvLr2Uru/szjwcm1ZTZGFU2wsCKaX7BIq9Ee8AEL8
# f2F14MW6kr/N2mN1fvzz0FFTcO4C94o0kOlXE3SPq3DSSdBmvQfT/UJ7/qurqnjl
# 4hv9lYCeRlx9MXwTExG76RiMBWK4HIocuXPGfDIIr1qWzC7RwRVtkEtwFEVg0yZD
# SYVXqLzdfrKx5TexCm3Q2iWtm0wkR8yfiobRSuRT1R3m6bk9Lsawf25fwq0E35Kb
# h4JO0S6CdNk0ZWVgVJmhghSyMIIUrgYKKwYBBAGCNwMDATGCFJ4wghSaBgkqhkiG
# 9w0BBwKgghSLMIIUhwIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBagYLKoZIhvcNAQkQ
# AQSgggFZBIIBVTCCAVECAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQg
# aF5lkU9WICdJzI3rl8k3PcIqtwMk1nrwgGjgaps+SmMCBmqSUe6OMhgTMjAyNjA4
# MzEwODMxMjUuOTY1WjAEgAIB9KCB6aSB5jCB4zELMAkGA1UEBhMCVVMxEzARBgNV
# BAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jv
# c29mdCBDb3Jwb3JhdGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3Bl
# cmF0aW9ucyBMaW1pdGVkMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046N0ExQS0w
# NUUwLUQ5NDcxNTAzBgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3Rh
# bXBpbmcgQXV0aG9yaXR5oIIPKTCCB4IwggVqoAMCAQICEzMAAAAF5c8P/2YuyYcA
# AAAAAAUwDQYJKoZIhvcNAQEMBQAwdzELMAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1p
# Y3Jvc29mdCBDb3Jwb3JhdGlvbjFIMEYGA1UEAxM/TWljcm9zb2Z0IElkZW50aXR5
# IFZlcmlmaWNhdGlvbiBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAyMDIwMB4X
# DTIwMTExOTIwMzIzMVoXDTM1MTExOTIwNDIzMVowYTELMAkGA1UEBhMCVVMxHjAc
# BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0
# IFB1YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjAwggIiMA0GCSqGSIb3DQEB
# AQUAA4ICDwAwggIKAoICAQCefOdSY/3gxZ8FfWO1BiKjHB7X55cz0RMFvWVGR3eR
# wV1wb3+yq0OXDEqhUhxqoNv6iYWKjkMcLhEFxvJAeNcLAyT+XdM5i2CgGPGcb95W
# JLiw7HzLiBKrxmDj1EQB/mG5eEiRBEp7dDGzxKCnTYocDOcRr9KxqHydajmEkzXH
# OeRGwU+7qt8Md5l4bVZrXAhK+WSk5CihNQsWbzT1nRliVDwunuLkX1hyIWXIArCf
# rKM3+RHh+Sq5RZ8aYyik2r8HxT+l2hmRllBvE2Wok6IEaAJanHr24qoqFM9WLeBU
# Sudz+qL51HwDYyIDPSQ3SeHtKog0ZubDk4hELQSxnfVYXdTGncaBnB60QrEuazvc
# ob9n4yR65pUNBCF5qeA4QwYnilBkfnmeAjRN3LVuLr0g0FXkqfYdUmj1fFFhH8k8
# YBozrEaXnsSL3kdTD01X+4LfIWOuFzTzuoslBrBILfHNj8RfOxPgjuwNvE6YzauX
# i4orp4Sm6tF245DaFOSYbWFK5ZgG6cUY2/bUq3g3bQAqZt65KcaewEJ3ZyNEobv3
# 5Nf6xN6FrA6jF9447+NHvCjeWLCQZ3M8lgeCcnnhTFtyQX3XgCoc6IRXvFOcPVrr
# 3D9RPHCMS6Ckg8wggTrtIVnY8yjbvGOUsAdZbeXUIQAWMs0d3cRDv09SvwVRd61e
# vQIDAQABo4ICGzCCAhcwDgYDVR0PAQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEA
# MB0GA1UdDgQWBBRraSg6NS9IY0DPe9ivSek+2T3bITBUBgNVHSAETTBLMEkGBFUd
# IAAwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9Eb2NzL1JlcG9zaXRvcnkuaHRtMBMGA1UdJQQMMAoGCCsGAQUFBwMIMBkGCSsG
# AQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgw
# FoAUyH7SaoUqG8oZmAQHJ89QEE9oqKIwgYQGA1UdHwR9MHsweaB3oHWGc2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMElkZW50
# aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9y
# aXR5JTIwMjAyMC5jcmwwgZQGCCsGAQUFBwEBBIGHMIGEMIGBBggrBgEFBQcwAoZ1
# aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQl
# MjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZpY2F0ZSUy
# MEF1dGhvcml0eSUyMDIwMjAuY3J0MA0GCSqGSIb3DQEBDAUAA4ICAQBfiHbHfm21
# WhV150x4aPpO4dhEmSUVpbixNDmv6TvuIHv1xIs174bNGO/ilWMm+Jx5boAXrJxa
# gRhHQtiFprSjMktTliL4sKZyt2i+SXncM23gRezzsoOiBhv14YSd1Klnlkzvgs29
# XNjT+c8hIfPRe9rvVCMPiH7zPZcw5nNjthDQ+zD563I1nUJ6y59TbXWsuyUsqw7w
# XZoGzZwijWT5oc6GvD3HDokJY401uhnj3ubBhbkR83RbfMvmzdp3he2bvIUztSOu
# FzRqrLfEvsPkVHYnvH1wtYyrt5vShiKheGpXa2AWpsod4OJyT4/y0dggWi8g/tgb
# hmQlZqDUf3UqUQsZaLdIu/XSjgoZqDjamzCPJtOLi2hBwL+KsCh0Nbwc21f5xvPS
# wym0Ukr4o5sCcMUcSy6TEP7uMV8RX0eH/4JLEpGyae6Ki8JYg5v4fsNGif1OXHJ2
# IWG+7zyjTDfkmQ1snFOTgyEX8qBpefQbF0fx6URrYiarjmBprwP6ZObwtZXJ23jK
# 3Fg/9uqM3j0P01nzVygTppBabzxPAh/hHhhls6kwo3QLJ6No803jUsZcd4JQxiYH
# Hc+Q/wAMcPUnYKv/q2O444LO1+n6j01z5mggCSlRwD9faBIySAcA9S8h22hIAcRQ
# qIGEjolCK9F6nK9ZyX4lhthsGHumaABdWzCCB58wggWHoAMCAQICEzMAAABbSrWN
# QTJt3HQAAAAAAFswDQYJKoZIhvcNAQEMBQAwYTELMAkGA1UEBhMCVVMxHjAcBgNV
# BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAGA1UEAxMpTWljcm9zb2Z0IFB1
# YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjAwHhcNMjYwMTA4MTg1OTA1WhcN
# MjcwMTA3MTg1OTA1WjCB4zELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0
# b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3Jh
# dGlvbjEtMCsGA1UECxMkTWljcm9zb2Z0IElyZWxhbmQgT3BlcmF0aW9ucyBMaW1p
# dGVkMScwJQYDVQQLEx5uU2hpZWxkIFRTUyBFU046N0ExQS0wNUUwLUQ5NDcxNTAz
# BgNVBAMTLE1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWUgU3RhbXBpbmcgQXV0aG9y
# aXR5MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAkFTMFtueUNd57QHQ
# oPkbj/jvm2EXJ9y0LK4RJNZBe+UuLhbH+13apR16riJ156DpVaGI4d+7fAlXhNQZ
# JG2qH0JyvUGaIEq/2K4WmAfIgG7lDHfxmzHCUV5dVL5mokkqddFsM1B1xhKgL/pz
# SFAn88fnQMFENCQ9dXDIWLMutEf0CWsl5SDsEp5PbfN+1Lz8o4ku8QRsc4XqlI5j
# dlWmtlRZtaNbBFOagdpD8Ty+ta0s3IQn5vTz1VbUiStre3gZMHlZvLcIvUrbNicD
# EEi9p+wowXKP065cdxM8owOgVIx5qYb0wo4xvq6gbU+N2cOCws/oQ4xFLOssvuMQ
# PWZsH1FJ31+G3L4dCvq9mCwGfqhTL5hOk1UuyTB21QzzZZgCQ/O2U63cCIvSrJXv
# 9TeP+6re8cyM8zTDTfjQzns16LSDgEJwy3R1uqhz3VWAJvf/fqwdAA2ie2fUc4Xa
# guTzX3RBFLjeKwdWtrwfyx/n4aWohixiIIpfTgdmI7NlbzbqdUjp377yXJN5aamP
# 3RRr249smFWPATeiHq07nXTJKqZIxIsQ3Tuncht7cToEBvbD3etbNvbr52lK2Fso
# XiQCmh+oGxY9fgwS0cpI5+0+ZVMJDju2CGtW4eJr2Nj4eyPTWbgpbha2SZWbcvqE
# xkQIxriyMzEBfP5tf8AmFZN7pNkCAwEAAaOCAcswggHHMB0GA1UdDgQWBBTv8upS
# VZZiFcl1fCBgrHhvwa/StjAfBgNVHSMEGDAWgBRraSg6NS9IY0DPe9ivSek+2T3b
# ITBsBgNVHR8EZTBjMGGgX6BdhltodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NybC9NaWNyb3NvZnQlMjBQdWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmcl
# MjBDQSUyMDIwMjAuY3JsMHkGCCsGAQUFBwEBBG0wazBpBggrBgEFBQcwAoZdaHR0
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBQ
# dWJsaWMlMjBSU0ElMjBUaW1lc3RhbXBpbmclMjBDQSUyMDIwMjAuY3J0MAwGA1Ud
# EwEB/wQCMAAwFgYDVR0lAQH/BAwwCgYIKwYBBQUHAwgwDgYDVR0PAQH/BAQDAgeA
# MGYGA1UdIARfMF0wUQYMKwYBBAGCN0yDfQEBMEEwPwYIKwYBBQUHAgEWM2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTAI
# BgZngQwBBAIwDQYJKoZIhvcNAQEMBQADggIBAAAf7N35cqHg7FdgxYWa2CKVcBAZ
# y06MJQHXD+4GIL85dwfchrj9dt1SErMVtqJNsgTq9hkp3Wni7uco4uRrDKYAxXK4
# 7stKXqssq21kjIuFaNMrTNc7PS7jEur35tG0EQom8DqwPmcnAfUg7rPViLPK4hGh
# qUwKdutSLF9bFCfhMCY3u326T5fYVROERrd7DNHCG0b7HBoBssyTFGZHbgmd9d3V
# XEqj3T6btbO6i/3pS6DHnBl17CIgibVlZOPiUIke6nrv0tw5ru0DEkyKlVpKW1Af
# 1+b1M4pzOV/G1a4FwtTh25l+rCCwguwfs8yRxfXPBDNAPTIC0+GdjP0o0bXbltf6
# KKU57VLxEeq/ZtsGkylqjiRxS9Ajp0yApG8WabV4tuFI05CmUMxMYPW01V00aQj3
# qNS762uhSNYwyLjpNB8EAfG0NOlGEi7/zu8BVDxnpEeEXF6zPgR3klOFohBEDLoZ
# w78mT5DMPOhnRqtEiQiwYnutmA5UCPH1y1/DyUf1F+NzAHfB0YFg0w1UmpClRqLZ
# Np11/mlfNNkQciosQXndKsGMh4iehCs/tTlWVeIxCzF7At0g2sATaXZNHcoGKRv5
# FBHKBtOnyOPbKILQ0JTAb4r6d2CU3lExteMVbpoprn1er5vxfMr8Mr4Am2A6keAm
# /xCuTrYD63A5Us6mMYID1DCCA9ACAQEweDBhMQswCQYDVQQGEwJVUzEeMBwGA1UE
# ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVi
# bGljIFJTQSBUaW1lc3RhbXBpbmcgQ0EgMjAyMAITMwAAAFtKtY1BMm3cdAAAAAAA
# WzANBglghkgBZQMEAgEFAKCCAS0wGgYJKoZIhvcNAQkDMQ0GCyqGSIb3DQEJEAEE
# MC8GCSqGSIb3DQEJBDEiBCAe5F5qr10Cj+M7iHZD2SK8EpOQkUa4oF5Odt9u4+5a
# 4zCB3QYLKoZIhvcNAQkQAi8xgc0wgcowgccwgaAEIC8xA1VdnRvTHGUbDxf/cgTJ
# s5u5PprlbV3rUJb5wYPvMHwwZaRjMGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVN
# aWNyb3NvZnQgQ29ycG9yYXRpb24xMjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMg
# UlNBIFRpbWVzdGFtcGluZyBDQSAyMDIwAhMzAAAAW0q1jUEybdx0AAAAAABbMCIE
# IFGHpyXywqq6GChkOy16vdw6ZeHGpF77EooDacFKRViDMA0GCSqGSIb3DQEBCwUA
# BIICABoSHtvUsczjGnwJYY0XWCAtUk0yEHzNzl//h3jeUOIGKLCULV6eO6A4aDab
# qMesgNJtkQvktRxuZGAECd+TvIlnhRG6G9tZCWLgOGOCBXCTq9a35isttD/wFrZ1
# HsBdhta6i/lw9zxXrfMu8Kw1HhvwRrj1Uz1uWSnmUiS52yXqaM56NjU3Erecbvne
# +kIwVGgk//7vqN/m6XHdZPWJzn6AfD++/GIdwLrkANZfpLNIQNqqa2suB4UuEmDb
# wlReWfJEyW5mhlWwAFr7fpSV9NqXmvCI3bryDLsU2JKu2ezkc8V88iB7eaopqpng
# 8RIk70qqDs8H6afGxKI+NwXHiYNDe9wyE+Vhoa/19GjkSeMbBScPNoPA83LLOaVR
# +9nhKCJ2PH4HlmfKvJMXh+DS0h3s8/yEkBXGIY/sdpCDzrt4hETmWgMGXqp3w7rv
# a1hlr38JmmPI8DhbTV4GPMUKPNM2bBXoHm0zfMU/77g4o0FDmj76q6WqZlOqGv/X
# GFA82DYULmxQQ1rbudi+UzmQqPxHtD+0xu7s7DAHJkPhGe0s8TSlnaEJOm+b0uzK
# ODqDjIfY5ETmwyuYX7MZoCF6KUYNl02RiwOevJ5BNYP2AhgH1xbm3XCvZCg3Eowb
# 3c9gLpOHmQoX9y9G46hosiTfpOU3tuzwSR1aPjg0lm++caXf
# SIG # End signature block
