functions/DailyBuild/Prepare-DailyBuildBranch.ps1

<#
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, You can obtain one at https://mozilla.org/MPL/2.0/.
#>


[CmdletBinding()]
param(
    [string]$OrganizationUri = $env:SYSTEM_COLLECTIONURI,
    [string]$Project = $env:SYSTEM_TEAMPROJECTID,
    [string]$RepositoryName = $env:BUILD_REPOSITORY_NAME,
    [string]$DailyBuildBranch = 'daily-build',
    [ValidateSet('merge', 'squash')]
    [string]$MergeStrategy = 'merge',
    [int]$DefaultPriority = 100,
    [string]$Pat = $env:DEVOPS_PAT,
    [switch]$SkipUnchangedPush
)


if ($MyInvocation.InvocationName -eq '.') {
    return
}

$gitArgs = @(
    '-c',
    "http.extraheader=AUTHORIZATION: Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("PAT:$Pat")))"
)

function Resolve-PullRequestPriority {
    param(
        [Parameter(Mandatory = $true)]
        $Labels
    )

    $resolved = $DefaultPriority
    foreach ($label in @($Labels | ForEach-Object { $_.name })) {
        if ($label -match '^priority:(\d+)$') {
            $val = [int]$Matches[1]
            if ($val -lt $resolved) { $resolved = $val }
        }
    }
    return $resolved
}

function Invoke-Git {
    param(
        [Parameter(Mandatory = $true)]
        [string[]]$Args
    )

    & git @gitArgs @Args
    if ($LASTEXITCODE -ne 0) {
        throw "git $($Args -join ' ') failed with exit code $LASTEXITCODE."
    }
}

function Get-CommitIdentity {
    param(
        [Parameter(Mandatory = $true)]
        [string]$Ref
    )

    $identity = & git @gitArgs 'show' '--no-patch' "--format=%an`n%ae" $Ref
    if ($LASTEXITCODE -ne 0) {
        throw "Failed to resolve commit identity for $Ref."
    }

    $identityLines = @($identity | Where-Object { $_ -ne $null })
    if ($identityLines.Count -lt 2) {
        throw "Commit identity for $Ref is incomplete."
    }

    return @{
        Name  = $identityLines[0]
        Email = $identityLines[1]
    }
}

function Invoke-GitWithCommitIdentity {
    param(
        [Parameter(Mandatory = $true)]
        [hashtable]$Identity,
        [Parameter(Mandatory = $true)]
        [string[]]$Args
    )

    & git @gitArgs '-c' "user.name=$($Identity.Name)" '-c' "user.email=$($Identity.Email)" @Args
    if ($LASTEXITCODE -ne 0) {
        throw "git $($Args -join ' ') failed with exit code $LASTEXITCODE."
    }
}

function Get-BuildResultsUrl {
    $collectionUri = if ($env:SYSTEM_COLLECTIONURI) { $env:SYSTEM_COLLECTIONURI } else { $OrganizationUri }
    if ([string]::IsNullOrWhiteSpace($collectionUri)) {
        return ''
    }

    $buildId = $env:BUILD_BUILDID
    if ([string]::IsNullOrWhiteSpace($buildId)) {
        return ''
    }

    $projectName = if ($env:SYSTEM_TEAMPROJECT) { $env:SYSTEM_TEAMPROJECT } else { $Project }
    $baseUri = $collectionUri.TrimEnd('/')
    $queryParts = @{
        "buildId" = $buildId
        'view'    = 'logs'
        "j"       = $env:SYSTEM_JOBID
        "t"       = $env:SYSTEM_TASKINSTANCEID
        "s"       = $env:SYSTEM_STAGEID
    }

    $queryString = ($queryParts.GetEnumerator() | ForEach-Object { "$($_.Key)=$([uri]::EscapeDataString($_.Value))" }) -join '&'

    return "$baseUri/$([Uri]::EscapeDataString($projectName))/_build/results?$queryString"
}

function Set-PullRequestStatus {
    param(
        [Parameter(Mandatory = $true)]
        [int]$PullRequestId,
        [Parameter(Mandatory = $true)]
        [int]$IterationId,
        [Parameter(Mandatory = $true)]
        [ValidateSet('succeeded', 'failed', 'pending', 'notSet', 'error')]
        [string]$State,
        [Parameter(Mandatory = $true)]
        [string]$Description
    )

    $authHeader = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("PAT:$Pat")))"
    $targetUrl = Get-BuildResultsUrl
    $body = @{
        state       = $State
        description = $Description
        iterationId = $IterationId
        context     = @{
            name  = 'daily-build'
            genre = 'daily-build'
        }
        targetUrl   = $targetUrl
    } | ConvertTo-Json
    $uri = "$OrganizationUri/$([Uri]::EscapeDataString($Project))/_apis/git/repositories/$repositoryId/pullRequests/$PullRequestId/statuses?api-version=7.1"
    try {
        Invoke-RestMethod -Uri $uri -Method Post -Body $body -ContentType 'application/json' -Headers @{ Authorization = $authHeader } | Out-Null
    }
 catch {
        Write-Warning "Failed to post status to PR !$PullRequestId : $_"
    }
}

function Get-LatestPullRequestIteration {
    param(
        [Parameter(Mandatory = $true)]
        [int]$PullRequestId
    )

    $authHeader = "Basic $([System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes("PAT:$Pat")))"
    $uri = "$OrganizationUri/$([Uri]::EscapeDataString($Project))/_apis/git/repositories/$repositoryId/pullRequests/$PullRequestId/iterations?includeCommits=false&api-version=7.1"
    $response = Invoke-RestMethod -Uri $uri -Method Get -Headers @{ Authorization = $authHeader }

    if (-not $response -or -not $response.value -or $response.value.Count -eq 0) {
        throw "No iterations found for PR !$PullRequestId."
    }

    # The API returns iterations in ascending order; the last one is the current iteration.
    return $response.value[-1]
}

function Resolve-IterationIdForStatus {
    param(
        [Parameter(Mandatory = $true)]
        $PullRequestItem
    )

    if ($PullRequestItem.PSObject.Properties.Name -contains 'Iteration' -and $PullRequestItem.Iteration -and $PullRequestItem.Iteration.Id) {
        return [int]$PullRequestItem.Iteration.Id
    }

    return 1
}

az devops configure --defaults organization=$OrganizationUri project=$Project

# future idea - dependency-aware ordering (depends-on PR list)
$prResponse = az repos pr list --repository "$RepositoryName" --target-branch main --status active --query '[?!isDraft]' --output json
$pr = ($prResponse | ConvertFrom-Json)
$pr = $pr | Where-Object {
    if (!$_.labels) { $_.labels = @() }
    $labelNames = @($_.labels | ForEach-Object { $_.name })
    $labelNames -notcontains 'AutoMergeIgnore'
}

$pr = $pr | Sort-Object -Property @(
    @{ Expression = { Resolve-PullRequestPriority $_.labels }; Ascending = $true },
    @{ Expression = { $_.pullRequestId }; Ascending = $true }
)

$repositoryId = (az repos show --repository "$RepositoryName" --query id --output tsv).Trim()

Invoke-Git @('fetch', 'origin', 'main')
Invoke-Git @('checkout', '-B', $DailyBuildBranch, 'origin/main')
$mergeLabelScriptPath = Join-Path (Split-Path $PSScriptRoot -Parent) 'MergeDriver/Merge-LabelFile.ps1'
if (Test-Path -Path $mergeLabelScriptPath) {
    Invoke-Git @('config', 'merge.d365fo-label.driver', "pwsh -File `"$mergeLabelScriptPath`" -Base %O -Ours %A -Theirs %B -MarkerSize %L -FilePath %P")
}
else {
    Write-Verbose "Merge label driver script not found at $mergeLabelScriptPath. Skipping merge.d365fo-label.driver configuration."
}
$mergedPRs = @()
$skippedPRs = @()

foreach ($item in $pr) {
    if (-not $item.sourceRefName) {
        Write-Warning "Skipping PR $($item.pullRequestId): missing sourceRefName."
        continue
    }

    if ($item.supportsIterations) {
        $iteration = Get-LatestPullRequestIteration -PullRequestId $item.pullRequestId
        $item | Add-Member -MemberType NoteProperty -Name Iteration -Value $iteration
        if ($item.lastMergeSourceCommit.commitId -ne $item.Iteration.sourceRefCommit.commitId) {
            Write-Warning "Skipping PR $($item.pullRequestId): source branch has new commits since last iteration."
            $skippedPRs += $item
            continue
        }
    }

    $sourceBranch = $item.sourceRefName -replace '^refs/heads/', ''
    $resolvedPriority = Resolve-PullRequestPriority $item.labels
    $sourceIdentity = Get-CommitIdentity "origin/$sourceBranch"
    Write-Host "Merging PR $($item.pullRequestId) from $sourceBranch (priority: $resolvedPriority)"

    try {
        switch ($MergeStrategy) {
            'squash' {
                Invoke-Git @('merge', '--squash', "origin/$sourceBranch")
                Invoke-GitWithCommitIdentity $sourceIdentity @('commit', '-m', "Squash PR !$($item.pullRequestId)")
            }
            default {
                Invoke-GitWithCommitIdentity $sourceIdentity @('merge', '--no-ff', "origin/$sourceBranch", '-m', "Merge PR !$($item.pullRequestId)")
            }
        }
        $mergedPRs += $item
    }
 catch {
        Write-Warning "Merge failed for PR $($item.pullRequestId) ($sourceBranch). Skipping."
        & git merge --abort | Out-Null
        & git reset --hard HEAD | Out-Null
        $skippedPRs += $item
        continue
    }
}

$shouldPush = $true
if ($SkipUnchangedPush) {
    # Silently try to fetch the remote daily-build branch (may not exist yet)
    & git @gitArgs fetch origin $DailyBuildBranch 2>$null | Out-Null
    # Check if the remote ref exists
    & git rev-parse --verify "origin/$DailyBuildBranch" 2>$null | Out-Null
    if ($LASTEXITCODE -eq 0) {
        # Compare trees; exit code 0 means no difference
        & git diff --quiet "origin/$DailyBuildBranch" HEAD
        if ($LASTEXITCODE -eq 0) {
            Write-Host "No content changes vs 'origin/$DailyBuildBranch' - skipping push."
            $shouldPush = $false
        }
    }
}

if ($shouldPush) {
    Invoke-Git @('push', '--force', 'origin', $DailyBuildBranch)
}

foreach ($item in $mergedPRs) {
    try {
        $iterationId = Resolve-IterationIdForStatus -PullRequestItem $item
        Set-PullRequestStatus -PullRequestId $item.pullRequestId -IterationId $iterationId -State 'succeeded' -Description "Merged into daily-build (iteration: $iterationId) $($item.lastMergeSourceCommit.commitId)"
    }
 catch {
        Write-Warning "Failed to post status for PR $($item.pullRequestId): $_"
    }
}
foreach ($item in $skippedPRs) {
    try {
        $iterationId = Resolve-IterationIdForStatus -PullRequestItem $item
        Set-PullRequestStatus -PullRequestId $item.pullRequestId -IterationId $iterationId -State 'failed' -Description "Merge conflict - skipped (iteration: $iterationId) $($item.lastMergeSourceCommit.commitId)"
    }
 catch {
        Write-Warning "Failed to post status for PR $($item.pullRequestId): $_"
    }
}

Write-Host ''
Write-Host '=== Daily Build Summary ==='
if ($mergedPRs.Count -gt 0) {
    $mergedList = ($mergedPRs | ForEach-Object { "!$($_.pullRequestId)" }) -join ', '
    Write-Host "Merged: $mergedList"
}
else {
    Write-Host 'Merged: (none)'
}
if ($skippedPRs.Count -gt 0) {
    $skippedList = ($skippedPRs | ForEach-Object { "!$($_.pullRequestId) (merge conflict)" }) -join ', '
    Write-Host "Skipped: $skippedList"
}
else {
    Write-Host 'Skipped: (none)'
}

# SIG # Begin signature block
# MIIzNwYJKoZIhvcNAQcCoIIzKDCCMyQCAQExDzANBglghkgBZQMEAgEFADB5Bgor
# BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG
# KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCAoWKhCzhaLrC99
# qZackd8Ix2t6eAXpP6xDEKclVfNiTqCCGzQwggXMMIIDtKADAgECAhBUmNLR1FsZ
# 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
# 03u4aUoqlmZpxJTG9F9urJh4iIAGXKKy7aIwggaSMIIEeqADAgECAhMzAAHCNlwV
# oThYUayrAAAAAcI2MA0GCSqGSIb3DQEBDAUAMFoxCzAJBgNVBAYTAlVTMR4wHAYD
# VQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKzApBgNVBAMTIk1pY3Jvc29mdCBJ
# RCBWZXJpZmllZCBDUyBBT0MgQ0EgMDQwHhcNMjYwNjA2MTgxMDQxWhcNMjYwNjA5
# MTgxMDQxWjBVMQswCQYDVQQGEwJTSTESMBAGA1UEBxMJTGp1YmxqYW5hMRgwFgYD
# VQQKEw9CRS10ZXJuYSBkLm8uby4xGDAWBgNVBAMTD0JFLXRlcm5hIGQuby5vLjCC
# AaIwDQYJKoZIhvcNAQEBBQADggGPADCCAYoCggGBALaWg1OTtYVfHq18hH1jA6C8
# R3M5z670BLVLEXT0ejKLyVZWwaYKstssBVS2I5A6w4C5Q5GK9FZtb/g6DN3kASZY
# VrzbWWoWM1/ics495BNzE81FrsaQgnNvL8ysA+R4Qk/sdPYxMkOPxuWZ2Bfy0Cks
# 10qXNrV4xrXEYFXwoKkcSg27PiYGTPXKWh7mPqtEVq1Ey9trVX//3zlWUe3v79Sf
# H1Ytpz83Gf8cuw8SFJz7Od+pu8P1ECO+e9KiLouVaGRZrn5QHybNsNTpr/KaIiB7
# ESAkEGY8JgOaeP+Cs9NpcLE+qnn3cEGnf2P3E+TxdBBWGN/SFSiAupMC5vtzZRL+
# XtyvKah+NUK1eGKhAhe8OjFihBD7FzZzXY10kG84OtCUiGT1FeC/gNQgdGLQ0efK
# eJhMnAqewLw73XCVSwa1p6CUP0QOjkgrTXxJW55/XIIhnvQTTVdrzGxTRSAG0JDm
# eh2yf2pZegU5zRqUcpexXPfWQ5uhv7gGj3xJk5FgnwIDAQABo4IB1DCCAdAwDAYD
# VR0TAQH/BAIwADAOBgNVHQ8BAf8EBAMCB4AwOwYDVR0lBDQwMgYKKwYBBAGCN2EB
# AAYIKwYBBQUHAwMGGisGAQQBgjdhpOaoI4H67850gfzolDeutrtWMB0GA1UdDgQW
# BBQvDlUAdUQbfggmQNOEmp55qsjIYjAfBgNVHSMEGDAWgBRrJUHe+2t8/RiACi1/
# j3ZdqnM9uDBnBgNVHR8EYDBeMFygWqBYhlZodHRwOi8vd3d3Lm1pY3Jvc29mdC5j
# b20vcGtpb3BzL2NybC9NaWNyb3NvZnQlMjBJRCUyMFZlcmlmaWVkJTIwQ1MlMjBB
# T0MlMjBDQSUyMDA0LmNybDB0BggrBgEFBQcBAQRoMGYwZAYIKwYBBQUHMAKGWGh0
# dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY2VydHMvTWljcm9zb2Z0JTIw
# SUQlMjBWZXJpZmllZCUyMENTJTIwQU9DJTIwQ0ElMjAwNC5jcnQwVAYDVR0gBE0w
# SzBJBgRVHSAAMEEwPwYIKwYBBQUHAgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNv
# bS9wa2lvcHMvRG9jcy9SZXBvc2l0b3J5Lmh0bTANBgkqhkiG9w0BAQwFAAOCAgEA
# sxG0x+S2zzCLtdYefomtd5lAzPlumZYDlRSYF4PgZpqhddLlg2YgUTinhzvaNWWf
# ujJ7FUwypNJxlfLDGlECYAa2RjdLi7NgISTP48lNhKbtexaymXC6GT8Epzd1tYXK
# jNpl2j8s1e6Kv7ubprTv5+bC5V9IjHTFseTXqEQjyR6RCx1Y7bRReWa01OE9XjIj
# Zw8Vmufz5YjQKrBMI+X/MwKzXwPoZxcauAxAjXbxodWwUgetIeXo0jVao2ZdFFtd
# c/+aWMDbZataXvWpBlyQR55/r9hwJfqQE2SXEU7v+6trXnGl+jtIyoBP8Bsd/HQm
# Fgiixlb+a5jk8SXH7Hl/YySGfZYjLpB/Z3vOesB3Dgs6hqLFtwrMZ1HhK66znZS0
# IV93RWDf8PZ+cE9G29gXm6MBPdllosgzM3MYTLmvJXxZIB3lODZY/nmzKFFItsUb
# yV5R/7M6tWeJhNHpvSTzQ+e6aCkn4UBvFKph5B/n+DwS5dMkRKd13qEMpgXnm/GX
# fF2vKJD7FDjSlDa0psqZfDui2G4O6Ip+EwesIhNSswjNOdmBSkF6eOPkuIXexMI6
# LoR4O/Rcz8U25EpD8WXYapPs4MbnB5RJWJBTKki5kNJ/JNrV1oFzml3jlDMzVHWN
# cBxS/zoQVQQTxHgnHnknynthBYs/Z6MWlrfyZKFAizgwggcoMIIFEKADAgECAhMz
# AAAAFjGSjZICZXuaAAAAAAAWMA0GCSqGSIb3DQEBDAUAMGMxCzAJBgNVBAYTAlVT
# MR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xNDAyBgNVBAMTK01pY3Jv
# c29mdCBJRCBWZXJpZmllZCBDb2RlIFNpZ25pbmcgUENBIDIwMjEwHhcNMjYwMzI2
# MTgxMTI5WhcNMzEwMzI2MTgxMTI5WjBaMQswCQYDVQQGEwJVUzEeMBwGA1UEChMV
# TWljcm9zb2Z0IENvcnBvcmF0aW9uMSswKQYDVQQDEyJNaWNyb3NvZnQgSUQgVmVy
# aWZpZWQgQ1MgQU9DIENBIDA0MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKC
# AgEAylX6yNvoCTDP9G0OTlSjXbzgEsy21FDL17n/lZe2BrqHz2mR1aN4DBxeYp0/
# hjEqSHHyGfarV1NVBuvK8vLzW0LTi+DZt9In16aiNfgcogFiztWE9Fp8xu1zzrqE
# 3nlrDWb+RZo8QrEXgWb8s8swsl2W7tREHycVkx+Hm1MLQIlva6jH/Xg4/8GIYhHz
# bXiVd2RXomw9s7Qh6/SYRXXfe125wh4EKEyKnNNl+cZUSrVBgWvvjrRwQY4if7sA
# Z805KruBY6WY0Hiba5nWvrq9Qk9o35ViAf8qZ+7u1fbb1vcCWyWLfx9hLSdBjjVs
# SWe0xLvI1j4p3Tjt5czz+1Lc0v5lQ1feB7nFmpbZrK2us0hvAaBCfOyDPEEm+735
# vzuNRYWJFL/PViI+REtjuJMcojEn3veQjIrwrmK0T9oSr8e3oDzK1oAwwZMTC4Ky
# mTvYUTVDJvL5N8OW/UqIBzsiVYcchZvGhV3yMYKgxeEtIOG4W4Z85Y5kpQi5bpjG
# XFxRg46RdrTaALt1RhRmLR7U0jVSr2aYAd2+Mp2qA5Gz3/loOOdt47eFZ3mrAYGY
# QtbK2SNjQpwgQX4Iy6tOKahCgFhKIcltitvSkpJB77eVWhNWnN2LfqMojszEue7V
# 8EAySxry4PzlxTtFTb3Mw53XyH12BMQf2m9j7jEsHeVSATsCAwEAAaOCAdwwggHY
# MA4GA1UdDwEB/wQEAwIBhjAQBgkrBgEEAYI3FQEEAwIBADAdBgNVHQ4EFgQUayVB
# 3vtrfP0YgAotf492XapzPbgwVAYDVR0gBE0wSzBJBgRVHSAAMEEwPwYIKwYBBQUH
# AgEWM2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvRG9jcy9SZXBvc2l0
# b3J5Lmh0bTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTASBgNVHRMBAf8ECDAG
# AQH/AgEAMB8GA1UdIwQYMBaAFNlBKbAPD2Ns72nX9c0pnqRIajDmMHAGA1UdHwRp
# MGcwZaBjoGGGX2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01p
# Y3Jvc29mdCUyMElEJTIwVmVyaWZpZWQlMjBDb2RlJTIwU2lnbmluZyUyMFBDQSUy
# MDIwMjEuY3JsMH0GCCsGAQUFBwEBBHEwbzBtBggrBgEFBQcwAoZhaHR0cDovL3d3
# dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNyb3NvZnQlMjBJRCUyMFZl
# cmlmaWVkJTIwQ29kZSUyMFNpZ25pbmclMjBQQ0ElMjAyMDIxLmNydDANBgkqhkiG
# 9w0BAQwFAAOCAgEABtVQXlR01UQZY5XGQ9yIjMcD8jI0MizWhJ1buZjg5toUQSXx
# /BrASwE5qxwHPBeO45pOQp6VD4iILgm8OmfylY+A7KIqttvDUizC3sBXxjK4u7sD
# RiyEguXHKfL1HQAwxCLEtnRPkCPTsJA6b917lA+3foQIHC1XDDpdQLHxGbbGXp4R
# r0mFK5vxbi6tAahBi/RlzOXPh6PavKPlZ/0vhlkDdsvoJETtebNJCNOZ1Kav3Tg+
# K4va4FbOrYqRHdGGahoA/gmTYmmVqw0zkGzT53HdhfajrFGttJomK7qE+T8CQGiP
# kEIkxNmSXjCTpDqc4U1IKlTGcGYnRFGSgqrnWnkANPFsJ5EDHysh82lPI+PFC3FO
# IVMLzLL+30rqznvRgHUUAj7xfFnEiuaAx3vFVSTOLb+iigpvdR6i8fSWpgYESOkd
# kn2N57tuhBs57tKwoP++vc/MVpuD1XAtmWi+lZSlahadTbDfGKjMn+bfm2xlW9PZ
# 6BSnCRv1MMhpcUZkAZX3gVEMef8rZc2c7BJ4ayRfX0wH43vI9znV+ZRJ3j0xUC0Z
# b82RQalF5yHkCr93x0IwvZtn6P2dNQyCP6qd3fC4RlVFtAQhtOH0cByTR/Iqqghv
# 6qHzL/pMptgMQQ5x8zYEYy+tCThYgYIrq7y4WEDYQfeSlqIxQOrIUJ4IJDEwggee
# MIIFhqADAgECAhMzAAAAB4ejNKN7pY4cAAAAAAAHMA0GCSqGSIb3DQEBDAUAMHcx
# CzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xSDBG
# BgNVBAMTP01pY3Jvc29mdCBJZGVudGl0eSBWZXJpZmljYXRpb24gUm9vdCBDZXJ0
# aWZpY2F0ZSBBdXRob3JpdHkgMjAyMDAeFw0yMTA0MDEyMDA1MjBaFw0zNjA0MDEy
# MDE1MjBaMGMxCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9y
# YXRpb24xNDAyBgNVBAMTK01pY3Jvc29mdCBJRCBWZXJpZmllZCBDb2RlIFNpZ25p
# bmcgUENBIDIwMjEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCy8MCv
# GYgo4t1UekxJbGkIVQm0Uv96SvjB6yUo92cXdylN65Xy96q2YpWCiTas7QPTkGnK
# 9QMKDXB2ygS27EAIQZyAd+M8X+dmw6SDtzSZXyGkxP8a8Hi6EO9Zcwh5A+wOALNQ
# bNO+iLvpgOnEM7GGB/wm5dYnMEOguua1OFfTUITVMIK8faxkP/4fPdEPCXYyy8NJ
# 1fmskNhW5HduNqPZB/NkWbB9xxMqowAeWvPgHtpzyD3PLGVOmRO4ka0WcsEZqyg6
# efk3JiV/TEX39uNVGjgbODZhzspHvKFNU2K5MYfmHh4H1qObU4JKEjKGsqqA6Rzi
# ybPqhvE74fEp4n1tiY9/ootdU0vPxRp4BGjQFq28nzawuvaCqUUF2PWxh+o5/TRC
# b/cHhcYU8Mr8fTiS15kRmwFFzdVPZ3+JV3s5MulIf3II5FXeghlAH9CvicPhhP+V
# aSFW3Da/azROdEm5sv+EUwhBrzqtxoYyE2wmuHKws00x4GGIx7NTWznOm6x/niqV
# i7a/mxnnMvQq8EMse0vwX2CfqM7Le/smbRtsEeOtbnJBbtLfoAsC3TdAOnBbUkbU
# fG78VRclsE7YDDBUbgWt75lDk53yi7C3n0WkHFU4EZ83i83abd9nHWCqfnYa9qIH
# PqjOiuAgSOf4+FRcguEBXlD9mAInS7b6V0UaNwIDAQABo4ICNTCCAjEwDgYDVR0P
# AQH/BAQDAgGGMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBTZQSmwDw9jbO9p
# 1/XNKZ6kSGow5jBUBgNVHSAETTBLMEkGBFUdIAAwQTA/BggrBgEFBQcCARYzaHR0
# cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9Eb2NzL1JlcG9zaXRvcnkuaHRt
# MBkGCSsGAQQBgjcUAgQMHgoAUwB1AGIAQwBBMA8GA1UdEwEB/wQFMAMBAf8wHwYD
# VR0jBBgwFoAUyH7SaoUqG8oZmAQHJ89QEE9oqKIwgYQGA1UdHwR9MHsweaB3oHWG
# c2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUy
# MElkZW50aXR5JTIwVmVyaWZpY2F0aW9uJTIwUm9vdCUyMENlcnRpZmljYXRlJTIw
# QXV0aG9yaXR5JTIwMjAyMC5jcmwwgcMGCCsGAQUFBwEBBIG2MIGzMIGBBggrBgEF
# BQcwAoZ1aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9wcy9jZXJ0cy9NaWNy
# b3NvZnQlMjBJZGVudGl0eSUyMFZlcmlmaWNhdGlvbiUyMFJvb3QlMjBDZXJ0aWZp
# Y2F0ZSUyMEF1dGhvcml0eSUyMDIwMjAuY3J0MC0GCCsGAQUFBzABhiFodHRwOi8v
# b25lb2NzcC5taWNyb3NvZnQuY29tL29jc3AwDQYJKoZIhvcNAQEMBQADggIBAH8l
# Kp7+1Kvq3WYK21cjTLpebJDjW4ZbOX3HD5ZiG84vjsFXT0OB+eb+1TiJ55ns0BHl
# uC6itMI2vnwc5wDW1ywdCq3TAmx0KWy7xulAP179qX6VSBNQkRXzReFyjvF2BGt6
# FvKFR/imR4CEESMAG8hSkPYso+GjlngM8JPn/ROUrTaeU/BRu/1RFESFVgK2wMz7
# fU4VTd8NXwGZBe/mFPZG6tWwkdmA/jLbp0kNUX7elxu2+HtHo0QO5gdiKF+YTYd1
# BGrmNG8sTURvn09jAhIUJfYNotn7OlThtfQjXqe0qrimgY4Vpoq2MgDW9ESUi1o4
# pzC1zTgIGtdJ/IvY6nqa80jFOTg5qzAiRNdsUvzVkoYP7bi4wLCj+ks2GftUct+f
# GUxXMdBUv5sdr0qFPLPB0b8vq516slCfRwaktAxK1S40MCvFbbAXXpAZnU20FaAo
# Dwqq/jwzwd8Wo2J83r7O3onQbDO9TyDStgaBNlHzMMQgl95nHBYMelLEHkUnVVVT
# UsgC0Huj09duNfMaJ9ogxhPNThgq3i8w3DAGZ61AMeF0C1M+mU5eucj1Ijod5O2M
# MPeJQ3/vKBtqGZg4eTtUHt/BPjN74SsJsyHqAdXVS5c+ItyKWg3Eforhox9k3Wgt
# WTpgV4gkSiS4+A09roSdOI4vrRw+p+fL4WrxSK5nMYIXWTCCF1UCAQEwcTBaMQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSswKQYD
# VQQDEyJNaWNyb3NvZnQgSUQgVmVyaWZpZWQgQ1MgQU9DIENBIDA0AhMzAAHCNlwV
# oThYUayrAAAAAcI2MA0GCWCGSAFlAwQCAQUAoIGEMBgGCisGAQQBgjcCAQwxCjAI
# oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB
# CzEOMAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEILFW6sL+ri0/q9u0kqDy
# Xq6Fwd4lpUUYceZgyxSjAKHvMA0GCSqGSIb3DQEBAQUABIIBgFl9GBrGtNzr0+Xb
# jGXcryWCR3LjEI9h0CdgwygunBGob3mD5Uks6Ub2sBQ6mSqvuc/bV+SHTtHzwSc2
# RKiqDZETVetGFMiEXFy7BQDs8782uIzkVHaEvXICdHSXZhzx0sn9r8twnmxL+m31
# 83AfUekSfYH+sttj/9SaL6vZFEexjnvuqwAa1eGMYNnUAkhI5sbmvzCjBMrhtTQG
# y8Hhy5tjCufxoimi748y5tJ3gDQBgByiVRvkRs1mAnafyAZkNWUdKr+dVuDRUMtU
# iJ8PP6YdV6NdE+mLUyyl+mjUX0VlLqtZh7dUOkVEdJplhorYp62n27YC56utgexV
# egbwQAru5jC04/fOaYhEQPRFi5MOLeNSYdj5t8iA3NH6BswnVi8X7WMiyqA+UMQV
# Kodux7ItaozQ2CX5L4vq5OxUKfNX5rnjQ/RpQzw4qtQwVZSoSQc5B80rTuAl1f3/
# RPmCu4HotiY7q1To1SZ7U9FVEpkP5INeBNGegq0w6t2anIAk0qGCFLIwghSuBgor
# BgEEAYI3AwMBMYIUnjCCFJoGCSqGSIb3DQEHAqCCFIswghSHAgEDMQ8wDQYJYIZI
# AWUDBAIBBQAwggFqBgsqhkiG9w0BCRABBKCCAVkEggFVMIIBUQIBAQYKKwYBBAGE
# WQoDATAxMA0GCWCGSAFlAwQCAQUABCDeDcnlyeeGAI7gGV3uZ19QEmuD56GWRIEa
# rxhVHnclqAIGahmAnDb2GBMyMDI2MDYwNzIyMjcxNi45NjJaMASAAgH0oIHppIHm
# MIHjMQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMH
# UmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQL
# EyRNaWNyb3NvZnQgSXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsT
# Hm5TaGllbGQgVFNTIEVTTjo0OTFBLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9z
# b2Z0IFB1YmxpYyBSU0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHmggg8pMIIHgjCC
# BWqgAwIBAgITMwAAAAXlzw//Zi7JhwAAAAAABTANBgkqhkiG9w0BAQwFADB3MQsw
# CQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMUgwRgYD
# VQQDEz9NaWNyb3NvZnQgSWRlbnRpdHkgVmVyaWZpY2F0aW9uIFJvb3QgQ2VydGlm
# aWNhdGUgQXV0aG9yaXR5IDIwMjAwHhcNMjAxMTE5MjAzMjMxWhcNMzUxMTE5MjA0
# MjMxWjBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0
# aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcg
# Q0EgMjAyMDCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJ5851Jj/eDF
# nwV9Y7UGIqMcHtfnlzPREwW9ZUZHd5HBXXBvf7KrQ5cMSqFSHGqg2/qJhYqOQxwu
# EQXG8kB41wsDJP5d0zmLYKAY8Zxv3lYkuLDsfMuIEqvGYOPURAH+Ybl4SJEESnt0
# MbPEoKdNihwM5xGv0rGofJ1qOYSTNcc55EbBT7uq3wx3mXhtVmtcCEr5ZKTkKKE1
# CxZvNPWdGWJUPC6e4uRfWHIhZcgCsJ+sozf5EeH5KrlFnxpjKKTavwfFP6XaGZGW
# UG8TZaiTogRoAlqcevbiqioUz1Yt4FRK53P6ovnUfANjIgM9JDdJ4e0qiDRm5sOT
# iEQtBLGd9Vhd1MadxoGcHrRCsS5rO9yhv2fjJHrmlQ0EIXmp4DhDBieKUGR+eZ4C
# NE3ctW4uvSDQVeSp9h1SaPV8UWEfyTxgGjOsRpeexIveR1MPTVf7gt8hY64XNPO6
# iyUGsEgt8c2PxF87E+CO7A28TpjNq5eLiiunhKbq0XbjkNoU5JhtYUrlmAbpxRjb
# 9tSreDdtACpm3rkpxp7AQndnI0Shu/fk1/rE3oWsDqMX3jjv40e8KN5YsJBnczyW
# B4JyeeFMW3JBfdeAKhzohFe8U5w9WuvcP1E8cIxLoKSDzCCBOu0hWdjzKNu8Y5Sw
# B1lt5dQhABYyzR3dxEO/T1K/BVF3rV69AgMBAAGjggIbMIICFzAOBgNVHQ8BAf8E
# BAMCAYYwEAYJKwYBBAGCNxUBBAMCAQAwHQYDVR0OBBYEFGtpKDo1L0hjQM972K9J
# 6T7ZPdshMFQGA1UdIARNMEswSQYEVR0gADBBMD8GCCsGAQUFBwIBFjNodHRwOi8v
# d3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9yeS5odG0wEwYD
# VR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUAYgBDAEEwDwYD
# VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBTIftJqhSobyhmYBAcnz1AQT2ioojCB
# hAYDVR0fBH0wezB5oHegdYZzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9jcmwvTWljcm9zb2Z0JTIwSWRlbnRpdHklMjBWZXJpZmljYXRpb24lMjBSb290
# JTIwQ2VydGlmaWNhdGUlMjBBdXRob3JpdHklMjAyMDIwLmNybDCBlAYIKwYBBQUH
# AQEEgYcwgYQwgYEGCCsGAQUFBzAChnVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20v
# cGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMElkZW50aXR5JTIwVmVyaWZpY2F0aW9u
# JTIwUm9vdCUyMENlcnRpZmljYXRlJTIwQXV0aG9yaXR5JTIwMjAyMC5jcnQwDQYJ
# KoZIhvcNAQEMBQADggIBAF+Idsd+bbVaFXXnTHho+k7h2ESZJRWluLE0Oa/pO+4g
# e/XEizXvhs0Y7+KVYyb4nHlugBesnFqBGEdC2IWmtKMyS1OWIviwpnK3aL5Jedwz
# beBF7POyg6IGG/XhhJ3UqWeWTO+Czb1c2NP5zyEh89F72u9UIw+IfvM9lzDmc2O2
# END7MPnrcjWdQnrLn1Ntday7JSyrDvBdmgbNnCKNZPmhzoa8PccOiQljjTW6GePe
# 5sGFuRHzdFt8y+bN2neF7Zu8hTO1I64XNGqst8S+w+RUdie8fXC1jKu3m9KGIqF4
# aldrYBamyh3g4nJPj/LR2CBaLyD+2BuGZCVmoNR/dSpRCxlot0i79dKOChmoONqb
# MI8m04uLaEHAv4qwKHQ1vBzbV/nG89LDKbRSSvijmwJwxRxLLpMQ/u4xXxFfR4f/
# gksSkbJp7oqLwliDm/h+w0aJ/U5ccnYhYb7vPKNMN+SZDWycU5ODIRfyoGl59BsX
# R/HpRGtiJquOYGmvA/pk5vC1lcnbeMrcWD/26ozePQ/TWfNXKBOmkFpvPE8CH+Ee
# GGWzqTCjdAsno2jzTeNSxlx3glDGJgcdz5D/AAxw9Sdgq/+rY7jjgs7X6fqPTXPm
# aCAJKVHAP19oEjJIBwD1LyHbaEgBxFCogYSOiUIr0Xqcr1nJfiWG2GwYe6ZoAF1b
# MIIHnzCCBYegAwIBAgITMwAAAFr2DWeMhe3dCAAAAAAAWjANBgkqhkiG9w0BAQwF
# ADBhMQswCQYDVQQGEwJVUzEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9u
# MTIwMAYDVQQDEylNaWNyb3NvZnQgUHVibGljIFJTQSBUaW1lc3RhbXBpbmcgQ0Eg
# MjAyMDAeFw0yNjAxMDgxODU5MDNaFw0yNzAxMDcxODU5MDNaMIHjMQswCQYDVQQG
# EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG
# A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQg
# SXJlbGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNT
# IEVTTjo0OTFBLTA1RTAtRDk0NzE1MDMGA1UEAxMsTWljcm9zb2Z0IFB1YmxpYyBS
# U0EgVGltZSBTdGFtcGluZyBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4IC
# DwAwggIKAoICAQDv9DtHlo4FG/a5x3EC0XX1jzeB/vdWt2J5Wj+OhNZuLg/iSsen
# LFjErV+/X8SyVAKhyakFhNfVJTTIUvYxAd9nQCeMrlrB8lLjPnaYYw8+BOY5eIGB
# mRJmjqyrzbfiqpRWssoP6E4NwZS0buGgavOuvAOapR3H7Loeg3UqhSA9YsSRWcx6
# 2RRtYhgRu1NQZ9jjSw6O428F+azHD3bkwFMP3OzN1oUsUAbmaUIs/EUBiiKginyM
# YEJCnc6QqVNElkDhPw4E12893NeSjEQnZBpS9s2/pZ7kleLLHkJt6n5WYmXJC8p9
# sSSPGVw5KviIPm/67DzyHyPHYttvFrytY+uyV6cnlQmklDvRK85S506540JHl1UC
# Ke98blQVa5r6E3/7+GuzJ65riksiF3ObyVBxBgd+OfjvKJhbdcPG/l4PQ/TyiEag
# zxL+x0ZNAvmL8bvBbxyb0qHEiGSvr/xZihToqWJ6T++sgJiTZ8oXrnEoToJPEIlO
# d1Ep//gMjG+8VvdOYGZ8jam9vR3lXUNe+aQxyRhM/AsecIh3lZYhs+YQAbnBQ8pU
# fc9y0k5gevt2biMXhvQWUuOj+gDT5Llbg+ZvMIHOxiy84O9wrAxdPbpLfFH/HU3D
# AV966Pu/5PTOl7fFjxuyC/b/+A78jGNN7ZG/WPUYuh1mr10T2EQlHj7KTwIDAQAB
# o4IByzCCAccwHQYDVR0OBBYEFI5jskOrcDHD9WW0crScSOH515nCMB8GA1UdIwQY
# MBaAFGtpKDo1L0hjQM972K9J6T7ZPdshMGwGA1UdHwRlMGMwYaBfoF2GW2h0dHA6
# Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY3Jvc29mdCUyMFB1Ymxp
# YyUyMFJTQSUyMFRpbWVzdGFtcGluZyUyMENBJTIwMjAyMC5jcmwweQYIKwYBBQUH
# AQEEbTBrMGkGCCsGAQUFBzAChl1odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp
# b3BzL2NlcnRzL01pY3Jvc29mdCUyMFB1YmxpYyUyMFJTQSUyMFRpbWVzdGFtcGlu
# ZyUyMENBJTIwMjAyMC5jcnQwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggr
# BgEFBQcDCDAOBgNVHQ8BAf8EBAMCB4AwZgYDVR0gBF8wXTBRBgwrBgEEAYI3TIN9
# AQEwQTA/BggrBgEFBQcCARYzaHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraW9w
# cy9Eb2NzL1JlcG9zaXRvcnkuaHRtMAgGBmeBDAEEAjANBgkqhkiG9w0BAQwFAAOC
# AgEAgJTPK/rd4SG9odZQ0wMfomJEJcRblO0DjXsiBSAWdvcbxpfKXoSsRKw8yJ4j
# qSF/3pblAMECqGiNM8LigHUdJq0h1wp4jKCzZKOVvua+7FzWpil+0DFdwXxjl94I
# valX8clHuwB126kPCgUBzWApzRbUEB4AEa5WIbcgCqJeXLTNAgHP8t6GO20zLFSb
# 5wObuw1Vj3l6Ek9ihDA3iwbyWKtCCWesjKQzli2eFD/Nm5LMkoSAf13WsIqyBi3b
# Hrna8kcVTJN9d5gHIxkW+ffiLbbeqLVb2EFqh/jxq01MxHHs/GkLjt7pqDWYyrha
# F+VbDz/4EmbHvqK4Rt832ZPSA8hNw31Ba4b5L+h9LYoytQ9LiBocDAVkpvZLUOqH
# lPmrq2RcdzCPizg5x7G0RWQMtdbjL8CqvmTQtUnuLSDNbvaYlgIZ0z6IeplCyopB
# zlYR2jved7ZMwwrY7LHuRlCjsfcoPZ6hyljIJzg6etv7jz8wv8gxCEq1wnFO1Ae7
# QE6981jRHbTOHdNPYl1iOnVf0nXCCF+OK6aC8gi8Pp148afn2P3coCzu1HUkGlWl
# BVY9ytp1crroz7KbeS7p3ORb7mD6pov8/JAEppsG4hfltD9FE1hWgvODFn1NoejA
# 4ObNKMZnTRSu+o1698GX3UqFexQin6uRnXhqMuVMA0MDAtAxggPUMIID0AIBATB4
# MGExCzAJBgNVBAYTAlVTMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x
# MjAwBgNVBAMTKU1pY3Jvc29mdCBQdWJsaWMgUlNBIFRpbWVzdGFtcGluZyBDQSAy
# MDIwAhMzAAAAWvYNZ4yF7d0IAAAAAABaMA0GCWCGSAFlAwQCAQUAoIIBLTAaBgkq
# hkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIEIA9ja7G/Bc6S
# skFaIV5vuab3sUWd12ZXnCkPcunzOm0LMIHdBgsqhkiG9w0BCRACLzGBzTCByjCB
# xzCBoAQgYrlkQIvqfej0bAbd08Ft4zaM4D0EvkHKNQlZvzWlNEMwfDBlpGMwYTEL
# MAkGA1UEBhMCVVMxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEyMDAG
# A1UEAxMpTWljcm9zb2Z0IFB1YmxpYyBSU0EgVGltZXN0YW1waW5nIENBIDIwMjAC
# EzMAAABa9g1njIXt3QgAAAAAAFowIgQg+WAS4SwaycwaUND05QdnGKhtWmC4cypY
# iiE+N8HVkVwwDQYJKoZIhvcNAQELBQAEggIAadL4++jc/qrTQSb4fjcrjh54ekmw
# 4lYty7CFa5FLK2nUJ8WCuX0vsM4mzC1Z0yZPi293wkKNGgQiQfmIy3o0u5NVTvLi
# DMw4tPfzaw4L5oyTVuuJP5HCohaX4lBV5+p08ccxgIV9sy/a3NztofemSdawejuc
# +ye8wy6ybv90mBdsJEi0few8kfG/cvG//pZk3fc0gN94quD3vPo0HobD/nHqxvCx
# aY31JI2eXFRKdlqg/+3w7BzyVPRqjKiFuV12L8EaPpwv2NeeiKigadb6dSa9bpPC
# VCRgXdpOG5EKhdYGWdJuaLiyTr5rseIMaZ2WPdHKZWPimqRb3hByOZNyjPLTqiZW
# EeAMvw33y9gWy9LiFjR7mT+ZvHJt1A5lR4u68Apb5y9FDjGgurXbB8BvW51V9ecQ
# OZ9t44zmJYoDrqnUC/WGsV+uO79ZceJFmrptFiSvo1vKxuSOuiVe5/KTNEFDIPTY
# PdJf1+Yd9Gpdmx5jG+qcN7lVm/BVgvmZ2+qeiH+yWRcZxGDQCQ9YtJZKHMd4lj+9
# fHrOfaoNhmlIz6hyktGaZKrFRz1HrB7cUni5WJVWd87PpCJm6+ttXhKC1ZCsyemT
# 5xTaawd2+xp40YeXGAtA7SPTCeYuW8KG2n84K5Q8pmGUqF1GqvbvIhUPBxZ4WtD5
# ELT6IcbWwarF8ks=
# SIG # End signature block