From dd1299e1d6d7a55b21eefdfb2581e50c5481a556 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=AA=20Khang?= <111333721+neyfua@users.noreply.github.com> Date: Mon, 3 Aug 2026 19:27:34 +0700 Subject: [PATCH] feat(obs-integration): add OBS integration plugin (#210) * feat(obs-integration): add OBS integration plugin * docs(obs-integration): add README.md * chore(obs-integration): rename obs-integration-thumbnail.webp to thumbnail.webp * i18n(obs-integration): fix PR check * fix(obs-integration): honor selected rebuild architecture * fix(obs-integration): reject dot-prefixed names in validName * fix(obs-integration): treat empty checkout_dir as unset * feat(obs-integration): add repo/arch rebuild selection with confirmation * chore(obs-integration): add opensuse tag to plugin.toml * chore(obs-integration): new thumbnail * fix(obs-integration): fix rebuild controls inheriting flexGrow from reused nodes * feat(obs-integration): overhaul package actions, logging, and navigation * chore(obs-integration): new thumbnail * feat(obs-integration): label Service Run All button, move build logs * fix(obs-integration): split logs based on action source * fix(obs-integration): correct log display locations and resets * feat(obs-integration): add confirmation to remove file * feat(obs-integration): move edit package meta to header * fix(obs-integration): layout repo/arch label/select alignment * fix(obs-integration): clean rebuild log duplication * fix(obs-integration): persist logSource in nav state for panel reopen * i18n(obs-integration): change 'Repo' to 'Repositories' and 'Arch' to 'Architectures' * feat(obs-integration): add home nav button, fix header label clipping, rebuild controls layout * chore(obs-integration): change plugin's panel height * docs(obs-integration): document source-service operations in README * fix(obs-integration): correct rebuild log display and persistence, sync UI layout --------- Co-authored-by: neyfua --- obs-integration/README.md | 95 ++ obs-integration/panel.luau | 1498 ++++++++++++++++++++++++++ obs-integration/plugin.toml | 36 + obs-integration/thumbnail.webp | Bin 0 -> 47524 bytes obs-integration/translations/en.json | 69 ++ obs-integration/widget.luau | 46 + 6 files changed, 1744 insertions(+) create mode 100644 obs-integration/README.md create mode 100644 obs-integration/panel.luau create mode 100644 obs-integration/plugin.toml create mode 100644 obs-integration/thumbnail.webp create mode 100644 obs-integration/translations/en.json create mode 100644 obs-integration/widget.luau diff --git a/obs-integration/README.md b/obs-integration/README.md new file mode 100644 index 0000000..d2abe5c --- /dev/null +++ b/obs-integration/README.md @@ -0,0 +1,95 @@ +# OBS Integration + +Manage openSUSE Build Service projects and packages from Noctalia. The bar +widget toggles a panel for browsing your projects, checking out packages, +editing metadata and files, and triggering rebuilds on OBS — without leaving +the shell. + +## Plugin + +| Field | Value | +| --- | --- | +| ID | `neyfua/obs-integration` | +| Entries | Bar widget: `obs-integrate`; panel: `panel` | + +## Requirements + +Install the openSUSE Build Service `osc` CLI on `PATH` and configure your +credentials in `~/.config/osc/oscrc` (for example with `osc apiservice` setup +or by copying a working `oscrc`). The plugin shells out to `osc` for every +operation, so all authentication stays in your normal OBS configuration. + +## Usage + +Add the `obs-integrate` widget to a bar. Left-click it to open the panel. + +Open the panel directly with: + +```sh +noctalia msg panel-toggle neyfua/obs-integration:panel +``` + +### My Projects + +The panel opens on **My Projects**: every project you maintain, plus every +project where you are listed as a package maintainer on OBS. Search filters the +list, and the sort button toggles A-Z / Z-A order. The pen icon edits the +project metadata (`osc meta prj -e`). + +### Inside a project + +Click a project to list its packages. A package's icon turns **primary** when +that package is checked out in your local directory. Click a package to open +its actions: + +- **Checkout package** — `osc co` in the configured checkout directory + (hidden once the package is already checked out). +- **Edit files** — expandable list of editable sources: `_service` and the + package's `.spec` open in your `$EDITOR`; the `.changes` file runs + `osc vc`. +- **Files** — lists every non-dotfile in the checkout. Each file has a remove + button; below the list, **Add/Remove** runs `osc ar` asynchronously in the + panel. **Commit** runs `osc status` first; if pending changes exist it + opens a terminal with `osc ci` so you can edit the commit message, otherwise + the commit runs asynchronously in the panel. +- **Service Local Run** — runs `osc service r` in the checkout, executing the + package's source-service scripts locally (local side effects: the `_service` + scripts can modify files in the checkout). +- **Service Manual Run** — runs `osc service mr` in the checkout, running the + source-service scripts locally in "manual" mode (local side effects, like + Service Local Run). +- **Service Run All** — runs `osc service ra` in the checkout, running all + source-service scripts locally. Requires a confirmation click (turns + **secondary** with a **check** glyph) before it executes. +- **Service Remote Run** — runs `osc service rr` on the OBS server for the + package on the remote project. No local code executes; the request triggers + server-side service runs, and a confirmation is not required. +- **Rebuild package** — pick an architecture (or **All**) and trigger + `osc rebuild`. Confirmation is required before it runs. +- **Edit package meta** — `osc meta pkg -e` in a terminal. +- **Remove package** — deletes the checkout from disk only (never touches the + OBS project); confirm before it runs. If it was the last package in the + project directory, the directory is removed too. + +### Sticky navigation + +The panel reopens where you left off — inside the same project or package. + +## Settings + +| Setting | Type | Default | Description | +| --- | --- | --- | --- | +| `checkout_dir` | `string` | `~/OBS` | Base directory where packages are checked out. Packages land in `//`. | +| `show_label` | `bool` | `false` | Show the "OBS" label next to the bar icon. | + +## Notes + +The plugin runs the `osc` CLI with your existing credentials — it stores +nothing itself beyond a small cache of project/package listings and your last +navigated view. Removal is local-only and never modifies the OBS project. +Most operations (rebuilds, service runs, updates, add/remove) run +asynchronously and display their output directly in the panel. The Commit +operation opens a terminal only when `osc status` reports pending changes; +otherwise, it runs asynchronously in the panel. Confirmation prompts precede +destructive and side-effecting operations: Rebuild package, Remove package, +and Service Run All. diff --git a/obs-integration/panel.luau b/obs-integration/panel.luau new file mode 100644 index 0000000..42fd196 --- /dev/null +++ b/obs-integration/panel.luau @@ -0,0 +1,1498 @@ +--!nonstrict + +local OSC_CONFIG = noctalia.expandPath("~/.config/osc/oscrc") +local CACHE_FILE = "projects_cache.json" +local NAV_FILE = "nav_state.json" + +local projects = {} +local packages = {} +local selectedProject = nil +local selectedPackage = nil +local packageFilter = "" +local projectFilter = "" +local sortAsc = true +local editFilesOpen = false +local filesOpen = false +local filesPackage = nil +local packageFiles = {} +local rebuildArchIndex = 0 +local rebuildRepos = {} +local rebuildRepoIndex = 0 +local rebuildConfirm = false +local runAllConfirm = false +local repoMap = {} +local savedRebuildRepo = nil +local savedRebuildArch = nil +local rebuildLoaded = false +local isCheckingOut = false +local checkoutLog = "" +local isActionLoading = false +local actionStatus = "" +local logSource = "" +local loadPackageFiles +local resolveCheckoutDir +local maintainerMap = {} +local ownedProjects = {} +local projectsLoading = false +local packagesLoading = false +local errorText = "" +local commandLog = "" +local logPackage = nil +local pendingProject = nil +local removeConfirm = false +local removeFileConfirm = false +local removeFileTarget = nil +local restoreProject = nil +local restorePackage = nil +local restoreFilesOpen = false +local restoreFilesPackage = nil +local restoreCommandLog = nil +local restoreErrorText = nil +local restoreLogSource = nil +local saveCache +local saveNav +local maybeVerify + +local ownedDone = false +local oscUser = nil +local oscWhoPending = false + +local function shellQuote(value) + return "'" .. tostring(value):gsub("'", "'\\''") .. "'" +end + +local function commandError(result) + return noctalia.string.trim(result.stderr ~= "" and result.stderr or result.stdout) +end + +local function setCommandLog(result, refreshFiles, emptyMsg) + local err = commandError(result) + if result.exitCode ~= 0 then + errorText = err ~= "" and err or ("Command failed (exit " .. tostring(result.exitCode) .. ")") + commandLog = "" + else + errorText = "" + commandLog = noctalia.string.trim(result.stdout) + if commandLog == "" and emptyMsg then + commandLog = emptyMsg + end + if refreshFiles then + local checkoutDir = resolveCheckoutDir() + loadPackageFiles(checkoutDir .. "/" .. selectedProject .. "/" .. selectedPackage, selectedPackage) + end + end + logPackage = selectedPackage + render() + saveNav() +end + +local function showCommandLog(result) + setCommandLog(result, false) +end + +local function runActionAsync(cmd, statusText, refreshFiles, pkgDir, pkg, emptyMsg, source) + isActionLoading = true + actionStatus = statusText + logSource = source or "" + errorText = "" + commandLog = "" + render() + noctalia.runAsync(cmd, function(result) + isActionLoading = false + if refreshFiles and result.exitCode == 0 then + local dir = pkgDir + if not dir then + local checkoutDir = resolveCheckoutDir() + dir = checkoutDir .. "/" .. selectedProject .. "/" .. selectedPackage + end + loadPackageFiles(dir, pkg or selectedPackage) + end + setCommandLog(result, false, emptyMsg) + end, 60000) +end + +-- OBS project/package identifiers: reject anything that could escape the +-- checkout dir or inject into shell commands (slashes, leading dots, spaces). +local function validName(value) + return type(value) == "string" + and value ~= "" + and not value:find("/", 1, true) + and value:match("^[%w:.+%-_]+$") ~= nil + and value:match("^%.") == nil +end + +resolveCheckoutDir = function() + local checkoutDir = noctalia.getConfig("checkout_dir") + if type(checkoutDir) ~= "string" or checkoutDir:match("^%s*$") then + checkoutDir = "~/OBS" + end + return noctalia.expandPath(checkoutDir) +end + + +-- Estimate the combined width (px) of the two .changes buttons to decide +-- whether they fit side-by-side or must stack. +local function changesButtonsFit(pkg) + -- Rough per-char width at the button font size, plus glyph+padding budget. + local charW = 7 + local base = 16 + 24 + local editW = (#"Edit " + #pkg + #".changes") * charW + base + local updateW = (#"Update " + #pkg + #".changes") * charW + base + return editW + updateW + 8 <= 396 +end + +local function parseLines(stdout) + local out = {} + for line in tostring(stdout or ""):gmatch("[^\n]+") do + line = noctalia.string.trim(line) + if line ~= "" then + table.insert(out, line) + end + end + return out +end + +local function filterList(list, filter, ascending) + local lower = filter:lower() + local filtered + if filter == "" then + filtered = list + else + filtered = {} + for _, name in ipairs(list) do + if name:lower():find(lower, 1, true) then + table.insert(filtered, name) + end + end + end + table.sort(filtered, function(a, b) + if ascending then + return a < b + else + return a > b + end + end) + return filtered +end + +local function configureOsc() + noctalia.runInTerminal("osc version") +end + +local function checkoutPackage(project, pkg) + if not validName(project) or not validName(pkg) then + return + end + local checkoutDir = resolveCheckoutDir() + local pkgPath = checkoutDir .. "/" .. project .. "/" .. pkg + isCheckingOut = true + checkoutLog = noctalia.tr("panel.checking_out") + render() + + noctalia.runAsync( + "cd " .. shellQuote(checkoutDir) .. " && osc co " .. shellQuote(project) .. " " .. shellQuote(pkg), + function(result) + isCheckingOut = false + if result.exitCode == 0 then + errorText = "" + loadPackageFiles(pkgPath, pkg) + else + errorText = commandError(result) + end + render() + saveNav() + end, + 60000 + ) +end + +local function editProjectMeta(project) + if not validName(project) then + return + end + noctalia.runInTerminal("osc meta prj " .. shellQuote(project) .. " -e") +end + +local function editPackageMeta(project, pkg) + if not validName(project) or not validName(pkg) then + return + end + noctalia.runInTerminal("osc meta pkg " .. shellQuote(project) .. " " .. shellQuote(pkg) .. " -e") +end + +local function rebuildPackage(project, pkg, repo, arch) + if not validName(project) or not validName(pkg) then + return + end + local cmd = "osc rebuild " .. shellQuote(project) .. " " .. shellQuote(pkg) + if repo ~= nil and repo ~= "All" and repo ~= "" then + cmd = cmd .. " -r " .. shellQuote(repo) + end + if arch ~= nil and arch ~= "All" and arch ~= "" then + cmd = cmd .. " -a " .. shellQuote(arch) + end + runActionAsync(cmd, noctalia.tr("panel.rebuilding_pkg"), false, nil, nil, nil, "rebuild") +end + +loadPackageFiles = function(pkgDir, pkg) + noctalia.runAsync( + "find " .. shellQuote(pkgDir) .. " -maxdepth 1 -not -name '.*' -printf '%f\\n'", + function(result) + local list = {} + if result.exitCode == 0 then + for _, f in ipairs(parseLines(result.stdout)) do + if f ~= pkg and f ~= ".osc" then + table.insert(list, f) + end + end + end + table.sort(list) + packageFiles = list + render() + end, + 5000 + ) + -- Re-fetch after a short delay so callers that just created the dir (checkout, + -- osc up, service runs) settle into the complete file list. + noctalia.runAsync("sleep 1", function() + noctalia.runAsync( + "find " .. shellQuote(pkgDir) .. " -maxdepth 1 -not -name '.*' -printf '%f\\n'", + function(result) + local list = {} + if result.exitCode == 0 then + for _, f in ipairs(parseLines(result.stdout)) do + if f ~= pkg and f ~= ".osc" then + table.insert(list, f) + end + end + end + table.sort(list) + packageFiles = list + render() + end, + 5000 + ) + end, 2000) +end + +local function loadRebuildArches(project, pkg) + rebuildLoaded = false + noctalia.runAsync("osc results " .. shellQuote(project) .. " " .. shellQuote(pkg), function(result) + local map = {} + if result.exitCode == 0 then + for line in tostring(result.stdout):gmatch("[^\n]+") do + line = noctalia.string.trim(line) + local repo, arch, _, status = line:match("^(%S+)%s+(%S+)%s+(%S+)%s+(%S+)") + if repo ~= nil and arch ~= nil and status ~= "disabled" then + if not map[repo] then + map[repo] = {} + end + local found = false + for _, a in ipairs(map[repo]) do + if a == arch then + found = true + break + end + end + if not found then + table.insert(map[repo], arch) + end + end + end + end + local repos = {} + for repo in pairs(map) do + table.insert(repos, repo) + end + table.sort(repos) + for repo in pairs(map) do + table.sort(map[repo]) + end + repoMap = map + rebuildRepos = repos + local repoIndex = 0 + if savedRebuildRepo then + for i, repo in ipairs(repos) do + if repo == savedRebuildRepo then + repoIndex = i + break + end + end + end + rebuildRepoIndex = repoIndex + local archIndex = 0 + local repoArchs = savedRebuildRepo and map[savedRebuildRepo] or {} + if savedRebuildArch then + for i, arch in ipairs(repoArchs or {}) do + if arch == savedRebuildArch then + archIndex = i + break + end + end + end + rebuildArchIndex = archIndex + rebuildLoaded = true + render() + end, 15000) +end + +local function removeFileLocal(path, pkgDir, pkg) + noctalia.runAsync("rm " .. shellQuote(path), function(result) + if result.exitCode == 0 then + loadPackageFiles(pkgDir, pkg) + else + errorText = commandError(result) + render() + end + end, 15000) +end + +local function editFilePlain(path) + noctalia.runInTerminal("${EDITOR:-nano} " .. shellQuote(path)) +end + +local function editFile(path, pkgDir, pkg, filename) + if not validName(pkg) then + return + end + if filename:match("%.changes$") then + noctalia.runInTerminal("cd " .. shellQuote(pkgDir) .. " && osc vc") + else + editFilePlain(path) + end +end + +local function oscAddRemove(pkgDir) + runActionAsync( + "cd " .. shellQuote(pkgDir) .. " && osc ar", + noctalia.tr("panel.adding_removing"), + true, + pkgDir, + nil, + noctalia.tr("panel.no_changes", { name = selectedPackage }) + ) +end + +local function oscCommit(pkgDir) + local cmd = "cd " .. shellQuote(pkgDir) .. " && osc ci" + isActionLoading = true + actionStatus = noctalia.tr("panel.committing") + logSource = "" + errorText = "" + commandLog = "" + render() + noctalia.runAsync("cd " .. shellQuote(pkgDir) .. " && osc status", function(result) + local output = result.stdout .. "\n" .. result.stderr + local hasChanges = result.exitCode == 0 and noctalia.string.trim(output) ~= "" + isActionLoading = false + if hasChanges then + noctalia.runInTerminal(cmd) + else + noctalia.runAsync(cmd, showCommandLog, 60000) + end + end, 15000) +end + +local function oscUpdate(pkgDir) + runActionAsync( + "cd " .. shellQuote(pkgDir) .. " && osc up", + noctalia.tr("panel.updating_dir"), + true, + pkgDir + ) +end + +local function oscServiceRun(pkgDir) + runActionAsync( + "cd " .. shellQuote(pkgDir) .. " && osc service mr", + noctalia.tr("panel.running_manual_service"), + true, + pkgDir + ) +end + +local function oscServiceRemoteRun(project, pkg) + runActionAsync( + "osc service rr " .. shellQuote(project) .. " " .. shellQuote(pkg), + noctalia.tr("panel.running_remote_service"), + false + ) +end + +local function oscServiceLocalRun(pkgDir) + runActionAsync( + "cd " .. shellQuote(pkgDir) .. " && osc service r", + noctalia.tr("panel.running_local_service"), + true, + pkgDir + ) +end + +local function oscServiceRunAll(pkgDir) + runActionAsync( + "cd " .. shellQuote(pkgDir) .. " && osc service ra", + noctalia.tr("panel.running_all_services"), + true, + pkgDir + ) +end + +local function removePackageLocal(project, pkg) + if not validName(project) or not validName(pkg) then + return + end + local checkoutDir = resolveCheckoutDir() + local projectDir = checkoutDir .. "/" .. project + local pkgDir = projectDir .. "/" .. pkg + local cmd = "rm -rf " .. shellQuote(pkgDir) + .. "\nif ! ls -A " .. shellQuote(projectDir) .. " | grep -q -v '^\\.osc$'; then rm -rf " .. shellQuote(projectDir) .. "; fi" + noctalia.runAsync(cmd, function(result) + if result.exitCode ~= 0 then + errorText = commandError(result) + end + selectedPackage = nil + removeConfirm = false + render() + saveNav() + end, 15000) +end + +local function loadPackages(project) + selectedProject = project + selectedPackage = nil + packageFilter = "" + editFilesOpen = false + filesOpen = false + packageFiles = {} + removeConfirm = false + rebuildConfirm = false + runAllConfirm = false + isCheckingOut = false + checkoutLog = "" + isActionLoading = false + actionStatus = "" + logSource = "" + packages = maintainerMap[project] or {} + + if #packages == 0 and projectsLoading then + pendingProject = project + packagesLoading = true + render() + return + end + + if #packages == 0 and ownedProjects[project] then + packagesLoading = true + render() + noctalia.runAsync("osc ls " .. shellQuote(project), function(result) + packagesLoading = false + if result.exitCode == 0 then + packages = parseLines(result.stdout) + maintainerMap[project] = packages + saveCache() + errorText = "" + elseif errorText == "" then + errorText = commandError(result) + end + render() + end, 15000) + saveNav() + return + end + + packagesLoading = false + errorText = "" + render() + saveNav() +end + +local function cachePath() + local dir, _ = noctalia.pluginDataDir() + if not dir then + return nil + end + return dir .. "/" .. CACHE_FILE +end + +local function navPath() + local dir, _ = noctalia.pluginDataDir() + if not dir then + return nil + end + return dir .. "/" .. NAV_FILE +end + +saveNav = function() + local path = navPath() + if not path then + return + end + noctalia.writeFile(path, noctalia.json.encode({ + project = selectedProject, + package = selectedPackage, + filesOpen = filesOpen, + filesPackage = filesPackage, + commandLog = commandLog, + errorText = errorText, + logSource = logSource, + })) +end +local function readNav() + local path = navPath() + if not path or not noctalia.fileExists(path) then + return nil, nil, false, nil, nil, nil + end + local data, _ = noctalia.readFile(path) + if not data then + return nil, nil, false, nil, nil, nil + end + local parsed, _ = noctalia.json.decode(data) + if type(parsed) ~= "table" then + return nil, nil, false, nil, nil, nil + end + return parsed.project, parsed.package, parsed.filesOpen == true, parsed.filesPackage, parsed.commandLog, + parsed.errorText, parsed.logSource +end + +saveCache = function() + local path = cachePath() + if not path or #projects == 0 then + return + end + local ownedList = {} + for project in pairs(ownedProjects) do + table.insert(ownedList, project) + end + noctalia.writeFile(path, noctalia.json.encode({ + owned = ownedList, + packages = maintainerMap, + })) +end + +local function prefetchOwnedPackages() + for project in pairs(ownedProjects) do + if not maintainerMap[project] then + noctalia.runAsync("osc ls " .. shellQuote(project), function(result) + if result.exitCode == 0 and not maintainerMap[project] then + local list = parseLines(result.stdout) + maintainerMap[project] = list + saveCache() + if selectedProject == project then + packages = list + packagesLoading = false + errorText = "" + render() + end + end + end, 15000) + end + end +end + +local function readCache() + local path = cachePath() + if not path or not noctalia.fileExists(path) then + return false + end + local data, _ = noctalia.readFile(path) + if not data then + return false + end + local parsed, _ = noctalia.json.decode(data) + if type(parsed) ~= "table" then + return false + end + local cachedPkgs = parsed.packages + local cachedOwned = parsed.owned + if type(cachedPkgs) ~= "table" or type(cachedOwned) ~= "table" then + return false + end + for key, list in pairs(cachedPkgs) do + if type(key) ~= "string" or type(list) ~= "table" then + return false + end + end + maintainerMap = cachedPkgs + ownedProjects = {} + for _, project in ipairs(cachedOwned) do + ownedProjects[project] = true + end + projects = {} + local seen = {} + for project in pairs(maintainerMap) do + projects[#projects + 1] = project + seen[project] = true + end + for project in pairs(ownedProjects) do + if not seen[project] then + projects[#projects + 1] = project + end + end + table.sort(projects) + return true +end + +local function finalize() + local merged = {} + for project in pairs(ownedProjects) do + merged[project] = true + end + for project in pairs(maintainerMap) do + merged[project] = true + end + projects = {} + for project in pairs(merged) do + table.insert(projects, project) + end + table.sort(projects) + + saveCache() + + local deferred = pendingProject + pendingProject = nil + projectsLoading = false + if deferred then + loadPackages(deferred) + return + end + render() + prefetchOwnedPackages() +end + +local function loadProjects(clearNav) + readCache() + + selectedProject = nil + selectedPackage = nil + packages = {} + projectFilter = "" + pendingProject = nil + projectsLoading = true + errorText = "" + ownedDone = false + oscUser = nil + oscWhoPending = false + + if restoreProject then + local proj = restoreProject + local pkg = restorePackage + local filesOpenRestore = restoreFilesOpen + local filesPackageRestore = restoreFilesPackage + restoreProject = nil + restorePackage = nil + restoreFilesOpen = false + restoreFilesPackage = nil + if proj and (maintainerMap[proj] or ownedProjects[proj]) then + projectsLoading = false + loadPackages(proj) + if pkg then + selectedPackage = pkg + filesOpen = filesOpenRestore + filesPackage = filesPackageRestore + if restoreCommandLog ~= nil then + commandLog = restoreCommandLog + end + if restoreErrorText ~= nil then + errorText = restoreErrorText + end + if restoreLogSource ~= nil then + logSource = restoreLogSource + end + render() + saveNav() + loadRebuildArches(proj, pkg) + if filesOpen then + local checkoutDir = resolveCheckoutDir() + loadPackageFiles(checkoutDir .. "/" .. proj .. "/" .. pkg, pkg) + end + return + end + end + end + + render() + if clearNav then + saveNav() + end + + noctalia.runAsync("osc search --project --maintainer --csv", function(result) + if result.exitCode == 0 then + ownedProjects = {} + for _, line in ipairs(parseLines(result.stdout)) do + ownedProjects[line] = true + end + end + ownedDone = true + maybeVerify() + end) + + if oscUser == nil then + oscWhoPending = true + noctalia.runAsync("osc who | cut -d: -f1", function(userResult) + if userResult.exitCode == 0 then + oscUser = noctalia.string.trim(userResult.stdout) + else + oscUser = "" + local err = commandError(userResult) + if err ~= "" then + errorText = err + end + end + oscWhoPending = false + maybeVerify() + end, 15000) + end +end + +maybeVerify = function() + if not ownedDone then + return + end + + if oscWhoPending then + return + end + + if oscUser == nil then + finalize() + return + end + + if oscUser == "" then + finalize() + return + end + + local url = "/search/package_id?match=person/@userid='" .. oscUser .. "' and person/@role='maintainer'" + noctalia.runAsync("osc api " .. shellQuote(url), function(verifyResult) + if verifyResult.exitCode == 0 then + maintainerMap = {} + for line in tostring(verifyResult.stdout):gmatch("[^\n]+") do + local project, name = line:match("z(QfdP6h^nElhJ6wGJ@LFxhc3H99ovF)#>BoAzL3^QQZ8 zIS2lq%YVuf8xq-QCtm(h_S5=zw;9rdE9XysyZdln_>b>j>)-#o_rLXr;*RK|9=0^TCRGRf4~20e_Q{r{r&$N?0@$M@c)Yc|F^+b|Ih9J{$KkK=ii*a z`oH$C^*{Rm&i~8))4sJ{?3e$G`*-dA|F8eQ=D++8#*X^gzmI*<|8f0l{;c}EzY+gV z{#X7p|Mvf1`>*~}`FFQ|@z3-t^^f_Vp1-00aQ>0~v+5)N{rv0w>;0epPqQoQ7Rt@~ zQ~zuExBM^hclU3tfBoP6>+!GkSL{XpN&dS2_x#7-f9!AYe>nfR{?h*K|GWNu{+s=u z{}=y(`cIWgwYUH7|GU0G{;~Y&{X71b{uljM{(Jua{_XnD|DUbz{BQX0^dJ8J>$~h{ z*XRD%|HuEA{kQ-7`v3M1>zeAt{`vl0{oDP={V(x%>VMbo{5}2u;&;s7*8i8^S^nz& zZ~b%m_don>xAJ)LB0i$4`<<97zq0J2#`0^a;%#eheeyb~bW-N-huel8e_jf2_n8#? z`1yvXQ;z23yxO_op!TE(`mPT?F-b1&;Cj03T1VFDqF?(onggni-@dN;KVSG>lGb#w zKf8CyIxl_s)8BEcslwfIqu=j7>nm9*sHI$6&if%~Tkr2qiB6R&;Y|0l@yqV$EMX8m zK6mn|xM{zyt}UIi|G&@qIUg_2oVvuNv0BRf=FVGl91EhWJO8dZ+j(dGv$y`c^#@}|4MThm@{OYUxZe^vd*Y)2CFK?9Eow9yXQ%KzBpt&CYc2C<) z)u%3tG-eam;17NgeEUh;ws!~b#RgU!HNE5fr?DdM!;y&R5gUwNzHQQYQMK&Ca~1W1 zsux11c684FFT*r@-vM5YtW6!V_l4GN&QL1towTCjZ{23T^B2!9OU?Q+t-h0~t}yjy zwWQM9-CZ6!|8JU!A8X~wS8V>a?^~s1mn(zz zZDC$J^^YFhGvxxLJv`Jx514E}AzNa0Zo!R*RzKdpJ;!sp!~gkWZ--M+@vNsWM{V1G zKVVm1<{0-R#^aC8tmAGOsef0#Z2d`P2a6otlR#?TwLUk>iQc+$EVjnYUW9q#+_1fMn$ndxZ=7Z@4*@-)rRJ^ zayw^lTt3b2`Scd=_`kgJkuP{XiZ{Exz0~ac`1QG5+45LH!>WdelCU}RY?==}v5c>J zloB!_V6t!X@hxgK=kj=$fBIFJWqgO9k@wS-=3gR}1`DRon{cf8)tczzhSn|pi5v%7 z)xTy3&p0tHSxL0s?a}$ib3RB3+DQ3ba0<-hp8xc{#EJ+a;J{8aI=O93_=f?DBivu)M}THL)BVR0&X z#$w0ISud7cDqS7BsblMjtB1Y!Kbx~Z*Vdr)JRO~;B0US!W_7s*Z1$L06RIHm`=%d%Bu{4nkt zKk7W&k1F=9EbIR|`PcHg50hL~n?)zilX9N)x<#*9o$;nnmZqfB8SA|+4yvw-oYpdj zb}wwQ&gU`YWZe+cWHfQwq6;yPbC|YF(9-I=s2}&`ZrYaLo*yl@n`w%ldYh0{(~y>W zEBCm`+wB6o7ZmU^8qH#sW0`qwTzsuCcBU=^Qyz=xhy|x zh{ewDiQ+tGTN3==-ZSxSs(XQ#e(Ai3=IyWqc)ApG1Dk3^51t+-0{0v<4pCm>X**7dEAct8eawsVg#f1?vgLb-$B} zR6nrWJ!t0Zv(~I<6pmDH{`6Hd`IJ!H&rqXpjlLf&nxuVA4vK%)&u4lNU-69bm#W~W zx=-m3s*|V0iuPS!_@?Kp?2{k=}r!LNLOaoq;*$$`SFgx0<} zaIN&fa;f~%qdcy=lk-299O92$b@`z_>!FJxx?V3%U$a_fzq$3;w+UwzIWod(8?3ih z*k{~S`4h54LTO3XAJwz3G$ozR>WfWIm-&7=B$DIHky74^${!a-fB$}H;S<|ieO-CC zxBgLVN?7msa+l2iShY#Q5`HIb+q54}w__~--2Ue8WW(aOCyrfv!EY7*B%uC-I`bVr zJ7*?YB{9WU!Pi6Bj%sYWH*5Ol3bDI)G$vXdST6MaT=kqQj)twXvNYK)zdhd)I{j=3 z$GR1>i+n}>R?mOA{*r`oiPhY{qMt9+TfQpu=f1RHnTS&HEvN2+4=E-~{_|){Y`;?Q z(X?Rhjm7U)sLj*N2^EVEJ(Sk4?y7A?y^>Fc>ZEAjZB+|CAL|OK5m=D^!?ssL+*oAY z$GZxJivCOQZGYBRGW-98n-2SC#W(KUrZxTMp2DeNyS~oiogKf%bx!V~+f#p^jauWh zFD-VO%J;mIt2;H@)Rr7QGim;+fa%h+rheVoCGp^P^Z&0ezsFbePFwMMi5;VsTeIBP z6O&T7H%J`}R=C+DeAU-IV`psHlOK+9VoJ7)-ewov-Y9%Af2!+;+*bD;temVns^gWV zzcZEV9*(FqXDW9T)N)Ag47BMf@%h}v)Xiz2`a3D^{~GBfdpy~M{hla&T%XQi6Ju`| z;&Y;RMajI5BQNIWH)`K8=U_SadDb+(bdl?m4L@(wux-sT*zUXSMZI`(Ld15VRVL4q zBo(_8cqjSi9(_3@wOF3#!kj0^+yZ%cPdnZ(fBy9NOo@jQl3rrD2Ah3dmDN`*ezzg} z!;P>D>wYlX+NgY-tD0_mtc3G>1f6yF#p8OZ3q7CR6OzJSnaj*hy2Zol3UyU*>MznKK62o&gDS& z$IM51HzpSv+V?G=d{5%qt4kvF_uO(%KRUZ>=KFWcm))GIZnAFwUcIGNQfq(Og?s-# z7yG2+ii;Kd1efN3L~WZ1)!GWv9wpV=XRmlf5FP%f4oZEgQT5j&$o^@`&BBiCxJb7;)jDgLiG%-4UvD;JsDb$b~5iw zX*wJ8urBIHyNHX?wdhF|mzoW=@}?D*p12?4G(~1hME{Z>a^0EVw9KBJc=T?^roHP` zyCYs-dwTh~`L@_p7gJfyaErvl;4&4Ji@7u@{sMn@mAz<|$C}Vi?}e=Df?1LoaffdoJRl@rvuOKgm%m>! zT_4RdX5M)5jPR_#Zu=fEZh4{SQ+9myGz(jfTL(niYVUujes)WxLa^84qU=wm&#ygJ zPt{Z8E=*hW=Gl$7))_UK>w@kdH{*ZW%J7e;aLJ0Z-aNKv_J7`fPIYI4#iuOE+3VWm z5}U1_T~Exs{oE{PlbvjXSU(qUpx6HCe1%!MS1;IH5k9cD{&>Q1E6K{mJfT*uEtwaV zCZ+AIHJ>2dGRbHAwrKacv(IG580~V|`J=eVz+A$#N$cM2_ihf2ZlRZ>7u@UFbMa-= zq{)4)r&Twqea@d^;P>B4HOji-w!>1krJtABT4|=YF1!C~`ijm+&Jt(NCOAs1xq0q* zf5~n~#(CVWEBhGhU)pFCa2zzf%{VPc;-H*u+2ZDGk*D(MNv`?66IiTb<5!1DsIHX~ z;B@Qb+x=ihQLwoGegOfGql`QY>$PnduQERQ;&A<{+xq90{jNW4TlDNJrpM2n9aeF) z>FfLL{2rf{9K7bQ>D;v9(f8k-|Ln4BoVzEBPS!MgqmpIZc$#arS)R+W`Eq-`MXpU~ z_Ww3_&fA&dAAZja`?In*`?Ji{Nf*v;TqE|Noj1@kw!ZqrZ{c=E?NbWBn`_@Y>}+zJ zdiY+*(c7t-|4$!`nKGwgZ^e7NeLiX#306H}t%96q7fMU-ep_5-G-ZdBgpfhRtfnJ! z9h)!M74*G)E3FhG=Dd5~n#-5JZEwE6x9s_%V2eMK)-rAGVpvqzm-_x$Gvnla>a!Mk zgcT;gUGaU2e3z8)`8_ASY)XzU5{h~jAJekv&;F9D5h2}E%U5U2eeR7x>;Z6pFX-yWZ1@1gid+l*r zG%(L#V>I)m`nEGickI@Zv3>PB+~|+NtU9}$Svx&jKLpm#Es?BX^Hp`YW~RiCo8fC7JjiUz&RcZ)oX2k4 zO6}5$?B>qGBlb!&fk7CsV;rD;aQ*G@heSP=LP>? z(y8nc*Pp&qtNF=7%l#R()Bb4}hj3I&U;OHQws2R(LD#;l)|fAzx35i9DdDvC)mi7f z=yC6(CzJm16@)jE;O zV!ss~zJKQB`om$^*e&AFdfJ@r!rNoPwQrs3QnJ$~<}~H7J=tM%QRdr}*iVLgxa`}H zUJF>g_?u3h%G`eD`^&hwzesEM6zzF!wLhtHK}#p6)2#L1_V&Eqc*Sv(sGm2dPR{YB z!zS;R#;Qv1aFB{#XfNG-RWGG)-?fDsk1BR(zx&seZ*g?pj=7iHHFH;bSrqqsu=smU z)&FKOcT2sTgL_*C=b@#3JV#ns=IW&JbLXqw+OS1sNrlw(_L)!Bcw7?Z-?;n!Psy|` zVnL!7elM;|uWsG_Q?i!D?`~Z0>(Cb8wH1%g8f)>EK8>ChI6Wj*w$nzwW&7d6a+#Cr z+qAhS#FXWm?*BheU8wVa)_F~}GcRT5eOvjkwbEUF)h-)(u2)4%*VHYatj+RnvtjO= z{?~HvP8zAEIi0)2m3hp2a>8LYNwH(!RJA65Z&uptb5!xp ziTB4QFS-1Vb6;~oF6;60{}tyMUiA_<@MW#qX+_x>Tc?=0k8dR}@mtw+$oYdF&)USC z`CEP#rs~w+GT8i2#Q(QNNpt(AGzpcxDo2z~l)B5t889iE?VjRw{mCqWLQ8W8!(bg= zQR^#LGVDAwcTCB*Tq9m#baDCIoPN$ZX?A-WZeKRNW0#?%WaPPI&9{8d-w$bU;V6E1B5C>F?cE0#7JrOhxjFxp(EnVo&QCIth9c~? zH{=|(WF7MC*)RH4J06|1M`djmx1D6X=SnG#sh8ij9Y6YyLu+Z3I72`MOC5xKG)tdD*qUv06X1_(x&I!ug5yZ6@ERK6Jkt6=7;3Q*@4F zRatkz^Ny9%Zf9mbaf$Rw)~^<^TcUM+#eE6?v$NKAee&Z=>pSmr#c*8@-<7rf z(SI`5FF5AI|D@j`+%n^2wxImm#Yc}#n6&?V*Z)nYRyK>gzp(R~Jp;qP|Mxv-$rQ$y zCeF91+0kZUaQ>|94YP~R%PsRJ>)cz@y{NY!u{q-u1Fw%Y^A)q)7N*!UmJ0+f$zsZsW?>cTN7!8m^N% zXP^E#WXAsPen{PP@0P3g-zf5J;xRBXP&>T(A*3$(nHEQmnOx@9o}|^S(tCBoy$GRg`dmbu4XrVB>LiF=LEGb zo9?I5g=ZAfri3l^)d~CM@+!38p_RYFrhdm4Ord_Bf+1e{pN;uar`U4N5PIBRC#k#l z)o!1>d+bl7_I%{Y`|~m3;ez*;b;504rRU!Xo@q2@wQc>pYj)1(7035S{nEYLzu3}h z`zpO_i`#j09~}}dS*OPv>AZZSkZ_9Rmt&41x!yd@?%E8y7uQ>=EMl#$z23q#g)zLh z%wsllThz*h%S*J5%}+Fbud|VJ18bni&#;J`qu!p+l#VMc)6sksl&QHZblaB42U`~V zHf%oC&VF0MyYk><-^3M{LRTxP6;>Fw>7^NT+mt@tZl2~7F`?lYbC*PzPWeN}_e)G3 zyS5dcof+oBy{q@6;`38Zb8ahYIYs_@8r9bkGij>VcK$_K_3C5!#}L^h?X`Edq-yoY3buZ}dGJ$8v={5WUoTFX+zQNE@ja%Qf#X$4qV3ezyr<>-ryOstxOlO) z>B6~tmm?N9rLa#s!{WQdly%>)lQ){r^HxN2SM0RU=4ZPs)>`Hz5-xMW$w z*_J2i9DiP4f1E8N-}^-I@J{A6sW%RuHsM+LICG7-P@%)!n&~IcJ@6A}@m45vPIwva z+_fs|MD*#OLV45M_Pg`cb9c;@x;-y+GTY3eJ^#PP-H-U4bxnkG zf4k0tqo0n~Y1Odmi@(TKooJr*jos7WK)sr^qIquJoS!Wd1OItd$Sz6O5%YY^EpujS z%~k2Pi-GdxFDny^0t*xFZPVB&H1)@-cj@cbPMCY8DESNjIoI6}OT#{J*?TZ9yQ0qSN-U{wFf@{*$Y|@=K&Zu)M z)&0OBYJOBba{cp@oGjOxljbb=eeP|LiK=c_-o4kVGfr+}+xq9hmJ?ms%;GOp($}}2 z);+Q9fNIN}=MAksLi<^KJ(o|A*0$L8@$z%IZJ!2|V_`z)up@O9cB zw)p&xcF6vl;&aINfzaUxJq8P2SAJft^Zd4^Q>LoyoqvDsw%@Is8Tw}8q2y_KSvofR zrUknHS|RuS_qnOjyWYQys{Sk8l$N9Rwma%cUgi^dk$3}%{znV8?`m46edgC1vqh1C z=Atjn@0?%u@m)!!zP-r0Zyz~Vblp)=+j~+odgWg$GuK&9XBIx0xA^CS4a?>%vbp}^ zk-Mr;`PPT8{wrPOPwWVo{#f>O{mli3mU^c)I9a5W#@%ja{q%HK;i6Z~MQ zds_4f-kKJ^!-@SsvkN)ldabjo z(uQlnGwZ);@jX?%4=qoMPnqhaJaO)ObL+$Wk%A9+-7UVaxuN)}gRddoFY+y|`rSl>FDL1ERuu z?!1jz@I5iymhEeUzrs9@xpu!&1O83l^t=1UlUxmMm2zR34maT%AxvYoMK z4!!xOZtyEv@qLZ>74Nw{|FRuFd`{kYguAu-Hq)n%+09z1Uo9BFfAb5RIm1V$gZ*9R z%$tX{_x`Z?#VWMr*CrP(rOv1a)_Z49vo*f^YTjaNJ^8Brr)B!@Z2q+QkSdF4@a-M_ zZ@m^o{mHe2#`&!pWs%*zhg+s-Mx zyS%!VP1w50bI1NLo1}$lXV-j*Sk88FOZDe%i z`=^}n(M;La+mG0qEAREEdH8s~_3>XQ_kYIQ8@rwu-xqxJw9vLXYSTZf@_Tz(Ugwo; z%Xr@)aNpcgHcn&pGL30`AH23-IUr;ZpPd{cbMNV__ZmMIrPcnci8Qu*(P;8{4%7Ar zbCS=T;{PvgdvmsR{DC?xUMsf5kdtNG*!5T0m#Z>f}>}P?!I?HlDGetalneHg~lH_N{`2@d}_LEQQpXQqUz}`+lq&3Gb0Q4bhIWt zyC!s;vFXg*Ptt4Rtsk~7JMz&x<0=dI zx+K5BE73=b_uBuzenB8wV$GoWh_XiHDwfTHbxn$c@6cN=vC zUN15C%X`1%eS1{iUp@ETZJv^P^XZMR-T6PCvIx1iBv)(U13<xhVq5Kh3#CY>y<) zbZ_0GX!P@vZtjdWVaKVbq-U!Od@g$9o#0THx3^2f@=Vd=SI63uy%l^~ou2D^JWE-i zqui#?=AHDIYVP+OnYXa31zy>7WNt)T+>xTSHyBpVTNt;=+Cyp5((gOE|9$&% zRp52|9-AxgE9@=S-IP7lZlou;BixA5pq1-2=lvu3vklxQW|W&MDgI7*le=))N?x)5 zzhf_a@?C3Psyj8~ONrd3PbdG{UU=j<#qprce*cV~wxGj|XD6JVoTJ`i!)@scGho9 z_UOC6N1pjm^c=MVKM%CD>M_o_DI8?$b>iK8r9IrgC3=g?SA5X8?pHPC+Y#||`X0G; zDk?z*Jp~Ka{{J&`!~b{5>3qR$E%FK`Q_cR_@g_N!XeGTdpSJ9n|NNk-a+mHHXq48! z2ro5P%#)wRlf&XBaaGphQgh^w2AwJS3h8^@%lUV^rslBj?|gi%vZwd?=fez}U-iZn zPPlyde5B^J!%_?hM`CsU$FlC}dL0;<^l92Q!H<4i#{`!gk6x#-=w{WHTQ`3hv&T4I zU$JH7-Hw-LM+z>*-AUTZ^*yt{Reg)!;@837x!tX%o5%{5%bRW6d`c%diQ8{;k8j2G z{_oroUWd=eR6mhq=63kBy|Ox@G~-&0VYabS%ctNM%GHsjIsC_^BGbHP-V>cBqLB4< z`+sxihn_y#j5`7nJ7X`bh+Hldlearg*U4$q>&j&nhrS-W%=tok$z6>HTyG=)|3C2d zdA-n7lZW;f&zh>7+0W;md1~uFTLHF;{>=$CREL)BJ_gSG>L(VsUkks*>7AO%9EkRO92p$(2p3-2W|DEu`AME3MI5SyqL;R zd;7u<=T03KE8nXsnf&PM$^NR32kY9_3j9&Ml~kMi?1cUgdjkQBJ4?3M?3^L5t4>Ce?5idd|MY)cc0ABP&+N&w5nv5=AOQV_N$b+LZ2&c zc=bIy@|5%p;B?TWp|zt zqIR|J%)Ri?CHtRVE_Cxhy1oBrUqX%Au5Sxs4|o=R6v}$EarLCXi)Sj&tDm-{?MCkj zmrwEsqRQ@WpOWM0@?+AnS00a!&xkmpqnY>b{>~TId1cR*)ckuZJ~O^VY0De&NY%Q+ z<9|+k7fji(#4(|mA@Sv@jf#cG`S$Y1yj{2@?ysBHHO*2}+3T-9R2P4|xUK5CSW;iq zgNg;q!x%g^%`2%^SQEUMrSSGW6WKh;t1(k!LynhMKQcRB+^izoAa?r5IYpbkGlq@* z$x}|RF5%jsD$9n&oSHcwG3XIkSysV3h8Laow>B-`(YRJ8r?XVW zOmlN-qu2f;kE42iTl`{dw)+_)CnEVIKQ^pt@#m#wx?J@ganjG3&O6+f`=#qsFLi74 z8izMhO@CAVcx`jhuw?2?t8SJL`1dKKDb7>uAuCh9!Jn0%*f*FiaaH?U%}_Dd@pB0W zcZkPypCFH6?PnPa=nRit4I~ z&vZ}6NQC^XU3k&+;LC-}Kk}J1#{ONlV}x)n_p>%zOi0o(roo|`?6g%OCvWtTp&2F z&c}Ru$Y-VN8u!+1+SV1kZ?#y>@!wT%kIt~y(8~TBa4xzEkP>OJ#3`1=;y6`ImcAF33Z5Zx2J$ z#J&l}-#e%KoMmrc#bTe9(Rp&O-^+y=EbF$H=I|ad%8&0oHSf|RpPb3(uQhD@|LWyu zjl@gWDxbbOS$wuIhxz>Tqf3Q-mu^~DrL;tuaq5pW*)Xf8%IlItj$PqQj@8IpZ5uG> z-8Z2uhqu13&~7Wuvc00wZB%h)H4Oe^c)9|z0YRITED*6zka=r^h)JFC$=3C zJG4hlNpai$hNctq9=+`kU_Zcmo=ZGPulOU!A+0sjwM)KzGG*|}F4En>_xzh(Oxy?8 z2G5SQu5veb{J+2UM1TD3BR&;M69t){eiJlox-MVCI&<~K?FmgHi%(zT>RvtP3d>nm zHcpmw#kqG5KVi(RI{xw2tfC272ih!uTsLO5=h!gwh<(G8UG}9G_h0BPF1+%NTS0f{ zB9p1Lg-`w+(Ua~?={_JWD)VReJzH%%i|SjqS!Y(RJsWmuS?M2#YW0T;Z~pEzYxLOD zw?turdRB(^>lFTn)jPKQda`5tnT0_+^VVHF5G1+zSiqCrOP^{Puh24)h+?19H0S%< zkf{I1&vS@Glqo*Tc+;lTW6I&Pc;;V&je%3rq!+g*Ub^)0pZM0o?vobvl9zw7w0j*n zKJQUs?fc`QS%zP)hG;rP&Jl$1)WhTJln3(`N;-z-hO-F8$vj zG)Gocbr<8^YcqKjuDY|DoakuhlL?Iz*`dY%_-jB&qQ=|*Tj!hoe_tbP)SSF+nu+C0 zw@SO^jQe8yCBxTUcx}tKBfNsiZ$H1xjnLr4=)8i5pW@%@Gl%@&+*M)vGB19n&eKa~ za@)^sTUqtu!qxC+2keb^iu^scX|96nfraN7^6DEiSbS@k2YU&!1Dwouz};g{>-JFcy)j+_s|%{DImv3U!V z-pbEU88W6Hd%~J6VBUCGb<67Q)@QmWt_|AvCboBrc-pG(dfnUm9ir#nys#|x!c^VM z8;e#a+2<|a-@5*2e)=YN3ESYOFD@_y|DN~uw&Gi-*7^QP?ECCK*;@x(x{zsc@bD%M z#d^Vcm&KpocMIj2eKzlA#Oo7}Uma=nHlFl~&B3GmV3AXD{(%O;PMfFiCR?-J7t*`# ze_v5Q%EwE07gx`%3Iv0k3byX{^au$$bq z*hoI#{>#+AXHJUrw6xjVhHt#vz5a#ou3S5=Wt=64%k;l=zHHt8oY{4DaS?-Ngy<#b zSILG45|Vcu%#d|l~(dOw<6c8P>MpU`EXlYR5iR?AP>=kIbmYDjT+*Y~BUb)R+F zcUErdBlG({f5L-!PbasTOxCpeuxNX|lw9_M(CX@qYtw~x%dLO!)wLi={~6QG88_@+ zW+k)>`(NLDDn@FP13%9#Y2AqxUXf?GmbzZpGF3Ct$)oV-?~DUgD}LChdCk@;=-t?o zIpO?MZ^wVr)#tY-uB^7UDsl;1?a1-B`}3*QKNMm+D{d^mqET>#OYFFHLAK*IwUDjG zr_A>8rmj}pChzh5#j!)3iw>_>|5}?Ts``%MsiTEQDFQUI){3UXj^L5#Z zs^y%^Zp}ZvUQ^(bdt+kWlqy1y*r&;OX4hpw3(ls+M0@nid}g^>alxBu={t}MMQ z@$kEu>`b|*qF(z%)`f^4Wb6>xe2de_!-Z2oLYkSQWoqH?<<-TXc79WS7W(hVF7I|; z(|KE+r^LuvTsnFBz(!r=Q$gRY-9kKb^4%;{Cmh*aDtDP}-zCv$EoW~pUH-_{)bT^AVbp2H z*%SR01vS2UTzMsRhe7G+vD)KPR)1SxqxDtM=A&g~yt5nQDaPXJH>^hU4%%`>Sm&6s zl)O`Ad=&DX*Y~FKv69kiZHBazw>wOYpINdA@dWKV)TiruB5Z4o<%x2p=^xE5OTRkl zKcOvm(d`AA2Y<1y2r~7WzrF1B#yHh`Pa6ODFWJro5v|pBCt53LAkHRf2s}F z%OD5V)_~4=zq75vmMAW=juG8qnJ?Ut@1UB`R$|s`^*h~LXc5n>FNcNa-510oLZai}?_vIa)-bo|-9}Lc#{E}Z)a1=VFJzuHVDCCvT5?sj`mE{; zO$CFM|L=U9qZ3?m%qb~xie`zh;mIDxjs~HhE{ooBb0}T2k$e)#%JJ>|N~YzD>LmUc zD4acM{6?ge@#&7q%NP7gzHaZ5rcwAxb$3Kxvh<8AYWW+IzOFX2dinjem{Xkg66S-6 zG3KERu?uhMAK0+LF_7^_R=kJzdu9FYk3*N;+qHU+vSo4Pqj};n{X4ZDjZG4)z_DEW4(W@E3e~;YJYUg(3 ztvqyM#bLIOI=9Qzo=C@(FlKqp(Bp}<3bcIktA=f=TJ|g119o}rbEh?_v}SEN*qRxk z^PKHoP-54_X6w6~yiAzZo_qACX;#*a7*GBA`_=UKZwr&Va*O-xye@@e!=+e>%qTD|Uu?T{Adxaat`@8hy_JIr+4inc$BGG2DCE6_H2g>pxd zQ&LRl$|mUv$2@HBHW{zF@0FzRa|wUz!Ghf)c@NX{IrY6672Vc6N{)8c4$w4TzF7B- z?m+>ga{Emxn(iljHZ{Il-Ly#9>QT_I?Y04FJ8sryrCQw&3%ak`=Ghjl-|f6W{YfB(Dp;`bABE9dG?E8_wHsk(J0-CcSM(dw_tz+ zR+jf?Pq7}At#>iu?VoSyU#EMeXo|5S|Ita47T4eAyT2iRCI6GmGdrIgPZylO`MDim zuWH-FnEv}G>inD+9gX~Vah_PsN3SrY*32hi!VjaSPO;>PzonZp_q@f53D?isT{zM0 zqOe!R`FeT7EHh~XhBLO)S>41-6!iBTK6hH>Y4MH1>neG2-b(Uv{%6kZN9uf@$aGY#|M9<4H#*Mp|K~Yf zamU$;4&j_48lsnCJ#recrH;yfxaA`_p-}wXQ+Hw}0FkdK8?|1NpOY7TDu#lBf`!`8< zfoKA|cTTWRYJuu=r$5s1^Xe30UKKbp9ksWRQlmn z%gDelvG@7+(%UCZwjGbyykW}^H;sOG+Zb!hrAAJtneOrYuAcH%>)(R+EY2tSObezJ zeVbMH;(7ThlNSY64|^xf5cG<3Et$qsD*RO8rvrC-(GBK6pRZ9tEiV%4?8J_5=Gf(X zc9zYD0-=7RhdR^v6zhMdFS~T&_i5c;Cc2S5^hkwd;Y~q-j;ds$Cw0yQ_DoMldOI@nWttj z{HV#$_x9W%n$Rk5{&7inm*NVyGfVHC*jd&WuX+2X(*A9&yH{-6TdHN6`r||4K6%-o zzygOaz5gGDuee7$3phd>KB1aqJNd~TWoW; zeer+4N@jS!#LZp3;*nO0rmv6OTYLR-`?Diip(ie}nx%QT{`yw9e79lCv$O`s)a<4= zmN&QE?dCY<{P9=Rx5a-KG`^Ve#I8Q%#gWxhySH{|`G23WN~Bq2@y6|vsfTBmohmAn zaWh|%`|aYaujv=|S6l36JY^wrL(5Z{_oi*jbZ3RnCx3S>Rqtb9wAWT~Rr@mSyJP60 z6!#us#xwf={;{_m*i3ei$K+rO8FPe>?;nyT``wsUp0zujM% z)5eS*jq_WlRMi#+c!xEqC2!d-kd$}4^$NS9*mR4lFW6-?^m)qtyPtgCwPJDOgIvaR z&f5jggL(uQ7#J9(+||-rO6yZxFC24ynebunvzCau11T#Xt{1rYh+)2;%Yq5?6_RBz1BrGRO^PD+|!Q-UMk#=vXysW(~jtRuiwzhcX8(P zndz)=CeN_15`HP~ps>i|R_0xsJ%Ztl!Lc(I+`IK+_oiN_pQ=|F`h+XC{A>J~82j%) zcGxntdBuNnIPLE3yz_5a{r_(9W9|X37AAXcdEUNw-Gd$07s>@4nU#eZGp62`D*`C|(f7xgM zX>aQRgUge+R^3=`zVp%M3rDgXf5^+ck=B0{cSVXtHsflbtWU(rx%5<)3;>Y{~kQC#u||x))5F(SG`3ztH52g2`?tKR0cTn)l~2 zUz)jmKvauWc<{$k(muQSLHzg8GKbwzZwj7o?6}u+`G|=#l-c?#>^XgT?Ygdj z!rnxrGJX1;zt+%u`S@-UtDo6;;Q7%#1jiN zIdyHE53v?)S$RjIkZ+r@#s7(AEk*lV_iCD~{w}stU8(5zPWKZ3b-o%mPh9Zws62W{ zxViC>n8?EBoAp2TzHi|5T+Y~Un7A^FFZt(*`UzoA6^`C|a5im=%a?*R6MaMf@ABNn z^!i7f?gQ2Rrz@wb_s4aWfA6tkbZBOhH>WFW>G}ul(N_{DD!$un*%{q3f4%FZ6EYUt@{7LT4iR}g z)pVj@&gu6yrr+g%@7)|WDgNherz5*QtUeiX{oZ;zrkpQl#20*+SiKXVM7952^ZnX0~5zyJD)&*QWEHawZO zySwJFp@vG3MwM*BhA3Z;b7jJ6Trb6%5+D2BSi=_*px75X&0u}~E#Zv53Udji87vOfLv(oypVZ{F_X zf0>`izcpdrzP}U1)~)?Lduf^IhdqJbkNXyOz1m&B$mW>3N_=^{$KlV58;lF)8j$j7da`>GgsU(-!_@+=bVpTb)8*d!Hl7iCfu#N*E_1~PM>{jO|5w+Tc#-cM)@So z)8|-{6^t)@e9>jDd-2Z2a)r4!!XmvM#J#NSu#TUYy5;=cIJy0V2DCgd063&g?uq>BrKfJ92%|CCBBmI-ftUHVbdedbZ5+Q;E5q(e)FH z^qn^{)-R0~F_km^<+!TNm#gF4iq|`s=A;~&)c5s|^v-~uzNry2PQ7Fi$jdcS{;;dl zox^m0o7UZPzKb_&uhy}NDUM8@6?xDx_A1wh2ivVh?mP?o*xtF?Z;8Tj@wHoKKUk-H z>kW7L(t-p9rtes#E3@BTR>C9IM$bLYvrDIe?IEqQONW$tZR^^Nu4 z$*5U3Ov64WeV@6Xk@@iD4`vF<8shp-Y=b6;pJ5c66HzngS>1HiD4YJX>eo;?mS^TbF+HrsxQZr&Wo;$T4OP}=UC2cedpVke({BB+3XCSCKO;$ zcgA1if{M0riTed{o#kJ-g0JT9Jh103%O;lB2mKW$=YS#wj3wt>;(xH}Xs|l3)aUzJ z4_$W0heb--c>MR79zOZB4xcB>fj#E+=g)Co{_p4P&T@Q3wKK&^A&S^Bg`%|}! z%&+-f>Ze_=)+Lm?d2y{`d~@*bfp;I1pKd#l`QgoNd&z0%9kzJ8%+s!%VUxwB{Y5qU z0khloCDT$)u5maoVdQ1iB_6Z(=C)4Z0B^p9ESr_=rwWS9X-wCeb81%uugaq<7dhjP z&uIVSePq8x{^Xh+LIw|${!JAA612))nO!e@;cPel15@^!@K4{i?{UFj#c>WN z!-l|&Pfqi$E$TaFLzds4sg@ex?>&*h>~7W1h`J9CBA3oIY}S_y*|BGPP+wRw#}E0-ZH&x5 zx{SXc{+hD?{@*HtDvnpqQ(|VnQBm|0Q!y*#?4Nt3Kgc~QS}pR3V}{6nUzM2;w?0zw z5Ej^Pdr!WTs+0*{9?)$v!pl*rYh6D3sZFikM-+J+SlW0bf$d`-9R^8B2vzYyyz0$wFVY8~) zB#SqT*;T&nc@;R>K+dP}U;S&20{$ZlO@pj1JFVMvXh&9yV}8PEyZmlR_Pu#F({>#3 zXqvZo)e)Z6n=kB|^K)^#ipB4H(fW(h^csF?M9irSnEPQ?EAxqOPdlbOQjy#3ud;1& z_44@cLm$!}9$d2e$Bs?b+hcaOcW9M7+99pt#UsKHwB^sA8+RF|OzzlNc9WA)wB^Dt zuIuaOoAVm{YQE3ZlK1ZaGRZL0-zi&Ut7kqr9RJ@`{) z*k+$NaANmi(YIwAL~L8XT=1`TndiZOZ9x>bc}K4SbM-sH& z`tU*5zjgahNzI-q|2oy+!RrN=?|R-6$az@Ce)v1D5QpCTYZc6%OaHE#l{m4klZen?&cf!tF$akjGS5d zzV36>(fw0TKRm_7E1TAPVN3Sg+a(-b(}gP(XBAnz(24Mv_jY3&_ui9-o%D1ij1txfZb3fPh^6E1IaR+%GXic`*Uhu3& zs6lg0defBd?I#!*WIsu)6pQ(zK7WdHXhP!Rcenl*JozT(9dhJx!KHl}R}xk|W-IrK zC^>wOLI0##c9l?=kzefXRcG2Q&-UE<)E;{*H+(_ny$#jX$vtO;L!6U-9`&8deOn|{ z;~nqCcJ}N3bsvxFl$K>xJX-D%mZ@E-bs_%oyAA!`X4CR#F7`8FyeX{3*u=7b>74zG z+OJ-0dl||2DL26^om>0Xnnx>5TdqvXwF=a|z;^D~?h|`ooDXQWv;WvB<_8r<6+b;dx zKh;NB=0|4QoOQWvSF=KX94~$3<0=?oA6}-IeD-6)mm>zucc$ECT$NhA`G!n*{KqgW zpW?@db8Qp;cEw4^^64!!%0H#qvUTUP;(1=Omv32UFK0@be)1YG!zhvh4IG&lWpcOHXc>g+7XlZ+k9fErn41qz}02x z?KX#9ZgzQoXp3XmnkjrL^ReAyk0!OEoUHSrwzkhrW{KuTKMHL9=k!#b-EN7|mnlE& zT;IK4F7vT%S{AETXf3yv=91%$ABqVM5=(*ppnDXRdKCyMC?KHG0vk-<^@h zmztm5Sdz75#pOplCr{36WH=(cHs;Npm<0?B_ToN&XG_)v_vzpGu~%YgHM?ekhroNL z!l+;!J=Uij6QWvUw?%)nm|;Kp>l(4LB8_(^7o2cWC|%4MQsNo-t7xrS za?%(674te~ychr9)5Yug_!JZ0{%W3=2d|4)nO^Hi75vTv0QPe$dz#_8|L|q~19f!_|8EHEKYPm*kbZ0X)h$js)g2R9Z+|hYwmNw1 zew6NfasJs!_w%>k+3Rrl`1-lGPUfjk{B8CwxOnHMIjraJ@g$wpQhYQgl%;KN^tzu6 z9Q8hbk0h}5MMfTQT5PGeeEw}!K*du!w3jN4Nud{?>X zbYNx7yA_YUrX{+4k9xD3C9%4$;N$5(M?H1FTi1T{ZETMGnNhH?^ZM~6d7A=f@EV0Z zo3LZKom8K+Z(@+v;;M`0iY>9PTXY__mugQG`0`3V_R6B1l^?b~Z0_1WrG-;> zAp-w`tefA2-R)XuIPcBnBhPv7+|Ab1JRG`3@YvBM>xAtLK6#3L(NQQ?k{1m68a{-23hSh7Ei*a>sZNn92WL zWExiB_4v-IITf2G#@t}~H|fND%jN%;rM*7r$*bI&9#j4}MfCFOC(a!j)_Je4$Q%FD zw;@j$*U(@|9b_uK;`v1V*Rg-8k66~qalboqfv5e`Hns_`&wVcAOIj!;Z+qEDEV*HM ztMRc@bGmHg@6EPlF`Of%!SFWaMQ6Gr@7B}5qfeiIqvrZ>e!%imR~6blQr2ydc>V0n z!MW;758vJQ%=FN?2}P4H%fHf(oBUW!jyrFgPjz?URNqNYPp+~s=aQ(Kc+vRm)8(u5 zM3b&tKU?to+z;IkH~i1?@7u;>CT(CO;UX13$6ouEQF4)KQ1vg?)nd7U%T{-+XN=l# zyCGGn=ZHkd&bYR^7CdU(+xwYi5pOH194-Ay^G=kv5?&HsMY zvQ_feeoc`25$V&l){a$cr|z#=?5#G{^JN4KLf@a;wKLnCEVj6|-#PF9*Z6kj(+!JvRi5CuxccxJ!Q<*B z>k{KMr~lA=Y!SD&srr}C4Tr;TOwA^1?%G%P%Hy=OC4MY+C&r@(fe)z*Kh2s>QnpmJA(ZuCT&Xbzvy+|r7q!e znX!J<4BMw>5jTz}^!TfueG|j<-e!{S%pR`1#WTb#H%YHMo#$O-7&rOYm7ZS#Q^NZG z|N7lidREf@Ohd+nr0?$H%~@X=PjC1+e@XiUE6bk~R(%SYUod~W4dca?;?)lhS$1Cx zx7JC1;?nT-q?carneOaKC5n>8axAS+w}oh5G7!?Q`^#RiJ#6+t;XlhZ_Qi|l3oh5c zTKm^3i)ZKh6|s9GzWQ}M=40D@LHo!>$7$8)=V*nq9&`J&{`Kl?_r?244jMg^U(L?@ zaJG(x&g_OX6Xw-S8cK#A-|y)Y-EG;?UBMW^?)9tdTV#~?ofHOZMh6C2jUVBcT^`jh zQ}mtkfI-DN(MM!zAkVG!vgwjcUc1^KubB4u_R_zW2F){8`v;^hm0l$2y^(He%s`0K5);#pNg!{@im#ycft=pybU{Z9564Tj;-T!#!?6X-@;QU_q=4q3Y zvivhl|y_seQj%V88tH;D1qD6`fawS6N)}Uh}MZ;_+bL^_Dx9pN-%BM0euJ zpo@RElwbPVxuJNH^SfG)oy!wvJ-hzk>=C0sHiiAiI>i!|8}{wi*cCrzMYvJYT(J(8 zXNk;Hbzit|TUWh#6|WrQ``~(|Ti175H_Vaz{Tu-*GuI$}(BABt@`&GNY*{R9%?wq{eBeBV=!Nt{bUcqkh?;_VXy}0vo&8>%T_cAt$IrHrnKjdgUNiS+`L6XWTN#*99 zllb!8E`RPto-be6pf`3mmKiQXf?N{z*2Eo_w2y&4~9l zLyhqb<+Q%H#>+l1ozY&u{efNPKLe+gZ@cbmF=cyfXjmvX9?GZ1*wDbXxhm&D87T@wV-Her4{; zf32U(M=xgkG1GbC#;dPOLyxT%^ga`JQbzIHua65(?p)~k;P2K?r#>%|^0W8yzEHom z$?56omyJR4t(;d&zWmFvHL|@?bUo!%dR*$h>8S@r9<9w)3T6+#8FIk3PpRpA&h|^2 z)eAVT%89xL(Auhu8UbKCXY+wsTnFF&>CiJb zcwCdMy^%RMeAb3}9Eys}hYP$rR)w`Q-1SL$`d^wgP5Ixu6VoT`{`lp=-eqF@4WCXv zvD*5G;+9(ss(icm{*rZH%?!V}kd#^ZE zm#>^+Zn>e^CPFBx&eB?U|9V$p#*PMYJ}HHFzRN0&jf5nR?$Xe(tZ2C=B7H>gm&);Y z7n7De(8LkHQ1OPXy}M+tGB$m-UKRM>c=_Le6XltTI$WCPer_y!9Qx-;ZqWDnR~OBC z=UbSgV;50pwV>lpd*iA8;-^#3+gR}N@4wfe;`M&h%2NU=O8Q@oHLg26`2PKOg7l~K zfKw+pqGWxgW8;q2dhI*%=&G!G8@urPH+ui1+#gTeQ2uw??qd~K7t6lV4*FrIIoIT6 z>NGyX2eJ#*ecv3mU4DK2_q_>wUigb&KfLT1Q|hxbYy9_`Re!m1!~QJ$VXIy9q_Q{s zOX0E$;~uru6^4_iQdw! zXL+j=W4q>6Jl{|@IpadKXOqqY?$giLF6t=~dQ&sKHk3naf8eHq11pbuSCyYx8kK8R zcu=R?Pw;_CSpQQ^d8f;hErY*$FFPC&QDmMYtspPVarU8#o*M6#jKV*;?1>-RbZ@N@ z<^EyiqOg`>a>43%40kI3Z+gFd_JNOA^Y@I{>pZi$ zLQZ5}jXAy2Q#Uq;SMQc(KGN^@`g7@|76H{S*LPX6 zOWjGh)3kf8`-lH!hObyY_*FjHY$9Pg>*=$J9~#bm)-$S}EG@^zAZz!)=cifBjpIu~ zmSt4*>(5xFl=M<=jv{}<}0cy8bORljO%9{;^@fUSQ1C980gl~)D7LrI;g@7eCC}E2gZXd_p+DWZj{&vd>#yH||?CG3UzKm4{6C?pD^g;`g~h?^&?d z`jB2Ff3Aj;m+Z?~n2hapJd=5ky|~SLZ-dQY`KziwJ3rm~Vtw!b4jGH%OxHiYSz3}1 z)SSOI_QxXw$Cu`Zmp)(8wav>VCFa>Vw>=($+x&m)lyS|tz{M4Px_5Q-jF&AM5AHEp zAIs!@U6qn^^4jNT4!ifORw=PZ8r4~}DmycOW_!Od%V9nr)BALXw{2Q&R?I)v{obQ_ z;&H;~+b^}woHo|KV3ozCvBpxci+QiQ;yeB3iH5no`pswM@A5N$7MD92cKv~IjFwv^ zqj#A3tyNnT4cA=V+`pa+a=ljFuK5v$bA-{pk*S)FRjV4{QlJA_ye6Dnlfrn?mJQ(o-0n z17u!G9C)zuyTxgr-^u%?O+Pz#CRdwZZ=rxB0|UdPdzXcoD+NWj`F^{zIiLAS$=;VS zVlx!fQa$#Darzxh>xlci&9Z+1$A-fBs`uv{w{n+xoA-IH75CGV=T|WBopahE6uy(Q zaPPggy#a2auh)w8XZ2`*w3gn>`*dwbisY{B38&{scpc_XOWXGOrXJIZX1OUY>tcD! ze)atQw&$8z+3A08%D(wamvZ@h*V1h}@wKfuMdl-8v|+EnpO9_-f^qv-G8J(r>reLj zAF<*IliOXXX*_4HhTCjAWVX!a>w~3i>^e4TOB-fdyJ6}^X(CKyCCsg=Y#J05Pz2{`&yCh5*g5Ta= zUY+xk;mf^`mc0r8*IW|XDm2GaW0P#=vww_I`yZ`cs=i_>zn0|0wa*ewtbLjL!*VRP z-giDLx6l8U2(+DeI#@?-Ta4WsxhuI^pSP{FtGpc|l&BqI<>e^1q;Qk< z-`I5mevu28Ol)cR%~akd)7ZVVvrOHyXXoQLpE-}P=zn8W-&=mu$MAA}`~ilCCzF1h zlJ4B0t+@4x(vSBV3?j>yq;VXyX<8@$D(>~4$+oQ#H*fQ1us*E1KjqG`1C0eM9Is3~ z9u^UL<5ldEKgnLVYBn6w4nOgHdFZo=8!KH>S1#NV{i$c)zxa#ami^4o4b-8-C3S;0&5Pwy64b^p-0 zb01R-BLsx6GMt^2p1yJJysG(&>Q6S!sxkcc=e=*$_4!N(f0(epsCnPMfsKA>~9Xtlbv zBsr+UGM`U+rt;QV2EMX;uD_`Id@U@}t&{Oz4yQy~%Y&i@?(Gi0c3xll^R@1R4YGoV zbQe88lx=Q!Y}vP*wspGFd`jka%#&F3JxwLj)hB#^CFVQp?IE`6%tz~wo}Td1XraQ^ z_}@t{O*}m3O+5Rl^l$(DHD_;$_B@XEy8kUbq;CDGO~2l63_Ukfq@Y5lsbeW;wQ$q_ zo%x?_m;6{R(sfp*dUd9t^$a1yqd6j7oWHG-OfTN#;+OaB2@;O=%$apR;cPLZ)!`L~ z@+LU^+xKVBi#5j)|XP&m4oN#^X zpCq=+|GN(6vy2`r={rxo zQ>g4as$mx8^DN}7j@IoWjt1>bTUBHQSW^@y5q5kEUHbdMEMhJ9VAU8hLMHz8rFSVGSK4^Kl^rU-~O|X^YYc1!G718i+vp5-|^qlvhlMvZ}oirA1-$1{$Ib! zXIx|X;>D9`iQd<`0()B)Jn_ogU~ufe7x$|tbIY&Dx^wuwnBKg98hfjO1h4j=+l!Bj z246CBjXZti&x)calefyec+}~2{Z@gfs8mzKYg?Q6u%i1K<=Z}1$JzDzAHFborRDB@ z+y&L^HGhkjo8L>mzVf+nbott2?+q6xHvBVoi*>2HTb`WQ_V|TEFM$Rw`Ao^9xM+Y4%rJ$#&h%9iO%o3%}X&IQ8nDxxrp@jqlt0-`sx7Y+?V~ zPsbjuo?U-5y4L;RO3vj;({SQ7-mgC1(QoWB!&A)j$C|{1_y;xZ zH={#ye(@YMV6%O5COASN#i?Z0EWk-TEQ?`11e6-mMq3OHMVd{c2_( zCb55wz`D;1o|ww}NqKPY;jtsKg4H2HYy z3Y|bU{UVuf$i^lAUE}%BgS_`tFR?B8Sa5y95$(UK zmPrlL+(J89SnH2`J8|V^#!YYcQl$m?6ImVJJX&&P4Q(f8?T9Uzd!ia=S2RD6P@$*&qze= zk9~QV=lq|@wO5L{WYnjgGdL&JlDi=Ni$iYw8ttUof8k#W=)15peAEeHH zHKDWT-{+?Sf{BGKF%mJ$Ree*lCJ0w?mS4Vc{ob(;6Wo_7hHrY5Ad~j%7L&Bk@rD|& zg%1|)eIVL?bhdZw1m;fh73IEbUi(Yka+$!YRX52=(S$*AhVy~an%%q2RcHKS{kbw} z@#~H1mQ(+)X_0=D)?jhbW0#i}?@iq+hV8+Or9qw_FJwLDmP>wo^2Lj_WchM+ytV3tk7G^FK)emzh{7!y}z$mxA^IdYaGm_%nVDPmHF=dHAAD5Lptk7 zPH(2?dDWXL|23s6w`Fc!UlEwj&YAm9Gw0S~cZ0nRd3%=oT9|KezptPCD#Xz+O7s_d z`Q8bBO!Zdc6%l9FTweQ;|J26s`BJm@ly8YBy1Rc{T9Ah}!+w^${w9fVW!E>FsXx{p zc#|^WBzw`}reA8@9~WnEGTq@-kzb!XIZRwhF7&a%eo0@Z=Uh2@+n>umdw-N;x;Br; zFaH!?s}s|V#h*7f$Zco6zT}F-R8H22kCHr!JRL8!D^Cl|3|}5_F`)J6sr%ElzlqFv zVs`M2hJOBrOs5a#;;$Fy?=^pCIX})Sc<%OqU#FT?b0$4*(z<=I^G*5F4{;?6pMIb8 zQP%kMQk731iq|Rb{JQp6$lQI`zt;WYar@R(6`$Q4x&NA?QT-Bb*50S_%YELiF`0Duf(h( z*6us1rxPI7DE-YXJLCJQM~2G`0~Nl^OaGF_`niHzs`Y@nf!)b(nm&2K@mm$=USyj0 z!}oAfm3(Xc@3ysnP+N9thPS;p!}{dC{@&+3RvqngzB=juDn3m&E$fAK-uLs@tvg*Y ziR0%({z=QS8&@U0FO%9=tmtt-`hi-|fjtV9vT|*XKi`OYH-K%Fe)C0Z#nlC6?d$%oM$@Nvyj7o_|hix zZakISwM?3eBU+=ip|Jk3k1T`S^&{t^|3~s~X{s?z^4sg4)ukvljrGm61dHD2)0Lr` ze`0svHt7(pi@AMD>~F&qd(IEhUyQHmzxl|QSU#yH$*#TS_w%WHCQf&Lr+exX-$I!+ zeW$dtOr>;Q-J2BB_Gr7u{w)tR6;n6dekdWa)2?gXzX|t@6MAE&O*`{O_Upcsw-0A_ zJ@DK9e}zZF`-)f0vA#T~{^o6&->x8+l47HJ|H@nI>tFw@XU=-I^_JZtl|ANrH2gKX z^4yj)B)?SOHPh`x`tx4arc}2{{C~Lbayb^woarZX{}fx!^v#NPy$9ZX^l0k4`}>Y! zjDpnr2~K~4|6Y7uw6kn&^s5uI<<|4n@6=edL4SA2XUlIVwl_#{KE2Ykd1GKJW6qA< zH+D=u8=G>QyK8cIbL%&s{gWNU>R4`iGfsW{R`}HmjnMS?!mq+V7%lc29P8(b?Xb3P zJbl^f<=K^5W|O`IFKX+weCPL3_WFY|t{~USbDQkBloZc#>5?oEET zo#}Pa6n5z+^M$@iId^IL_uQ+wIzP$g?+MYh>m5s1S^E8b*75!r>jC*=C$|g4n>#f$ znZ~4@F8Cw9M~$yvsQq!rA|(g6+Yh>!3||!)pLANPSZ7d?+WTwgEj6E$_uje2#n0p^ z?|QmYGIUp0jLRp9(+qaai%rGP-(Y?5tLa*)1N+q8RjHK)haZaa+UI+7Jk+?XdSdpk zeJ=k~dkt=;N6)OcJ@{@}-+A#o*7j*k-A>LC3z}UHK5}@>?nZMWxFhJ3Z{-&7xS<1edljC=a@Z|j+2AKS~aUA?7u=d9Ulho?e*7oQxkj@!<9 zTWg-{x_PG>SA;wM7ifOLw&;BK#J}@SEMIP##PrE(Zszq*X7cMA>h`}|AmZ1jZt~kV zeD1s@POQ`QHeP#s*6P!TW%83(J0;9K>i+Z0mruQ6yB>Wy_~dF$6N6IR%N)BUCRd{K zt~^^*Es~l2aQ@_H?(K&kt;qRY{=@eCr`GDED=vjhE4QY6y(^a2SW~^#QR>d^Ls>^3 z<*T1|Zsq;CFm{n{*xR~Q>~kxB9NH-Po809RAKz$zhZFQ z@AsYg@{fX__Doy!p|U62jl=lDmwJ|$Hqk488ei*9E_iv>E5UrRsF3p;#@ib;lBLdl z-2E!^^8`8JY}vV-KMode>fm!OKJfC*xp2RZm9n#^w9ahZ^>fB)9>35Z+dl_R%-G|h z`_D%E#Pe%OcR8oKt9x&`;8ZQu8|m}s#&VVhzEdn|#~&Xqttt^o+oJ05QT-b0riPz4 z4ha3zy8SYGLd(0W&9}Dh_&n+Pd$VsGJ5{djw`^az@OfvR?IVvl6BrdHsu^TYXULqi ze)ft*YoBafc+rj3;8H@Cx7wP8rq>QfuGy~s=vsW8uK$$luT*c8{;ga-{b+zDSE+XB zj?^2A#3nME_N?_^vcW;@?3_n;SKc(Stg=7zFZrce(6RKi`#%{1^DkAb+q8aZYv_Zn zOtlTo_ZXMfyeymkXukZ3Upvp;T{e5I#;o|6(~W<2$vw0+v~23=WKus~nJjR8`m))Z z9ffayt7rfXROC2tPKi6T<9Gi}hnsR)uK#&_SBSW^2u3Gr_FY$8sWNl2o$+1=sn;IQ zSmhVRyw}V-%COV%f~uz9e7`5fPSa!;d}(ldtljNa!^Jgw0lyskWNY^+R}~my11efB zh{)vsZ22v?oJ(5VkEP_J$i+v@+t*EG%hKIr!SPeaX2MiyUFB)UGek-f->{||&)0l= z%QM&9U+qQck1LWV559a7@#*c(+v(8_r#6V*^$c0+{CU@5|Ea~9>lUs(v$XB{)@Pm9 z`#uXx?yrz%pRn`l_oAaq)3Y7-SA~B|dcI)p3=P%WDVBkGuZ}2(uYFyYE$~hy(J+76 z5yj-RKw;NcYJ&0we|E^vLhP21{h6E^M}Oti z7vDEeEb=!pNxS4DdZXgw;gdXT6Hac~aXr7i!kR-r@$$F%OqW_8trkcZt^GgQ;lb7m zbNGK)*FLx0w9D#se2w7PKo1xzHN7*eeB}!N;N~Nqb6GRj=KF>rFKhy1n;?MTa|hs z=6QyB&-EgYxs}#we3z`ZN6q2>>h*0-$;ydus}o))bv!Pc_+$lJuS8t7*w3R3TmP6b z);FXzUOdO#!NM1^r`d3d>dTlNe<~MDc+7OIx4)gwV~vJ+jE}#-pH|_Sg?C?@|9{}C zp{7-Lu<+iVRojK+oSi(X?4G~#%kw-q_ms`wJfkO{>%*?rJI`P#>swW z#`%KpzKhs*x~g)=rUw6feNk}vs>(S*5rx_*sb zx0VX?FXIC_&yMZ7c!aU@Zt~X8heg$9swuoZz$o3F|8jOfq%l*d?livd-xox4?tIa| zI$KtJ7@A(P^U>M2{gXL=A2rPT_4!%J0k`=DwvBy%m%R3g zh;x*-{JiSCJ@+d`6kvU(=&h3NHET*pye+9j9*m18k;2z3ddi>A?kzZea{_Dj0>2&e zK5bagR#w5lC8NbD+r3w(S&F;bnI*_QX5WP+Rn|T$mLHD&bHC(6QtgCiU)e%BcP{y@ zC&m9=*?j3dt*oW$HaC|BuU~Cbth83Pc+122a|M+DdG);6_;QwM)dOeGbu16{L*}KK zKUj0ca;9mT!sv8knEpOYt^@RdcjoxTG_vwFQh$BS{kn5XSlm9 z#-`smyp-j&TF%M4!5-0I=>D%~gdxf1uZyaQ|AEAf8Y zd`HGzf9WFLi|>E!i=C0Z@ZZmM7f+tsZo6Sm*2l99yK67avny2E`#iRWVM=nNbnJvL zf6v&>zLP64$I9G0&_dnt%BMdrdtO-7l@;C6>$$MdmNotTmaS*J<(IatYqoLn<-X;9 z_KwU4Q}^0i*CW|PKh$sX4%f8bGx2cByhF#HJ$rWh{jWPmx8LD=-~1uAl#?KXcDtcJSs~!Ft|zJf9dBsY{$#*W`JRYvqRp zm(In0t?ZcS@^I4ps=nF5N}Cc5By|_uuAIfkbG7(gdHkVSGatS@c}d(rXZuZ+v|_>U zvfQ#0xL@7>btiglZp;?dV{mEeY#m(H{LKkThn-B`L=l1IlWA&-+7g1|5#m~e=U)<_f44lx>>INhgFq= zwy}7AufM36rC^X$fB(T!#(gtY_C%{pm0g|5wCZD4=@R>W!PE0+7}dO)UpV3JzvX*# z&a0_4@HZ$faQoNR`OVw*(+oR>`^$PW^|wAd8g=weTiJV;dzKHUEBI70ZwX)iVb1aw zit@j^uAKOyEj@d-NTA)7UH5!@HMX4Lxs!dGO~dqjbz-^5g#7-JEs~mx-+Y_u7Pm!~A>2&&^CGJapVryK~F6 zADO=^7i&BAb6hfH?Y?Gk>Azc~?d-^cg2$>~uOBF1?Pl0&Aa&GyMmA@hpr+j8X?dly zwirxny(IbR`4h$eVgKXae*OJZ-pn~PS-th}p{-X=F50pCop4;`ya{(!%Ni~3-v9Dj z3X{X58fO+tNWzHq3YdV>Y0}Qxu3Q8Tw#HL1lxwGKRjmbIT>9b zRm7URRPas4-hOvW5rxY0M}>l!I6i&6$NRLzB-FR0#5K3>_}5LFQu0o0U~{THl;D0x z$>weE%D5fBI(9z4a>MS*E%{v{=k~`qYD|8dH|5~-G>PCRFHJ7$+5WSgf4H_l>FbxO zS>OErEzzFoZ5lem=PMV({x|Ap-Uq+vnJ2ut-1^Gn30v;peBEguY5cWS{%b@3HH{s4 z$)30O*;lMte&STwe)Tr4?iK%cx1H>MG?(x0v2~^=?rKIK&~Nyy$P_4*f8mzplaKsLCwuJhUv~%cL;7uLPJC3wx+u2t__VYB(U7ljata7P> zH6XUi>x;9ppUk>T*KCyyw;I!-Tz*FCcC#pgqc z)|=X*+O<|6`lwY`AowHp*^l@mfr3pu_t&PoOsMej<eT;kyNHL1o%<-x$yUI!A>6vc$@T#cg)Z%GdI5$R^;Tm+>!Ip(Ue__V#IsZKZI`m zyXNlqnuRV`6TVm7&vJd6-`_duT7-W>WBC01FFZy^D-1UE*<6|Y_V#~~3j(sqq9>~x zAD_N3Wz+QFGq?ZW-mU(+JpG375w~N_I!j+3JGCK1F7V(kF+TSF^U=-=UjtGOw|6YxI$Jw_(!au|-zwnee%{cq)l0=F`dfzdGlrfItM1uO;Baqqn_7HWU#XY%?r-}G9MUP1IJjr_=B^6= zX#e+x_QIH@oZdqF3&M?RZff?h?Mr>o_;QEW%Pah+Q_lFZ@3fZ=2n?-hPsqPyz3#GY zj>N9ejqJB4o&25pn{|);#v^me7vC#fyd-aNOQ-I|zl*kHO#5!se%1BXBe%rGyIk_N zJa}~B9K#g0zPT<+L1}sscmK8hSMjaxWZoY9T2JtFl3j+N>?aXDt^39QxZG<`e?9KQ z6JewvCsT6cO~QsNW@TOfCzUKI*tY+JvcZ-ab03E~*Zhil$ltSY-g~_Wi;%_IpJv_p zw0XguMy?GN=XY0y6wMh- zpYMNY{=WRflq0TRq&2(UeKXfAyyg(cSIVVWIC1CT0aaH9N6;BRi}5%x$V4{_dV2KWp;AQi0&+Beq`_ z8C0s8eqmGlxon-yYi7p$M?F?Gr#pr1oEOMTy_>pbn#q-^&3EQo%xc!ZIhlR>CE3j` zVkIjo47RqdGHU7SwhfwalIg&AY4hZ7sXrVv-({9g@w_e{>s}HRb=J(_j^%DHF6P4(ehT`_S-?2$8nMTK2fUXCe|+9{BCG5L99pW+m=du#t6ZJ+sbs*FZ>!Jfy9 zX3a@r4_@*9hEeB~#D>+~@<$gNJ!Lce^^kYr92?V#xvTv316~WIs9L=(JmmP9an5H| z<9nM9Y`7QxK{=*jL9K4%DVwE*RlldX?mjQcqii$N;Mrt_LyVc_&u*XG(ZC_E>7*T_ zc1_@Gs)6H@=%>2cHTOkdN>ApgYwb1`owsPc+Uz^J){A`D)tL^jk30EtwS802yuW{P zCrc%C|B5)Wz|uJJsqu|Bd@^U-!}s3!*|18kg>CM;&rAO*vCj{1@6Db1*ZjeuJ-eU$ zwut?}YptBTVuomG{A;%VIX7K0zPhgcspXNhpu}T&ZfA+mDG|T_ch{+&j|&K4efpud zYF+jEB#2;p` z+CFnnIsa`H2LC#-YpdfD&)L}eMQ#h&ocfKGZO)&ZV;|Q(HC_4KYGS#<)pNm}b3Vzt ze<@kEzjd$N7e0B1gDW!1*ZysMq0{%^+`J|I`>+31_hi`df={ok`3?Uq)#BE)ClB+t ztqYOQuQ+|u`enT>e->*4^MvYLDsLYNqVD9Bpe%vP5Mz#qE|7`?#pM zYUhO9?D<(N-s@F$s~JwDJ+yccS=ZFq5w==xe+fgbk$~gxel45WLt9+Z-qhcw_KVYCKr)>L%?tO55;V~m6QHdZajXxdINtFQ@vPjsh1JM zzlc`_M;0}=>L;3rJnFM` z%hBnJZD8_?$-i#38E5H!R@gjs@m_E7)R_lg{%O`I=GLF zd^l6(%ke4q%fqJICfS^Ly5|2E+3?33S2EXDZ3{eTK8Zz`(f&!se_0(*AHFkcCIb5x zRaY_B&fE9Vd#S2riwXbD)xz6of*S>2~tK-qNjJ^Jo4c4kC{WG zh@vQO=#cRLFY+c&A37sZd0R*Qh}5Tl*IE82-t$yEz3fY%GULKqI=+Sq zmtwnX<(wB?{iG5#H@dCN-e~%a0v_>;A-7hyp1E3d;KqWV?`nT|c{u)e33K^Yp04#% zYu{Wy|D0oA&UXFDT;prH`&XD@g5bxC`S#k~F$B%`)zvFg8~-6H(OQ!0GR_qd&(7xn6}(8S}8E9#cWr~T&s6tmdr z5A)USM)h9#Vc{x=d?lqtrX;NspP%ph{p~&Gqo%j)PG9#5N!h0-p1P#-PT!>1h^h$_ zRZX1_-`i`XcWTG9)ZmQ*ZVM-@nDc1Mirts?FldC|ocsA}kK`>`#y_>Hx_3U1pOV!o$s!_RZL{{F*J=pOFrC2>aci#jyXX1B({A+qTgc}AmFGlpL{UXymgTXwnOD~Kns3brzZRHM zWmmP~htV&wCdc}CzoX{_dW9x=)cRRUDrS6~xjju+B5z~czVr7II$r99#h+=7;^3%O zdSDcLY~9Dx&VAp1%-kCN`PohJ^XfeRrc5Z{Te4)=Wa1P}nOQ>Fz&=OVV3qdq^oW`$|i}S8a}G?(O*4^;NdZO-#VywCO8uIjz`= zHTTt?D-8T$z6QsH)~V(F6Wb?wl%j7{@dG^ zxUAUPEuG`gOim`_)&1v#Bi__LKCtA{b-#SQH4Rm7=YCMu_-tj*@=G8->x6*M`&Eg) z_a?u(_pJBz49+h1!l!rBANUus&3$2JDkc~2&L_I@LTTql(d?aP9|zh_z1BbT*Y9I) znYR}PUHH*^^6wmZ)?JEiPWnOrUO#8(tl})ZF_ZNoH(RHv%r&m9k50YH-x_td+?kz! zjf5z#@#z5LM4O4ev!|Qxm}($(-FWxz10JvS0>ANFJvuev=Yze^|B0M->9UuXI&$7R=Je&VTnuGrj~{pzVRul)P^dC^t9_WlxahWC}m$3NORc*?GE zcS$~TMrhWy{L6Ma(giz~&wJPE7L?FCaVszDuYLP`omsd}_ay#&dVZ-!*?Ds}7fWaF zMT;blZz=!%$FpF&x8}^O?ybk%Wm|jJu4v4Veei05Sw#F+)5~W&r&P~<$j7$qf2bo4wJo%>|{@ZoG+?<5{Yolc@r~UK!d2;o7 z&De^{a9_`^GnITxBDXKoah$QW;dra~Byj`F>AW+8(-uWq+D|`zzh&Qr72LwVo0b(P z39o27^}6w2+qBL#PHsKMI^9m+JJgS6if)?b(#x;jm$k|Jt3im}a`RQ9T4x?x-Ie@3 z>9qHjvOnVP5iO>!8BQ^Jz8_Y9u`Hh9wM4_m{;Wdu_O9(N``&2H6Tj^cpWA0`87o(s zE_z|_ag9fwm%nYF@#wy|>CC%kpPKWI*Z!Vj;2wGSt%^bLQuh<);_X}hXC^q$?37=? z#(L%a>ZunG{hBQxGHEi)e14a;pBNuKtZI{qx|8lw{d1|3?j2zt;W_t{Io#H&y4M6o zMgIO#@$XI1kqnili!e0>mD&}{->QeGv4)?|Hq9p|GwUT zK+)>Pwbz`}=M|o`T4}kR`SYdKI~Q1*sPJ?37H!}EV9zO+k_5k2+ed*S5!d6t)lRuQ z%5Z#$*bv$-kiN&7A9v#(7`)Xjf$uTqHPnId~PVyXh_~{}~@?Z&c~BUw6KxE&kZ)HEMA|61&V)CGxAPT6gTxVNmqncMw$nKg5jplz6v`9a2e ztD`ClHQTpd-)=*jYN@TR?!@e` zAvy|Yy%%*YJa+xmMmgKsLdL!y8@<`eo>&~;d4liewP3c8zdDJJ_ID|)Qjqgpdz$CH z_5D{p%&XbwcVu>)GJbK#;Nv-!Bir^~T>N{Iq>`jl+ZwyTY7U;tAE)iqS2YE)&e*-g zH^+Ob{&W+bzb`puy&4jIJ+G#9v07g{CKIvouw&@?=9w#<-}I;y1oW$2FV}NC`Neu_ zP)fm*1lHwGzkX@0+BkjjiETx1QZH$8MsBPWP|J>aoI82f=L5#e;@+RG`}tf``r6Xp znKh>-oZa^2ah1g+$CCvjML(X;wy!iav@H0yHecx``w6cLA1A1A$fi4;@85Lb@SIOA z^`%K`&fom@m32|5CA0aB@V(V7%J;rrEjhO0!SOB9={Ld*d1p`CT0W8EPcFkc<|SEv zl^2~ty2GMOzdRIM$$am_lP!vIvRa@29kt%z+f$l1FGjAo)Gk=lF1o4Mxo4^M0>|%0 z!S3R0U)Ik}X;@e@zcsgg&j-C1H*)VZ&foB%@p@)+nM+((pUU?BsptB)POrW2{&VS4 zrT0%-qE$s^FlU*mTbK&)UK5Vz{?obfVlVsCD`B$_%xbbo{i1Ow`5U*h^GRjK^`{w6 zzO-Jwh}Gp=-|RBK%jpv;Zl;GxEwQN=ePndg>5fEBM(DlC&G{c)L@4fZf^Ik}O@8Z7We4+OAf#cV9A8<@({7|NtJ>}DBMbrJWHM~6QZ{7N0 z?tDy7_~|PC=y^BIKOK8L$J27v--KuFhLfUwR-WuC6JD|)PhR%YDGRAKz133|md|f? za<%#!T-D+CGpzK;V=>VRf7u5oKTUO>matx;_M!)S#3RND3@Xf$XDw7uSLPk}bJIQc zbXiDfM@P=8C+|0=Tw3EK`7NgL05{76L#MVYs`~6}3;b=wAF^``xU@Q5`S>vKVsp1g zuc6|-d46*y*i3Sc*~Pb{@qe27;azMys;=wV>(zXBS$4U`$oz80#iH}o*Pf{!JZhcw z?R=BRhI4LrE~>s-?a2DBOWRZUjQ8e)51YB}^-FHE}B>}kgP{Fk!e&i=&A*Gw(X+;3lK^zq)k ztd+;^9p|RSYRe*@*x!#A4gA+smbCNNstNUfKJJ$8&+1Wjn_!pzpz`Eq(M=0kTK*TQ zD{OOEmLPU4fJw#iyyI*By4R0I{yl$R^FNMjkHM}V4jRe7vZd^bR!Pdc{W(?CUZB9% z+gH~sf5U29#&rJvl{Je$HEtElxpknS|Kl~y@AWTD&glKz?x(rby_4biuE`P&d2^M* zQ$N1vljQrY!fWW{u}*{0SkaMb{yT;}({*4i{r-eUm2H=kc>g}(-^JMI`&;Ktl;xAS zHHoX|?VGYU+#>UL(#ky9je2VY<}*C>IknDM^2U-mM|SK#bgkkXlk4jR9y9t9KXZuf z|8o1v_hqZD&RoIfpDlN+@3VmKQp2>Y_8F4}S9-aAcp{6i(Wn> zPV;H#{7X6Kp7G@NDDyqL`=#!_)wPS$Zuflme!Hj4{2AxDxSx{>BMw)+-@W_xwReSQ zuAAiCPS~&W!l{{WiAq0%hS#Z_HLH##ILJl{uT~3PV9d|vdhgAv`xA0AyUo|XDGTE6 zF`d0>a;j#2_Fc=VjOWj{Jl?^IyrbYiXC~g%|QBtqqR-WwF^$)~;yMdFbaE|1W0s;`6V5?kP<-OW5`D zr0%Qz1|L~IrxuoU9X_Np{qwh)S<|=jl>Jb8)S&oI&UM|tCC@EbdH?=B5p3~;f4Qs0 zyw(ZtwKllzy&}pSdL?Fc8n@D?w8n`6%qC01es>>t|M+LW ztci~~p3i?`_&xQ~1;^P(YbHm|=X;zU-1PU3*38|0YyKS8-)GC~;4QeIbKTjnUsEsb z-ytj99K84HL9JOdW>TyMtBFq0q6@jQpKsv~IUtew&sB>Umirp@*J|?fZU}S5yD} zw7IWr`#Gybc2D6`j-9`#r|3unt8xT`33 zdi`CO-{rUBxMS~|?(^2;DPMWckAG95rkeTZ$j!>1Z%A&LU%mFklFfL8y#zwg8sCaNBpYR2g6vmy(jvty$)0E9Sg3`9D3j1FTXCf$$O9YO7nf)2b1gT%pndsaN|5TRn&}_@KkZt2UbnM% z`Tmz?+j)&I8@=1w)-b6c;9qIjQ}dJCb~6NgEl=BW-NQXM~J&ncN@b34UI=Vu>A8WnhcH&l?`jTZ6x?~qFFS>NAY}@g| zOJP5+dqw-4`Oq&X%=Z5}@7L1xB^i&S?tYtp;j-_8N7uUCubIDS;=Q;2-ocr>*k!bB zt}k32qI@=ZVMXR{wVk19xo23PFz*oL`O133C!?WWHsr&x;%4PZKex-@nH3P^Z;`ZO z;eqh~o2_?ws${YpnI+#3tJ9u-sAF9{t#)&+-_dGa@%Scp=A%t+kqna81H3Dq@ve9fBKR+_uYc1-cQS>^S!^i;+D={VTP~VzUl5#OGMAA*J!3Vu-G1POw1|x zd1Pzb*N@tMhwbJaa0?3h_HgrIi(4N!Og#1;XjEp}|Fv=62EUufZ!hNEmv^^4nZYM- zrcj%iEcbf-jTiqWAK{%ogRw6t>gD70;lDqh`n)U6t-HdxExz{EQL`;6opyci(lrD( z-uf%(#nv~UXUh%yJ*xy5pUV|>ScQe!zqX5R61>nkJGI5ivv1+^yj2B>>CfNsiKgqt zaztw^E55Pv_JVT_MpZliylFSExIBGMzOwT5G{3ptmRq%EtkwOnp!iKbi@N^C-IWC= zPJc3=|L@l7s&bU-L~uJLX>VBob2eN6z!5)uN@ohOCrkJv~*_&m}za1(4*C6Nf*`Dd$#g%`y+ue7xUOC5@^}0>Txg9OSk*~uU zIXgs_|C?O@?#4UA#O-w#b9WTX{8^m2ZBC6?B6%u*Ajr7w%gN_>9# z?e-P5B8Sr1nT=v;>1Ski85z%2F}^D6DDD-p{gC#Atd+Jm)_Zj5%+HnUQvG9OV6`GX zYgLl=-o=dW8S(yo0u<>z!kpse^l_Q zC8b3#H0oc6PBn>6Pbh0Y7|u0q(OE@ZF8i=0QCyl8wh4S+AC=Y|E#~l;^5^QR=;r#l zAOEwRb>94O^Qo*p1IwaEIcHajJ7;SxpVr-e{@?MOKhmZJPd=V~&v8vj@1O49Nm>qP z63s6cO}VjQs*^O^PT#M2vHR{@Y}I#LBi?sNPxiF(gQcNKf_5pFz8#P%7S-ExD9L2; zbeoAMpKNGl437L*$QI-szvPvZOLk_!V;(V=3FjU5Ui;~yPm3v6xMt;^EI>aTw%Gqq1Fz*1g0euIm- zcCU);@-XgyR?04uxjYvA{rzU;AKB}_IIDZtY&On(wNlq!TKBj3t*;KhwN;}o_Om|w zx83heHPb)2pUO`kMe+w6`E-3{X4E&Kt<}ND`VTK$8euNZvBp$Ic$MGh_fNkcxS+fF zfN`_bru+4umnUg&Jhdh3cHa6oQ?DEd4!IilM)QKzx$wC&d3(dfmNeX%8KWlS-`M|i zYmJ7+=fg8>kN^6hmG0!qwe-`Si2Rpl>UFH1ggraDX@BeNnf9ljuP>Yw|J*}=oAln< zb8M2fhD;R{u~9qX=Av`h(Y3uWYU`^Bm#>$_F}np_+P}-h)bpF>;yu;nTk;pmoImn; zUd8jL(XKbOu3H)|44B8b6(R7dlt@gZwCR1BlOZ06{{U9?TZpk_%}{d=qGZy8+s=eVCf9Xw%%j(^zc z%tvL>jguLgyF50t736NwW@3w(l9%~$xpAkoMB;(p3rmu>Uy=B&c>YoCiz+X-A9=Ft zK9{t09}z#5Uz)yF=+ZoerKdca9Bm%RUyhl2{>np_h;IU3EJw_5Z8O%kte-!9(fL}r z4F5Z?u1Ox}J(eW6;H_h1$iho041ZoulWBB3^vdXgq%B|_<7@3 zzVm8x=3Q^*;=25Et?+A2Rn>Lt&nH$?a|TA0tPV|DAopR1htY$_&z3Y?7JSEe_T$n? zH&~XiB%E7ZY{L<|wRvvV8Oyt=U51aMw%ffG6r9b>`f5$d$CkH;l1oD#N6b57x^>>N zWxo~X*q+losH54dKF8~D&7RpkCEx$u{4UGC<0bEkCB|uDw>t0jwfS&XhzH4KrBv5{ zo_kOENNBo3Yv+m}4*F1xBw>8#YY|p#JRk<_#`G(m%28y;`Z{OTGx^l(K<&!-^ zCdp+anAWX(xIyiU>&*L2E^GllH}?Jh@Beb~rv(!pmzjGdDJAEB-mHA($j_SlVLT2m zcb~JWekXeB(DrXnnpQ6e6Z&Z-UA^#aYmCaNwht==PpV$roE~v7P;t5$*Vn=vVg75z zA0#YaujyUOYT&&x^XcTRGu|hZKN8w2DEt5Mvce-Pf7Pnm{(5t(NiRwCr2dw_CGT_I znpK_7W?uW7;Z|d6gY(C%&qCX)S6}+R_Ed82p_=7MHyuO&%qg9q^ToaG>OV)uYmSAt zMKr3<)O}c&dW3P;Pk|SYx5-DpiN4Eu(UGye_;T3lBUO1B@67i*-!v3{Z>m+u{3hp5 zB8Qfh)-o-bP-eZI@qU?k7ZN2nzR&Ex-5d93PPWBrN%8)Q^o@!K=Nfu0`F;5J?2t9j zGSZqqw$`UeR7Y-pE%Z?2a!A>J`6<(Uk48PyzGl9naF=t!h076(Wv9xQ35%C*jUy8k;$n?ww_xU&Qe~zC5sC&a3cx^;p&CSDsFhH#;WwyfTg{tmmPY z(gK#|y&VtAg~FRy=B?b#qW)Y+R-RS=AD7mq*@Ze6W%lfOA+>RSC~FM|yP_+vgxVSR z*<#K!eJ&~<(|wREIG@$l_v8t))wBL-^WRPo3}Gt05~jR$dtt-m^NO;CZ&p8_xk)v* zblu{xg4k`}!ajaf(!aKs?}~j%ruvMJD%Yn^+Fj|nI4)mWKl$r?ku=LW;eWk1F8#d3 z#&C~VZb|8^X*<>)b!Rab_xi!-kQ2EPi``? ze0YA~i^RD^(Mh|GuDP7DUiQSSo`)XyC-PqM{UR&z>bkC{g20+t_h)jfTyT3$=G23^ z9j~-FvVvF+Snf#Q^g8u}+vWl*DV7eb{kk!KIRkuMe&N zW7n&4<9g>Mf1y$>v-HkQVuzFtnl%QRnMqEm{J7R&fw9RGJrdte&%dh<{oi?Ld;kygV#2F9#(swX0Ffa)*9p&*gxU6{O)xS8$zitW> zSO4jG;`t}l@%QUFw%sf{Cq?{UoA-8dd#SkC?`rp3YjbYQ`?rKIJK90%gYQifmwvU9 zXD|Hr#BiUQ!6x#S=gN-fMnCv1k25mN5IwrsVyS6l)0VPn|I8&+^eZHOIP<7X{&V&3 z&zKEoTAoRrQeYBT!1&O;VaLX&^~<|TCY$~D{T6Wa-+JAXj5D^W|JeA6n`!M=N9_ZP zr&{tZU$>@W#_c!L_M};#o!{&~QujH!z>tZ%!QP~%<|yC6=KHdL5?5E3FBABXBK0)%qR92N z5^trrm#tCaIvN=)t*O0l(St75uexI0rD^NmT3gMLG1xg%c&>_`5z~#sRUNsaP4oGU zQ*RzRq`cU-%e}}@cl#R&_i4Y2UUdDnj`^0Vb7B4N06X`)^`5D7`W{#5?%f`AIq}y; zufH`<*3a*eI`UxMjg87LKL0a!wsa5utT}0e^V~^7-$P&3XV>1iz2{}P_xiof=O(_< zm!96{#rHbn{Cb9le4#Q`r#+2^Jq)Loba^w+mK2GcT^;;yMNTHW=T+W&3wTc!nculG z^_;@PqPYPsk3;R}eQ-Q{s>DENLhi<^J0c7vQ={JeT4!A&R>m>+^$kvGD~0-~vW|!C ztn;(oKJJ@wn`wsbgv)QkBD#LFgzhPPvuEO$hb$}pYtA}RF3joZyy>Ds#%o>oTbF8U zRW_G)gm=g;u6h2N)*swf3C0I(5qlu7ZP0i5&$i&^)&Rkiw=>j!dOXay5$SzX zc!lw|1)66REF*2Rd+xZ!O*%faGvnRI^_6d4a2Ywey506t7kH+?_(mY(ri`=r1zvND z(_d}wo}X!87bIe=JXy)5VH5W(`41OaCHI6lr5$b36BmzLx$xJn(inB8O0HcFWfv9q zwx`yFe|G=-Ubt_~>?exPmK}d=$0Rr@xS}=UaY}p6@6B?GR&Nh{7x=%zZNsPByYXuy z;y#Dzd=+-T`cp)Pqpl=Zs9JVQPwnO(2i`~775f>!Yl6qCF9zug7- z?E7a=QCB}Sd*?g1Ir=Oy_PZoaSMIf((vy_ZcBKet&mv)uVgnmR#Sq?NfTdT>1Wp+l-x_r$oX| zDZj0$*tLL1vw%C)erm*9m&TQgUQXai5S+N<&@PF^Z*q!$-ah!tOLybpJl`r2md6f8 zYht@zKA-rsb;-m;_DM(k=4b0pm-$f{6%`$lab>Er;Q?L7{WmoKUy(a@HRsXVaBImK z`#m3C6-!xIDLemXk>0WA?LHNP$}TyqVOpsz_QH1Z%@OCGSjyk|#C2@8jOMiS>&p!~ zE#4pQ)czdY9C)4Cg+E28_TX;in@OIl4*r++_OdO1#=dP)@jMx^=K(nl9b!8~bA;ci zBrlH&`aCBfpY^ojlygR{0TaS)CIlSiW9ggvKqObltAoMs_@zhNzl5F=-nDJMbd{fg z-ktxILG13AnCDfpU1UGA)~@bd>J#%7yPdg8SJd#k>{NeTt1)-+MxA*g1&*ix-As~}lGLLVJE zJmsV5!iuM_4(5lK2L(??>g5AzyDagd%f`8eyvoE zW9vBAU)?L)-ozDrS*=}a|L@Ho`eJ1jSGe4eW(qhgWwxbOYJ>jt&3kM_WW;|j&WN)q z;Qe}2gU^0b*^#4cKTLVJ98Nx|2oLGlduUU|b1Lt78<#5n z@;mAAop)NP`=3WI|Cayz{NK0ANODTS+$OvF%Slti&wH?DTzed`Aa}z%xf?gX`OliX zGIaArnQ5DLN=|LJ(Cj&;{Kv{s|3K#H)4J6k*OqX4-Z$8$YIEJ|_pg>+;m7xfsN8@5 zKl$C>x$n7a?>$oBXGyU7u9NCBvq#Z+>Kn@?zZQw@$d#FzvGvX6+NX!A#Uq@~?s8jN zlH}L6`p;%x>6P(44xA6>NUjVz*j^_0+hUK>lDy)7qFxi~n@au^>u=j#c2lNy{m%w= z_u4y;ubYKuJeqQUO=_V^s*Y*VwbkqI@7j1Q_UKQ)7j5e~>jcjGe$na-OfjFaVD^%= z1qZ^ppY8b^JK^;*tyK9!tFSrdY7hRrsmXZ$Iy;Z~fgxjE;pMM= zItq*WCUhkn&gnnlu=L;5-MyTLX5L?Z%Q@jeHk18rfhCikn9o7=}qo8u}Fx@my{fp8HcXsQWXVu8Q6gBE} zsbqXKLm;m6&$46rGX=9-y_z1aO6jW*ExYog?Om8-Mn z?~|(K+$^0NwPh4uaG0*hiBSGg>AuwZiI70bR<2o3!X9p7>ps}87UZE|HkYBU?j%b< zsN^Ot{WMQ`JG(PN|GH-BNZx!hzh_2J8i!tDfxFO!vL|oaXP>|9oYFOikA10=ByY#W z;<*f!(-!F$+nDTlr6GCPtiZv-_PF;U)hRz_R5G1CP@`S3uj#8m^_)ZdqfP%Gh?WyE zz2&n^Na%5(puhLcn5GVex2fz8zaIN_VCA`>*$(oHrJIH)HBrjt?t~TTUH*eE6)%`3o$GcV=$+XO)r7!PfX{=?{kTTVVxT^&*_>&#-PR z*4El|UwEf-+5VMR^%*b9oUkz}@1HHa!?AhpzIFW5zusQ`(Z97X)=2>~GwJn~|H3Hp~{(h=}GrrIN9)J?!EJE&k_vtyY&E5;8w& zl%JWATrYcJYn?uKOJ=cr>)nIb_g)oV#qs4E;|m!clLue_9_P!-HB+!TRWmK*{j#mD zaRIDba|}0qNohB9F#6Uk#C_iX&mWenXVsn--Cnw7Y3wA!u=ywc)ugSx+i29hR)3E+ zU;W0uNfj>poOPt$Z0I|~(B7Duzt~Id$Zyw2k1H>gpIc#Mc&~3&xlo~!?)FdCYI5^a zuHEIlwZVJQzK62c-+J#jaCu&YS>A_!w;iDpkp>cMZ)X{sB_}X{PIi5vYQxAj>C;i^ zN{dMg0(`_dmh4=eTPvsbY5{X**>~TvX*>CL3rIgZQZ9Qos%PHn7}mhD@tWHyeW0GG7nwS6==nGa7vr~{)OvyZfgBhEtguiRrmKqDa~u~_Zae( z)hmTJ@~>-g=CfbU{VFXWx_H;oCAs}qzWmdgecWc*j^E#oi@B}s;|t%x{(9Mqu-wJJ zM7>ro%9(lN;q8X72zBq9XCtgX>KPYY>fw~DIqz4!+}dfgs8ZI?twH^2A2-!YDU@YS zpPa_@w*RQOg!%^U=l?iYXuj&4mRTkDJouuKQEO-6pGCGgC-R@PvaVXSr*;3{lvXo6 z&BnH*qB-Z5TrQaZW^LjL;Rhby#V%C$+j4hi2;Z}wxm81Hhv|#SZflckWgjiQ^k|M# z*8%r)x0e+i->boRb-PZkkZ)c1Rc+IXb+h-dJ1(luQ>}Xcz$g0O)4fSMt{>*r?!79= zQQdY)o3&at8 znSJ|vg(~WoJv_3d;zd-C*Q!%?*{@!$Q(dY*bKm>9kLR)nr`$horNO-4{m5sZYwIUP zl&zh2XP0L1r|B_ns!Mp=v}|LRrIy~&JQ>3yboX9izsmie?p}@Z>L<3yHQ&_VBl2T| zx&NHw_D8#OY7+A9e0q6q`t0e)f|kulKmF&+IhPH(dXIB>zTNB9UX%Zmdw#&I6cg8* zli5T%qLNq3{|H>H98mu6o!n;TyJ8%6cU&fk9s6|f&D*nbrW2(MS8em=l}j?PzbYA@ zs$KIc^|9^A7u!9nqu29HbcojYsj@{{@r7Yx@@)RC^|@|;>vWI5%k0|z(BCEQ!glUw z=}KvH>(vAIKKy!2L&SByY0XW=SCR7aNoO<93#agXO_t(R@7&gUlkI!;&9q&|6J(R; z|Gq9|oj$|PZ`*sfM-vQrY}ShFB#0@i*e&|Xvt#qwnne}=YmRsZsCihv`uW@H=!d4K zx9#VIne}v>UvIx6V_St^U+vrf=|3jzy6EQcVafMjCXM28FHd~5hpS0osj$1e#zqnIMq z9CG^onp~TX_FL)<^KLGU_!zHwaGPTL+FB{i6I+vt7v19ZRk*&tugOKRYi+sC{LG2B zc1)ibdn|v+wY5vnEjV}T%GSyqJlnUwiCZ1In`Qcan{Pg4N+;)s`W>9GEpqQ#N%7}Z z^Q_Li8 zSIet<7c3}!lzGY{)~fNLyU*nPXRYdfpWiB7J?Z6EwJy;k8h?||KD@1x@~EQc&V;&4 zbNGuZuf?jqTL0yvwM_c5O=th*F>!vFw)MlIgS|oO^5H3`*Tk;7IxWtx=6CF)9CPKq zsNPk9>o+z>?qkqdb7F_=jJ>PxzgK-)7a-}_!<%f&dhXn;KQDgYxD#SH`_~4KO6KPZ z;i^m8nEr3My;tvtw?IVKWGrlPKvMx3gFWa;1zxwToj5WQ_&I<}(++!Gj!S%@O*1Wai`fWkc`ZhKz znxj_grTjVKyy|}Nu3a%4o?>xyDxk|_rl&|Z*z3be1*Et3JJJaRHn{T6J#z*)ATKO*tS|WV@|*^*RAan9~@Ouzx417 zXRQ5m-z?Ol(^-<1 zJ_&3&c}!bIMaQ^D?cm?fTWog6eEW0a_s94pMj43>K}*d#Rkz)F8(!=@`+viiHP>&c zcs`Sxp*VY`ZfdXbg1(f1gI4=IN;a%{`0hqTl|lQ>8B-(<{fZ2UJY#*$Kp_89(L=qg zy3ghFk8|8n3eButvZ{Pf$62=5#lO{lywB9ok=hIbOWC?bX~D zCWp3{{WMzmciy|RGO8Aw)>cc_M05T;dRV|ga?kTk70c~K8bnuk@fMXwH54eWTj%xU zNo?hF;nW3cf2{i^ZgqW<>+hY@8Nb7sE#|}O@+ARF4-|gM5T7CVVRI^ln8fYfe!GSK@VyN3Nx$mCx1dil;CP+y z+a=m&k#;|7i>9=!z1g(c{p9@w-4%b&EINA2twsD6gI{6T1+Mctb(&U_c2wMRu_*{%tz^*I#v&$UkynfidQ zQggzu^Goz)u1vJM9I#yF#;Qy2xA2$0>S_)DWgZe45c2x)F5~3*ZvLQj^QQCjTs|Al zocDW0P(kiN^|co_$d+4~=X}?<{TX#6)@1wr%isTAJH2j8yCL(F$C?#WN>-)h$GvzW zS>wWxvFWJTDa&%x?OcCPIi;EzYhAjL#Ay}r8S%de^bc;-eMntQf8?6h0?Yr(wmnD2A^tai@tkMo-sW~m#aaQLd&&MTdQ;oBM* zPBdQoRGxmW-7qb#@AKLK6~83b%hy(Cxh5|9lXdQxW{TlLcIH%@Z1$Qxx+M>aiob+- zzcAvxxMu29uS}*p|CSs}&_15Up6jm=;N!cY<-c5#e`}M$r>gxonxi`GGyQ#J(hM|x zpQv`<-!a?#MOx*(_!XrGzPv2+Xenz>ZuxeVljoqWlZS@6!-KHERWsWJtEFcxy|tma zUU$b&m#43)7A{-m;M6ozJmd8%0o|s>(>mgnH!Kl~bFK=F>f3V>> zjew)YFB0yUE{@~MJGVmWc-1~B>9yM-5Zh3z{Zhv@slh$;e;3ATHcIUMQ%GX;Go{?@Hssz?SuU_7Yf-7bcdE$_qkY&H9E zXsX<^kEfF7vTysRvbbTv`I+3`u6N4Z6OEExu5V)dCxheU?>`Z(@l)p=nP&AvxqIqa zzq4_|d(Zz1ky<*(q(6V@`^7AFtv2U)#`%7E2dA$DV;N|qB$j;`_;Q$@!#Tw|C(QQ^qX4z?J=*sn=<1Oi`ak3Rfk?bTyReL zz{l8zoaY@YHhr<3c24!?zlC!yJ=6LVAsN_fC8x>G__+V?|DUUbh1RTI_x)Uj!S&9K z%iryg$cTTQ|LI`aAjlQZu(1(NWt!wM@xam{rVwNDfB?v?$2(>=re*@Is8<1CjQLt}p)dmZ0yt+4m@v2vvu zW;c#6I~Dfg$>gtr1@7$crN0%G5OhA+l8}x_5~;(W%x8RHfnKse|eO&@-O8b zs_t7fn7ug}#iX^4eOz5QamQKi2S+bjJovACIQR0i>4%eSG()d`kln0#;kZy*gYw?B zZ>F#&Zr?dCE~sT2|9#aLM~hGxw6)=4fpokdH*nA;)UiZ`cowDcJ5-0 z+cC|c`*3mBiI%r!lDm)H{oeDy`tIek&$spbk;EQsdI46 zHJ-h*PVSv>OU6G(oBM(-cSCfT1SiLt?R$<^CYo6XrFlKUdtFlJ2M=z1b;RJmm~a zKF9m(b#bB`_ZD-$n|Dru$*iJK&G}73;F`wYPo8Wpc!(iyZ_l+OzxTB6ZVy~;CuHVQdgz1v{fUW_6*#`1 z?9NQ}{p&ix;j@lad%W4}8yUiHzKgx73YfHO()va{{eHKoFT4JTzTrG8ziPJQqsEzu zeXq83`D{12kdil{{&M>*3y$~SZcDAKkMxY2mAGf>(m(TKw||?&bIr5kThlLJW~bS# zH9{{LSep{JYNna+9^(?#P}ULIb3sH~Na?f=FpaPW%V#iRcct;JqGc#wWPv2JneGUZJIch=q5{_i0BGPZX= zXD&P;puO{^VOUSX(p3{;Q`T?W)hIM0X;bjM^V|a8Zt(;}pFG-?to#l9;^k03;Q)}YoQ#+f@RtT$1nY*Gw>bF*2;HnQ(mtNhzwrGoN*}q`FjhD9Bvh1xW zpVE9`e+S1cneFUNv-UD1bw?@nFG2iE$>SFDZ>{&(Z6nRJEFVdcG@sSj>{ zn57Wgy*8*PQQbz{T4cX>cE{;Y`?k$#oar;~=&hIA>eYgJ->n}y_zKfOA zw*2ooJ3+@Xy=&6#3#s$&+r-P>^8EN=@qxKjoU8lGPF&1uo8fX@zddKBzlxf+```XA zwWYJx>wNaCP0@Im887r%!Ilscl_6 zXL-4^TiuIa2OeK)%%8XUori0Q^7&Mikiv?!`;Q3duVmt}+ZKIlW1i$ZXX8_g-``vQ z?rK=?=`vs4$ovlzZ?!EuH0MJ2y}bML`q&xIObkmioXW(YKUvk%N#Cg1e+}=%tNvCA z(U%>Ut*Dzg!}<2#n!;C8HU6#Kw;*K>WAtp_C)-zN82o$aHl;T}roCaGk4dUi1k=U? zGroPjEa&>Uo^gA(PiTT%b3)t^URP()$$t(XDA^%bo3K!A@BI@W*D~iBbwxbMyAt%< zYo?3KCw-Nr#}CiH|AfouQSRei*(XlRzLqeb^i<*K9fPb1cWMqRika_Qd-0P{CGWG| z%7pTj=`LlnYB^-NEE|@$2(blgF@<&Cf4AJ!E#Tn~-R#Q~r=GhT#XPmstzLbJ-n1<% z8Cf4(xc1pj@s*Q?k;|0nsV|NebUj?slj$~HyX^TrYlYJy$=^TSaoJgGWyu=0u<>U~ z=D{aZI7`aRn##iK#P)98(VuU3*`z%{BBqO<`K?B3>A$!WOLGs+Ww1V3o3-hCOZrZW zi$2b`;yGG*L_{_V#j_jsbp3weC+O%^^nuUj6vt8XN0~gfWj+}iv5D_FR@(c8yzD*t z(o-?`>Tdh&Xnl?a)283zU3dIz0ONXNS-w9RPsM)q+`js7U8iM2UGCK88*W=RoKu)I z!AX2U*ZQAR1GFYDJ~(Z%~b|NXc8r`d!})m5y|qO)8KmWf?hoHbdd z`pf+7UwV8rcXx@-lGt@Fq|JM);a9=OXEyhqtn`nmpR()c$2&#mW_fnT+Xu=iUF&{U z7XFyMT*v*tO3G>0?i*?U^=t}fzfEgC$6^?Is;{u9_nM%V>>7jFI;S?sJ<)&n-#|a? z-@H%Xy04{F9{PVp#fj^F&AnS8#}e*MVYIr@6X7AMRaYxhoA=r1`~Fg4wJpm+5_oUd z>!*5mwLI&O4;71x-JE7+#j5HjTYG4dX0+GN#rEo*+GX$Oa;<83q3!Q&v}?--3#G+h z%(|m{_tZYJJ5Z;C-@d-akr-C^B87XmZC%Kdl}k>wrYbxZ`0X#hLyxO{QCiNi_?yJFjgoYRr+}S$ZSRVy|M2myWvffy#=vY~@N9 zf1Q1NW~-1{$M&lhk9~FhO*C?X-Sh<0-m0z1bf5pCN+@07im%cIec!?oi?0Xsej9&? zzRwr@YVIx1z@lHPXS*I+ey+L6@$lPaLb|GJ8d=P?dArYy?h{yfc=pkii$8tSJ->L3 zzf7-Y?yJcPPwX$s2+sS+Q_CO`bm`HJ-uFL!w}&(**{(FYAGv8hn}TxUGoj%6JD=yx zPnn{_Ti2nLeI_I+JV=*CMly~|G~;*v`-KgCzWpw?Zbz9;38b;`@G!gy{}p0AU67IQ zQ{jSna